HBASE-15290 Hbase Rest CheckAndAPI should save other cells along with compared 
cell (Ajith)


Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/d233e09c
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/d233e09c
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/d233e09c

Branch: refs/heads/branch-1
Commit: d233e09c1479ab0e46adf7bfc27cb890b493ae23
Parents: 46ffa85
Author: Enis Soztutar <e...@apache.org>
Authored: Fri Feb 26 15:05:59 2016 -0800
Committer: Enis Soztutar <e...@apache.org>
Committed: Fri Feb 26 15:06:05 2016 -0800

----------------------------------------------------------------------
 .../apache/hadoop/hbase/rest/RowResource.java   | 32 +++++++--
 .../hadoop/hbase/rest/RowResourceBase.java      | 39 +++++++++--
 .../hbase/rest/TestGetAndPutResource.java       | 69 ++++++++++++++++++++
 3 files changed, 129 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hbase/blob/d233e09c/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 dad5a32..39a4128 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
@@ -455,20 +455,40 @@ public class RowResource extends ResourceBase {
       byte[][] valueToPutParts = KeyValue.parseColumn(valueToCheckColumn);
       if (valueToPutParts.length == 2 && valueToPutParts[1].length > 0) {
         CellModel valueToPutCell = null;
+
+        // Copy all the cells to the Put request
+        // and track if the check cell's latest value is also sent
         for (int i = 0, n = cellModelCount - 1; i < n ; i++) {
-          if(Bytes.equals(cellModels.get(i).getColumn(),
-              valueToCheckCell.getColumn())) {
-            valueToPutCell = cellModels.get(i);
-            break;
+          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();
+          }
+
+          byte [][] parts = KeyValue.parseColumn(col);
+
+          if (parts.length != 2) {
+            return Response.status(Response.Status.BAD_REQUEST)
+                    .type(MIMETYPE_TEXT).entity("Bad request" + CRLF)
+                    .build();
+          }
+          put.addImmutable(parts[0], parts[1], cell.getTimestamp(), 
cell.getValue());
+
+          if(Bytes.equals(col,
+                  valueToCheckCell.getColumn())) {
+            valueToPutCell = cell;
           }
         }
+
         if (valueToPutCell == null) {
           servlet.getMetrics().incrementFailedPutRequests(1);
           return 
Response.status(Response.Status.BAD_REQUEST).type(MIMETYPE_TEXT)
               .entity("Bad request: The column to put and check do not match." 
+ CRLF).build();
         } else {
-          put.addImmutable(valueToPutParts[0], valueToPutParts[1], 
valueToPutCell.getTimestamp(),
-            valueToPutCell.getValue());
           retValue = table.checkAndPut(key, valueToPutParts[0], 
valueToPutParts[1],
             valueToCheckCell.getValue(), put);
         }

http://git-wip-us.apache.org/repos/asf/hbase/blob/d233e09c/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 0e74b46..c88bd4c 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
@@ -22,6 +22,7 @@ import static org.junit.Assert.assertEquals;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.StringWriter;
+import java.util.*;
 
 import javax.ws.rs.core.MediaType;
 import javax.xml.bind.JAXBContext;
@@ -29,6 +30,7 @@ import javax.xml.bind.JAXBException;
 import javax.xml.bind.Marshaller;
 import javax.xml.bind.Unmarshaller;
 
+import org.apache.commons.collections.keyvalue.AbstractMapEntry;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.HBaseTestingUtility;
 import org.apache.hadoop.hbase.HColumnDescriptor;
@@ -228,13 +230,22 @@ public class RowResourceBase {
   }
 
   protected static Response checkAndPutValuePB(String url, String table,
-      String row, String column, String valueToCheck, String valueToPut)
+      String row, String column, String valueToCheck, String valueToPut, 
HashMap<String,String> otherCells)
         throws IOException {
     RowModel rowModel = new RowModel(row);
     rowModel.addCell(new CellModel(Bytes.toBytes(column),
       Bytes.toBytes(valueToPut)));
+
+    if(otherCells != null) {
+      for (Map.Entry<String,String> entry :otherCells.entrySet()) {
+        rowModel.addCell(new CellModel(Bytes.toBytes(entry.getKey()), 
Bytes.toBytes(entry.getValue())));
+      }
+    }
+
+    // This Cell need to be added as last cell.
     rowModel.addCell(new CellModel(Bytes.toBytes(column),
       Bytes.toBytes(valueToCheck)));
+
     CellSetModel cellSetModel = new CellSetModel();
     cellSetModel.addRow(rowModel);
     Response response = client.put(url, Constants.MIMETYPE_PROTOBUF,
@@ -245,6 +256,10 @@ public class RowResourceBase {
 
   protected static Response checkAndPutValuePB(String table, String row,
       String column, String valueToCheck, String valueToPut) throws 
IOException {
+    return checkAndPutValuePB(table,row,column,valueToCheck,valueToPut,null);
+  }
+    protected static Response checkAndPutValuePB(String table, String row,
+      String column, String valueToCheck, String valueToPut, 
HashMap<String,String> otherCells) throws IOException {
     StringBuilder path = new StringBuilder();
     path.append('/');
     path.append(table);
@@ -252,15 +267,23 @@ public class RowResourceBase {
     path.append(row);
     path.append("?check=put");
     return checkAndPutValuePB(path.toString(), table, row, column,
-      valueToCheck, valueToPut);
+      valueToCheck, valueToPut, otherCells);
   }
 
   protected static Response checkAndPutValueXML(String url, String table,
-      String row, String column, String valueToCheck, String valueToPut)
+      String row, String column, String valueToCheck, String valueToPut, 
HashMap<String,String> otherCells)
         throws IOException, JAXBException {
     RowModel rowModel = new RowModel(row);
     rowModel.addCell(new CellModel(Bytes.toBytes(column),
       Bytes.toBytes(valueToPut)));
+
+    if(otherCells != null) {
+      for (Map.Entry<String,String> entry :otherCells.entrySet()) {
+        rowModel.addCell(new CellModel(Bytes.toBytes(entry.getKey()), 
Bytes.toBytes(entry.getValue())));
+      }
+    }
+
+    // This Cell need to be added as last cell.
     rowModel.addCell(new CellModel(Bytes.toBytes(column),
       Bytes.toBytes(valueToCheck)));
     CellSetModel cellSetModel = new CellSetModel();
@@ -274,7 +297,13 @@ public class RowResourceBase {
   }
 
   protected static Response checkAndPutValueXML(String table, String row,
-      String column, String valueToCheck, String valueToPut)
+                                                String column, String 
valueToCheck, String valueToPut)
+          throws IOException, JAXBException {
+    return checkAndPutValueXML(table,row,column,valueToCheck,valueToPut, null);
+  }
+
+  protected static Response checkAndPutValueXML(String table, String row,
+      String column, String valueToCheck, String valueToPut, 
HashMap<String,String> otherCells)
         throws IOException, JAXBException {
     StringBuilder path = new StringBuilder();
     path.append('/');
@@ -283,7 +312,7 @@ public class RowResourceBase {
     path.append(row);
     path.append("?check=put");
     return checkAndPutValueXML(path.toString(), table, row, column,
-      valueToCheck, valueToPut);
+      valueToCheck, valueToPut, otherCells);
   }
 
   protected static Response checkAndDeleteXML(String url, String table,

http://git-wip-us.apache.org/repos/asf/hbase/blob/d233e09c/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 959cb50..2fc7035 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
@@ -25,7 +25,10 @@ import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.StringWriter;
 import java.net.URLEncoder;
+import java.util.Dictionary;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import javax.xml.bind.JAXBException;
 
@@ -129,6 +132,72 @@ public class TestGetAndPutResource extends RowResourceBase 
{
   }
 
   @Test
+  public void testMultipleCellCheckPutPB() throws IOException, JAXBException {
+    Response response = getValuePB(TABLE, ROW_1, COLUMN_1);
+    assertEquals(response.getCode(), 404);
+
+    // Add 2 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);
+
+    HashMap<String,String> otherCells = new HashMap<String, String>();
+    otherCells.put(COLUMN_2,VALUE_3);
+
+    // On Success update both the cells
+    response = checkAndPutValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1, VALUE_3, 
otherCells);
+    assertEquals(response.getCode(), 200);
+    checkValuePB(TABLE, ROW_1, COLUMN_1, VALUE_3);
+    checkValuePB(TABLE, ROW_1, COLUMN_2, VALUE_3);
+
+    // On Failure, we dont update any cells
+    response = checkAndPutValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1, VALUE_4, 
otherCells);
+    assertEquals(response.getCode(), 304);
+    checkValuePB(TABLE, ROW_1, COLUMN_1, VALUE_3);
+    checkValuePB(TABLE, ROW_1, COLUMN_2, VALUE_3);
+
+    response = deleteRow(TABLE, ROW_1);
+    assertEquals(response.getCode(), 200);
+  }
+
+  @Test
+  public void testMultipleCellCheckPutXML() throws IOException, JAXBException {
+    Response response = getValuePB(TABLE, ROW_1, COLUMN_1);
+    assertEquals(response.getCode(), 404);
+
+    // Add 2 Columns to setup the test
+    response = putValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1);
+    assertEquals(response.getCode(), 200);
+    checkValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1);
+
+    response = putValueXML(TABLE, ROW_1, COLUMN_2, VALUE_2);
+    assertEquals(response.getCode(), 200);
+    checkValueXML(TABLE, ROW_1, COLUMN_2, VALUE_2);
+
+    HashMap<String,String> otherCells = new HashMap<String, String>();
+    otherCells.put(COLUMN_2,VALUE_3);
+
+    // On Success update both the cells
+    response = checkAndPutValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1, VALUE_3, 
otherCells);
+    assertEquals(response.getCode(), 200);
+    checkValueXML(TABLE, ROW_1, COLUMN_1, VALUE_3);
+    checkValueXML(TABLE, ROW_1, COLUMN_2, VALUE_3);
+
+    // On Failure, we dont update any cells
+    response = checkAndPutValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1, VALUE_4, 
otherCells);
+    assertEquals(response.getCode(), 304);
+    checkValueXML(TABLE, ROW_1, COLUMN_1, VALUE_3);
+    checkValueXML(TABLE, ROW_1, COLUMN_2, 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);

Reply via email to