HBASE-18671 Support Append/Increment in rest api

Signed-off-by: tedyu <yuzhihong@gmail.com>
This commit is contained in:
Guangxu Cheng 2017-08-25 08:16:08 +08:00 committed by tedyu
parent 37c40afaff
commit e58670683b
7 changed files with 523 additions and 12 deletions

View File

@ -52,6 +52,14 @@ public interface MetricsRESTSource extends BaseSource, JvmPauseMonitorSource {
String FAILED_SCAN_KEY = "failedScanCount"; 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 * Increment the number of requests
* *
@ -111,7 +119,35 @@ public interface MetricsRESTSource extends BaseSource, JvmPauseMonitorSource {
/** /**
* Increment the number failed scan requests. * Increment the number failed scan requests.
* *
* @param inc the inc * @param inc Number of failed scan requests.
*/ */
void incrementFailedScanRequests(final int inc); 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);
} }

View File

@ -37,10 +37,14 @@ public class MetricsRESTSourceImpl extends BaseSourceImpl implements MetricsREST
private MutableFastCounter sucPut; private MutableFastCounter sucPut;
private MutableFastCounter sucDel; private MutableFastCounter sucDel;
private MutableFastCounter sucScan; private MutableFastCounter sucScan;
private MutableFastCounter sucAppend;
private MutableFastCounter sucIncrement;
private MutableFastCounter fGet; private MutableFastCounter fGet;
private MutableFastCounter fPut; private MutableFastCounter fPut;
private MutableFastCounter fDel; private MutableFastCounter fDel;
private MutableFastCounter fScan; private MutableFastCounter fScan;
private MutableFastCounter fAppend;
private MutableFastCounter fIncrement;
// pause monitor metrics // pause monitor metrics
private final MutableFastCounter infoPauseThresholdExceeded; private final MutableFastCounter infoPauseThresholdExceeded;
@ -76,11 +80,15 @@ public class MetricsRESTSourceImpl extends BaseSourceImpl implements MetricsREST
sucPut = getMetricsRegistry().getCounter(SUCCESSFUL_PUT_KEY, 0l); sucPut = getMetricsRegistry().getCounter(SUCCESSFUL_PUT_KEY, 0l);
sucDel = getMetricsRegistry().getCounter(SUCCESSFUL_DELETE_KEY, 0l); sucDel = getMetricsRegistry().getCounter(SUCCESSFUL_DELETE_KEY, 0l);
sucScan = getMetricsRegistry().getCounter(SUCCESSFUL_SCAN_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); fGet = getMetricsRegistry().getCounter(FAILED_GET_KEY, 0l);
fPut = getMetricsRegistry().getCounter(FAILED_PUT_KEY, 0l); fPut = getMetricsRegistry().getCounter(FAILED_PUT_KEY, 0l);
fDel = getMetricsRegistry().getCounter(FAILED_DELETE_KEY, 0l); fDel = getMetricsRegistry().getCounter(FAILED_DELETE_KEY, 0l);
fScan = getMetricsRegistry().getCounter(FAILED_SCAN_KEY, 0l); fScan = getMetricsRegistry().getCounter(FAILED_SCAN_KEY, 0l);
fAppend = getMetricsRegistry().getCounter(FAILED_APPEND_KEY, 0l);
fIncrement = getMetricsRegistry().getCounter(FAILED_INCREMENT_KEY, 0L);
} }
@Override @Override
@ -128,6 +136,26 @@ public class MetricsRESTSourceImpl extends BaseSourceImpl implements MetricsREST
fScan.incr(inc); fScan.incr(inc);
} }
@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 @Override
public void incInfoThresholdExceeded(int count) { public void incInfoThresholdExceeded(int count) {
infoPauseThresholdExceeded.incr(count); infoPauseThresholdExceeded.incr(count);

View File

@ -100,4 +100,32 @@ public class MetricsREST {
source.incrementFailedScanRequests(inc); 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);
}
} }

View File

@ -44,8 +44,11 @@ import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil; import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.KeyValue; 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.Delete;
import org.apache.hadoop.hbase.client.Increment;
import org.apache.hadoop.hbase.client.Put; 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.client.Table;
import org.apache.hadoop.hbase.rest.model.CellModel; import org.apache.hadoop.hbase.rest.model.CellModel;
import org.apache.hadoop.hbase.rest.model.CellSetModel; import org.apache.hadoop.hbase.rest.model.CellSetModel;
@ -56,22 +59,27 @@ import org.apache.hadoop.hbase.util.Bytes;
public class RowResource extends ResourceBase { public class RowResource extends ResourceBase {
private static final Log LOG = LogFactory.getLog(RowResource.class); private static final Log LOG = LogFactory.getLog(RowResource.class);
static final String CHECK_PUT = "put"; private static final String CHECK_PUT = "put";
static final String CHECK_DELETE = "delete"; private static final String CHECK_DELETE = "delete";
private static final String CHECK_APPEND = "append";
private static final String CHECK_INCREMENT = "increment";
TableResource tableResource; private TableResource tableResource;
RowSpec rowspec; private RowSpec rowspec;
private String check = null; private String check = null;
private boolean returnResult = false;
/** /**
* Constructor * Constructor
* @param tableResource * @param tableResource
* @param rowspec * @param rowspec
* @param versions * @param versions
* @param check
* @param returnResult
* @throws IOException * @throws IOException
*/ */
public RowResource(TableResource tableResource, String rowspec, public RowResource(TableResource tableResource, String rowspec,
String versions, String check) throws IOException { String versions, String check, String returnResult) throws IOException {
super(); super();
this.tableResource = tableResource; this.tableResource = tableResource;
this.rowspec = new RowSpec(rowspec); this.rowspec = new RowSpec(rowspec);
@ -79,6 +87,9 @@ public class RowResource extends ResourceBase {
this.rowspec.setMaxVersions(Integer.parseInt(versions)); this.rowspec.setMaxVersions(Integer.parseInt(versions));
} }
this.check = check; this.check = check;
if (returnResult != null) {
this.returnResult = Boolean.valueOf(returnResult);
}
} }
@GET @GET
@ -182,6 +193,10 @@ public class RowResource extends ResourceBase {
return checkAndPut(model); return checkAndPut(model);
} else if (CHECK_DELETE.equalsIgnoreCase(check)) { } else if (CHECK_DELETE.equalsIgnoreCase(check)) {
return checkAndDelete(model); 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) { } else if (check != null && check.length() > 0) {
return Response.status(Response.Status.BAD_REQUEST) return Response.status(Response.Status.BAD_REQUEST)
.type(MIMETYPE_TEXT).entity("Invalid check value '" + check + "'" + CRLF) .type(MIMETYPE_TEXT).entity("Invalid check value '" + check + "'" + CRLF)
@ -544,7 +559,7 @@ public class RowResource extends ResourceBase {
if (model.getRows().size() != 1) { if (model.getRows().size() != 1) {
servlet.getMetrics().incrementFailedDeleteRequests(1); servlet.getMetrics().incrementFailedDeleteRequests(1);
return Response.status(Response.Status.BAD_REQUEST) 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(); .build();
} }
RowModel rowModel = model.getRows().get(0); 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);
}
}
}
} }

View File

@ -105,8 +105,9 @@ public class TableResource extends ResourceBase {
// the RowSpec constructor has a chance to parse // the RowSpec constructor has a chance to parse
final @PathParam("rowspec") @Encoded String rowspec, final @PathParam("rowspec") @Encoded String rowspec,
final @QueryParam("v") String versions, final @QueryParam("v") String versions,
final @QueryParam("check") String check) throws IOException { final @QueryParam("check") String check,
return new RowResource(this, rowspec, versions, check); final @QueryParam("rr") String returnResult) throws IOException {
return new RowResource(this, rowspec, versions, check, returnResult);
} }
@Path("{suffixglobbingspec: .*\\*/.+}") @Path("{suffixglobbingspec: .*\\*/.+}")
@ -115,8 +116,9 @@ public class TableResource extends ResourceBase {
// the RowSpec constructor has a chance to parse // the RowSpec constructor has a chance to parse
final @PathParam("suffixglobbingspec") @Encoded String suffixglobbingspec, final @PathParam("suffixglobbingspec") @Encoded String suffixglobbingspec,
final @QueryParam("v") String versions, final @QueryParam("v") String versions,
final @QueryParam("check") String check) throws IOException { final @QueryParam("check") String check,
return new RowResource(this, suffixglobbingspec, versions, check); final @QueryParam("rr") String returnResult) throws IOException {
return new RowResource(this, suffixglobbingspec, versions, check, returnResult);
} }
@Path("{scanspec: .*[*]$}") @Path("{scanspec: .*[*]$}")

View File

@ -30,7 +30,6 @@ import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller; import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller; import javax.xml.bind.Unmarshaller;
import org.apache.commons.collections.keyvalue.AbstractMapEntry;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseTestingUtility; import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.HColumnDescriptor; import org.apache.hadoop.hbase.HColumnDescriptor;
@ -70,6 +69,8 @@ public class RowResourceBase {
protected static final String VALUE_3 = "testvalue3"; protected static final String VALUE_3 = "testvalue3";
protected static final String ROW_4 = "testrow4"; protected static final String ROW_4 = "testrow4";
protected static final String VALUE_4 = "testvalue4"; 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 HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
protected static final HBaseRESTTestingUtility REST_TEST_UTIL = protected static final HBaseRESTTestingUtility REST_TEST_UTIL =
@ -176,6 +177,19 @@ public class RowResourceBase {
assertEquals(Bytes.toString(cell.getValue()), value); 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 { protected static Response getValuePB(String url) throws IOException {
Response response = client.get(url, Constants.MIMETYPE_PROTOBUF); Response response = client.get(url, Constants.MIMETYPE_PROTOBUF);
return response; return response;
@ -233,6 +247,19 @@ public class RowResourceBase {
assertEquals(Bytes.toString(cell.getValue()), value); 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, protected static Response checkAndPutValuePB(String url, String table,
String row, String column, String valueToCheck, String valueToPut, HashMap<String,String> otherCells) String row, String column, String valueToCheck, String valueToPut, HashMap<String,String> otherCells)
throws IOException { throws IOException {
@ -520,6 +547,20 @@ public class RowResourceBase {
assertEquals(Bytes.toString(cell.getValue()), value); 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, protected static Response putValueJson(String table, String row, String column,
String value) throws IOException, JAXBException { String value) throws IOException, JAXBException {
StringBuilder path = new StringBuilder(); StringBuilder path = new StringBuilder();
@ -546,4 +587,69 @@ public class RowResourceBase {
return response; 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);
}
} }

View File

@ -699,5 +699,110 @@ public class TestGetAndPutResource extends RowResourceBase {
response = deleteRow(TABLE, ROW_2); response = deleteRow(TABLE, ROW_2);
assertEquals(response.getCode(), 200); 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);
}
} }