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();

Reply via email to