You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by zh...@apache.org on 2019/01/16 12:52:53 UTC
[hbase] branch master updated: HBASE-21732 Should call toUpperCase
before using Enum.valueOf in some methods for ColumnFamilyDescriptor
This is an automated email from the ASF dual-hosted git repository.
zhangduo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hbase.git
The following commit(s) were added to refs/heads/master by this push:
new 348cbf6 HBASE-21732 Should call toUpperCase before using Enum.valueOf in some methods for ColumnFamilyDescriptor
348cbf6 is described below
commit 348cbf63ec793317420d9996a53b6356c7f11aef
Author: Duo Zhang <zh...@apache.org>
AuthorDate: Wed Jan 16 18:38:58 2019 +0800
HBASE-21732 Should call toUpperCase before using Enum.valueOf in some methods for ColumnFamilyDescriptor
Signed-off-by: Zheng Hu <op...@gmail.com>
---
.../client/ColumnFamilyDescriptorBuilder.java | 30 +++---
.../TestColumnFamilyDescriptorLowerCaseEnum.java | 104 +++++++++++++++++++++
2 files changed, 119 insertions(+), 15 deletions(-)
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ColumnFamilyDescriptorBuilder.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ColumnFamilyDescriptorBuilder.java
index d7feea6..da7bdda 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ColumnFamilyDescriptorBuilder.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ColumnFamilyDescriptorBuilder.java
@@ -17,7 +17,6 @@
*/
package org.apache.hadoop.hbase.client;
-import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
@@ -25,21 +24,23 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
-
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.KeepDeletedCells;
import org.apache.hadoop.hbase.MemoryCompactionPolicy;
-import org.apache.yetus.audience.InterfaceAudience;
import org.apache.hadoop.hbase.exceptions.DeserializationException;
import org.apache.hadoop.hbase.exceptions.HBaseException;
import org.apache.hadoop.hbase.io.compress.Compression;
import org.apache.hadoop.hbase.io.encoding.DataBlockEncoding;
import org.apache.hadoop.hbase.regionserver.BloomType;
-import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
-import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ColumnFamilySchema;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.PrettyPrinter;
import org.apache.hadoop.hbase.util.PrettyPrinter.Unit;
+import org.apache.yetus.audience.InterfaceAudience;
+
+import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;
+
+import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
+import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ColumnFamilySchema;
/**
* @since 2.0.0
@@ -129,7 +130,6 @@ public class ColumnFamilyDescriptorBuilder {
private static final Bytes BLOOMFILTER_BYTES = new Bytes(Bytes.toBytes(BLOOMFILTER));
@InterfaceAudience.Private
public static final String REPLICATION_SCOPE = "REPLICATION_SCOPE";
- private static final Bytes REPLICATION_SCOPE_BYTES = new Bytes(Bytes.toBytes(REPLICATION_SCOPE));
@InterfaceAudience.Private
public static final String MAX_VERSIONS = HConstants.VERSIONS;
private static final Bytes MAX_VERSIONS_BYTES = new Bytes(Bytes.toBytes(MAX_VERSIONS));
@@ -778,8 +778,7 @@ public class ColumnFamilyDescriptorBuilder {
@Override
public Compression.Algorithm getCompressionType() {
return getStringOrDefault(COMPRESSION_BYTES,
- Compression.Algorithm::valueOf,
- DEFAULT_COMPRESSION);
+ n -> Compression.Algorithm.valueOf(n.toUpperCase()), DEFAULT_COMPRESSION);
}
/**
@@ -799,8 +798,7 @@ public class ColumnFamilyDescriptorBuilder {
@Override
public DataBlockEncoding getDataBlockEncoding() {
return getStringOrDefault(DATA_BLOCK_ENCODING_BYTES,
- DataBlockEncoding::valueOf,
- DataBlockEncoding.NONE);
+ n -> DataBlockEncoding.valueOf(n.toUpperCase()), DataBlockEncoding.NONE);
}
/**
@@ -833,8 +831,7 @@ public class ColumnFamilyDescriptorBuilder {
@Override
public Compression.Algorithm getCompactionCompressionType() {
return getStringOrDefault(COMPRESSION_COMPACT_BYTES,
- Compression.Algorithm::valueOf,
- getCompressionType());
+ n -> Compression.Algorithm.valueOf(n.toUpperCase()), getCompressionType());
}
/**
@@ -868,7 +865,8 @@ public class ColumnFamilyDescriptorBuilder {
@Override
public MemoryCompactionPolicy getInMemoryCompaction() {
- return getStringOrDefault(IN_MEMORY_COMPACTION_BYTES, MemoryCompactionPolicy::valueOf, null);
+ return getStringOrDefault(IN_MEMORY_COMPACTION_BYTES,
+ n -> MemoryCompactionPolicy.valueOf(n.toUpperCase()), null);
}
/**
@@ -962,7 +960,8 @@ public class ColumnFamilyDescriptorBuilder {
@Override
public BloomType getBloomFilterType() {
- return getStringOrDefault(BLOOMFILTER_BYTES, BloomType::valueOf, DEFAULT_BLOOMFILTER);
+ return getStringOrDefault(BLOOMFILTER_BYTES, n -> BloomType.valueOf(n.toUpperCase()),
+ DEFAULT_BLOOMFILTER);
}
public ModifyableColumnFamilyDescriptor setBloomFilterType(final BloomType bt) {
@@ -1302,7 +1301,8 @@ public class ColumnFamilyDescriptorBuilder {
@Override
public MobCompactPartitionPolicy getMobCompactPartitionPolicy() {
return getStringOrDefault(MOB_COMPACT_PARTITION_POLICY_BYTES,
- MobCompactPartitionPolicy::valueOf, DEFAULT_MOB_COMPACT_PARTITION_POLICY);
+ n -> MobCompactPartitionPolicy.valueOf(n.toUpperCase()),
+ DEFAULT_MOB_COMPACT_PARTITION_POLICY);
}
/**
diff --git a/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestColumnFamilyDescriptorLowerCaseEnum.java b/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestColumnFamilyDescriptorLowerCaseEnum.java
new file mode 100644
index 0000000..ac8aed8
--- /dev/null
+++ b/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestColumnFamilyDescriptorLowerCaseEnum.java
@@ -0,0 +1,104 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hbase.client;
+
+import static org.junit.Assert.assertEquals;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import org.apache.hadoop.hbase.HBaseClassTestRule;
+import org.apache.hadoop.hbase.testclassification.ClientTests;
+import org.apache.hadoop.hbase.testclassification.SmallTests;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Testcase for HBASE-21732. Make sure that all enum configurations can accept lower case value.
+ */
+@Category({ ClientTests.class, SmallTests.class })
+public class TestColumnFamilyDescriptorLowerCaseEnum {
+
+ @ClassRule
+ public static final HBaseClassTestRule CLASS_RULE =
+ HBaseClassTestRule.forClass(TestColumnFamilyDescriptorLowerCaseEnum.class);
+
+ private static final Logger LOG =
+ LoggerFactory.getLogger(TestColumnFamilyDescriptorLowerCaseEnum.class);
+
+ private Method getSetMethod(Method getMethod, Class<?> enumType) throws NoSuchMethodException {
+ String methodName = getMethod.getName().replaceFirst("get", "set");
+ return ColumnFamilyDescriptorBuilder.class.getMethod(methodName, enumType);
+ }
+
+ private Enum<?> getEnumValue(Class<?> enumType) {
+ for (Enum<?> enumConst : enumType.asSubclass(Enum.class).getEnumConstants()) {
+ if (!enumConst.name().equalsIgnoreCase("NONE") && !enumConst.name().equals("DEFAULT")) {
+ return enumConst;
+ }
+ }
+ throw new NoSuchElementException(enumType.getName());
+ }
+
+ private boolean contains(Collection<Enum<?>> enumConsts, String value) {
+ return enumConsts.stream().anyMatch(e -> e.name().equals(value));
+ }
+
+ @Test
+ public void test()
+ throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
+ Map<Method, Enum<?>> getMethod2Value = new HashMap<>();
+ ColumnFamilyDescriptorBuilder builder =
+ ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("test"));
+ for (Method method : ColumnFamilyDescriptor.class.getMethods()) {
+ if (method.getParameterCount() == 0 && method.getReturnType().isEnum()) {
+ LOG.info("Checking " + method);
+ Class<?> enumType = method.getReturnType();
+ Method setMethod = getSetMethod(method, enumType);
+ Enum<?> enumConst = getEnumValue(enumType);
+ LOG.info("Using " + setMethod + " to set the value to " + enumConst);
+ setMethod.invoke(builder, enumConst);
+ getMethod2Value.put(method, enumConst);
+ }
+ }
+ ColumnFamilyDescriptor desc = builder.build();
+ ColumnFamilyDescriptorBuilder builder2 =
+ ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("test2"));
+ desc.getValues().forEach((k, v) -> {
+ LOG.info(k.toString() + "=>" + v.toString());
+ String str = Bytes.toString(v.get(), v.getOffset(), v.getLength());
+ if (contains(getMethod2Value.values(), str)) {
+ LOG.info("Set to lower case " + str.toLowerCase());
+ builder2.setValue(k, new Bytes(Bytes.toBytes(str.toLowerCase())));
+ }
+ });
+
+ ColumnFamilyDescriptor desc2 = builder2.build();
+ for (Map.Entry<Method, Enum<?>> entry : getMethod2Value.entrySet()) {
+ assertEquals(entry.getKey() + " should return " + entry.getValue(), entry.getValue(),
+ entry.getKey().invoke(desc2));
+ }
+ }
+}