You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by en...@apache.org on 2016/02/29 22:01:01 UTC
[3/5] hbase git commit: HBASE-15323 Hbase Rest CheckAndDeleteAPi
should be able to delete more cells (Ajith)
HBASE-15323 Hbase Rest CheckAndDeleteAPi should be able to delete more cells (Ajith)
Conflicts:
hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RowResource.java
Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/56553517
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/56553517
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/56553517
Branch: refs/heads/branch-1.3
Commit: 5655351788133f2ac992b2888ff59ebb1879632f
Parents: 5a9539e
Author: Enis Soztutar <en...@apache.org>
Authored: Mon Feb 29 12:24:18 2016 -0800
Committer: Enis Soztutar <en...@apache.org>
Committed: Mon Feb 29 12:36:18 2016 -0800
----------------------------------------------------------------------
.../apache/hadoop/hbase/rest/RowResource.java | 52 ++++++++++++++++---
.../hadoop/hbase/rest/client/RemoteHTable.java | 1 +
.../hadoop/hbase/rest/RowResourceBase.java | 49 +++++++++++++++---
.../hbase/rest/TestGetAndPutResource.java | 53 ++++++++++++++++++++
4 files changed, 142 insertions(+), 13 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/hbase/blob/56553517/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RowResource.java
----------------------------------------------------------------------
diff --git a/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RowResource.java b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RowResource.java
index 39a4128..bd1ea24 100644
--- a/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RowResource.java
+++ b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RowResource.java
@@ -553,9 +553,12 @@ public class RowResource extends ResourceBase {
.build();
}
+ List<CellModel> cellModels = rowModel.getCells();
+ int cellModelCount = cellModels.size();
+
delete = new Delete(key);
boolean retValue;
- CellModel valueToDeleteCell = rowModel.getCells().get(0);
+ CellModel valueToDeleteCell = rowModel.getCells().get(cellModelCount -1);
byte[] valueToDeleteColumn = valueToDeleteCell.getColumn();
if (valueToDeleteColumn == null) {
try {
@@ -567,25 +570,62 @@ public class RowResource extends ResourceBase {
.build();
}
}
- byte[][] parts = KeyValue.parseColumn(valueToDeleteColumn);
+
+ byte[][] parts ;
+ // Copy all the cells to the Delete request if extra cells are sent
+ if(cellModelCount > 1) {
+ for (int i = 0, n = cellModelCount - 1; i < n; i++) {
+ CellModel cell = cellModels.get(i);
+ byte[] col = cell.getColumn();
+
+ if (col == null) {
+ servlet.getMetrics().incrementFailedPutRequests(1);
+ return Response.status(Response.Status.BAD_REQUEST)
+ .type(MIMETYPE_TEXT).entity("Bad request: Column found to be null." + CRLF)
+ .build();
+ }
+
+ parts = KeyValue.parseColumn(col);
+
+ if (parts.length == 1) {
+ // Only Column Family is specified
+ delete.addFamily(parts[0], cell.getTimestamp());
+ } else if (parts.length == 2) {
+ delete.addColumn(parts[0], parts[1], cell.getTimestamp());
+ } else {
+ servlet.getMetrics().incrementFailedDeleteRequests(1);
+ return Response.status(Response.Status.BAD_REQUEST)
+ .type(MIMETYPE_TEXT)
+ .entity("Bad request: Column to delete incorrectly specified." + CRLF)
+ .build();
+ }
+ }
+ }
+
+ parts = KeyValue.parseColumn(valueToDeleteColumn);
if (parts.length == 2) {
if (parts[1].length != 0) {
- delete.deleteColumns(parts[0], parts[1]);
+ // To support backcompat of deleting a cell
+ // if that is the only cell passed to the rest api
+ if(cellModelCount == 1) {
+ delete.addColumns(parts[0], parts[1]);
+ }
retValue = table.checkAndDelete(key, parts[0], parts[1],
valueToDeleteCell.getValue(), delete);
} else {
// The case of empty qualifier.
- delete.deleteColumns(parts[0], Bytes.toBytes(StringUtils.EMPTY));
+ if(cellModelCount == 1) {
+ delete.addColumns(parts[0], Bytes.toBytes(StringUtils.EMPTY));
+ }
retValue = table.checkAndDelete(key, parts[0], Bytes.toBytes(StringUtils.EMPTY),
valueToDeleteCell.getValue(), delete);
}
} else {
servlet.getMetrics().incrementFailedDeleteRequests(1);
return Response.status(Response.Status.BAD_REQUEST)
- .type(MIMETYPE_TEXT).entity("Bad request: Column incorrectly specified." + CRLF)
+ .type(MIMETYPE_TEXT).entity("Bad request: Column to check incorrectly specified." + CRLF)
.build();
}
- delete.deleteColumns(parts[0], parts[1]);
if (LOG.isDebugEnabled()) {
LOG.debug("CHECK-AND-DELETE " + delete.toString() + ", returns "
http://git-wip-us.apache.org/repos/asf/hbase/blob/56553517/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/client/RemoteHTable.java
----------------------------------------------------------------------
diff --git a/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/client/RemoteHTable.java b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/client/RemoteHTable.java
index 0300ea2..b6ed330 100644
--- a/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/client/RemoteHTable.java
+++ b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/client/RemoteHTable.java
@@ -720,6 +720,7 @@ public class RemoteHTable implements Table {
public boolean checkAndDelete(byte[] row, byte[] family, byte[] qualifier,
byte[] value, Delete delete) throws IOException {
Put put = new Put(row);
+ put.setFamilyCellMap(delete.getFamilyCellMap());
// column to check-the-value
put.add(new KeyValue(row, family, qualifier, value));
CellSetModel model = buildModelFromPut(put);
http://git-wip-us.apache.org/repos/asf/hbase/blob/56553517/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/RowResourceBase.java
----------------------------------------------------------------------
diff --git a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/RowResourceBase.java b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/RowResourceBase.java
index c88bd4c..060409e 100644
--- a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/RowResourceBase.java
+++ b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/RowResourceBase.java
@@ -316,9 +316,16 @@ public class RowResourceBase {
}
protected static Response checkAndDeleteXML(String url, String table,
- String row, String column, String valueToCheck)
+ String row, String column, String valueToCheck, HashMap<String,String> cellsToDelete)
throws IOException, JAXBException {
RowModel rowModel = new RowModel(row);
+
+ if(cellsToDelete != null) {
+ for (Map.Entry<String,String> entry :cellsToDelete.entrySet()) {
+ rowModel.addCell(new CellModel(Bytes.toBytes(entry.getKey()), Bytes.toBytes(entry.getValue())));
+ }
+ }
+ // Add this at the end
rowModel.addCell(new CellModel(Bytes.toBytes(column),
Bytes.toBytes(valueToCheck)));
CellSetModel cellSetModel = new CellSetModel();
@@ -333,30 +340,46 @@ public class RowResourceBase {
protected static Response checkAndDeleteXML(String table, String row,
String column, String valueToCheck) throws IOException, JAXBException {
+ return checkAndDeleteXML(table, row, column, valueToCheck, null);
+ }
+ protected static Response checkAndDeleteXML(String table, String row,
+ String column, String valueToCheck, HashMap<String,String> cellsToDelete) throws IOException, JAXBException {
StringBuilder path = new StringBuilder();
path.append('/');
path.append(table);
path.append('/');
path.append(row);
path.append("?check=delete");
- return checkAndDeleteXML(path.toString(), table, row, column, valueToCheck);
+ return checkAndDeleteXML(path.toString(), table, row, column, valueToCheck, cellsToDelete);
}
protected static Response checkAndDeleteJson(String table, String row,
String column, String valueToCheck) throws IOException, JAXBException {
+ return checkAndDeleteJson(table, row, column, valueToCheck, null);
+ }
+
+ protected static Response checkAndDeleteJson(String table, String row,
+ String column, String valueToCheck, HashMap<String,String> cellsToDelete) throws IOException, JAXBException {
StringBuilder path = new StringBuilder();
path.append('/');
path.append(table);
path.append('/');
path.append(row);
path.append("?check=delete");
- return checkAndDeleteJson(path.toString(), table, row, column, valueToCheck);
+ return checkAndDeleteJson(path.toString(), table, row, column, valueToCheck, cellsToDelete);
}
protected static Response checkAndDeleteJson(String url, String table,
- String row, String column, String valueToCheck)
+ String row, String column, String valueToCheck, HashMap<String,String> cellsToDelete)
throws IOException, JAXBException {
RowModel rowModel = new RowModel(row);
+
+ if(cellsToDelete != null) {
+ for (Map.Entry<String,String> entry :cellsToDelete.entrySet()) {
+ rowModel.addCell(new CellModel(Bytes.toBytes(entry.getKey()), Bytes.toBytes(entry.getValue())));
+ }
+ }
+ // Add this at the end
rowModel.addCell(new CellModel(Bytes.toBytes(column),
Bytes.toBytes(valueToCheck)));
CellSetModel cellSetModel = new CellSetModel();
@@ -370,19 +393,31 @@ public class RowResourceBase {
protected static Response checkAndDeletePB(String table, String row,
String column, String value) throws IOException {
+
+ return checkAndDeletePB(table, row, column, value, null);
+ }
+
+ protected static Response checkAndDeletePB(String table, String row,
+ String column, String value, HashMap<String,String> cellsToDelete) throws IOException {
StringBuilder path = new StringBuilder();
path.append('/');
path.append(table);
path.append('/');
path.append(row);
path.append("?check=delete");
- return checkAndDeleteValuePB(path.toString(), table, row, column, value);
+ return checkAndDeleteValuePB(path.toString(), table, row, column, value, cellsToDelete);
}
-
protected static Response checkAndDeleteValuePB(String url, String table,
- String row, String column, String valueToCheck)
+ String row, String column, String valueToCheck, HashMap<String,String> cellsToDelete)
throws IOException {
RowModel rowModel = new RowModel(row);
+
+ if(cellsToDelete != null) {
+ for (Map.Entry<String,String> entry :cellsToDelete.entrySet()) {
+ rowModel.addCell(new CellModel(Bytes.toBytes(entry.getKey()), Bytes.toBytes(entry.getValue())));
+ }
+ }
+ // Add this at the end
rowModel.addCell(new CellModel(Bytes.toBytes(column), Bytes
.toBytes(valueToCheck)));
CellSetModel cellSetModel = new CellSetModel();
http://git-wip-us.apache.org/repos/asf/hbase/blob/56553517/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestGetAndPutResource.java
----------------------------------------------------------------------
diff --git a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestGetAndPutResource.java b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestGetAndPutResource.java
index 2fc7035..5c6fd91 100644
--- a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestGetAndPutResource.java
+++ b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestGetAndPutResource.java
@@ -198,6 +198,59 @@ public class TestGetAndPutResource extends RowResourceBase {
}
@Test
+ public void testMultipleCellCheckDeletePB() throws IOException, JAXBException {
+ Response response = getValuePB(TABLE, ROW_1, COLUMN_1);
+ assertEquals(response.getCode(), 404);
+
+ // Add 3 Columns to setup the test
+ response = putValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1);
+ assertEquals(response.getCode(), 200);
+ checkValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1);
+
+ response = putValuePB(TABLE, ROW_1, COLUMN_2, VALUE_2);
+ assertEquals(response.getCode(), 200);
+ checkValuePB(TABLE, ROW_1, COLUMN_2, VALUE_2);
+
+ response = putValuePB(TABLE, ROW_1, COLUMN_3, VALUE_3);
+ assertEquals(response.getCode(), 200);
+ checkValuePB(TABLE, ROW_1, COLUMN_3, VALUE_3);
+
+ // Deletes the following columns based on Column1 check
+ HashMap<String,String> cellsToDelete = new HashMap<String, String>();
+ cellsToDelete.put(COLUMN_2,VALUE_2); // Value does not matter
+ cellsToDelete.put(COLUMN_3,VALUE_3); // Value does not matter
+
+ // On Success update both the cells
+ response = checkAndDeletePB(TABLE, ROW_1, COLUMN_1, VALUE_1, cellsToDelete);
+ assertEquals(response.getCode(), 200);
+
+ checkValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1);
+
+ response = getValuePB(TABLE, ROW_1, COLUMN_2);
+ assertEquals(response.getCode(), 404);
+
+ response = getValuePB(TABLE, ROW_1, COLUMN_3);
+ assertEquals(response.getCode(), 404);
+
+ response = putValuePB(TABLE, ROW_1, COLUMN_2, VALUE_2);
+ assertEquals(response.getCode(), 200);
+ checkValuePB(TABLE, ROW_1, COLUMN_2, VALUE_2);
+
+ response = putValuePB(TABLE, ROW_1, COLUMN_3, VALUE_3);
+ assertEquals(response.getCode(), 200);
+ checkValuePB(TABLE, ROW_1, COLUMN_3, VALUE_3);
+
+ // On Failure, we dont update any cells
+ response = checkAndDeletePB(TABLE, ROW_1, COLUMN_1, VALUE_3, cellsToDelete);
+ assertEquals(response.getCode(), 304);
+ checkValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1);
+ checkValuePB(TABLE, ROW_1, COLUMN_2, VALUE_2);
+ checkValuePB(TABLE, ROW_1, COLUMN_3, VALUE_3);
+
+ response = deleteRow(TABLE, ROW_1);
+ assertEquals(response.getCode(), 200);
+ }
+ @Test
public void testSingleCellGetPutBinary() throws IOException {
final String path = "/" + TABLE + "/" + ROW_3 + "/" + COLUMN_1;
final byte[] body = Bytes.toBytes(VALUE_3);