You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by gx...@apache.org on 2018/09/12 16:00:42 UTC
[1/2] hbase git commit: HBASE-21174 [REST] Failed to parse empty
qualifier in TableResource#getScanResource
Repository: hbase
Updated Branches:
refs/heads/branch-1 158607bf2 -> 4256d38ba
refs/heads/branch-1.4 aa28cf7e9 -> 4b5d2def3
HBASE-21174 [REST] Failed to parse empty qualifier in TableResource#getScanResource
Signed-off-by: tedyu <yu...@gmail.com>
Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/4256d38b
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/4256d38b
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/4256d38b
Branch: refs/heads/branch-1
Commit: 4256d38bac0b02946f269d6332449dd87f522578
Parents: 158607b
Author: Guangxu Cheng <gu...@gmail.com>
Authored: Wed Sep 12 22:51:03 2018 +0800
Committer: Guangxu Cheng <gu...@gmail.com>
Committed: Wed Sep 12 23:00:34 2018 +0800
----------------------------------------------------------------------
.../apache/hadoop/hbase/rest/TableResource.java | 37 ++++++-------
.../apache/hadoop/hbase/rest/TestTableScan.java | 55 +++++++++++++++++---
2 files changed, 64 insertions(+), 28 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/hbase/blob/4256d38b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/TableResource.java
----------------------------------------------------------------------
diff --git a/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/TableResource.java b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/TableResource.java
index a1a60bb..b208c96 100644
--- a/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/TableResource.java
+++ b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/TableResource.java
@@ -24,16 +24,14 @@ import java.util.List;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.Encoded;
-import javax.ws.rs.HeaderParam;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.UriInfo;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.classification.InterfaceAudience;
import org.apache.hadoop.hbase.client.Scan;
@@ -129,7 +127,7 @@ public class TableResource extends ResourceBase {
@QueryParam(Constants.SCAN_LIMIT) int userRequestedLimit,
@DefaultValue("") @QueryParam(Constants.SCAN_START_ROW) String startRow,
@DefaultValue("") @QueryParam(Constants.SCAN_END_ROW) String endRow,
- @DefaultValue("") @QueryParam(Constants.SCAN_COLUMN) List<String> column,
+ @QueryParam(Constants.SCAN_COLUMN) List<String> column,
@DefaultValue("1") @QueryParam(Constants.SCAN_MAX_VERSIONS) int maxVersions,
@DefaultValue("-1") @QueryParam(Constants.SCAN_BATCH_SIZE) int batchSize,
@DefaultValue("0") @QueryParam(Constants.SCAN_START_TIME) long startTime,
@@ -162,26 +160,21 @@ public class TableResource extends ResourceBase {
tableScan.setStartRow(Bytes.toBytes(startRow));
}
tableScan.setStopRow(Bytes.toBytes(endRow));
- for (String csplit : column) {
- String[] familysplit = csplit.trim().split(":");
- if (familysplit.length == 2) {
- if (familysplit[1].length() > 0) {
- if (LOG.isTraceEnabled()) {
- LOG.trace("Scan family and column : " + familysplit[0] + " " + familysplit[1]);
- }
- tableScan.addColumn(Bytes.toBytes(familysplit[0]), Bytes.toBytes(familysplit[1]));
- } else {
- tableScan.addFamily(Bytes.toBytes(familysplit[0]));
- if (LOG.isTraceEnabled()) {
- LOG.trace("Scan family : " + familysplit[0] + " and empty qualifier.");
- }
- tableScan.addColumn(Bytes.toBytes(familysplit[0]), null);
+ for (String col : column) {
+ byte [][] parts = KeyValue.parseColumn(Bytes.toBytes(col.trim()));
+ if (parts.length == 1) {
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Scan family : " + Bytes.toStringBinary(parts[0]));
}
- } else if (StringUtils.isNotEmpty(familysplit[0])) {
+ tableScan.addFamily(parts[0]);
+ } else if (parts.length == 2) {
if (LOG.isTraceEnabled()) {
- LOG.trace("Scan family : " + familysplit[0]);
+ LOG.trace("Scan family and column : " + Bytes.toStringBinary(parts[0])
+ + " " + Bytes.toStringBinary(parts[1]));
}
- tableScan.addFamily(Bytes.toBytes(familysplit[0]));
+ tableScan.addColumn(parts[0], parts[1]);
+ } else {
+ throw new IllegalArgumentException("Invalid column specifier.");
}
}
@@ -205,7 +198,7 @@ public class TableResource extends ResourceBase {
tableScan.setCaching(fetchSize);
tableScan.setReversed(reversed);
tableScan.setCacheBlocks(cacheBlocks);
- return new TableScanResource(hTable.getScanner(tableScan), userRequestedLimit);
+ return new TableScanResource(hTable.getScanner(tableScan), userRequestedLimit);
} catch (Exception exp) {
servlet.getMetrics().incrementFailedScanRequests(1);
processException(exp);
http://git-wip-us.apache.org/repos/asf/hbase/blob/4256d38b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestTableScan.java
----------------------------------------------------------------------
diff --git a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestTableScan.java b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestTableScan.java
index d3e618b..0c7d6d8 100644
--- a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestTableScan.java
+++ b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestTableScan.java
@@ -81,9 +81,11 @@ public class TestTableScan {
private static final String CFB = "b";
private static final String COLUMN_1 = CFA + ":1";
private static final String COLUMN_2 = CFB + ":2";
+ private static final String COLUMN_EMPTY = CFA + ":";
private static Client client;
private static int expectedRows1;
private static int expectedRows2;
+ private static int expectedRows3;
private static Configuration conf;
private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
@@ -100,12 +102,13 @@ public class TestTableScan {
REST_TEST_UTIL.getServletPort()));
Admin admin = TEST_UTIL.getHBaseAdmin();
if (!admin.tableExists(TABLE)) {
- HTableDescriptor htd = new HTableDescriptor(TABLE);
- htd.addFamily(new HColumnDescriptor(CFA));
- htd.addFamily(new HColumnDescriptor(CFB));
- admin.createTable(htd);
- expectedRows1 = TestScannerResource.insertData(conf, TABLE, COLUMN_1, 1.0);
- expectedRows2 = TestScannerResource.insertData(conf, TABLE, COLUMN_2, 0.5);
+ HTableDescriptor htd = new HTableDescriptor(TABLE);
+ htd.addFamily(new HColumnDescriptor(CFA));
+ htd.addFamily(new HColumnDescriptor(CFB));
+ admin.createTable(htd);
+ expectedRows1 = TestScannerResource.insertData(conf, TABLE, COLUMN_1, 1.0);
+ expectedRows2 = TestScannerResource.insertData(conf, TABLE, COLUMN_2, 0.5);
+ expectedRows3 = TestScannerResource.insertData(conf, TABLE, COLUMN_EMPTY, 1.0);
}
}
@@ -620,6 +623,46 @@ public class TestTableScan {
}
}
+ @Test
+ public void testColumnWithEmptyQualifier() throws IOException, JAXBException {
+ // Test scanning with empty qualifier
+ StringBuilder builder = new StringBuilder();
+ builder.append("/*");
+ builder.append("?");
+ builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_EMPTY);
+ Response response = client.get("/" + TABLE + builder.toString(),
+ Constants.MIMETYPE_JSON);
+ assertEquals(200, response.getCode());
+ assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type"));
+ ObjectMapper mapper = new JacksonProvider()
+ .locateMapper(CellSetModel.class, MediaType.APPLICATION_JSON_TYPE);
+ CellSetModel model = mapper.readValue(response.getStream(), CellSetModel.class);
+ int count = TestScannerResource.countCellSet(model);
+ assertEquals(expectedRows3, count);
+ checkRowsNotNull(model);
+ RowModel startRow = model.getRows().get(0);
+ assertEquals("aaa", Bytes.toString(startRow.getKey()));
+ assertEquals(1, startRow.getCells().size());
+
+ // Test scanning with empty qualifier and normal qualifier
+ builder = new StringBuilder();
+ builder.append("/*");
+ builder.append("?");
+ builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_1);
+ builder.append("&");
+ builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_EMPTY);
+ response = client.get("/" + TABLE + builder.toString(),
+ Constants.MIMETYPE_JSON);
+ assertEquals(200, response.getCode());
+ assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type"));
+ mapper = new JacksonProvider()
+ .locateMapper(CellSetModel.class, MediaType.APPLICATION_JSON_TYPE);
+ model = mapper.readValue(response.getStream(), CellSetModel.class);
+ count = TestScannerResource.countCellSet(model);
+ assertEquals(expectedRows1 + expectedRows3, count);
+ checkRowsNotNull(model);
+ }
+
public static class CustomFilter extends PrefixFilter {
private byte[] key = null;
[2/2] hbase git commit: HBASE-21174 [REST] Failed to parse empty
qualifier in TableResource#getScanResource
Posted by gx...@apache.org.
HBASE-21174 [REST] Failed to parse empty qualifier in TableResource#getScanResource
Signed-off-by: tedyu <yu...@gmail.com>
Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/4b5d2def
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/4b5d2def
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/4b5d2def
Branch: refs/heads/branch-1.4
Commit: 4b5d2def398abf7d8e02fe3fe1387e107272ea49
Parents: aa28cf7
Author: Guangxu Cheng <gu...@gmail.com>
Authored: Wed Sep 12 22:51:03 2018 +0800
Committer: Guangxu Cheng <gu...@gmail.com>
Committed: Wed Sep 12 23:01:13 2018 +0800
----------------------------------------------------------------------
.../apache/hadoop/hbase/rest/TableResource.java | 37 ++++++-------
.../apache/hadoop/hbase/rest/TestTableScan.java | 55 +++++++++++++++++---
2 files changed, 64 insertions(+), 28 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/hbase/blob/4b5d2def/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/TableResource.java
----------------------------------------------------------------------
diff --git a/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/TableResource.java b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/TableResource.java
index a1a60bb..b208c96 100644
--- a/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/TableResource.java
+++ b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/TableResource.java
@@ -24,16 +24,14 @@ import java.util.List;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.Encoded;
-import javax.ws.rs.HeaderParam;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.UriInfo;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.classification.InterfaceAudience;
import org.apache.hadoop.hbase.client.Scan;
@@ -129,7 +127,7 @@ public class TableResource extends ResourceBase {
@QueryParam(Constants.SCAN_LIMIT) int userRequestedLimit,
@DefaultValue("") @QueryParam(Constants.SCAN_START_ROW) String startRow,
@DefaultValue("") @QueryParam(Constants.SCAN_END_ROW) String endRow,
- @DefaultValue("") @QueryParam(Constants.SCAN_COLUMN) List<String> column,
+ @QueryParam(Constants.SCAN_COLUMN) List<String> column,
@DefaultValue("1") @QueryParam(Constants.SCAN_MAX_VERSIONS) int maxVersions,
@DefaultValue("-1") @QueryParam(Constants.SCAN_BATCH_SIZE) int batchSize,
@DefaultValue("0") @QueryParam(Constants.SCAN_START_TIME) long startTime,
@@ -162,26 +160,21 @@ public class TableResource extends ResourceBase {
tableScan.setStartRow(Bytes.toBytes(startRow));
}
tableScan.setStopRow(Bytes.toBytes(endRow));
- for (String csplit : column) {
- String[] familysplit = csplit.trim().split(":");
- if (familysplit.length == 2) {
- if (familysplit[1].length() > 0) {
- if (LOG.isTraceEnabled()) {
- LOG.trace("Scan family and column : " + familysplit[0] + " " + familysplit[1]);
- }
- tableScan.addColumn(Bytes.toBytes(familysplit[0]), Bytes.toBytes(familysplit[1]));
- } else {
- tableScan.addFamily(Bytes.toBytes(familysplit[0]));
- if (LOG.isTraceEnabled()) {
- LOG.trace("Scan family : " + familysplit[0] + " and empty qualifier.");
- }
- tableScan.addColumn(Bytes.toBytes(familysplit[0]), null);
+ for (String col : column) {
+ byte [][] parts = KeyValue.parseColumn(Bytes.toBytes(col.trim()));
+ if (parts.length == 1) {
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Scan family : " + Bytes.toStringBinary(parts[0]));
}
- } else if (StringUtils.isNotEmpty(familysplit[0])) {
+ tableScan.addFamily(parts[0]);
+ } else if (parts.length == 2) {
if (LOG.isTraceEnabled()) {
- LOG.trace("Scan family : " + familysplit[0]);
+ LOG.trace("Scan family and column : " + Bytes.toStringBinary(parts[0])
+ + " " + Bytes.toStringBinary(parts[1]));
}
- tableScan.addFamily(Bytes.toBytes(familysplit[0]));
+ tableScan.addColumn(parts[0], parts[1]);
+ } else {
+ throw new IllegalArgumentException("Invalid column specifier.");
}
}
@@ -205,7 +198,7 @@ public class TableResource extends ResourceBase {
tableScan.setCaching(fetchSize);
tableScan.setReversed(reversed);
tableScan.setCacheBlocks(cacheBlocks);
- return new TableScanResource(hTable.getScanner(tableScan), userRequestedLimit);
+ return new TableScanResource(hTable.getScanner(tableScan), userRequestedLimit);
} catch (Exception exp) {
servlet.getMetrics().incrementFailedScanRequests(1);
processException(exp);
http://git-wip-us.apache.org/repos/asf/hbase/blob/4b5d2def/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestTableScan.java
----------------------------------------------------------------------
diff --git a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestTableScan.java b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestTableScan.java
index d3e618b..0c7d6d8 100644
--- a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestTableScan.java
+++ b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestTableScan.java
@@ -81,9 +81,11 @@ public class TestTableScan {
private static final String CFB = "b";
private static final String COLUMN_1 = CFA + ":1";
private static final String COLUMN_2 = CFB + ":2";
+ private static final String COLUMN_EMPTY = CFA + ":";
private static Client client;
private static int expectedRows1;
private static int expectedRows2;
+ private static int expectedRows3;
private static Configuration conf;
private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
@@ -100,12 +102,13 @@ public class TestTableScan {
REST_TEST_UTIL.getServletPort()));
Admin admin = TEST_UTIL.getHBaseAdmin();
if (!admin.tableExists(TABLE)) {
- HTableDescriptor htd = new HTableDescriptor(TABLE);
- htd.addFamily(new HColumnDescriptor(CFA));
- htd.addFamily(new HColumnDescriptor(CFB));
- admin.createTable(htd);
- expectedRows1 = TestScannerResource.insertData(conf, TABLE, COLUMN_1, 1.0);
- expectedRows2 = TestScannerResource.insertData(conf, TABLE, COLUMN_2, 0.5);
+ HTableDescriptor htd = new HTableDescriptor(TABLE);
+ htd.addFamily(new HColumnDescriptor(CFA));
+ htd.addFamily(new HColumnDescriptor(CFB));
+ admin.createTable(htd);
+ expectedRows1 = TestScannerResource.insertData(conf, TABLE, COLUMN_1, 1.0);
+ expectedRows2 = TestScannerResource.insertData(conf, TABLE, COLUMN_2, 0.5);
+ expectedRows3 = TestScannerResource.insertData(conf, TABLE, COLUMN_EMPTY, 1.0);
}
}
@@ -620,6 +623,46 @@ public class TestTableScan {
}
}
+ @Test
+ public void testColumnWithEmptyQualifier() throws IOException, JAXBException {
+ // Test scanning with empty qualifier
+ StringBuilder builder = new StringBuilder();
+ builder.append("/*");
+ builder.append("?");
+ builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_EMPTY);
+ Response response = client.get("/" + TABLE + builder.toString(),
+ Constants.MIMETYPE_JSON);
+ assertEquals(200, response.getCode());
+ assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type"));
+ ObjectMapper mapper = new JacksonProvider()
+ .locateMapper(CellSetModel.class, MediaType.APPLICATION_JSON_TYPE);
+ CellSetModel model = mapper.readValue(response.getStream(), CellSetModel.class);
+ int count = TestScannerResource.countCellSet(model);
+ assertEquals(expectedRows3, count);
+ checkRowsNotNull(model);
+ RowModel startRow = model.getRows().get(0);
+ assertEquals("aaa", Bytes.toString(startRow.getKey()));
+ assertEquals(1, startRow.getCells().size());
+
+ // Test scanning with empty qualifier and normal qualifier
+ builder = new StringBuilder();
+ builder.append("/*");
+ builder.append("?");
+ builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_1);
+ builder.append("&");
+ builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_EMPTY);
+ response = client.get("/" + TABLE + builder.toString(),
+ Constants.MIMETYPE_JSON);
+ assertEquals(200, response.getCode());
+ assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type"));
+ mapper = new JacksonProvider()
+ .locateMapper(CellSetModel.class, MediaType.APPLICATION_JSON_TYPE);
+ model = mapper.readValue(response.getStream(), CellSetModel.class);
+ count = TestScannerResource.countCellSet(model);
+ assertEquals(expectedRows1 + expectedRows3, count);
+ checkRowsNotNull(model);
+ }
+
public static class CustomFilter extends PrefixFilter {
private byte[] key = null;