HBASE-25368 Filter out more invalid encoded name in isEncodedRegionNa… (#2868)
HBASE-25368 Filter out more invalid encoded name in isEncodedRegionName(byte[] regionName) Signed-off-by: Duo Zhang <zhangduo@apache.org>
This commit is contained in:
parent
a37e727990
commit
5c13c68494
|
@ -2388,51 +2388,56 @@ class RawAsyncHBaseAdmin implements AsyncAdmin {
|
|||
if (regionNameOrEncodedRegionName == null) {
|
||||
return failedFuture(new IllegalArgumentException("Passed region name can't be null"));
|
||||
}
|
||||
try {
|
||||
CompletableFuture<Optional<HRegionLocation>> future;
|
||||
if (RegionInfo.isEncodedRegionName(regionNameOrEncodedRegionName)) {
|
||||
String encodedName = Bytes.toString(regionNameOrEncodedRegionName);
|
||||
if (encodedName.length() < RegionInfo.MD5_HEX_LENGTH) {
|
||||
// old format encodedName, should be meta region
|
||||
future = connection.registry.getMetaRegionLocations()
|
||||
.thenApply(locs -> Stream.of(locs.getRegionLocations())
|
||||
.filter(loc -> loc.getRegion().getEncodedName().equals(encodedName)).findFirst());
|
||||
} else {
|
||||
future = ClientMetaTableAccessor.getRegionLocationWithEncodedName(metaTable,
|
||||
regionNameOrEncodedRegionName);
|
||||
}
|
||||
|
||||
CompletableFuture<Optional<HRegionLocation>> future;
|
||||
if (RegionInfo.isEncodedRegionName(regionNameOrEncodedRegionName)) {
|
||||
String encodedName = Bytes.toString(regionNameOrEncodedRegionName);
|
||||
if (encodedName.length() < RegionInfo.MD5_HEX_LENGTH) {
|
||||
// old format encodedName, should be meta region
|
||||
future = connection.registry.getMetaRegionLocations()
|
||||
.thenApply(locs -> Stream.of(locs.getRegionLocations())
|
||||
.filter(loc -> loc.getRegion().getEncodedName().equals(encodedName)).findFirst());
|
||||
} else {
|
||||
RegionInfo regionInfo =
|
||||
CatalogFamilyFormat.parseRegionInfoFromRegionName(regionNameOrEncodedRegionName);
|
||||
if (regionInfo.isMetaRegion()) {
|
||||
future = connection.registry.getMetaRegionLocations()
|
||||
.thenApply(locs -> Stream.of(locs.getRegionLocations())
|
||||
.filter(loc -> loc.getRegion().getReplicaId() == regionInfo.getReplicaId())
|
||||
.findFirst());
|
||||
} else {
|
||||
future =
|
||||
ClientMetaTableAccessor.getRegionLocation(metaTable, regionNameOrEncodedRegionName);
|
||||
}
|
||||
future = ClientMetaTableAccessor.getRegionLocationWithEncodedName(metaTable,
|
||||
regionNameOrEncodedRegionName);
|
||||
}
|
||||
} else {
|
||||
// Not all regionNameOrEncodedRegionName here is going to be a valid region name,
|
||||
// it needs to throw out IllegalArgumentException in case tableName is passed in.
|
||||
RegionInfo regionInfo;
|
||||
try {
|
||||
regionInfo = CatalogFamilyFormat.parseRegionInfoFromRegionName(
|
||||
regionNameOrEncodedRegionName);
|
||||
} catch (IOException ioe) {
|
||||
return failedFuture(new IllegalArgumentException(ioe.getMessage()));
|
||||
}
|
||||
|
||||
CompletableFuture<HRegionLocation> returnedFuture = new CompletableFuture<>();
|
||||
addListener(future, (location, err) -> {
|
||||
if (err != null) {
|
||||
returnedFuture.completeExceptionally(err);
|
||||
return;
|
||||
}
|
||||
if (!location.isPresent() || location.get().getRegion() == null) {
|
||||
returnedFuture.completeExceptionally(
|
||||
new UnknownRegionException("Invalid region name or encoded region name: " +
|
||||
Bytes.toStringBinary(regionNameOrEncodedRegionName)));
|
||||
} else {
|
||||
returnedFuture.complete(location.get());
|
||||
}
|
||||
});
|
||||
return returnedFuture;
|
||||
} catch (IOException e) {
|
||||
return failedFuture(e);
|
||||
if (regionInfo.isMetaRegion()) {
|
||||
future = connection.registry.getMetaRegionLocations()
|
||||
.thenApply(locs -> Stream.of(locs.getRegionLocations())
|
||||
.filter(loc -> loc.getRegion().getReplicaId() == regionInfo.getReplicaId())
|
||||
.findFirst());
|
||||
} else {
|
||||
future =
|
||||
ClientMetaTableAccessor.getRegionLocation(metaTable, regionNameOrEncodedRegionName);
|
||||
}
|
||||
}
|
||||
|
||||
CompletableFuture<HRegionLocation> returnedFuture = new CompletableFuture<>();
|
||||
addListener(future, (location, err) -> {
|
||||
if (err != null) {
|
||||
returnedFuture.completeExceptionally(err);
|
||||
return;
|
||||
}
|
||||
if (!location.isPresent() || location.get().getRegion() == null) {
|
||||
returnedFuture.completeExceptionally(
|
||||
new UnknownRegionException("Invalid region name or encoded region name: " +
|
||||
Bytes.toStringBinary(regionNameOrEncodedRegionName)));
|
||||
} else {
|
||||
returnedFuture.complete(location.get());
|
||||
}
|
||||
});
|
||||
return returnedFuture;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -363,7 +363,23 @@ public interface RegionInfo extends Comparable<RegionInfo> {
|
|||
@InterfaceAudience.Private // For use by internals only.
|
||||
public static boolean isEncodedRegionName(byte[] regionName) {
|
||||
// If not parseable as region name, presume encoded. TODO: add stringency; e.g. if hex.
|
||||
return parseRegionNameOrReturnNull(regionName) == null && regionName.length <= MD5_HEX_LENGTH;
|
||||
if (parseRegionNameOrReturnNull(regionName) == null) {
|
||||
if (regionName.length > MD5_HEX_LENGTH) {
|
||||
return false;
|
||||
} else if (regionName.length == MD5_HEX_LENGTH) {
|
||||
return true;
|
||||
} else {
|
||||
String encodedName = Bytes.toString(regionName);
|
||||
try {
|
||||
Integer.parseInt(encodedName);
|
||||
// If this is a valid integer, it could be hbase:meta's encoded region name.
|
||||
return true;
|
||||
} catch(NumberFormatException er) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.apache.hadoop.hbase.client;
|
|||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
|
@ -99,6 +100,24 @@ public class TestAdmin1 extends TestAdminBase {
|
|||
assertTrue(exception instanceof TableNotFoundException);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompactATableWithSuperLongTableName() throws Exception {
|
||||
TableName tableName = TableName.valueOf(name.getMethodName());
|
||||
TableDescriptor htd = TableDescriptorBuilder.newBuilder(tableName)
|
||||
.setColumnFamily(ColumnFamilyDescriptorBuilder.of("fam1")).build();
|
||||
try {
|
||||
ADMIN.createTable(htd);
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> ADMIN.majorCompactRegion(tableName.getName()));
|
||||
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> ADMIN.majorCompactRegion(Bytes.toBytes("abcd")));
|
||||
} finally {
|
||||
ADMIN.disableTable(tableName);
|
||||
ADMIN.deleteTable(tableName);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompactionTimestamps() throws Exception {
|
||||
TableName tableName = TableName.valueOf(name.getMethodName());
|
||||
|
|
|
@ -298,11 +298,9 @@ public class TestAdmin2 extends TestAdminBase {
|
|||
if (!regionInfo.isMetaRegion()) {
|
||||
if (regionInfo.getRegionNameAsString().contains(name)) {
|
||||
info = regionInfo;
|
||||
try {
|
||||
ADMIN.unassign(Bytes.toBytes("sample"), true);
|
||||
} catch (UnknownRegionException nsre) {
|
||||
// expected, ignore it
|
||||
}
|
||||
assertThrows(UnknownRegionException.class,
|
||||
() -> ADMIN.unassign(Bytes.toBytes(
|
||||
"test,,1358563771069.acc1ad1b7962564fc3a43e5907e8db33."), true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue