HBASE-21732 Should call toUpperCase before using Enum.valueOf in some methods for ColumnFamilyDescriptor
Signed-off-by: Zheng Hu <openinx@gmail.com>
This commit is contained in:
parent
51c58e083c
commit
348cbf63ec
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue