HBASE-25368 Filter out more invalid encoded name in isEncodedRegionName(byte[] regionName) (#2753)
Signed-off-by: stack <stack@apache.com>
This commit is contained in:
parent
1c217da2ff
commit
c327680125
|
@ -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) {
|
||||
throw 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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -99,6 +99,25 @@ 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);
|
||||
try {
|
||||
ADMIN.majorCompactRegion(tableName.getName());
|
||||
ADMIN.majorCompactRegion(Bytes.toBytes("abcd"));
|
||||
} catch (IllegalArgumentException iae) {
|
||||
LOG.info("This is expected");
|
||||
}
|
||||
} finally {
|
||||
ADMIN.disableTable(tableName);
|
||||
ADMIN.deleteTable(tableName);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompactionTimestamps() throws Exception {
|
||||
TableName tableName = TableName.valueOf(name.getMethodName());
|
||||
|
|
Loading…
Reference in New Issue