Skip to content

Commit 541d748

Browse files
wchevreuilapurtell
authored andcommitted
HBASE-26881 Backport HBASE-25368 to branch-2 (#4267)
Signed-off-by: Andrew Purtell <[email protected]>
1 parent 5acfe6d commit 541d748

File tree

4 files changed

+86
-48
lines changed

4 files changed

+86
-48
lines changed

hbase-client/src/main/java/org/apache/hadoop/hbase/client/RawAsyncHBaseAdmin.java

Lines changed: 45 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2394,51 +2394,55 @@ CompletableFuture<HRegionLocation> getRegionLocation(byte[] regionNameOrEncodedR
23942394
if (regionNameOrEncodedRegionName == null) {
23952395
return failedFuture(new IllegalArgumentException("Passed region name can't be null"));
23962396
}
2397-
try {
2398-
CompletableFuture<Optional<HRegionLocation>> future;
2399-
if (RegionInfo.isEncodedRegionName(regionNameOrEncodedRegionName)) {
2400-
String encodedName = Bytes.toString(regionNameOrEncodedRegionName);
2401-
if (encodedName.length() < RegionInfo.MD5_HEX_LENGTH) {
2402-
// old format encodedName, should be meta region
2403-
future = connection.registry.getMetaRegionLocations()
2404-
.thenApply(locs -> Stream.of(locs.getRegionLocations())
2405-
.filter(loc -> loc.getRegion().getEncodedName().equals(encodedName)).findFirst());
2406-
} else {
2407-
future = AsyncMetaTableAccessor.getRegionLocationWithEncodedName(metaTable,
2408-
regionNameOrEncodedRegionName);
2409-
}
2397+
2398+
CompletableFuture<Optional<HRegionLocation>> future;
2399+
if (RegionInfo.isEncodedRegionName(regionNameOrEncodedRegionName)) {
2400+
String encodedName = Bytes.toString(regionNameOrEncodedRegionName);
2401+
if (encodedName.length() < RegionInfo.MD5_HEX_LENGTH) {
2402+
// old format encodedName, should be meta region
2403+
future = connection.registry.getMetaRegionLocations()
2404+
.thenApply(locs -> Stream.of(locs.getRegionLocations())
2405+
.filter(loc -> loc.getRegion().getEncodedName().equals(encodedName)).findFirst());
24102406
} else {
2411-
RegionInfo regionInfo =
2412-
MetaTableAccessor.parseRegionInfoFromRegionName(regionNameOrEncodedRegionName);
2413-
if (regionInfo.isMetaRegion()) {
2414-
future = connection.registry.getMetaRegionLocations()
2415-
.thenApply(locs -> Stream.of(locs.getRegionLocations())
2416-
.filter(loc -> loc.getRegion().getReplicaId() == regionInfo.getReplicaId())
2417-
.findFirst());
2418-
} else {
2419-
future =
2420-
AsyncMetaTableAccessor.getRegionLocation(metaTable, regionNameOrEncodedRegionName);
2421-
}
2407+
future = AsyncMetaTableAccessor.getRegionLocationWithEncodedName(metaTable,
2408+
regionNameOrEncodedRegionName);
2409+
}
2410+
} else {
2411+
// Not all regionNameOrEncodedRegionName here is going to be a valid region name,
2412+
// it needs to throw out IllegalArgumentException in case tableName is passed in.
2413+
RegionInfo regionInfo;
2414+
try {
2415+
regionInfo = MetaTableAccessor.parseRegionInfoFromRegionName(regionNameOrEncodedRegionName);
2416+
} catch (IOException ioe) {
2417+
return failedFuture(new IllegalArgumentException(ioe.getMessage()));
24222418
}
24232419

2424-
CompletableFuture<HRegionLocation> returnedFuture = new CompletableFuture<>();
2425-
addListener(future, (location, err) -> {
2426-
if (err != null) {
2427-
returnedFuture.completeExceptionally(err);
2428-
return;
2429-
}
2430-
if (!location.isPresent() || location.get().getRegion() == null) {
2431-
returnedFuture.completeExceptionally(
2432-
new UnknownRegionException("Invalid region name or encoded region name: " +
2433-
Bytes.toStringBinary(regionNameOrEncodedRegionName)));
2434-
} else {
2435-
returnedFuture.complete(location.get());
2436-
}
2437-
});
2438-
return returnedFuture;
2439-
} catch (IOException e) {
2440-
return failedFuture(e);
2420+
if (regionInfo.isMetaRegion()) {
2421+
future = connection.registry.getMetaRegionLocations()
2422+
.thenApply(locs -> Stream.of(locs.getRegionLocations())
2423+
.filter(loc -> loc.getRegion().getReplicaId() == regionInfo.getReplicaId())
2424+
.findFirst());
2425+
} else {
2426+
future =
2427+
AsyncMetaTableAccessor.getRegionLocation(metaTable, regionNameOrEncodedRegionName);
2428+
}
24412429
}
2430+
2431+
CompletableFuture<HRegionLocation> returnedFuture = new CompletableFuture<>();
2432+
addListener(future, (location, err) -> {
2433+
if (err != null) {
2434+
returnedFuture.completeExceptionally(err);
2435+
return;
2436+
}
2437+
if (!location.isPresent() || location.get().getRegion() == null) {
2438+
returnedFuture.completeExceptionally(
2439+
new UnknownRegionException("Invalid region name or encoded region name: " +
2440+
Bytes.toStringBinary(regionNameOrEncodedRegionName)));
2441+
} else {
2442+
returnedFuture.complete(location.get());
2443+
}
2444+
});
2445+
return returnedFuture;
24422446
}
24432447

24442448
/**

hbase-client/src/main/java/org/apache/hadoop/hbase/client/RegionInfo.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,9 +362,25 @@ static byte[] getStartKey(final byte[] regionName) throws IOException {
362362
* @return True if <code>regionName</code> represents an encoded name.
363363
*/
364364
@InterfaceAudience.Private // For use by internals only.
365-
public static boolean isEncodedRegionName(byte[] regionName) {
365+
static boolean isEncodedRegionName(byte[] regionName) {
366366
// If not parseable as region name, presume encoded. TODO: add stringency; e.g. if hex.
367-
return parseRegionNameOrReturnNull(regionName) == null && regionName.length <= MD5_HEX_LENGTH;
367+
if (parseRegionNameOrReturnNull(regionName) == null) {
368+
if (regionName.length > MD5_HEX_LENGTH) {
369+
return false;
370+
} else if (regionName.length == MD5_HEX_LENGTH) {
371+
return true;
372+
} else {
373+
String encodedName = Bytes.toString(regionName);
374+
try {
375+
Integer.parseInt(encodedName);
376+
// If this is a valid integer, it could be hbase:meta's encoded region name.
377+
return true;
378+
} catch(NumberFormatException er) {
379+
return false;
380+
}
381+
}
382+
}
383+
return false;
368384
}
369385

370386
/**

hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin1.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import static org.junit.Assert.assertEquals;
2121
import static org.junit.Assert.assertFalse;
2222
import static org.junit.Assert.assertNotNull;
23+
import static org.junit.Assert.assertThrows;
2324
import static org.junit.Assert.assertTrue;
2425
import static org.junit.Assert.fail;
2526

@@ -130,6 +131,24 @@ public void testSplitFlushCompactUnknownTable() throws InterruptedException {
130131
assertTrue(exception instanceof TableNotFoundException);
131132
}
132133

134+
@Test
135+
public void testCompactATableWithSuperLongTableName() throws Exception {
136+
TableName tableName = TableName.valueOf(name.getMethodName());
137+
TableDescriptor htd = TableDescriptorBuilder.newBuilder(tableName)
138+
.setColumnFamily(ColumnFamilyDescriptorBuilder.of("fam1")).build();
139+
try {
140+
ADMIN.createTable(htd);
141+
assertThrows(IllegalArgumentException.class,
142+
() -> ADMIN.majorCompactRegion(tableName.getName()));
143+
144+
assertThrows(IllegalArgumentException.class,
145+
() -> ADMIN.majorCompactRegion(Bytes.toBytes("abcd")));
146+
} finally {
147+
ADMIN.disableTable(tableName);
148+
ADMIN.deleteTable(tableName);
149+
}
150+
}
151+
133152
@Test
134153
public void testCompactionTimestamps() throws Exception {
135154
TableName tableName = TableName.valueOf(name.getMethodName());

hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin2.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import static org.junit.Assert.assertEquals;
2121
import static org.junit.Assert.assertFalse;
22+
import static org.junit.Assert.assertThrows;
2223
import static org.junit.Assert.assertTrue;
2324
import static org.junit.Assert.fail;
2425

@@ -316,11 +317,9 @@ public void testCloseRegionIfInvalidRegionNameIsPassed() throws Exception {
316317
if (!regionInfo.isMetaRegion()) {
317318
if (regionInfo.getRegionNameAsString().contains(name)) {
318319
info = regionInfo;
319-
try {
320-
ADMIN.unassign(Bytes.toBytes("sample"), true);
321-
} catch (UnknownRegionException nsre) {
322-
// expected, ignore it
323-
}
320+
assertThrows(UnknownRegionException.class,
321+
() -> ADMIN.unassign(Bytes.toBytes(
322+
"test,,1358563771069.acc1ad1b7962564fc3a43e5907e8db33."), true));
324323
}
325324
}
326325
}

0 commit comments

Comments
 (0)