hbase-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From te...@apache.org
Subject hbase git commit: HBASE-18671 Support Append/Increment in rest api
Date Sat, 26 Aug 2017 13:45:05 GMT
Repository: hbase
Updated Branches:
  refs/heads/branch-1.4 a02521929 -> ca3f2f48e


HBASE-18671 Support Append/Increment in rest api

Signed-off-by: tedyu <yuzhihong@gmail.com>


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

Branch: refs/heads/branch-1.4
Commit: ca3f2f48eba977cf12a0986874d9f4660a50c4f6
Parents: a025219
Author: Guangxu Cheng <guangxucheng@gmail.com>
Authored: Sat Aug 26 20:17:02 2017 +0800
Committer: tedyu <yuzhihong@gmail.com>
Committed: Sat Aug 26 06:44:59 2017 -0700

----------------------------------------------------------------------
 .../hadoop/hbase/rest/MetricsRESTSource.java    |  38 +++-
 .../hbase/rest/MetricsRESTSourceImpl.java       |  28 +++
 .../apache/hadoop/hbase/rest/MetricsREST.java   |  28 +++
 .../apache/hadoop/hbase/rest/RowResource.java   | 218 ++++++++++++++++++-
 .../apache/hadoop/hbase/rest/TableResource.java |  10 +-
 .../hadoop/hbase/rest/RowResourceBase.java      | 109 +++++++++-
 .../hbase/rest/TestGetAndPutResource.java       | 105 +++++++++
 7 files changed, 524 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hbase/blob/ca3f2f48/hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/rest/MetricsRESTSource.java
----------------------------------------------------------------------
diff --git a/hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/rest/MetricsRESTSource.java
b/hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/rest/MetricsRESTSource.java
index ceec41d..a5101e0 100644
--- a/hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/rest/MetricsRESTSource.java
+++ b/hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/rest/MetricsRESTSource.java
@@ -52,6 +52,14 @@ public interface MetricsRESTSource extends BaseSource, JvmPauseMonitorSource
{
   
   String FAILED_SCAN_KEY = "failedScanCount";
 
+  String SUCCESSFUL_APPEND_KEY = "successfulAppendCount";
+
+  String FAILED_APPEND_KEY = "failedAppendCount";
+
+  String SUCCESSFUL_INCREMENT_KEY = "successfulIncrementCount";
+
+  String FAILED_INCREMENT_KEY = "failedIncrementCount";
+
   /**
    * Increment the number of requests
    *
@@ -111,7 +119,35 @@ public interface MetricsRESTSource extends BaseSource, JvmPauseMonitorSource
{
   /**
    * Increment the number failed scan requests.
    *
-   * @param inc the inc
+   * @param inc Number of failed scan requests.
    */
   void incrementFailedScanRequests(final int inc);
+
+  /**
+   * Increment the number of successful append requests.
+   *
+   * @param inc Number of successful append requests.
+   */
+  void incrementSucessfulAppendRequests(final int inc);
+
+  /**
+   * Increment the number failed append requests.
+   *
+   * @param inc Number of failed append requests.
+   */
+  void incrementFailedAppendRequests(final int inc);
+
+  /**
+   * Increment the number of successful increment requests.
+   *
+   * @param inc Number of successful increment requests.
+   */
+  void incrementSucessfulIncrementRequests(final int inc);
+
+  /**
+   * Increment the number failed increment requests.
+   *
+   * @param inc Number of failed increment requests.
+   */
+  void incrementFailedIncrementRequests(final int inc);
 }

http://git-wip-us.apache.org/repos/asf/hbase/blob/ca3f2f48/hbase-hadoop2-compat/src/main/java/org/apache/hadoop/hbase/rest/MetricsRESTSourceImpl.java
----------------------------------------------------------------------
diff --git a/hbase-hadoop2-compat/src/main/java/org/apache/hadoop/hbase/rest/MetricsRESTSourceImpl.java
b/hbase-hadoop2-compat/src/main/java/org/apache/hadoop/hbase/rest/MetricsRESTSourceImpl.java
index 30625f8..9360e32 100644
--- a/hbase-hadoop2-compat/src/main/java/org/apache/hadoop/hbase/rest/MetricsRESTSourceImpl.java
+++ b/hbase-hadoop2-compat/src/main/java/org/apache/hadoop/hbase/rest/MetricsRESTSourceImpl.java
@@ -37,10 +37,14 @@ public class MetricsRESTSourceImpl extends BaseSourceImpl implements MetricsREST
   private MutableFastCounter sucPut;
   private MutableFastCounter sucDel;
   private MutableFastCounter sucScan;
+  private MutableFastCounter sucAppend;
+  private MutableFastCounter sucIncrement;
   private MutableFastCounter fGet;
   private MutableFastCounter fPut;
   private MutableFastCounter fDel;
   private MutableFastCounter fScan;
+  private MutableFastCounter fAppend;
+  private MutableFastCounter fIncrement;
 
   // pause monitor metrics
   private final MutableFastCounter infoPauseThresholdExceeded;
@@ -76,11 +80,15 @@ public class MetricsRESTSourceImpl extends BaseSourceImpl implements MetricsREST
     sucPut = getMetricsRegistry().getCounter(SUCCESSFUL_PUT_KEY, 0l);
     sucDel = getMetricsRegistry().getCounter(SUCCESSFUL_DELETE_KEY, 0l);
     sucScan = getMetricsRegistry().getCounter(SUCCESSFUL_SCAN_KEY, 0L);
+    sucAppend = getMetricsRegistry().getCounter(SUCCESSFUL_APPEND_KEY, 0l);
+    sucIncrement = getMetricsRegistry().getCounter(SUCCESSFUL_INCREMENT_KEY, 0L);
 
     fGet = getMetricsRegistry().getCounter(FAILED_GET_KEY, 0l);
     fPut = getMetricsRegistry().getCounter(FAILED_PUT_KEY, 0l);
     fDel = getMetricsRegistry().getCounter(FAILED_DELETE_KEY, 0l);
     fScan = getMetricsRegistry().getCounter(FAILED_SCAN_KEY, 0l);
+    fAppend = getMetricsRegistry().getCounter(FAILED_APPEND_KEY, 0l);
+    fIncrement = getMetricsRegistry().getCounter(FAILED_INCREMENT_KEY, 0L);
   }
 
   @Override
@@ -129,6 +137,26 @@ public class MetricsRESTSourceImpl extends BaseSourceImpl implements
MetricsREST
   }
 
   @Override
+  public void incrementSucessfulAppendRequests(int inc) {
+    sucAppend.incr(inc);
+  }
+
+  @Override
+  public void incrementFailedAppendRequests(int inc) {
+    fAppend.incr(inc);
+  }
+
+  @Override
+  public void incrementSucessfulIncrementRequests(int inc) {
+    sucIncrement.incr(inc);
+  }
+
+  @Override
+  public void incrementFailedIncrementRequests(int inc) {
+    fIncrement.incr(inc);
+  }
+
+  @Override
   public void incInfoThresholdExceeded(int count) {
     infoPauseThresholdExceeded.incr(count);
   }

http://git-wip-us.apache.org/repos/asf/hbase/blob/ca3f2f48/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/MetricsREST.java
----------------------------------------------------------------------
diff --git a/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/MetricsREST.java b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/MetricsREST.java
index e31037a..8389ed1 100644
--- a/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/MetricsREST.java
+++ b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/MetricsREST.java
@@ -100,4 +100,32 @@ public class MetricsREST {
     source.incrementFailedScanRequests(inc);
   }
 
+  /**
+   * @param inc How much to add to sucessfulAppendCount.
+   */
+  public synchronized void incrementSucessfulAppendRequests(final int inc) {
+    source.incrementSucessfulAppendRequests(inc);
+  }
+
+  /**
+   * @param inc How much to add to failedAppendCount.
+   */
+  public void incrementFailedAppendRequests(final int inc) {
+    source.incrementFailedAppendRequests(inc);
+  }
+
+  /**
+   * @param inc How much to add to sucessfulIncrementCount.
+   */
+  public synchronized void incrementSucessfulIncrementRequests(final int inc) {
+    source.incrementSucessfulIncrementRequests(inc);
+  }
+
+  /**
+   * @param inc How much to add to failedIncrementCount.
+   */
+  public void incrementFailedIncrementRequests(final int inc) {
+    source.incrementFailedIncrementRequests(inc);
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/hbase/blob/ca3f2f48/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 61cc795..bb28b1b 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
@@ -44,8 +44,11 @@ import org.apache.hadoop.hbase.Cell;
 import org.apache.hadoop.hbase.CellUtil;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.KeyValue;
+import org.apache.hadoop.hbase.client.Append;
 import org.apache.hadoop.hbase.client.Delete;
+import org.apache.hadoop.hbase.client.Increment;
 import org.apache.hadoop.hbase.client.Put;
+import org.apache.hadoop.hbase.client.Result;
 import org.apache.hadoop.hbase.client.Table;
 import org.apache.hadoop.hbase.rest.model.CellModel;
 import org.apache.hadoop.hbase.rest.model.CellSetModel;
@@ -56,22 +59,27 @@ import org.apache.hadoop.hbase.util.Bytes;
 public class RowResource extends ResourceBase {
   private static final Log LOG = LogFactory.getLog(RowResource.class);
 
-  static final String CHECK_PUT = "put";
-  static final String CHECK_DELETE = "delete";
+  private static final String CHECK_PUT = "put";
+  private static final String CHECK_DELETE = "delete";
+  private static final String CHECK_APPEND = "append";
+  private static final String CHECK_INCREMENT = "increment";
 
-  TableResource tableResource;
-  RowSpec rowspec;
+  private TableResource tableResource;
+  private RowSpec rowspec;
   private String check = null;
+  private boolean returnResult = false;
 
   /**
    * Constructor
    * @param tableResource
    * @param rowspec
    * @param versions
+   * @param check
+   * @param returnResult
    * @throws IOException
    */
   public RowResource(TableResource tableResource, String rowspec,
-      String versions, String check) throws IOException {
+      String versions, String check, String returnResult) throws IOException {
     super();
     this.tableResource = tableResource;
     this.rowspec = new RowSpec(rowspec);
@@ -79,6 +87,9 @@ public class RowResource extends ResourceBase {
       this.rowspec.setMaxVersions(Integer.parseInt(versions));
     }
     this.check = check;
+    if (returnResult != null) {
+      this.returnResult = Boolean.valueOf(returnResult);
+    }
   }
 
   @GET
@@ -182,6 +193,10 @@ public class RowResource extends ResourceBase {
       return checkAndPut(model);
     } else if (CHECK_DELETE.equalsIgnoreCase(check)) {
       return checkAndDelete(model);
+    } else if (CHECK_APPEND.equalsIgnoreCase(check)) {
+      return append(model);
+    } else if (CHECK_INCREMENT.equalsIgnoreCase(check)) {
+      return increment(model);
     } else if (check != null && check.length() > 0) {
       return Response.status(Response.Status.BAD_REQUEST)
         .type(MIMETYPE_TEXT).entity("Invalid check value '" + check + "'" + CRLF)
@@ -544,7 +559,7 @@ public class RowResource extends ResourceBase {
       if (model.getRows().size() != 1) {
         servlet.getMetrics().incrementFailedDeleteRequests(1);
         return Response.status(Response.Status.BAD_REQUEST)
-          .type(MIMETYPE_TEXT).entity("Bad request" + CRLF)
+          .type(MIMETYPE_TEXT).entity("Bad request: Number of rows specified is not 1." +
CRLF)
           .build();
       }
       RowModel rowModel = model.getRows().get(0);
@@ -658,4 +673,195 @@ public class RowResource extends ResourceBase {
       }
     }
   }
+
+  /**
+   * Validates the input request parameters, parses columns from CellSetModel,
+   * and invokes Append on HTable.
+   *
+   * @param model instance of CellSetModel
+   * @return Response 200 OK, 304 Not modified, 400 Bad request
+   */
+  Response append(final CellSetModel model) {
+    Table table = null;
+    Append append = null;
+    try {
+      table = servlet.getTable(tableResource.getName());
+      if (model.getRows().size() != 1) {
+        servlet.getMetrics().incrementFailedAppendRequests(1);
+        return Response.status(Response.Status.BAD_REQUEST)
+                .type(MIMETYPE_TEXT).entity("Bad request: Number of rows specified is not
1." + CRLF)
+                .build();
+      }
+      RowModel rowModel = model.getRows().get(0);
+      byte[] key = rowModel.getKey();
+      if (key == null) {
+        key = rowspec.getRow();
+      }
+      if (key == null) {
+        servlet.getMetrics().incrementFailedAppendRequests(1);
+        return Response.status(Response.Status.BAD_REQUEST)
+                .type(MIMETYPE_TEXT).entity("Bad request: Row key found to be null." + CRLF)
+                .build();
+      }
+
+      append = new Append(key);
+      append.setReturnResults(returnResult);
+      int i = 0;
+      for (CellModel cell: rowModel.getCells()) {
+        byte[] col = cell.getColumn();
+        if (col == null) {
+          try {
+            col = rowspec.getColumns()[i++];
+          } catch (ArrayIndexOutOfBoundsException e) {
+            col = null;
+          }
+        }
+        if (col == null) {
+          servlet.getMetrics().incrementFailedAppendRequests(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) {
+          servlet.getMetrics().incrementFailedAppendRequests(1);
+          return Response.status(Response.Status.BAD_REQUEST)
+                  .type(MIMETYPE_TEXT).entity("Bad request: Column incorrectly specified."
+ CRLF)
+                  .build();
+        }
+        append.add(parts[0], parts[1], cell.getValue());
+      }
+
+      if (LOG.isDebugEnabled()) {
+        LOG.debug("APPEND " + append.toString());
+      }
+      Result result = table.append(append);
+      if (returnResult) {
+        if (result.isEmpty()) {
+          servlet.getMetrics().incrementFailedAppendRequests(1);
+          return Response.status(Response.Status.NOT_MODIFIED)
+                  .type(MIMETYPE_TEXT).entity("Append return empty." + CRLF)
+                  .build();
+        }
+
+        CellSetModel rModel = new CellSetModel();
+        RowModel rRowModel = new RowModel(result.getRow());
+        for (Cell cell : result.listCells()) {
+          rRowModel.addCell(new CellModel(CellUtil.cloneFamily(cell), CellUtil.cloneQualifier(cell),
+                  cell.getTimestamp(), CellUtil.cloneValue(cell)));
+        }
+        rModel.addRow(rRowModel);
+        servlet.getMetrics().incrementSucessfulAppendRequests(1);
+        return Response.ok(rModel).build();
+      }
+      servlet.getMetrics().incrementSucessfulAppendRequests(1);
+      return Response.ok().build();
+    } catch (Exception e) {
+      servlet.getMetrics().incrementFailedAppendRequests(1);
+      return processException(e);
+    } finally {
+      if (table != null) try {
+        table.close();
+      } catch (IOException ioe) {
+        LOG.debug("Exception received while closing the table" + table.getName(), ioe);
+      }
+    }
+  }
+
+  /**
+   * Validates the input request parameters, parses columns from CellSetModel,
+   * and invokes Increment on HTable.
+   *
+   * @param model instance of CellSetModel
+   * @return Response 200 OK, 304 Not modified, 400 Bad request
+   */
+  Response increment(final CellSetModel model) {
+    Table table = null;
+    Increment increment = null;
+    try {
+      table = servlet.getTable(tableResource.getName());
+      if (model.getRows().size() != 1) {
+        servlet.getMetrics().incrementFailedIncrementRequests(1);
+        return Response.status(Response.Status.BAD_REQUEST)
+                .type(MIMETYPE_TEXT).entity("Bad request: Number of rows specified is not
1." + CRLF)
+                .build();
+      }
+      RowModel rowModel = model.getRows().get(0);
+      byte[] key = rowModel.getKey();
+      if (key == null) {
+        key = rowspec.getRow();
+      }
+      if (key == null) {
+        servlet.getMetrics().incrementFailedIncrementRequests(1);
+        return Response.status(Response.Status.BAD_REQUEST)
+                .type(MIMETYPE_TEXT).entity("Bad request: Row key found to be null." + CRLF)
+                .build();
+      }
+
+      increment = new Increment(key);
+      increment.setReturnResults(returnResult);
+      int i = 0;
+      for (CellModel cell: rowModel.getCells()) {
+        byte[] col = cell.getColumn();
+        if (col == null) {
+          try {
+            col = rowspec.getColumns()[i++];
+          } catch (ArrayIndexOutOfBoundsException e) {
+            col = null;
+          }
+        }
+        if (col == null) {
+          servlet.getMetrics().incrementFailedIncrementRequests(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) {
+          servlet.getMetrics().incrementFailedIncrementRequests(1);
+          return Response.status(Response.Status.BAD_REQUEST)
+                  .type(MIMETYPE_TEXT).entity("Bad request: Column incorrectly specified."
+ CRLF)
+                  .build();
+        }
+        increment.addColumn(parts[0], parts[1], Long.parseLong(Bytes.toStringBinary(cell.getValue())));
+      }
+
+      if (LOG.isDebugEnabled()) {
+        LOG.debug("INCREMENT " + increment.toString());
+      }
+      Result result = table.increment(increment);
+
+      if (returnResult) {
+        if (result.isEmpty()) {
+          servlet.getMetrics().incrementFailedIncrementRequests(1);
+          return Response.status(Response.Status.NOT_MODIFIED)
+                  .type(MIMETYPE_TEXT).entity("Increment return empty." + CRLF)
+                  .build();
+        }
+
+        CellSetModel rModel = new CellSetModel();
+        RowModel rRowModel = new RowModel(result.getRow());
+        for (Cell cell : result.listCells()) {
+          rRowModel.addCell(new CellModel(CellUtil.cloneFamily(cell), CellUtil.cloneQualifier(cell),
+                  cell.getTimestamp(), CellUtil.cloneValue(cell)));
+        }
+        rModel.addRow(rowModel);
+        servlet.getMetrics().incrementSucessfulIncrementRequests(1);
+        return Response.ok(rModel).build();
+      }
+
+      ResponseBuilder response = Response.ok();
+      servlet.getMetrics().incrementSucessfulIncrementRequests(1);
+      return response.build();
+    } catch (Exception e) {
+      servlet.getMetrics().incrementFailedIncrementRequests(1);
+      return processException(e);
+    } finally {
+      if (table != null) try {
+        table.close();
+      } catch (IOException ioe) {
+        LOG.debug("Exception received while closing the table " + table.getName(), ioe);
+      }
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/hbase/blob/ca3f2f48/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 2127dad..a1a60bb 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
@@ -105,8 +105,9 @@ public class TableResource extends ResourceBase {
       // the RowSpec constructor has a chance to parse
       final @PathParam("rowspec") @Encoded String rowspec,
       final @QueryParam("v") String versions,
-      final @QueryParam("check") String check) throws IOException {
-    return new RowResource(this, rowspec, versions, check);
+      final @QueryParam("check") String check,
+      final @QueryParam("rr") String returnResult) throws IOException {
+    return new RowResource(this, rowspec, versions, check, returnResult);
   }
 
   @Path("{suffixglobbingspec: .*\\*/.+}")
@@ -115,8 +116,9 @@ public class TableResource extends ResourceBase {
       // the RowSpec constructor has a chance to parse
       final @PathParam("suffixglobbingspec") @Encoded String suffixglobbingspec,
       final @QueryParam("v") String versions,
-      final @QueryParam("check") String check) throws IOException {
-    return new RowResource(this, suffixglobbingspec, versions, check);
+      final @QueryParam("check") String check,
+      final @QueryParam("rr") String returnResult) throws IOException {
+    return new RowResource(this, suffixglobbingspec, versions, check, returnResult);
   }
 
   @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="REC_CATCH_EXCEPTION")

http://git-wip-us.apache.org/repos/asf/hbase/blob/ca3f2f48/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 060409e..00abe3a 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
@@ -30,7 +30,6 @@ 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;
@@ -45,6 +44,7 @@ import org.apache.hadoop.hbase.rest.model.CellSetModel;
 import org.apache.hadoop.hbase.rest.model.RowModel;
 import org.apache.hadoop.hbase.rest.provider.JacksonProvider;
 import org.apache.hadoop.hbase.util.Bytes;
+import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider;
 import org.codehaus.jackson.map.ObjectMapper;
 import org.junit.After;
 import org.junit.AfterClass;
@@ -67,6 +67,8 @@ public class RowResourceBase {
   protected static final String VALUE_3 = "testvalue3";
   protected static final String ROW_4 = "testrow4";
   protected static final String VALUE_4 = "testvalue4";
+  protected static final String VALUE_5 = "5";
+  protected static final String VALUE_6 = "6";
 
   protected static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
   protected static final HBaseRESTTestingUtility REST_TEST_UTIL =
@@ -172,6 +174,19 @@ public class RowResourceBase {
     assertEquals(Bytes.toString(cell.getValue()), value);
   }
 
+  protected static void checkIncrementValueXML(String table, String row, String column,
+                                      long value) throws IOException, JAXBException {
+    Response response1 = getValueXML(table, row, column);
+    assertEquals(response1.getCode(), 200);
+    assertEquals(Constants.MIMETYPE_XML, response1.getHeader("content-type"));
+    CellSetModel cellSet = (CellSetModel)
+            xmlUnmarshaller.unmarshal(new ByteArrayInputStream(response1.getBody()));
+    RowModel rowModel = cellSet.getRows().get(0);
+    CellModel cell = rowModel.getCells().get(0);
+    assertEquals(Bytes.toString(cell.getColumn()), column);
+    assertEquals(Bytes.toLong(cell.getValue()), value);
+  }
+
   protected static Response getValuePB(String url) throws IOException {
     Response response = client.get(url, Constants.MIMETYPE_PROTOBUF); 
     return response;
@@ -229,6 +244,19 @@ public class RowResourceBase {
     assertEquals(Bytes.toString(cell.getValue()), value);
   }
 
+  protected static void checkIncrementValuePB(String table, String row, String column,
+      long value) throws IOException {
+    Response response = getValuePB(table, row, column);
+    assertEquals(response.getCode(), 200);
+    assertEquals(Constants.MIMETYPE_PROTOBUF, response.getHeader("content-type"));
+    CellSetModel cellSet = new CellSetModel();
+    cellSet.getObjectFromMessage(response.getBody());
+    RowModel rowModel = cellSet.getRows().get(0);
+    CellModel cell = rowModel.getCells().get(0);
+    assertEquals(Bytes.toString(cell.getColumn()), column);
+    assertEquals(Bytes.toLong(cell.getValue()), value);
+  }
+
   protected static Response checkAndPutValuePB(String url, String table,
       String row, String column, String valueToCheck, String valueToPut, HashMap<String,String>
otherCells)
         throws IOException {
@@ -516,6 +544,20 @@ public class RowResourceBase {
     assertEquals(Bytes.toString(cell.getValue()), value);
   }
 
+  protected static void checkIncrementValueJSON(String table, String row, String column,
+      long value) throws IOException, JAXBException {
+    Response response = getValueJson(table, row, column);
+    assertEquals(response.getCode(), 200);
+    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);
+    RowModel rowModel = cellSet.getRows().get(0);
+    CellModel cell = rowModel.getCells().get(0);
+    assertEquals(Bytes.toString(cell.getColumn()), column);
+    assertEquals(Bytes.toLong(cell.getValue()), value);
+  }
+
   protected static Response putValueJson(String table, String row, String column,
       String value) throws IOException, JAXBException {
     StringBuilder path = new StringBuilder();
@@ -542,4 +584,69 @@ public class RowResourceBase {
     return response;
   }
 
+  protected static Response appendValueXML(String table, String row, String column,
+      String value) throws IOException, JAXBException {
+    StringBuilder path = new StringBuilder();
+    path.append('/');
+    path.append(table);
+    path.append('/');
+    path.append(row);
+    path.append("?check=append");
+    return putValueXML(path.toString(), table, row, column, value);
+  }
+
+  protected static Response appendValuePB(String table, String row, String column,
+      String value) throws IOException, JAXBException {
+    StringBuilder path = new StringBuilder();
+    path.append('/');
+    path.append(table);
+    path.append('/');
+    path.append(row);
+    path.append("?check=append");
+    return putValuePB(path.toString(), table, row, column, value);
+  }
+
+  protected static Response appendValueJson(String table, String row, String column,
+      String value) throws IOException, JAXBException {
+    StringBuilder path = new StringBuilder();
+    path.append('/');
+    path.append(table);
+    path.append('/');
+    path.append(row);
+    path.append("?check=append");
+    return putValueJson(path.toString(), table, row, column, value);
+  }
+
+  protected static Response incrementValueXML(String table, String row, String column,
+      String value) throws IOException, JAXBException {
+    StringBuilder path = new StringBuilder();
+    path.append('/');
+    path.append(table);
+    path.append('/');
+    path.append(row);
+    path.append("?check=increment");
+    return putValueXML(path.toString(), table, row, column, value);
+  }
+
+  protected static Response incrementValuePB(String table, String row, String column,
+      String value) throws IOException, JAXBException {
+    StringBuilder path = new StringBuilder();
+    path.append('/');
+    path.append(table);
+    path.append('/');
+    path.append(row);
+    path.append("?check=increment");
+    return putValuePB(path.toString(), table, row, column, value);
+  }
+
+  protected static Response incrementValueJson(String table, String row, String column,
+      String value) throws IOException, JAXBException {
+    StringBuilder path = new StringBuilder();
+    path.append('/');
+    path.append(table);
+    path.append('/');
+    path.append(row);
+    path.append("?check=increment");
+    return putValueJson(path.toString(), table, row, column, value);
+  }
 }

http://git-wip-us.apache.org/repos/asf/hbase/blob/ca3f2f48/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 5c6fd91..25b445e 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
@@ -701,5 +701,110 @@ public class TestGetAndPutResource extends RowResourceBase {
     response = deleteRow(TABLE, ROW_2);
     assertEquals(response.getCode(), 200);
   }
+
+  @Test
+  public void testAppendXML() throws IOException, JAXBException {
+    Response response = getValueXML(TABLE, ROW_1, COLUMN_1);
+    assertEquals(response.getCode(), 404);
+
+    //append cell
+    response = appendValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1);
+    assertEquals(response.getCode(), 200);
+    checkValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1);
+    response = appendValueXML(TABLE, ROW_1, COLUMN_1, VALUE_2);
+    assertEquals(response.getCode(), 200);
+    checkValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1 + VALUE_2);
+
+    response = deleteRow(TABLE, ROW_1);
+    assertEquals(response.getCode(), 200);
+  }
+
+  @Test
+  public void testAppendPB() throws IOException, JAXBException {
+    Response response = getValuePB(TABLE, ROW_1, COLUMN_1);
+    assertEquals(response.getCode(), 404);
+
+    //append cell
+    response = appendValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1);
+    assertEquals(response.getCode(), 200);
+    checkValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1);
+    response = appendValuePB(TABLE, ROW_1, COLUMN_1, VALUE_2);
+    assertEquals(response.getCode(), 200);
+    checkValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1 + VALUE_2);
+
+    response = deleteRow(TABLE, ROW_1);
+    assertEquals(response.getCode(), 200);
+  }
+
+  @Test
+  public void testAppendJSON() throws IOException, JAXBException {
+    Response response = getValueJson(TABLE, ROW_1, COLUMN_1);
+    assertEquals(response.getCode(), 404);
+
+    //append cell
+    response = appendValueJson(TABLE, ROW_1, COLUMN_1, VALUE_1);
+    assertEquals(response.getCode(), 200);
+    putValueJson(TABLE, ROW_1, COLUMN_1, VALUE_1);
+    response = appendValueJson(TABLE, ROW_1, COLUMN_1, VALUE_2);
+    assertEquals(response.getCode(), 200);
+    putValueJson(TABLE, ROW_1, COLUMN_1, VALUE_1 + VALUE_2);
+
+    response = deleteRow(TABLE, ROW_1);
+    assertEquals(response.getCode(), 200);
+  }
+
+  @Test
+  public void testIncrementXML() throws IOException, JAXBException {
+    Response response = getValueXML(TABLE, ROW_1, COLUMN_1);
+    assertEquals(response.getCode(), 404);
+
+    //append single cell
+    response = incrementValueXML(TABLE, ROW_1, COLUMN_1, VALUE_5);
+    assertEquals(response.getCode(), 200);
+    checkIncrementValueXML(TABLE, ROW_1, COLUMN_1, Long.parseLong(VALUE_5));
+    response = incrementValueXML(TABLE, ROW_1, COLUMN_1, VALUE_6);
+    assertEquals(response.getCode(), 200);
+    checkIncrementValueXML(TABLE, ROW_1, COLUMN_1,
+        Long.parseLong(VALUE_5) + Long.parseLong(VALUE_6));
+
+    response = deleteRow(TABLE, ROW_1);
+    assertEquals(response.getCode(), 200);
+  }
+
+  @Test
+  public void testIncrementPB() throws IOException, JAXBException {
+    Response response = getValuePB(TABLE, ROW_1, COLUMN_1);
+    assertEquals(response.getCode(), 404);
+
+    //append cell
+    response = incrementValuePB(TABLE, ROW_1, COLUMN_1, VALUE_5);
+    assertEquals(response.getCode(), 200);
+    checkIncrementValuePB(TABLE, ROW_1, COLUMN_1, Long.parseLong(VALUE_5));
+    response = incrementValuePB(TABLE, ROW_1, COLUMN_1, VALUE_6);
+    assertEquals(response.getCode(), 200);
+    checkIncrementValuePB(TABLE, ROW_1, COLUMN_1,
+        Long.parseLong(VALUE_5) + Long.parseLong(VALUE_6));
+
+    response = deleteRow(TABLE, ROW_1);
+    assertEquals(response.getCode(), 200);
+  }
+
+  @Test
+  public void testIncrementJSON() throws IOException, JAXBException {
+    Response response = getValueJson(TABLE, ROW_1, COLUMN_1);
+    assertEquals(response.getCode(), 404);
+
+    //append cell
+    response = incrementValueJson(TABLE, ROW_1, COLUMN_1, VALUE_5);
+    assertEquals(response.getCode(), 200);
+    checkIncrementValueJSON(TABLE, ROW_1, COLUMN_1, Long.parseLong(VALUE_5));
+    response = incrementValueJson(TABLE, ROW_1, COLUMN_1, VALUE_6);
+    assertEquals(response.getCode(), 200);
+    checkIncrementValueJSON(TABLE, ROW_1, COLUMN_1,
+        Long.parseLong(VALUE_5) + Long.parseLong(VALUE_6));
+
+    response = deleteRow(TABLE, ROW_1);
+    assertEquals(response.getCode(), 200);
+  }
 }
 


Mime
View raw message