This is an automated email from the ASF dual-hosted git repository.
zhangduo pushed a commit to branch branch-2.6
in repository https://gitbox.apache.org/repos/asf/hbase.git
The following commit(s) were added to refs/heads/branch-2.6 by this push:
new d9d016dca9b HBASE-30007 Multiget with timestamp incorrectly returns
404 not found (#7956)
d9d016dca9b is described below
commit d9d016dca9b3552b384dff8d05227d861562d9dd
Author: Dimas Shidqi Parikesit <[email protected]>
AuthorDate: Fri Mar 27 02:23:23 2026 -0400
HBASE-30007 Multiget with timestamp incorrectly returns 404 not found
(#7956)
Signed-off-by: Duo Zhang <[email protected]>
(cherry picked from commit 742a83e69899a2564fc25a903b15d637fc45b6ab)
---
.../hadoop/hbase/rest/MultiRowResultReader.java | 6 +-
.../hbase/rest/MultiRowResourceTestBase.java | 74 ++++++++++++++++++++++
2 files changed, 79 insertions(+), 1 deletion(-)
diff --git
a/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/MultiRowResultReader.java
b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/MultiRowResultReader.java
index 2903c37edf9..28a63b5890c 100644
---
a/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/MultiRowResultReader.java
+++
b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/MultiRowResultReader.java
@@ -58,7 +58,11 @@ public class MultiRowResultReader {
}
}
}
- get.setTimeRange(rowspec.getStartTime(), rowspec.getEndTime());
+ if (rowspec.isPartialTimeRange()) {
+ get.setTimestamp(rowspec.getTimestamp());
+ } else {
+ get.setTimeRange(rowspec.getStartTime(), rowspec.getEndTime());
+ }
get.readVersions(rowspec.getMaxVersions());
if (filter != null) {
get.setFilter(filter);
diff --git
a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/MultiRowResourceTestBase.java
b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/MultiRowResourceTestBase.java
index 2eac0ad78aa..104a68c326d 100644
---
a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/MultiRowResourceTestBase.java
+++
b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/MultiRowResourceTestBase.java
@@ -58,6 +58,14 @@ public class MultiRowResourceTestBase {
private static final String VALUE_1 = "testvalue5";
private static final String ROW_2 = "testrow6";
private static final String VALUE_2 = "testvalue6";
+ private static final String TIMESTAMPED_ROW_1 = "testrow7";
+ private static final String TIMESTAMPED_ROW_2 = "testrow8";
+ private static final String TIMESTAMPED_OLD_VALUE_1 = "testvalue7-old";
+ private static final String TIMESTAMPED_NEW_VALUE_1 = "testvalue7-new";
+ private static final String TIMESTAMPED_OLD_VALUE_2 = "testvalue8-old";
+ private static final String TIMESTAMPED_NEW_VALUE_2 = "testvalue8-new";
+ private static final long TIMESTAMP_1 = 1000L;
+ private static final long TIMESTAMP_2 = 2000L;
private static final HBaseTestingUtility TEST_UTIL = new
HBaseTestingUtility();
private static final HBaseRESTTestingUtility REST_TEST_UTIL = new
HBaseRESTTestingUtility();
@@ -198,6 +206,72 @@ public class MultiRowResourceTestBase {
client.delete(row_6_url, extraHdr);
}
+ private void postBinaryWithTimestamp(String path, String value, long
timestamp)
+ throws IOException {
+ Header[] headers = new Header[] { new BasicHeader("Content-Type",
Constants.MIMETYPE_BINARY),
+ new BasicHeader("X-Timestamp", Long.toString(timestamp)), extraHdr };
+ Response response = client.post(path, headers, Bytes.toBytes(value));
+ assertEquals(200, response.getCode());
+ }
+
+ @Test
+ public void testMultiCellGetWithExactTimestampJSON() throws IOException {
+ String row_7_url = "/" + TABLE + "/" + TIMESTAMPED_ROW_1 + "/" + COLUMN_1;
+ String row_8_url = "/" + TABLE + "/" + TIMESTAMPED_ROW_2 + "/" + COLUMN_2;
+ String row_7_delete_url = "/" + TABLE + "/" + TIMESTAMPED_ROW_1;
+ String row_8_delete_url = "/" + TABLE + "/" + TIMESTAMPED_ROW_2;
+
+ postBinaryWithTimestamp(row_7_url, TIMESTAMPED_OLD_VALUE_1, TIMESTAMP_1);
+ postBinaryWithTimestamp(row_7_url, TIMESTAMPED_NEW_VALUE_1, TIMESTAMP_2);
+ postBinaryWithTimestamp(row_8_url, TIMESTAMPED_OLD_VALUE_2, TIMESTAMP_1);
+ postBinaryWithTimestamp(row_8_url, TIMESTAMPED_NEW_VALUE_2, TIMESTAMP_2);
+
+ try {
+ StringBuilder path = new StringBuilder();
+ path.append("/");
+ path.append(TABLE);
+ path.append("/multiget/?row=");
+ path.append(TIMESTAMPED_ROW_1);
+ path.append("/");
+ path.append("/");
+ path.append(TIMESTAMP_1);
+ path.append("&row=");
+ path.append(TIMESTAMPED_ROW_2);
+ path.append("/");
+ path.append("/");
+ path.append(TIMESTAMP_1);
+
+ Response response = client.get(path.toString(), Constants.MIMETYPE_JSON);
+ assertEquals(200, response.getCode());
+ assertEquals(Constants.MIMETYPE_JSON,
response.getHeader("content-type"));
+
+ ObjectMapper mapper = new
JacksonJaxbJsonProvider().locateMapper(CellSetModel.class,
+ MediaType.APPLICATION_JSON_TYPE);
+ CellSetModel cellSet = mapper.readValue(response.getBody(),
CellSetModel.class);
+
+ assertEquals(2, cellSet.getRows().size());
+
+ RowModel rowModel = cellSet.getRows().get(0);
+ assertEquals(TIMESTAMPED_ROW_1, Bytes.toString(rowModel.getKey()));
+ assertEquals(1, rowModel.getCells().size());
+ CellModel cell = rowModel.getCells().get(0);
+ assertEquals(COLUMN_1, Bytes.toString(cell.getColumn()));
+ assertEquals(TIMESTAMPED_OLD_VALUE_1, Bytes.toString(cell.getValue()));
+ assertEquals(TIMESTAMP_1, cell.getTimestamp());
+
+ rowModel = cellSet.getRows().get(1);
+ assertEquals(TIMESTAMPED_ROW_2, Bytes.toString(rowModel.getKey()));
+ assertEquals(1, rowModel.getCells().size());
+ cell = rowModel.getCells().get(0);
+ assertEquals(COLUMN_2, Bytes.toString(cell.getColumn()));
+ assertEquals(TIMESTAMPED_OLD_VALUE_2, Bytes.toString(cell.getValue()));
+ assertEquals(TIMESTAMP_1, cell.getTimestamp());
+ } finally {
+ client.delete(row_7_delete_url, extraHdr);
+ client.delete(row_8_delete_url, extraHdr);
+ }
+ }
+
@Test
public void testMultiCellGetNoKeys() throws IOException {
StringBuilder path = new StringBuilder();