You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by st...@apache.org on 2024/05/30 05:44:50 UTC
(hbase) branch branch-2 updated: HBASE-28626 MultiRowRangeFilter deserialization fails in org.apache.hadoop.hbase.rest.model.ScannerModel (#5951)
This is an automated email from the ASF dual-hosted git repository.
stoty pushed a commit to branch branch-2
in repository https://gitbox.apache.org/repos/asf/hbase.git
The following commit(s) were added to refs/heads/branch-2 by this push:
new bc96a95c913 HBASE-28626 MultiRowRangeFilter deserialization fails in org.apache.hadoop.hbase.rest.model.ScannerModel (#5951)
bc96a95c913 is described below
commit bc96a95c913f6d53594e24535ee3a9a70f48cac7
Author: Istvan Toth <st...@apache.org>
AuthorDate: Thu May 30 07:27:50 2024 +0200
HBASE-28626 MultiRowRangeFilter deserialization fails in org.apache.hadoop.hbase.rest.model.ScannerModel (#5951)
Signed-off-by: Ankit Singhal <an...@apache.org>
(cherry picked from commit cd0b29c0a8fed71ec7ccb9b05a2f9b1a65d07b64)
---
.../hadoop/hbase/rest/model/ScannerModel.java | 86 +++++++++++++++++++++-
.../hadoop/hbase/rest/TestScannersWithFilters.java | 15 ++++
2 files changed, 97 insertions(+), 4 deletions(-)
diff --git a/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/model/ScannerModel.java b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/model/ScannerModel.java
index 44b489db436..a8c52148e89 100644
--- a/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/model/ScannerModel.java
+++ b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/model/ScannerModel.java
@@ -23,10 +23,12 @@ import com.google.protobuf.Message;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Base64;
import java.util.List;
import java.util.Map;
import java.util.NavigableSet;
+import java.util.Objects;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@@ -201,6 +203,79 @@ public class ScannerModel implements ProtobufMessageHandler, Serializable {
}
+ /**
+ * This DTO omits the pseudo-getters in MultiRowRangeFilter.RowRange which break Jackson
+ * deserialization. It also avoids adding those as dummy JSON elements.
+ */
+ static class RowRangeModel {
+
+ protected byte[] startRow;
+
+ protected boolean startRowInclusive = true;
+
+ protected byte[] stopRow;
+
+ protected boolean stopRowInclusive = false;
+
+ public RowRangeModel() {
+ }
+
+ public RowRangeModel(MultiRowRangeFilter.RowRange rr) {
+ this.startRow = rr.getStartRow();
+ this.startRowInclusive = rr.isStartRowInclusive();
+ this.stopRow = rr.getStopRow();
+ this.stopRowInclusive = rr.isStopRowInclusive();
+ }
+
+ public MultiRowRangeFilter.RowRange build() {
+ return new MultiRowRangeFilter.RowRange(startRow, startRowInclusive, stopRow,
+ stopRowInclusive);
+ }
+
+ public byte[] getStartRow() {
+ return startRow;
+ }
+
+ public byte[] getStopRow() {
+ return stopRow;
+ }
+
+ /** Returns if start row is inclusive. */
+ public boolean isStartRowInclusive() {
+ return startRowInclusive;
+ }
+
+ /** Returns if stop row is inclusive. */
+ public boolean isStopRowInclusive() {
+ return stopRowInclusive;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + Arrays.hashCode(startRow);
+ result = prime * result + Arrays.hashCode(stopRow);
+ result = prime * result + Objects.hash(startRowInclusive, stopRowInclusive);
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!(obj instanceof RowRangeModel)) {
+ return false;
+ }
+ RowRangeModel other = (RowRangeModel) obj;
+ return Arrays.equals(startRow, other.startRow)
+ && startRowInclusive == other.startRowInclusive && Arrays.equals(stopRow, other.stopRow)
+ && stopRowInclusive == other.stopRowInclusive;
+ }
+
+ }
+
// A grab bag of fields, would have been a union if this were C.
// These are null by default and will only be serialized if set (non null).
@XmlAttribute
@@ -240,7 +315,7 @@ public class ScannerModel implements ProtobufMessageHandler, Serializable {
@XmlElement
public List<String> prefixes;
@XmlElement
- private List<RowRange> ranges;
+ private List<RowRangeModel> ranges;
@XmlElement
public List<Long> timestamps;
@@ -331,8 +406,7 @@ public class ScannerModel implements ProtobufMessageHandler, Serializable {
case MultiRowRangeFilter:
this.ranges = new ArrayList<>();
for (RowRange range : ((MultiRowRangeFilter) filter).getRowRanges()) {
- this.ranges.add(new RowRange(range.getStartRow(), range.isStartRowInclusive(),
- range.getStopRow(), range.isStopRowInclusive()));
+ this.ranges.add(new RowRangeModel(range));
}
break;
case PageFilter:
@@ -436,7 +510,11 @@ public class ScannerModel implements ProtobufMessageHandler, Serializable {
}
break;
case MultiRowRangeFilter: {
- filter = new MultiRowRangeFilter(ranges);
+ ArrayList<MultiRowRangeFilter.RowRange> rowRanges = new ArrayList<>(ranges.size());
+ for (RowRangeModel rangeModel : ranges) {
+ rowRanges.add(rangeModel.build());
+ }
+ filter = new MultiRowRangeFilter(rowRanges);
}
break;
case PageFilter:
diff --git a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestScannersWithFilters.java b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestScannersWithFilters.java
index a6fe3ad3e21..0d01fc888c5 100644
--- a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestScannersWithFilters.java
+++ b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestScannersWithFilters.java
@@ -51,6 +51,7 @@ import org.apache.hadoop.hbase.filter.FilterList;
import org.apache.hadoop.hbase.filter.FilterList.Operator;
import org.apache.hadoop.hbase.filter.FirstKeyOnlyFilter;
import org.apache.hadoop.hbase.filter.InclusiveStopFilter;
+import org.apache.hadoop.hbase.filter.MultiRowRangeFilter;
import org.apache.hadoop.hbase.filter.PageFilter;
import org.apache.hadoop.hbase.filter.PrefixFilter;
import org.apache.hadoop.hbase.filter.QualifierFilter;
@@ -957,4 +958,18 @@ public class TestScannersWithFilters {
new KeyValue(ROWS_TWO[3], FAMILIES[0], QUALIFIERS_TWO[0], VALUES[1]) };
verifyScanFull(s, kvs);
}
+
+ @Test
+ public void testMultiRowRangeFilter() throws Exception {
+ long expectedRows = 2;
+ long expectedKeys = colsPerRow;
+ List<MultiRowRangeFilter.RowRange> ranges = new ArrayList<>();
+ // Both return only the third element, as the second one is deleted during initialization.
+ ranges.add(new MultiRowRangeFilter.RowRange(ROWS_ONE[1], true, ROWS_ONE[2], true));
+ ranges.add(new MultiRowRangeFilter.RowRange(ROWS_TWO[0], false, ROWS_TWO[3], false));
+
+ Scan s = new Scan();
+ s.setFilter(new MultiRowRangeFilter(ranges));
+ verifyScan(s, expectedRows, expectedKeys);
+ }
}