HBASE-9524 Multi row get does not return any results even if any one of the rows specified in the query is missing and improve exception handling (Vandana Ayyalasomayajula)
git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1552368 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
c220ed07b2
commit
9f496164d6
|
@ -27,6 +27,8 @@ import javax.ws.rs.core.MultivaluedMap;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.apache.hadoop.classification.InterfaceAudience;
|
import org.apache.hadoop.classification.InterfaceAudience;
|
||||||
import org.apache.hadoop.hbase.Cell;
|
import org.apache.hadoop.hbase.Cell;
|
||||||
import org.apache.hadoop.hbase.CellUtil;
|
import org.apache.hadoop.hbase.CellUtil;
|
||||||
|
@ -36,6 +38,7 @@ import org.apache.hadoop.hbase.rest.model.RowModel;
|
||||||
|
|
||||||
@InterfaceAudience.Private
|
@InterfaceAudience.Private
|
||||||
public class MultiRowResource extends ResourceBase {
|
public class MultiRowResource extends ResourceBase {
|
||||||
|
private static final Log LOG = LogFactory.getLog(MultiRowResource.class);
|
||||||
public static final String ROW_KEYS_PARAM_NAME = "row";
|
public static final String ROW_KEYS_PARAM_NAME = "row";
|
||||||
|
|
||||||
TableResource tableResource;
|
TableResource tableResource;
|
||||||
|
@ -59,8 +62,7 @@ public class MultiRowResource extends ResourceBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Produces({MIMETYPE_XML, MIMETYPE_JSON, MIMETYPE_PROTOBUF,
|
@Produces({ MIMETYPE_XML, MIMETYPE_JSON, MIMETYPE_PROTOBUF, MIMETYPE_PROTOBUF_IETF })
|
||||||
MIMETYPE_PROTOBUF_IETF})
|
|
||||||
public Response get(final @Context UriInfo uriInfo) {
|
public Response get(final @Context UriInfo uriInfo) {
|
||||||
MultivaluedMap<String, String> params = uriInfo.getQueryParameters();
|
MultivaluedMap<String, String> params = uriInfo.getQueryParameters();
|
||||||
|
|
||||||
|
@ -76,31 +78,32 @@ public class MultiRowResource extends ResourceBase {
|
||||||
|
|
||||||
ResultGenerator generator =
|
ResultGenerator generator =
|
||||||
ResultGenerator.fromRowSpec(this.tableResource.getName(), rowSpec, null);
|
ResultGenerator.fromRowSpec(this.tableResource.getName(), rowSpec, null);
|
||||||
if (!generator.hasNext()) {
|
|
||||||
return Response.status(Response.Status.NOT_FOUND)
|
|
||||||
.type(MIMETYPE_TEXT).entity("Not found" + CRLF)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
Cell value = null;
|
Cell value = null;
|
||||||
RowModel rowModel = new RowModel(rk);
|
RowModel rowModel = new RowModel(rk);
|
||||||
|
if (generator.hasNext()) {
|
||||||
while ((value = generator.next()) != null) {
|
while ((value = generator.next()) != null) {
|
||||||
rowModel.addCell(new CellModel(CellUtil.cloneFamily(value),
|
rowModel.addCell(new CellModel(CellUtil.cloneFamily(value), CellUtil
|
||||||
CellUtil.cloneQualifier(value),
|
.cloneQualifier(value), value.getTimestamp(), CellUtil.cloneValue(value)));
|
||||||
value.getTimestamp(), CellUtil.cloneValue(value)));
|
}
|
||||||
|
model.addRow(rowModel);
|
||||||
|
} else {
|
||||||
|
LOG.trace("The row : " + rk + " not found in the table.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
model.addRow(rowModel);
|
if (model.getRows().size() == 0) {
|
||||||
}
|
//If no rows found.
|
||||||
|
servlet.getMetrics().incrementFailedGetRequests(1);
|
||||||
|
return Response.status(Response.Status.NOT_FOUND)
|
||||||
|
.type(MIMETYPE_TEXT).entity("No rows found." + CRLF)
|
||||||
|
.build();
|
||||||
|
} else {
|
||||||
servlet.getMetrics().incrementSucessfulGetRequests(1);
|
servlet.getMetrics().incrementSucessfulGetRequests(1);
|
||||||
return Response.ok(model).build();
|
return Response.ok(model).build();
|
||||||
} catch (IOException e) {
|
|
||||||
servlet.getMetrics().incrementFailedGetRequests(1);
|
|
||||||
return Response.status(Response.Status.SERVICE_UNAVAILABLE)
|
|
||||||
.type(MIMETYPE_TEXT).entity("Unavailable" + CRLF)
|
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
servlet.getMetrics().incrementFailedGetRequests(1);
|
||||||
|
return processException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,14 +21,73 @@ package org.apache.hadoop.hbase.rest;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.ws.rs.WebApplicationException;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
|
||||||
import org.apache.hadoop.classification.InterfaceAudience;
|
import org.apache.hadoop.classification.InterfaceAudience;
|
||||||
|
import org.apache.hadoop.hbase.TableNotFoundException;
|
||||||
|
import org.apache.hadoop.hbase.client.RetriesExhaustedWithDetailsException;
|
||||||
|
import org.apache.hadoop.hbase.regionserver.NoSuchColumnFamilyException;
|
||||||
|
import org.apache.hadoop.util.StringUtils;
|
||||||
|
|
||||||
@InterfaceAudience.Private
|
@InterfaceAudience.Private
|
||||||
public class ResourceBase implements Constants {
|
public class ResourceBase implements Constants {
|
||||||
|
|
||||||
RESTServlet servlet;
|
RESTServlet servlet;
|
||||||
|
Class<?> accessDeniedClazz;
|
||||||
|
|
||||||
public ResourceBase() throws IOException {
|
public ResourceBase() throws IOException {
|
||||||
servlet = RESTServlet.getInstance();
|
servlet = RESTServlet.getInstance();
|
||||||
|
try {
|
||||||
|
accessDeniedClazz = Class.forName("org.apache.hadoop.hbase.security.AccessDeniedException");
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Response processException(Throwable exp) {
|
||||||
|
Throwable curr = exp;
|
||||||
|
if(accessDeniedClazz != null) {
|
||||||
|
//some access denied exceptions are buried
|
||||||
|
while (curr != null) {
|
||||||
|
if(accessDeniedClazz.isAssignableFrom(curr.getClass())) {
|
||||||
|
throw new SecurityException("Unauthorized" + CRLF +
|
||||||
|
StringUtils.stringifyException(exp) + CRLF);
|
||||||
|
}
|
||||||
|
curr = curr.getCause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//TableNotFound may also be buried one level deep
|
||||||
|
if (exp instanceof TableNotFoundException ||
|
||||||
|
exp.getCause() instanceof TableNotFoundException) {
|
||||||
|
throw new WebApplicationException(
|
||||||
|
Response.status(Response.Status.NOT_FOUND)
|
||||||
|
.type(MIMETYPE_TEXT).entity("Not found" + CRLF +
|
||||||
|
StringUtils.stringifyException(exp) + CRLF)
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
if (exp instanceof NoSuchColumnFamilyException){
|
||||||
|
throw new WebApplicationException(
|
||||||
|
Response.status(Response.Status.NOT_FOUND)
|
||||||
|
.type(MIMETYPE_TEXT).entity("Not found" + CRLF +
|
||||||
|
StringUtils.stringifyException(exp) + CRLF)
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
if (exp instanceof RuntimeException) {
|
||||||
|
throw new WebApplicationException(
|
||||||
|
Response.status(Response.Status.BAD_REQUEST)
|
||||||
|
.type(MIMETYPE_TEXT).entity("Bad request" + CRLF +
|
||||||
|
StringUtils.stringifyException(exp) + CRLF)
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
if (exp instanceof RetriesExhaustedWithDetailsException) {
|
||||||
|
RetriesExhaustedWithDetailsException retryException =
|
||||||
|
(RetriesExhaustedWithDetailsException) exp;
|
||||||
|
processException(retryException.getCause(0));
|
||||||
|
}
|
||||||
|
throw new WebApplicationException(
|
||||||
|
Response.status(Response.Status.SERVICE_UNAVAILABLE)
|
||||||
|
.type(MIMETYPE_TEXT).entity("Unavailable" + CRLF +
|
||||||
|
StringUtils.stringifyException(exp) + CRLF)
|
||||||
|
.build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,11 +81,9 @@ public class RootResource extends ResourceBase {
|
||||||
response.cacheControl(cacheControl);
|
response.cacheControl(cacheControl);
|
||||||
servlet.getMetrics().incrementSucessfulGetRequests(1);
|
servlet.getMetrics().incrementSucessfulGetRequests(1);
|
||||||
return response.build();
|
return response.build();
|
||||||
} catch (IOException e) {
|
} catch (Exception e) {
|
||||||
servlet.getMetrics().incrementFailedGetRequests(1);
|
servlet.getMetrics().incrementFailedGetRequests(1);
|
||||||
return Response.status(Response.Status.SERVICE_UNAVAILABLE)
|
return processException(e);
|
||||||
.type(MIMETYPE_TEXT).entity("Unavailable" + CRLF)
|
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.Response.ResponseBuilder;
|
import javax.ws.rs.core.Response.ResponseBuilder;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.apache.hadoop.classification.InterfaceAudience;
|
import org.apache.hadoop.classification.InterfaceAudience;
|
||||||
|
@ -42,7 +43,6 @@ 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.TableNotFoundException;
|
|
||||||
import org.apache.hadoop.hbase.client.Delete;
|
import org.apache.hadoop.hbase.client.Delete;
|
||||||
import org.apache.hadoop.hbase.client.HTableInterface;
|
import org.apache.hadoop.hbase.client.HTableInterface;
|
||||||
import org.apache.hadoop.hbase.client.Put;
|
import org.apache.hadoop.hbase.client.Put;
|
||||||
|
@ -118,21 +118,9 @@ public class RowResource extends ResourceBase {
|
||||||
model.addRow(rowModel);
|
model.addRow(rowModel);
|
||||||
servlet.getMetrics().incrementSucessfulGetRequests(1);
|
servlet.getMetrics().incrementSucessfulGetRequests(1);
|
||||||
return Response.ok(model).build();
|
return Response.ok(model).build();
|
||||||
} catch (RuntimeException e) {
|
|
||||||
servlet.getMetrics().incrementFailedGetRequests(1);
|
|
||||||
if (e.getCause() instanceof TableNotFoundException) {
|
|
||||||
return Response.status(Response.Status.NOT_FOUND)
|
|
||||||
.type(MIMETYPE_TEXT).entity("Not found" + CRLF)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
return Response.status(Response.Status.BAD_REQUEST)
|
|
||||||
.type(MIMETYPE_TEXT).entity("Bad request" + CRLF)
|
|
||||||
.build();
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
servlet.getMetrics().incrementFailedGetRequests(1);
|
servlet.getMetrics().incrementFailedPutRequests(1);
|
||||||
return Response.status(Response.Status.SERVICE_UNAVAILABLE)
|
return processException(e);
|
||||||
.type(MIMETYPE_TEXT).entity("Unavailable" + CRLF)
|
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,9 +134,9 @@ public class RowResource extends ResourceBase {
|
||||||
// doesn't make sense to use a non specific coordinate as this can only
|
// doesn't make sense to use a non specific coordinate as this can only
|
||||||
// return a single cell
|
// return a single cell
|
||||||
if (!rowspec.hasColumns() || rowspec.getColumns().length > 1) {
|
if (!rowspec.hasColumns() || rowspec.getColumns().length > 1) {
|
||||||
return Response.status(Response.Status.BAD_REQUEST)
|
servlet.getMetrics().incrementFailedGetRequests(1);
|
||||||
.type(MIMETYPE_TEXT).entity("Bad request" + CRLF)
|
return Response.status(Response.Status.BAD_REQUEST).type(MIMETYPE_TEXT)
|
||||||
.build();
|
.entity("Bad request: Either 0 or more than 1 columns specified." + CRLF).build();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
ResultGenerator generator =
|
ResultGenerator generator =
|
||||||
|
@ -164,17 +152,16 @@ public class RowResource extends ResourceBase {
|
||||||
response.header("X-Timestamp", value.getTimestamp());
|
response.header("X-Timestamp", value.getTimestamp());
|
||||||
servlet.getMetrics().incrementSucessfulGetRequests(1);
|
servlet.getMetrics().incrementSucessfulGetRequests(1);
|
||||||
return response.build();
|
return response.build();
|
||||||
} catch (IOException e) {
|
} catch (Exception e) {
|
||||||
servlet.getMetrics().incrementFailedGetRequests(1);
|
servlet.getMetrics().incrementFailedGetRequests(1);
|
||||||
return Response.status(Response.Status.SERVICE_UNAVAILABLE)
|
return processException(e);
|
||||||
.type(MIMETYPE_TEXT).entity("Unavailable" + CRLF)
|
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Response update(final CellSetModel model, final boolean replace) {
|
Response update(final CellSetModel model, final boolean replace) {
|
||||||
servlet.getMetrics().incrementRequests(1);
|
servlet.getMetrics().incrementRequests(1);
|
||||||
if (servlet.isReadOnly()) {
|
if (servlet.isReadOnly()) {
|
||||||
|
servlet.getMetrics().incrementFailedPutRequests(1);
|
||||||
return Response.status(Response.Status.FORBIDDEN)
|
return Response.status(Response.Status.FORBIDDEN)
|
||||||
.type(MIMETYPE_TEXT).entity("Forbidden" + CRLF)
|
.type(MIMETYPE_TEXT).entity("Forbidden" + CRLF)
|
||||||
.build();
|
.build();
|
||||||
|
@ -200,8 +187,9 @@ public class RowResource extends ResourceBase {
|
||||||
key = rowspec.getRow();
|
key = rowspec.getRow();
|
||||||
}
|
}
|
||||||
if (key == null) {
|
if (key == null) {
|
||||||
|
servlet.getMetrics().incrementFailedPutRequests(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: Row key not specified." + CRLF)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
Put put = new Put(key);
|
Put put = new Put(key);
|
||||||
|
@ -214,8 +202,9 @@ public class RowResource extends ResourceBase {
|
||||||
col = null;
|
col = null;
|
||||||
}
|
}
|
||||||
if (col == null) {
|
if (col == null) {
|
||||||
|
servlet.getMetrics().incrementFailedPutRequests(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: Column found to be null." + CRLF)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
byte [][] parts = KeyValue.parseColumn(col);
|
byte [][] parts = KeyValue.parseColumn(col);
|
||||||
|
@ -237,11 +226,9 @@ public class RowResource extends ResourceBase {
|
||||||
ResponseBuilder response = Response.ok();
|
ResponseBuilder response = Response.ok();
|
||||||
servlet.getMetrics().incrementSucessfulPutRequests(1);
|
servlet.getMetrics().incrementSucessfulPutRequests(1);
|
||||||
return response.build();
|
return response.build();
|
||||||
} catch (IOException e) {
|
} catch (Exception e) {
|
||||||
servlet.getMetrics().incrementFailedPutRequests(1);
|
servlet.getMetrics().incrementFailedPutRequests(1);
|
||||||
return Response.status(Response.Status.SERVICE_UNAVAILABLE)
|
return processException(e);
|
||||||
.type(MIMETYPE_TEXT).entity("Unavailable" + CRLF)
|
|
||||||
.build();
|
|
||||||
} finally {
|
} finally {
|
||||||
if (table != null) try {
|
if (table != null) try {
|
||||||
table.close();
|
table.close();
|
||||||
|
@ -256,6 +243,7 @@ public class RowResource extends ResourceBase {
|
||||||
final boolean replace) {
|
final boolean replace) {
|
||||||
servlet.getMetrics().incrementRequests(1);
|
servlet.getMetrics().incrementRequests(1);
|
||||||
if (servlet.isReadOnly()) {
|
if (servlet.isReadOnly()) {
|
||||||
|
servlet.getMetrics().incrementFailedPutRequests(1);
|
||||||
return Response.status(Response.Status.FORBIDDEN)
|
return Response.status(Response.Status.FORBIDDEN)
|
||||||
.type(MIMETYPE_TEXT).entity("Forbidden" + CRLF)
|
.type(MIMETYPE_TEXT).entity("Forbidden" + CRLF)
|
||||||
.build();
|
.build();
|
||||||
|
@ -282,8 +270,9 @@ public class RowResource extends ResourceBase {
|
||||||
timestamp = Long.valueOf(vals.get(0));
|
timestamp = Long.valueOf(vals.get(0));
|
||||||
}
|
}
|
||||||
if (column == null) {
|
if (column == null) {
|
||||||
|
servlet.getMetrics().incrementFailedPutRequests(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: Column found to be null." + CRLF)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
Put put = new Put(row);
|
Put put = new Put(row);
|
||||||
|
@ -301,15 +290,15 @@ public class RowResource extends ResourceBase {
|
||||||
}
|
}
|
||||||
servlet.getMetrics().incrementSucessfulPutRequests(1);
|
servlet.getMetrics().incrementSucessfulPutRequests(1);
|
||||||
return Response.ok().build();
|
return Response.ok().build();
|
||||||
} catch (IOException e) {
|
} catch (Exception e) {
|
||||||
servlet.getMetrics().incrementFailedPutRequests(1);
|
servlet.getMetrics().incrementFailedPutRequests(1);
|
||||||
return Response.status(Response.Status.SERVICE_UNAVAILABLE)
|
return processException(e);
|
||||||
.type(MIMETYPE_TEXT).entity("Unavailable" + CRLF)
|
|
||||||
.build();
|
|
||||||
} finally {
|
} finally {
|
||||||
if (table != null) try {
|
if (table != null) try {
|
||||||
table.close();
|
table.close();
|
||||||
} catch (IOException ioe) { }
|
} catch (IOException ioe) {
|
||||||
|
LOG.debug(ioe);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,6 +353,7 @@ public class RowResource extends ResourceBase {
|
||||||
}
|
}
|
||||||
servlet.getMetrics().incrementRequests(1);
|
servlet.getMetrics().incrementRequests(1);
|
||||||
if (servlet.isReadOnly()) {
|
if (servlet.isReadOnly()) {
|
||||||
|
servlet.getMetrics().incrementFailedDeleteRequests(1);
|
||||||
return Response.status(Response.Status.FORBIDDEN)
|
return Response.status(Response.Status.FORBIDDEN)
|
||||||
.type(MIMETYPE_TEXT).entity("Forbidden" + CRLF)
|
.type(MIMETYPE_TEXT).entity("Forbidden" + CRLF)
|
||||||
.build();
|
.build();
|
||||||
|
@ -406,15 +396,15 @@ public class RowResource extends ResourceBase {
|
||||||
if (LOG.isDebugEnabled()) {
|
if (LOG.isDebugEnabled()) {
|
||||||
LOG.debug("DELETE " + delete.toString());
|
LOG.debug("DELETE " + delete.toString());
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (Exception e) {
|
||||||
servlet.getMetrics().incrementFailedDeleteRequests(1);
|
servlet.getMetrics().incrementFailedDeleteRequests(1);
|
||||||
return Response.status(Response.Status.SERVICE_UNAVAILABLE)
|
return processException(e);
|
||||||
.type(MIMETYPE_TEXT).entity("Unavailable" + CRLF)
|
|
||||||
.build();
|
|
||||||
} finally {
|
} finally {
|
||||||
if (table != null) try {
|
if (table != null) try {
|
||||||
table.close();
|
table.close();
|
||||||
} catch (IOException ioe) { }
|
} catch (IOException ioe) {
|
||||||
|
LOG.debug(ioe);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return Response.ok().build();
|
return Response.ok().build();
|
||||||
}
|
}
|
||||||
|
@ -429,10 +419,11 @@ public class RowResource extends ResourceBase {
|
||||||
Response checkAndPut(final CellSetModel model) {
|
Response checkAndPut(final CellSetModel model) {
|
||||||
HTableInterface table = null;
|
HTableInterface table = null;
|
||||||
try {
|
try {
|
||||||
|
table = servlet.getTable(tableResource.getName());
|
||||||
if (model.getRows().size() != 1) {
|
if (model.getRows().size() != 1) {
|
||||||
return Response.status(Response.Status.BAD_REQUEST)
|
servlet.getMetrics().incrementFailedPutRequests(1);
|
||||||
.type(MIMETYPE_TEXT).entity("Bad request" + CRLF)
|
return Response.status(Response.Status.BAD_REQUEST).type(MIMETYPE_TEXT)
|
||||||
.build();
|
.entity("Bad request: Number of rows specified is not 1." + CRLF).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
RowModel rowModel = model.getRows().get(0);
|
RowModel rowModel = model.getRows().get(0);
|
||||||
|
@ -444,20 +435,21 @@ public class RowResource extends ResourceBase {
|
||||||
List<CellModel> cellModels = rowModel.getCells();
|
List<CellModel> cellModels = rowModel.getCells();
|
||||||
int cellModelCount = cellModels.size();
|
int cellModelCount = cellModels.size();
|
||||||
if (key == null || cellModelCount <= 1) {
|
if (key == null || cellModelCount <= 1) {
|
||||||
return Response.status(Response.Status.BAD_REQUEST)
|
servlet.getMetrics().incrementFailedPutRequests(1);
|
||||||
.type(MIMETYPE_TEXT).entity("Bad request" + CRLF)
|
return Response
|
||||||
|
.status(Response.Status.BAD_REQUEST)
|
||||||
|
.type(MIMETYPE_TEXT)
|
||||||
|
.entity(
|
||||||
|
"Bad request: Either row key is null or no data found for columns specified." + CRLF)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
Put put = new Put(key);
|
Put put = new Put(key);
|
||||||
|
boolean retValue;
|
||||||
CellModel valueToCheckCell = cellModels.get(cellModelCount - 1);
|
CellModel valueToCheckCell = cellModels.get(cellModelCount - 1);
|
||||||
byte[] valueToCheckColumn = valueToCheckCell.getColumn();
|
byte[] valueToCheckColumn = valueToCheckCell.getColumn();
|
||||||
byte[][] valueToPutParts = KeyValue.parseColumn(valueToCheckColumn);
|
byte[][] valueToPutParts = KeyValue.parseColumn(valueToCheckColumn);
|
||||||
if (valueToPutParts.length != 2) {
|
if (valueToPutParts.length == 2 && valueToPutParts[1].length > 0) {
|
||||||
return Response.status(Response.Status.BAD_REQUEST)
|
|
||||||
.type(MIMETYPE_TEXT).entity("Bad request" + CRLF)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
CellModel valueToPutCell = null;
|
CellModel valueToPutCell = null;
|
||||||
for (int i = 0, n = cellModelCount - 1; i < n ; i++) {
|
for (int i = 0, n = cellModelCount - 1; i < n ; i++) {
|
||||||
if(Bytes.equals(cellModels.get(i).getColumn(),
|
if(Bytes.equals(cellModels.get(i).getColumn(),
|
||||||
|
@ -466,34 +458,45 @@ public class RowResource extends ResourceBase {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (null == valueToPutCell) {
|
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);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
servlet.getMetrics().incrementFailedPutRequests(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: Column incorrectly specified." + CRLF)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
put.addImmutable(valueToPutParts[0], valueToPutParts[1], valueToPutCell
|
|
||||||
.getTimestamp(), valueToPutCell.getValue());
|
|
||||||
|
|
||||||
table = servlet.getTable(this.tableResource.getName());
|
|
||||||
boolean retValue = table.checkAndPut(key, valueToPutParts[0],
|
|
||||||
valueToPutParts[1], valueToCheckCell.getValue(), put);
|
|
||||||
if (LOG.isDebugEnabled()) {
|
if (LOG.isDebugEnabled()) {
|
||||||
LOG.debug("CHECK-AND-PUT " + put.toString() + ", returns " + retValue);
|
LOG.debug("CHECK-AND-PUT " + put.toString() + ", returns " + retValue);
|
||||||
}
|
}
|
||||||
|
if (!retValue) {
|
||||||
|
servlet.getMetrics().incrementFailedPutRequests(1);
|
||||||
|
return Response.status(Response.Status.NOT_MODIFIED)
|
||||||
|
.type(MIMETYPE_TEXT).entity("Value not Modified" + CRLF)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
table.flushCommits();
|
table.flushCommits();
|
||||||
ResponseBuilder response = Response.ok();
|
ResponseBuilder response = Response.ok();
|
||||||
if (!retValue) {
|
servlet.getMetrics().incrementSucessfulPutRequests(1);
|
||||||
response = Response.status(304);
|
|
||||||
}
|
|
||||||
return response.build();
|
return response.build();
|
||||||
} catch (IOException e) {
|
} catch (Exception e) {
|
||||||
return Response.status(Response.Status.SERVICE_UNAVAILABLE)
|
servlet.getMetrics().incrementFailedPutRequests(1);
|
||||||
.type(MIMETYPE_TEXT).entity("Unavailable" + CRLF)
|
return processException(e);
|
||||||
.build();
|
|
||||||
} finally {
|
} finally {
|
||||||
if (table != null) try {
|
if (table != null) try {
|
||||||
table.close();
|
table.close();
|
||||||
} catch (IOException ioe) { }
|
} catch (IOException ioe) {
|
||||||
|
LOG.debug("Exception received while closing the table", ioe);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -508,7 +511,9 @@ public class RowResource extends ResourceBase {
|
||||||
HTableInterface table = null;
|
HTableInterface table = null;
|
||||||
Delete delete = null;
|
Delete delete = null;
|
||||||
try {
|
try {
|
||||||
|
table = servlet.getTable(tableResource.getName());
|
||||||
if (model.getRows().size() != 1) {
|
if (model.getRows().size() != 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" + CRLF)
|
||||||
.build();
|
.build();
|
||||||
|
@ -519,48 +524,64 @@ public class RowResource extends ResourceBase {
|
||||||
key = rowspec.getRow();
|
key = rowspec.getRow();
|
||||||
}
|
}
|
||||||
if (key == null) {
|
if (key == null) {
|
||||||
|
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: Row key found to be null." + CRLF)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
delete = new Delete(key);
|
delete = new Delete(key);
|
||||||
|
boolean retValue;
|
||||||
CellModel valueToDeleteCell = rowModel.getCells().get(0);
|
CellModel valueToDeleteCell = rowModel.getCells().get(0);
|
||||||
byte[] valueToDeleteColumn = valueToDeleteCell.getColumn();
|
byte[] valueToDeleteColumn = valueToDeleteCell.getColumn();
|
||||||
if (valueToDeleteColumn == null) {
|
if (valueToDeleteColumn == null) {
|
||||||
try {
|
try {
|
||||||
valueToDeleteColumn = rowspec.getColumns()[0];
|
valueToDeleteColumn = rowspec.getColumns()[0];
|
||||||
} catch (final ArrayIndexOutOfBoundsException e) {
|
} catch (final ArrayIndexOutOfBoundsException e) {
|
||||||
|
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: Column not specified for check." + CRLF)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
byte[][] parts = KeyValue.parseColumn(valueToDeleteColumn);
|
byte[][] parts = KeyValue.parseColumn(valueToDeleteColumn);
|
||||||
if (parts.length != 2) {
|
if (parts.length == 2) {
|
||||||
|
if (parts[1].length != 0) {
|
||||||
|
delete.deleteColumns(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));
|
||||||
|
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)
|
return Response.status(Response.Status.BAD_REQUEST)
|
||||||
.type(MIMETYPE_TEXT).entity("Bad request" + CRLF)
|
.type(MIMETYPE_TEXT).entity("Bad request: Column incorrectly specified." + CRLF)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
delete.deleteColumns(parts[0], parts[1]);
|
delete.deleteColumns(parts[0], parts[1]);
|
||||||
|
|
||||||
table = servlet.getTable(tableResource.getName());
|
|
||||||
boolean retValue = table.checkAndDelete(key, parts[0], parts[1],
|
|
||||||
valueToDeleteCell.getValue(), delete);
|
|
||||||
if (LOG.isDebugEnabled()) {
|
if (LOG.isDebugEnabled()) {
|
||||||
LOG.debug("CHECK-AND-DELETE " + delete.toString() + ", returns "
|
LOG.debug("CHECK-AND-DELETE " + delete.toString() + ", returns "
|
||||||
+ retValue);
|
+ retValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!retValue) {
|
||||||
|
servlet.getMetrics().incrementFailedDeleteRequests(1);
|
||||||
|
return Response.status(Response.Status.NOT_MODIFIED)
|
||||||
|
.type(MIMETYPE_TEXT).entity(" Delete check failed." + CRLF)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
table.flushCommits();
|
table.flushCommits();
|
||||||
ResponseBuilder response = Response.ok();
|
ResponseBuilder response = Response.ok();
|
||||||
if (!retValue) {
|
servlet.getMetrics().incrementSucessfulDeleteRequests(1);
|
||||||
response = Response.status(304);
|
|
||||||
}
|
|
||||||
return response.build();
|
return response.build();
|
||||||
} catch (IOException e) {
|
} catch (Exception e) {
|
||||||
return Response.status(Response.Status.SERVICE_UNAVAILABLE)
|
servlet.getMetrics().incrementFailedDeleteRequests(1);
|
||||||
.type(MIMETYPE_TEXT).entity("Unavailable" + CRLF)
|
return processException(e);
|
||||||
.build();
|
|
||||||
} finally {
|
} finally {
|
||||||
if (table != null) try {
|
if (table != null) try {
|
||||||
table.close();
|
table.close();
|
||||||
|
|
|
@ -96,16 +96,9 @@ public class SchemaResource extends ResourceBase {
|
||||||
response.cacheControl(cacheControl);
|
response.cacheControl(cacheControl);
|
||||||
servlet.getMetrics().incrementSucessfulGetRequests(1);
|
servlet.getMetrics().incrementSucessfulGetRequests(1);
|
||||||
return response.build();
|
return response.build();
|
||||||
} catch (TableNotFoundException e) {
|
} catch (Exception e) {
|
||||||
servlet.getMetrics().incrementFailedGetRequests(1);
|
servlet.getMetrics().incrementFailedGetRequests(1);
|
||||||
return Response.status(Response.Status.NOT_FOUND)
|
return processException(e);
|
||||||
.type(MIMETYPE_TEXT).entity("Not found" + CRLF)
|
|
||||||
.build();
|
|
||||||
} catch (IOException e) {
|
|
||||||
servlet.getMetrics().incrementFailedGetRequests(1);
|
|
||||||
return Response.status(Response.Status.SERVICE_UNAVAILABLE)
|
|
||||||
.type(MIMETYPE_TEXT).entity("Unavailable" + CRLF)
|
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,10 +136,9 @@ public class SchemaResource extends ResourceBase {
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
return Response.created(uriInfo.getAbsolutePath()).build();
|
return Response.created(uriInfo.getAbsolutePath()).build();
|
||||||
} catch (IOException e) {
|
} catch (Exception e) {
|
||||||
return Response.status(Response.Status.SERVICE_UNAVAILABLE)
|
servlet.getMetrics().incrementFailedPutRequests(1);
|
||||||
.type(MIMETYPE_TEXT).entity("Unavailable" + CRLF)
|
return processException(e);
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,10 +173,9 @@ public class SchemaResource extends ResourceBase {
|
||||||
}
|
}
|
||||||
servlet.getMetrics().incrementSucessfulPutRequests(1);
|
servlet.getMetrics().incrementSucessfulPutRequests(1);
|
||||||
return Response.ok().build();
|
return Response.ok().build();
|
||||||
} catch (IOException e) {
|
} catch (Exception e) {
|
||||||
return Response.status(Response.Status.SERVICE_UNAVAILABLE)
|
servlet.getMetrics().incrementFailedPutRequests(1);
|
||||||
.type(MIMETYPE_TEXT).entity("Unavailable" + CRLF)
|
return processException(e);
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,11 +189,9 @@ public class SchemaResource extends ResourceBase {
|
||||||
} else {
|
} else {
|
||||||
return update(name, model, uriInfo, admin);
|
return update(name, model, uriInfo, admin);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (Exception e) {
|
||||||
servlet.getMetrics().incrementFailedPutRequests(1);
|
servlet.getMetrics().incrementFailedPutRequests(1);
|
||||||
return Response.status(Response.Status.SERVICE_UNAVAILABLE)
|
return processException(e);
|
||||||
.type(MIMETYPE_TEXT).entity("Unavailable" + CRLF)
|
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,16 +244,9 @@ public class SchemaResource extends ResourceBase {
|
||||||
admin.deleteTable(tableResource.getName());
|
admin.deleteTable(tableResource.getName());
|
||||||
servlet.getMetrics().incrementSucessfulDeleteRequests(1);
|
servlet.getMetrics().incrementSucessfulDeleteRequests(1);
|
||||||
return Response.ok().build();
|
return Response.ok().build();
|
||||||
} catch (TableNotFoundException e) {
|
} catch (Exception e) {
|
||||||
servlet.getMetrics().incrementFailedDeleteRequests(1);
|
servlet.getMetrics().incrementFailedDeleteRequests(1);
|
||||||
return Response.status(Response.Status.NOT_FOUND)
|
return processException(e);
|
||||||
.type(MIMETYPE_TEXT).entity("Not found" + CRLF)
|
|
||||||
.build();
|
|
||||||
} catch (IOException e) {
|
|
||||||
servlet.getMetrics().incrementFailedDeleteRequests(1);
|
|
||||||
return Response.status(Response.Status.SERVICE_UNAVAILABLE)
|
|
||||||
.type(MIMETYPE_TEXT).entity("Unavailable" + CRLF)
|
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,481 @@
|
||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.hadoop.hbase.rest;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import javax.xml.bind.JAXBContext;
|
||||||
|
import javax.xml.bind.JAXBException;
|
||||||
|
import javax.xml.bind.Marshaller;
|
||||||
|
import javax.xml.bind.Unmarshaller;
|
||||||
|
|
||||||
|
import org.apache.hadoop.conf.Configuration;
|
||||||
|
import org.apache.hadoop.hbase.HBaseTestingUtility;
|
||||||
|
import org.apache.hadoop.hbase.HColumnDescriptor;
|
||||||
|
import org.apache.hadoop.hbase.HTableDescriptor;
|
||||||
|
import org.apache.hadoop.hbase.TableName;
|
||||||
|
import org.apache.hadoop.hbase.client.HBaseAdmin;
|
||||||
|
import org.apache.hadoop.hbase.rest.client.Client;
|
||||||
|
import org.apache.hadoop.hbase.rest.client.Cluster;
|
||||||
|
import org.apache.hadoop.hbase.rest.client.Response;
|
||||||
|
import org.apache.hadoop.hbase.rest.model.CellModel;
|
||||||
|
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.map.ObjectMapper;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
|
||||||
|
public class RowResourceBase {
|
||||||
|
|
||||||
|
protected static final String TABLE = "TestRowResource";
|
||||||
|
protected static final String CFA = "a";
|
||||||
|
protected static final String CFB = "b";
|
||||||
|
protected static final String COLUMN_1 = CFA + ":1";
|
||||||
|
protected static final String COLUMN_2 = CFB + ":2";
|
||||||
|
protected static final String COLUMN_3 = CFA + ":";
|
||||||
|
protected static final String ROW_1 = "testrow1";
|
||||||
|
protected static final String VALUE_1 = "testvalue1";
|
||||||
|
protected static final String ROW_2 = "testrow2";
|
||||||
|
protected static final String VALUE_2 = "testvalue2";
|
||||||
|
protected static final String ROW_3 = "testrow3";
|
||||||
|
protected static final String VALUE_3 = "testvalue3";
|
||||||
|
protected static final String ROW_4 = "testrow4";
|
||||||
|
protected static final String VALUE_4 = "testvalue4";
|
||||||
|
|
||||||
|
protected static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
|
||||||
|
protected static final HBaseRESTTestingUtility REST_TEST_UTIL =
|
||||||
|
new HBaseRESTTestingUtility();
|
||||||
|
protected static Client client;
|
||||||
|
protected static JAXBContext context;
|
||||||
|
protected static Marshaller xmlMarshaller;
|
||||||
|
protected static Unmarshaller xmlUnmarshaller;
|
||||||
|
protected static Configuration conf;
|
||||||
|
protected static ObjectMapper jsonMapper;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpBeforeClass() throws Exception {
|
||||||
|
conf = TEST_UTIL.getConfiguration();
|
||||||
|
TEST_UTIL.startMiniCluster(3);
|
||||||
|
REST_TEST_UTIL.startServletContainer(conf);
|
||||||
|
context = JAXBContext.newInstance(
|
||||||
|
CellModel.class,
|
||||||
|
CellSetModel.class,
|
||||||
|
RowModel.class);
|
||||||
|
xmlMarshaller = context.createMarshaller();
|
||||||
|
xmlUnmarshaller = context.createUnmarshaller();
|
||||||
|
jsonMapper = new JacksonProvider()
|
||||||
|
.locateMapper(CellSetModel.class, MediaType.APPLICATION_JSON_TYPE);
|
||||||
|
client = new Client(new Cluster().add("localhost",
|
||||||
|
REST_TEST_UTIL.getServletPort()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void tearDownAfterClass() throws Exception {
|
||||||
|
REST_TEST_UTIL.shutdownServletContainer();
|
||||||
|
TEST_UTIL.shutdownMiniCluster();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void beforeMethod() throws Exception {
|
||||||
|
HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
|
||||||
|
if (admin.tableExists(TABLE)) {
|
||||||
|
TEST_UTIL.deleteTable(Bytes.toBytes(TABLE));
|
||||||
|
}
|
||||||
|
HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(TABLE));
|
||||||
|
htd.addFamily(new HColumnDescriptor(CFA));
|
||||||
|
htd.addFamily(new HColumnDescriptor(CFB));
|
||||||
|
admin.createTable(htd);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void afterMethod() throws Exception {
|
||||||
|
HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
|
||||||
|
if (admin.tableExists(TABLE)) {
|
||||||
|
TEST_UTIL.deleteTable(Bytes.toBytes(TABLE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Response putValuePB(String table, String row, String column,
|
||||||
|
String value) throws IOException {
|
||||||
|
StringBuilder path = new StringBuilder();
|
||||||
|
path.append('/');
|
||||||
|
path.append(table);
|
||||||
|
path.append('/');
|
||||||
|
path.append(row);
|
||||||
|
path.append('/');
|
||||||
|
path.append(column);
|
||||||
|
return putValuePB(path.toString(), table, row, column, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Response putValuePB(String url, String table, String row,
|
||||||
|
String column, String value) throws IOException {
|
||||||
|
RowModel rowModel = new RowModel(row);
|
||||||
|
rowModel.addCell(new CellModel(Bytes.toBytes(column),
|
||||||
|
Bytes.toBytes(value)));
|
||||||
|
CellSetModel cellSetModel = new CellSetModel();
|
||||||
|
cellSetModel.addRow(rowModel);
|
||||||
|
Response response = client.put(url, Constants.MIMETYPE_PROTOBUF,
|
||||||
|
cellSetModel.createProtobufOutput());
|
||||||
|
Thread.yield();
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void checkValueXML(String url, String table, String row,
|
||||||
|
String column, String value) throws IOException, JAXBException {
|
||||||
|
Response response = getValueXML(url);
|
||||||
|
assertEquals(response.getCode(), 200);
|
||||||
|
assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type"));
|
||||||
|
CellSetModel cellSet = (CellSetModel)
|
||||||
|
xmlUnmarshaller.unmarshal(new ByteArrayInputStream(response.getBody()));
|
||||||
|
RowModel rowModel = cellSet.getRows().get(0);
|
||||||
|
CellModel cell = rowModel.getCells().get(0);
|
||||||
|
assertEquals(Bytes.toString(cell.getColumn()), column);
|
||||||
|
assertEquals(Bytes.toString(cell.getValue()), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void checkValueXML(String table, String row, String column,
|
||||||
|
String value) throws IOException, JAXBException {
|
||||||
|
Response response = getValueXML(table, row, column);
|
||||||
|
assertEquals(response.getCode(), 200);
|
||||||
|
assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type"));
|
||||||
|
CellSetModel cellSet = (CellSetModel)
|
||||||
|
xmlUnmarshaller.unmarshal(new ByteArrayInputStream(response.getBody()));
|
||||||
|
RowModel rowModel = cellSet.getRows().get(0);
|
||||||
|
CellModel cell = rowModel.getCells().get(0);
|
||||||
|
assertEquals(Bytes.toString(cell.getColumn()), column);
|
||||||
|
assertEquals(Bytes.toString(cell.getValue()), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static Response getValuePB(String url) throws IOException {
|
||||||
|
Response response = client.get(url, Constants.MIMETYPE_PROTOBUF);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static Response putValueXML(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('/');
|
||||||
|
path.append(column);
|
||||||
|
return putValueXML(path.toString(), table, row, column, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static Response putValueXML(String url, String table, String row,
|
||||||
|
String column, String value) throws IOException, JAXBException {
|
||||||
|
RowModel rowModel = new RowModel(row);
|
||||||
|
rowModel.addCell(new CellModel(Bytes.toBytes(column),
|
||||||
|
Bytes.toBytes(value)));
|
||||||
|
CellSetModel cellSetModel = new CellSetModel();
|
||||||
|
cellSetModel.addRow(rowModel);
|
||||||
|
StringWriter writer = new StringWriter();
|
||||||
|
xmlMarshaller.marshal(cellSetModel, writer);
|
||||||
|
Response response = client.put(url, Constants.MIMETYPE_XML,
|
||||||
|
Bytes.toBytes(writer.toString()));
|
||||||
|
Thread.yield();
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static Response getValuePB(String table, String row, String column)
|
||||||
|
throws IOException {
|
||||||
|
StringBuilder path = new StringBuilder();
|
||||||
|
path.append('/');
|
||||||
|
path.append(table);
|
||||||
|
path.append('/');
|
||||||
|
path.append(row);
|
||||||
|
path.append('/');
|
||||||
|
path.append(column);
|
||||||
|
return getValuePB(path.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void checkValuePB(String table, String row, String column,
|
||||||
|
String 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.toString(cell.getValue()), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static Response checkAndPutValuePB(String url, String table,
|
||||||
|
String row, String column, String valueToCheck, String valueToPut)
|
||||||
|
throws IOException {
|
||||||
|
RowModel rowModel = new RowModel(row);
|
||||||
|
rowModel.addCell(new CellModel(Bytes.toBytes(column),
|
||||||
|
Bytes.toBytes(valueToPut)));
|
||||||
|
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,
|
||||||
|
cellSetModel.createProtobufOutput());
|
||||||
|
Thread.yield();
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static Response checkAndPutValuePB(String table, String row,
|
||||||
|
String column, String valueToCheck, String valueToPut) throws IOException {
|
||||||
|
StringBuilder path = new StringBuilder();
|
||||||
|
path.append('/');
|
||||||
|
path.append(table);
|
||||||
|
path.append('/');
|
||||||
|
path.append(row);
|
||||||
|
path.append("?check=put");
|
||||||
|
return checkAndPutValuePB(path.toString(), table, row, column,
|
||||||
|
valueToCheck, valueToPut);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static Response checkAndPutValueXML(String url, String table,
|
||||||
|
String row, String column, String valueToCheck, String valueToPut)
|
||||||
|
throws IOException, JAXBException {
|
||||||
|
RowModel rowModel = new RowModel(row);
|
||||||
|
rowModel.addCell(new CellModel(Bytes.toBytes(column),
|
||||||
|
Bytes.toBytes(valueToPut)));
|
||||||
|
rowModel.addCell(new CellModel(Bytes.toBytes(column),
|
||||||
|
Bytes.toBytes(valueToCheck)));
|
||||||
|
CellSetModel cellSetModel = new CellSetModel();
|
||||||
|
cellSetModel.addRow(rowModel);
|
||||||
|
StringWriter writer = new StringWriter();
|
||||||
|
xmlMarshaller.marshal(cellSetModel, writer);
|
||||||
|
Response response = client.put(url, Constants.MIMETYPE_XML,
|
||||||
|
Bytes.toBytes(writer.toString()));
|
||||||
|
Thread.yield();
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static Response checkAndPutValueXML(String table, String row,
|
||||||
|
String column, String valueToCheck, String valueToPut)
|
||||||
|
throws IOException, JAXBException {
|
||||||
|
StringBuilder path = new StringBuilder();
|
||||||
|
path.append('/');
|
||||||
|
path.append(table);
|
||||||
|
path.append('/');
|
||||||
|
path.append(row);
|
||||||
|
path.append("?check=put");
|
||||||
|
return checkAndPutValueXML(path.toString(), table, row, column,
|
||||||
|
valueToCheck, valueToPut);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static Response checkAndDeleteXML(String url, String table,
|
||||||
|
String row, String column, String valueToCheck)
|
||||||
|
throws IOException, JAXBException {
|
||||||
|
RowModel rowModel = new RowModel(row);
|
||||||
|
rowModel.addCell(new CellModel(Bytes.toBytes(column),
|
||||||
|
Bytes.toBytes(valueToCheck)));
|
||||||
|
CellSetModel cellSetModel = new CellSetModel();
|
||||||
|
cellSetModel.addRow(rowModel);
|
||||||
|
StringWriter writer = new StringWriter();
|
||||||
|
xmlMarshaller.marshal(cellSetModel, writer);
|
||||||
|
Response response = client.put(url, Constants.MIMETYPE_XML,
|
||||||
|
Bytes.toBytes(writer.toString()));
|
||||||
|
Thread.yield();
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static Response checkAndDeleteXML(String table, String row,
|
||||||
|
String column, String valueToCheck) 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static Response checkAndDeleteJson(String table, String row,
|
||||||
|
String column, String valueToCheck) 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static Response checkAndDeleteJson(String url, String table,
|
||||||
|
String row, String column, String valueToCheck)
|
||||||
|
throws IOException, JAXBException {
|
||||||
|
RowModel rowModel = new RowModel(row);
|
||||||
|
rowModel.addCell(new CellModel(Bytes.toBytes(column),
|
||||||
|
Bytes.toBytes(valueToCheck)));
|
||||||
|
CellSetModel cellSetModel = new CellSetModel();
|
||||||
|
cellSetModel.addRow(rowModel);
|
||||||
|
String jsonString = jsonMapper.writeValueAsString(cellSetModel);
|
||||||
|
Response response = client.put(url, Constants.MIMETYPE_JSON,
|
||||||
|
Bytes.toBytes(jsonString));
|
||||||
|
Thread.yield();
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static Response checkAndDeletePB(String table, String row,
|
||||||
|
String column, String value) 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static Response checkAndDeleteValuePB(String url, String table,
|
||||||
|
String row, String column, String valueToCheck)
|
||||||
|
throws IOException {
|
||||||
|
RowModel rowModel = new RowModel(row);
|
||||||
|
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,
|
||||||
|
cellSetModel.createProtobufOutput());
|
||||||
|
Thread.yield();
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static Response getValueXML(String table, String startRow,
|
||||||
|
String endRow, String column) throws IOException {
|
||||||
|
StringBuilder path = new StringBuilder();
|
||||||
|
path.append('/');
|
||||||
|
path.append(table);
|
||||||
|
path.append('/');
|
||||||
|
path.append(startRow);
|
||||||
|
path.append(",");
|
||||||
|
path.append(endRow);
|
||||||
|
path.append('/');
|
||||||
|
path.append(column);
|
||||||
|
return getValueXML(path.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static Response getValueXML(String url) throws IOException {
|
||||||
|
Response response = client.get(url, Constants.MIMETYPE_XML);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static Response getValueJson(String url) throws IOException {
|
||||||
|
Response response = client.get(url, Constants.MIMETYPE_JSON);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static Response deleteValue(String table, String row, String column)
|
||||||
|
throws IOException {
|
||||||
|
StringBuilder path = new StringBuilder();
|
||||||
|
path.append('/');
|
||||||
|
path.append(table);
|
||||||
|
path.append('/');
|
||||||
|
path.append(row);
|
||||||
|
path.append('/');
|
||||||
|
path.append(column);
|
||||||
|
Response response = client.delete(path.toString());
|
||||||
|
Thread.yield();
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static Response getValueXML(String table, String row, String column)
|
||||||
|
throws IOException {
|
||||||
|
StringBuilder path = new StringBuilder();
|
||||||
|
path.append('/');
|
||||||
|
path.append(table);
|
||||||
|
path.append('/');
|
||||||
|
path.append(row);
|
||||||
|
path.append('/');
|
||||||
|
path.append(column);
|
||||||
|
return getValueXML(path.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static Response deleteRow(String table, String row)
|
||||||
|
throws IOException {
|
||||||
|
StringBuilder path = new StringBuilder();
|
||||||
|
path.append('/');
|
||||||
|
path.append(table);
|
||||||
|
path.append('/');
|
||||||
|
path.append(row);
|
||||||
|
Response response = client.delete(path.toString());
|
||||||
|
Thread.yield();
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static Response getValueJson(String table, String row,
|
||||||
|
String column) throws IOException {
|
||||||
|
StringBuilder path = new StringBuilder();
|
||||||
|
path.append('/');
|
||||||
|
path.append(table);
|
||||||
|
path.append('/');
|
||||||
|
path.append(row);
|
||||||
|
path.append('/');
|
||||||
|
path.append(column);
|
||||||
|
return getValueJson(path.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void checkValueJSON(String table, String row, String column,
|
||||||
|
String 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 JacksonProvider()
|
||||||
|
.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.toString(cell.getValue()), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static Response putValueJson(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('/');
|
||||||
|
path.append(column);
|
||||||
|
return putValueJson(path.toString(), table, row, column, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static Response putValueJson(String url, String table, String row, String column,
|
||||||
|
String value) throws IOException, JAXBException {
|
||||||
|
RowModel rowModel = new RowModel(row);
|
||||||
|
rowModel.addCell(new CellModel(Bytes.toBytes(column),
|
||||||
|
Bytes.toBytes(value)));
|
||||||
|
CellSetModel cellSetModel = new CellSetModel();
|
||||||
|
cellSetModel.addRow(rowModel);
|
||||||
|
String jsonString = jsonMapper.writeValueAsString(cellSetModel);
|
||||||
|
Response response = client.put(url, Constants.MIMETYPE_JSON,
|
||||||
|
Bytes.toBytes(jsonString));
|
||||||
|
Thread.yield();
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,99 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.hadoop.hbase.rest;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.xml.bind.JAXBException;
|
||||||
|
|
||||||
|
import org.apache.hadoop.hbase.MediumTests;
|
||||||
|
import org.apache.hadoop.hbase.rest.client.Response;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.experimental.categories.Category;
|
||||||
|
|
||||||
|
|
||||||
|
@Category(MediumTests.class)
|
||||||
|
public class TestDeleteRow extends RowResourceBase {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteNonExistentColumn() throws Exception {
|
||||||
|
Response response = putValueJson(TABLE, ROW_1, COLUMN_1, VALUE_1);
|
||||||
|
assertEquals(response.getCode(), 200);
|
||||||
|
|
||||||
|
response = checkAndDeleteJson(TABLE, ROW_1, COLUMN_1, VALUE_2);
|
||||||
|
assertEquals(304, response.getCode());
|
||||||
|
assertEquals(200, getValueJson(TABLE, ROW_1, COLUMN_1).getCode());
|
||||||
|
|
||||||
|
response = checkAndDeleteJson(TABLE, ROW_2, COLUMN_1, VALUE_2);
|
||||||
|
assertEquals(304, response.getCode());
|
||||||
|
assertEquals(200, getValueJson(TABLE, ROW_1, COLUMN_1).getCode());
|
||||||
|
|
||||||
|
response = checkAndDeleteJson(TABLE, ROW_1, "dummy", VALUE_1);
|
||||||
|
assertEquals(400, response.getCode());
|
||||||
|
assertEquals(200, getValueJson(TABLE, ROW_1, COLUMN_1).getCode());
|
||||||
|
|
||||||
|
response = checkAndDeleteJson(TABLE, ROW_1, "dummy:test", VALUE_1);
|
||||||
|
assertEquals(404, response.getCode());
|
||||||
|
assertEquals(200, getValueJson(TABLE, ROW_1, COLUMN_1).getCode());
|
||||||
|
|
||||||
|
response = checkAndDeleteJson(TABLE, ROW_1, "a:test", VALUE_1);
|
||||||
|
assertEquals(304, response.getCode());
|
||||||
|
assertEquals(200, getValueJson(TABLE, ROW_1, COLUMN_1).getCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteXML() throws IOException, JAXBException {
|
||||||
|
Response response = putValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1);
|
||||||
|
assertEquals(response.getCode(), 200);
|
||||||
|
response = putValueXML(TABLE, ROW_1, COLUMN_2, VALUE_2);
|
||||||
|
assertEquals(response.getCode(), 200);
|
||||||
|
checkValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1);
|
||||||
|
checkValueXML(TABLE, ROW_1, COLUMN_2, VALUE_2);
|
||||||
|
|
||||||
|
response = deleteValue(TABLE, ROW_1, COLUMN_1);
|
||||||
|
assertEquals(response.getCode(), 200);
|
||||||
|
response = getValueXML(TABLE, ROW_1, COLUMN_1);
|
||||||
|
assertEquals(response.getCode(), 404);
|
||||||
|
checkValueXML(TABLE, ROW_1, COLUMN_2, VALUE_2);
|
||||||
|
|
||||||
|
response = putValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1);
|
||||||
|
assertEquals(response.getCode(), 200);
|
||||||
|
response = checkAndDeletePB(TABLE, ROW_1, COLUMN_1, VALUE_1);
|
||||||
|
assertEquals(response.getCode(), 200);
|
||||||
|
response = getValueXML(TABLE, ROW_1, COLUMN_1);
|
||||||
|
assertEquals(response.getCode(), 404);
|
||||||
|
|
||||||
|
response = deleteRow(TABLE, ROW_1);
|
||||||
|
assertEquals(response.getCode(), 200);
|
||||||
|
response = getValueXML(TABLE, ROW_1, COLUMN_1);
|
||||||
|
assertEquals(response.getCode(), 404);
|
||||||
|
response = getValueXML(TABLE, ROW_1, COLUMN_2);
|
||||||
|
assertEquals(response.getCode(), 404);
|
||||||
|
|
||||||
|
//Delete a row in non existent table
|
||||||
|
response = deleteValue("dummy", ROW_1, COLUMN_1);
|
||||||
|
assertEquals(response.getCode(), 404);
|
||||||
|
|
||||||
|
//Delete non existent column
|
||||||
|
response = deleteValue(TABLE, ROW_1, "dummy");
|
||||||
|
assertEquals(response.getCode(), 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,4 @@
|
||||||
/*
|
/**
|
||||||
*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
* or more contributor license agreements. See the NOTICE file
|
* or more contributor license agreements. See the NOTICE file
|
||||||
* distributed with this work for additional information
|
* distributed with this work for additional information
|
||||||
|
@ -28,23 +27,12 @@ import java.io.StringWriter;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.xml.bind.JAXBContext;
|
|
||||||
import javax.xml.bind.JAXBException;
|
import javax.xml.bind.JAXBException;
|
||||||
import javax.xml.bind.Marshaller;
|
|
||||||
import javax.xml.bind.Unmarshaller;
|
|
||||||
|
|
||||||
import org.apache.commons.httpclient.Header;
|
import org.apache.commons.httpclient.Header;
|
||||||
import org.apache.hadoop.conf.Configuration;
|
|
||||||
import org.apache.hadoop.hbase.CompatibilityFactory;
|
import org.apache.hadoop.hbase.CompatibilityFactory;
|
||||||
import org.apache.hadoop.hbase.HBaseTestingUtility;
|
|
||||||
import org.apache.hadoop.hbase.HColumnDescriptor;
|
|
||||||
import org.apache.hadoop.hbase.HConstants;
|
import org.apache.hadoop.hbase.HConstants;
|
||||||
import org.apache.hadoop.hbase.HTableDescriptor;
|
|
||||||
import org.apache.hadoop.hbase.MediumTests;
|
import org.apache.hadoop.hbase.MediumTests;
|
||||||
import org.apache.hadoop.hbase.TableName;
|
|
||||||
import org.apache.hadoop.hbase.client.HBaseAdmin;
|
|
||||||
import org.apache.hadoop.hbase.rest.client.Client;
|
|
||||||
import org.apache.hadoop.hbase.rest.client.Cluster;
|
|
||||||
import org.apache.hadoop.hbase.rest.client.Response;
|
import org.apache.hadoop.hbase.rest.client.Response;
|
||||||
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;
|
||||||
|
@ -53,388 +41,14 @@ import org.apache.hadoop.hbase.security.User;
|
||||||
import org.apache.hadoop.hbase.test.MetricsAssertHelper;
|
import org.apache.hadoop.hbase.test.MetricsAssertHelper;
|
||||||
import org.apache.hadoop.hbase.util.Bytes;
|
import org.apache.hadoop.hbase.util.Bytes;
|
||||||
import org.apache.hadoop.security.UserGroupInformation;
|
import org.apache.hadoop.security.UserGroupInformation;
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.AfterClass;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.BeforeClass;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.experimental.categories.Category;
|
import org.junit.experimental.categories.Category;
|
||||||
|
|
||||||
@Category(MediumTests.class)
|
@Category(MediumTests.class)
|
||||||
public class TestRowResource {
|
public class TestGetAndPutResource extends RowResourceBase {
|
||||||
private static final String TABLE = "TestRowResource";
|
|
||||||
private static final String CFA = "a";
|
|
||||||
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_3 = CFA + ":";
|
|
||||||
private static final String ROW_1 = "testrow1";
|
|
||||||
private static final String VALUE_1 = "testvalue1";
|
|
||||||
private static final String ROW_2 = "testrow2";
|
|
||||||
private static final String VALUE_2 = "testvalue2";
|
|
||||||
private static final String ROW_3 = "testrow3";
|
|
||||||
private static final String VALUE_3 = "testvalue3";
|
|
||||||
private static final String ROW_4 = "testrow4";
|
|
||||||
private static final String VALUE_4 = "testvalue4";
|
|
||||||
|
|
||||||
private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
|
|
||||||
private static final HBaseRESTTestingUtility REST_TEST_UTIL =
|
|
||||||
new HBaseRESTTestingUtility();
|
|
||||||
private static final MetricsAssertHelper METRICS_ASSERT =
|
private static final MetricsAssertHelper METRICS_ASSERT =
|
||||||
CompatibilityFactory.getInstance(MetricsAssertHelper.class);
|
CompatibilityFactory.getInstance(MetricsAssertHelper.class);
|
||||||
private static Client client;
|
|
||||||
private static JAXBContext context;
|
|
||||||
private static Marshaller marshaller;
|
|
||||||
private static Unmarshaller unmarshaller;
|
|
||||||
private static Configuration conf;
|
|
||||||
|
|
||||||
@BeforeClass
|
|
||||||
public static void setUpBeforeClass() throws Exception {
|
|
||||||
conf = TEST_UTIL.getConfiguration();
|
|
||||||
TEST_UTIL.startMiniCluster(3);
|
|
||||||
REST_TEST_UTIL.startServletContainer(conf);
|
|
||||||
context = JAXBContext.newInstance(
|
|
||||||
CellModel.class,
|
|
||||||
CellSetModel.class,
|
|
||||||
RowModel.class);
|
|
||||||
marshaller = context.createMarshaller();
|
|
||||||
unmarshaller = context.createUnmarshaller();
|
|
||||||
client = new Client(new Cluster().add("localhost",
|
|
||||||
REST_TEST_UTIL.getServletPort()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void beforeMethod() throws Exception {
|
|
||||||
HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
|
|
||||||
if (admin.tableExists(TABLE)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(TABLE));
|
|
||||||
htd.addFamily(new HColumnDescriptor(CFA));
|
|
||||||
htd.addFamily(new HColumnDescriptor(CFB));
|
|
||||||
admin.createTable(htd);
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void afterMethod() throws Exception {
|
|
||||||
HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
|
|
||||||
if (admin.tableExists(TABLE)) {
|
|
||||||
admin.disableTable(TABLE);
|
|
||||||
admin.deleteTable(TABLE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@AfterClass
|
|
||||||
public static void tearDownAfterClass() throws Exception {
|
|
||||||
REST_TEST_UTIL.shutdownServletContainer();
|
|
||||||
TEST_UTIL.shutdownMiniCluster();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Response deleteRow(String table, String row)
|
|
||||||
throws IOException {
|
|
||||||
StringBuilder path = new StringBuilder();
|
|
||||||
path.append('/');
|
|
||||||
path.append(table);
|
|
||||||
path.append('/');
|
|
||||||
path.append(row);
|
|
||||||
Response response = client.delete(path.toString());
|
|
||||||
Thread.yield();
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Response deleteValue(String table, String row, String column)
|
|
||||||
throws IOException {
|
|
||||||
StringBuilder path = new StringBuilder();
|
|
||||||
path.append('/');
|
|
||||||
path.append(table);
|
|
||||||
path.append('/');
|
|
||||||
path.append(row);
|
|
||||||
path.append('/');
|
|
||||||
path.append(column);
|
|
||||||
Response response = client.delete(path.toString());
|
|
||||||
Thread.yield();
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Response getValueXML(String table, String row, String column)
|
|
||||||
throws IOException {
|
|
||||||
StringBuilder path = new StringBuilder();
|
|
||||||
path.append('/');
|
|
||||||
path.append(table);
|
|
||||||
path.append('/');
|
|
||||||
path.append(row);
|
|
||||||
path.append('/');
|
|
||||||
path.append(column);
|
|
||||||
return getValueXML(path.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Response getValueXML(String table, String startRow,
|
|
||||||
String endRow, String column) throws IOException {
|
|
||||||
StringBuilder path = new StringBuilder();
|
|
||||||
path.append('/');
|
|
||||||
path.append(table);
|
|
||||||
path.append('/');
|
|
||||||
path.append(startRow);
|
|
||||||
path.append(",");
|
|
||||||
path.append(endRow);
|
|
||||||
path.append('/');
|
|
||||||
path.append(column);
|
|
||||||
return getValueXML(path.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Response getValueXML(String url) throws IOException {
|
|
||||||
Response response = client.get(url, Constants.MIMETYPE_XML);
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Response getValuePB(String table, String row, String column)
|
|
||||||
throws IOException {
|
|
||||||
StringBuilder path = new StringBuilder();
|
|
||||||
path.append('/');
|
|
||||||
path.append(table);
|
|
||||||
path.append('/');
|
|
||||||
path.append(row);
|
|
||||||
path.append('/');
|
|
||||||
path.append(column);
|
|
||||||
return getValuePB(path.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Response getValuePB(String url) throws IOException {
|
|
||||||
Response response = client.get(url, Constants.MIMETYPE_PROTOBUF);
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Response putValueXML(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('/');
|
|
||||||
path.append(column);
|
|
||||||
return putValueXML(path.toString(), table, row, column, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Response putValueXML(String url, String table, String row,
|
|
||||||
String column, String value) throws IOException, JAXBException {
|
|
||||||
RowModel rowModel = new RowModel(row);
|
|
||||||
rowModel.addCell(new CellModel(Bytes.toBytes(column),
|
|
||||||
Bytes.toBytes(value)));
|
|
||||||
CellSetModel cellSetModel = new CellSetModel();
|
|
||||||
cellSetModel.addRow(rowModel);
|
|
||||||
StringWriter writer = new StringWriter();
|
|
||||||
marshaller.marshal(cellSetModel, writer);
|
|
||||||
Response response = client.put(url, Constants.MIMETYPE_XML,
|
|
||||||
Bytes.toBytes(writer.toString()));
|
|
||||||
Thread.yield();
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void checkValueXML(String table, String row, String column,
|
|
||||||
String value) throws IOException, JAXBException {
|
|
||||||
Response response = getValueXML(table, row, column);
|
|
||||||
assertEquals(response.getCode(), 200);
|
|
||||||
assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type"));
|
|
||||||
CellSetModel cellSet = (CellSetModel)
|
|
||||||
unmarshaller.unmarshal(new ByteArrayInputStream(response.getBody()));
|
|
||||||
RowModel rowModel = cellSet.getRows().get(0);
|
|
||||||
CellModel cell = rowModel.getCells().get(0);
|
|
||||||
assertEquals(Bytes.toString(cell.getColumn()), column);
|
|
||||||
assertEquals(Bytes.toString(cell.getValue()), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void checkValueXML(String url, String table, String row,
|
|
||||||
String column, String value) throws IOException, JAXBException {
|
|
||||||
Response response = getValueXML(url);
|
|
||||||
assertEquals(response.getCode(), 200);
|
|
||||||
assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type"));
|
|
||||||
CellSetModel cellSet = (CellSetModel)
|
|
||||||
unmarshaller.unmarshal(new ByteArrayInputStream(response.getBody()));
|
|
||||||
RowModel rowModel = cellSet.getRows().get(0);
|
|
||||||
CellModel cell = rowModel.getCells().get(0);
|
|
||||||
assertEquals(Bytes.toString(cell.getColumn()), column);
|
|
||||||
assertEquals(Bytes.toString(cell.getValue()), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Response putValuePB(String table, String row, String column,
|
|
||||||
String value) throws IOException {
|
|
||||||
StringBuilder path = new StringBuilder();
|
|
||||||
path.append('/');
|
|
||||||
path.append(table);
|
|
||||||
path.append('/');
|
|
||||||
path.append(row);
|
|
||||||
path.append('/');
|
|
||||||
path.append(column);
|
|
||||||
return putValuePB(path.toString(), table, row, column, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Response putValuePB(String url, String table, String row,
|
|
||||||
String column, String value) throws IOException {
|
|
||||||
RowModel rowModel = new RowModel(row);
|
|
||||||
rowModel.addCell(new CellModel(Bytes.toBytes(column),
|
|
||||||
Bytes.toBytes(value)));
|
|
||||||
CellSetModel cellSetModel = new CellSetModel();
|
|
||||||
cellSetModel.addRow(rowModel);
|
|
||||||
Response response = client.put(url, Constants.MIMETYPE_PROTOBUF,
|
|
||||||
cellSetModel.createProtobufOutput());
|
|
||||||
Thread.yield();
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void checkValuePB(String table, String row, String column,
|
|
||||||
String 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.toString(cell.getValue()), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Response checkAndPutValuePB(String url, String table,
|
|
||||||
String row, String column, String valueToCheck, String valueToPut)
|
|
||||||
throws IOException {
|
|
||||||
RowModel rowModel = new RowModel(row);
|
|
||||||
rowModel.addCell(new CellModel(Bytes.toBytes(column),
|
|
||||||
Bytes.toBytes(valueToPut)));
|
|
||||||
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,
|
|
||||||
cellSetModel.createProtobufOutput());
|
|
||||||
Thread.yield();
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Response checkAndPutValuePB(String table, String row,
|
|
||||||
String column, String valueToCheck, String valueToPut) throws IOException {
|
|
||||||
StringBuilder path = new StringBuilder();
|
|
||||||
path.append('/');
|
|
||||||
path.append(table);
|
|
||||||
path.append('/');
|
|
||||||
path.append(row);
|
|
||||||
path.append("?check=put");
|
|
||||||
return checkAndPutValuePB(path.toString(), table, row, column,
|
|
||||||
valueToCheck, valueToPut);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Response checkAndPutValueXML(String url, String table,
|
|
||||||
String row, String column, String valueToCheck, String valueToPut)
|
|
||||||
throws IOException, JAXBException {
|
|
||||||
RowModel rowModel = new RowModel(row);
|
|
||||||
rowModel.addCell(new CellModel(Bytes.toBytes(column),
|
|
||||||
Bytes.toBytes(valueToPut)));
|
|
||||||
rowModel.addCell(new CellModel(Bytes.toBytes(column),
|
|
||||||
Bytes.toBytes(valueToCheck)));
|
|
||||||
CellSetModel cellSetModel = new CellSetModel();
|
|
||||||
cellSetModel.addRow(rowModel);
|
|
||||||
StringWriter writer = new StringWriter();
|
|
||||||
marshaller.marshal(cellSetModel, writer);
|
|
||||||
Response response = client.put(url, Constants.MIMETYPE_XML,
|
|
||||||
Bytes.toBytes(writer.toString()));
|
|
||||||
Thread.yield();
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Response checkAndPutValueXML(String table, String row,
|
|
||||||
String column, String valueToCheck, String valueToPut)
|
|
||||||
throws IOException, JAXBException {
|
|
||||||
StringBuilder path = new StringBuilder();
|
|
||||||
path.append('/');
|
|
||||||
path.append(table);
|
|
||||||
path.append('/');
|
|
||||||
path.append(row);
|
|
||||||
path.append("?check=put");
|
|
||||||
return checkAndPutValueXML(path.toString(), table, row, column,
|
|
||||||
valueToCheck, valueToPut);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Response checkAndDeleteXML(String url, String table,
|
|
||||||
String row, String column, String valueToCheck)
|
|
||||||
throws IOException, JAXBException {
|
|
||||||
RowModel rowModel = new RowModel(row);
|
|
||||||
rowModel.addCell(new CellModel(Bytes.toBytes(column),
|
|
||||||
Bytes.toBytes(valueToCheck)));
|
|
||||||
CellSetModel cellSetModel = new CellSetModel();
|
|
||||||
cellSetModel.addRow(rowModel);
|
|
||||||
StringWriter writer = new StringWriter();
|
|
||||||
marshaller.marshal(cellSetModel, writer);
|
|
||||||
Response response = client.put(url, Constants.MIMETYPE_XML,
|
|
||||||
Bytes.toBytes(writer.toString()));
|
|
||||||
Thread.yield();
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Response checkAndDeleteXML(String table, String row,
|
|
||||||
String column, String valueToCheck) 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Response checkAndDeletePB(String table, String row,
|
|
||||||
String column, String value) 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Response checkAndDeleteValuePB(String url, String table,
|
|
||||||
String row, String column, String valueToCheck)
|
|
||||||
throws IOException {
|
|
||||||
RowModel rowModel = new RowModel(row);
|
|
||||||
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,
|
|
||||||
cellSetModel.createProtobufOutput());
|
|
||||||
Thread.yield();
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDelete() throws IOException, JAXBException {
|
|
||||||
Response response = putValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1);
|
|
||||||
assertEquals(response.getCode(), 200);
|
|
||||||
response = putValueXML(TABLE, ROW_1, COLUMN_2, VALUE_2);
|
|
||||||
assertEquals(response.getCode(), 200);
|
|
||||||
checkValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1);
|
|
||||||
checkValueXML(TABLE, ROW_1, COLUMN_2, VALUE_2);
|
|
||||||
|
|
||||||
response = deleteValue(TABLE, ROW_1, COLUMN_1);
|
|
||||||
assertEquals(response.getCode(), 200);
|
|
||||||
response = getValueXML(TABLE, ROW_1, COLUMN_1);
|
|
||||||
assertEquals(response.getCode(), 404);
|
|
||||||
checkValueXML(TABLE, ROW_1, COLUMN_2, VALUE_2);
|
|
||||||
|
|
||||||
response = putValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1);
|
|
||||||
assertEquals(response.getCode(), 200);
|
|
||||||
response = checkAndDeletePB(TABLE, ROW_1, COLUMN_1, VALUE_1);
|
|
||||||
assertEquals(response.getCode(), 200);
|
|
||||||
response = getValueXML(TABLE, ROW_1, COLUMN_1);
|
|
||||||
assertEquals(response.getCode(), 404);
|
|
||||||
|
|
||||||
response = deleteRow(TABLE, ROW_1);
|
|
||||||
assertEquals(response.getCode(), 200);
|
|
||||||
response = getValueXML(TABLE, ROW_1, COLUMN_1);
|
|
||||||
assertEquals(response.getCode(), 404);
|
|
||||||
response = getValueXML(TABLE, ROW_1, COLUMN_2);
|
|
||||||
assertEquals(response.getCode(), 404);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testForbidden() throws IOException, JAXBException {
|
public void testForbidden() throws IOException, JAXBException {
|
||||||
|
@ -497,10 +111,6 @@ public class TestRowResource {
|
||||||
Response response = getValuePB(TABLE, ROW_1, COLUMN_1);
|
Response response = getValuePB(TABLE, ROW_1, COLUMN_1);
|
||||||
assertEquals(response.getCode(), 404);
|
assertEquals(response.getCode(), 404);
|
||||||
|
|
||||||
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_1, VALUE_1);
|
response = putValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1);
|
||||||
assertEquals(response.getCode(), 200);
|
assertEquals(response.getCode(), 200);
|
||||||
checkValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1);
|
checkValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1);
|
||||||
|
@ -559,30 +169,33 @@ public class TestRowResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMetrics() throws IOException, JAXBException {
|
public void testLatestCellGetJSON() throws IOException, JAXBException {
|
||||||
final String path = "/" + TABLE + "/" + ROW_4 + "/" + COLUMN_1;
|
final String path = "/" + TABLE + "/" + ROW_4 + "/" + COLUMN_1;
|
||||||
Response response = client.put(path, Constants.MIMETYPE_BINARY,
|
CellSetModel cellSetModel = new CellSetModel();
|
||||||
Bytes.toBytes(VALUE_4));
|
RowModel rowModel = new RowModel(ROW_4);
|
||||||
|
CellModel cellOne = new CellModel(Bytes.toBytes(COLUMN_1), 1L,
|
||||||
|
Bytes.toBytes(VALUE_1));
|
||||||
|
CellModel cellTwo = new CellModel(Bytes.toBytes(COLUMN_1), 2L,
|
||||||
|
Bytes.toBytes(VALUE_2));
|
||||||
|
rowModel.addCell(cellOne);
|
||||||
|
rowModel.addCell(cellTwo);
|
||||||
|
cellSetModel.addRow(rowModel);
|
||||||
|
String jsonString = jsonMapper.writeValueAsString(cellSetModel);
|
||||||
|
Response response = client.put(path, Constants.MIMETYPE_JSON,
|
||||||
|
Bytes.toBytes(jsonString));
|
||||||
assertEquals(response.getCode(), 200);
|
assertEquals(response.getCode(), 200);
|
||||||
Thread.yield();
|
Thread.yield();
|
||||||
response = client.get(path, Constants.MIMETYPE_JSON);
|
response = client.get(path, Constants.MIMETYPE_JSON);
|
||||||
assertEquals(response.getCode(), 200);
|
assertEquals(response.getCode(), 200);
|
||||||
assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type"));
|
assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type"));
|
||||||
|
CellSetModel cellSet = jsonMapper.readValue(response.getBody(), CellSetModel.class);
|
||||||
|
assertTrue(cellSet.getRows().size() == 1);
|
||||||
|
assertTrue(cellSet.getRows().get(0).getCells().size() == 1);
|
||||||
|
CellModel cell = cellSet.getRows().get(0).getCells().get(0);
|
||||||
|
assertEquals(VALUE_2 , Bytes.toString(cell.getValue()));
|
||||||
|
assertEquals(2L , cell.getTimestamp());
|
||||||
response = deleteRow(TABLE, ROW_4);
|
response = deleteRow(TABLE, ROW_4);
|
||||||
assertEquals(response.getCode(), 200);
|
assertEquals(response.getCode(), 200);
|
||||||
|
|
||||||
UserGroupInformation ugi = User.getCurrent().getUGI();
|
|
||||||
METRICS_ASSERT.assertCounterGt("requests", 2l,
|
|
||||||
RESTServlet.getInstance(conf, ugi).getMetrics().getSource());
|
|
||||||
|
|
||||||
METRICS_ASSERT.assertCounterGt("successfulGet", 0l,
|
|
||||||
RESTServlet.getInstance(conf, ugi).getMetrics().getSource());
|
|
||||||
|
|
||||||
METRICS_ASSERT.assertCounterGt("successfulPut", 0l,
|
|
||||||
RESTServlet.getInstance(conf, ugi).getMetrics().getSource());
|
|
||||||
|
|
||||||
METRICS_ASSERT.assertCounterGt("successfulDelete", 0l,
|
|
||||||
RESTServlet.getInstance(conf, ugi).getMetrics().getSource());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -635,7 +248,7 @@ public class TestRowResource {
|
||||||
Bytes.toBytes(VALUE_4)));
|
Bytes.toBytes(VALUE_4)));
|
||||||
cellSetModel.addRow(rowModel);
|
cellSetModel.addRow(rowModel);
|
||||||
StringWriter writer = new StringWriter();
|
StringWriter writer = new StringWriter();
|
||||||
marshaller.marshal(cellSetModel, writer);
|
xmlMarshaller.marshal(cellSetModel, writer);
|
||||||
Response response = client.put(path, Constants.MIMETYPE_XML,
|
Response response = client.put(path, Constants.MIMETYPE_XML,
|
||||||
Bytes.toBytes(writer.toString()));
|
Bytes.toBytes(writer.toString()));
|
||||||
Thread.yield();
|
Thread.yield();
|
||||||
|
@ -706,7 +319,7 @@ public class TestRowResource {
|
||||||
response = getValueXML(TABLE, rows[0], rows[2], COLUMN_1);
|
response = getValueXML(TABLE, rows[0], rows[2], COLUMN_1);
|
||||||
assertEquals(200, response.getCode());
|
assertEquals(200, response.getCode());
|
||||||
CellSetModel cellSet = (CellSetModel)
|
CellSetModel cellSet = (CellSetModel)
|
||||||
unmarshaller.unmarshal(new ByteArrayInputStream(response.getBody()));
|
xmlUnmarshaller.unmarshal(new ByteArrayInputStream(response.getBody()));
|
||||||
assertEquals(2, cellSet.getRows().size());
|
assertEquals(2, cellSet.getRows().size());
|
||||||
for (int i = 0; i < cellSet.getRows().size()-1; i++) {
|
for (int i = 0; i < cellSet.getRows().size()-1; i++) {
|
||||||
RowModel rowModel = cellSet.getRows().get(i);
|
RowModel rowModel = cellSet.getRows().get(i);
|
||||||
|
@ -729,7 +342,7 @@ public class TestRowResource {
|
||||||
Bytes.toBytes(VALUE_1)));
|
Bytes.toBytes(VALUE_1)));
|
||||||
cellSetModel.addRow(rowModel);
|
cellSetModel.addRow(rowModel);
|
||||||
StringWriter writer = new StringWriter();
|
StringWriter writer = new StringWriter();
|
||||||
marshaller.marshal(cellSetModel, writer);
|
xmlMarshaller.marshal(cellSetModel, writer);
|
||||||
|
|
||||||
final String path = "/" + TABLE + "/" + ROW_1 + "/" + COLUMN_1 + "?check=blah";
|
final String path = "/" + TABLE + "/" + ROW_1 + "/" + COLUMN_1 + "?check=blah";
|
||||||
|
|
||||||
|
@ -739,31 +352,87 @@ public class TestRowResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLatestCellGetXML() throws IOException, JAXBException {
|
public void testInvalidColumnPut() throws IOException, JAXBException {
|
||||||
final String path = "/" + TABLE + "/" + ROW_1 + "/" + COLUMN_1;
|
String dummyColumn = "doesnot:exist";
|
||||||
CellSetModel cellSetModel = new CellSetModel();
|
CellSetModel cellSetModel = new CellSetModel();
|
||||||
RowModel rowModel = new RowModel(ROW_1);
|
RowModel rowModel = new RowModel(ROW_1);
|
||||||
CellModel cellOne = new CellModel(Bytes.toBytes(COLUMN_1), 1L, Bytes.toBytes(VALUE_1));
|
rowModel.addCell(new CellModel(Bytes.toBytes(dummyColumn),
|
||||||
CellModel cellTwo = new CellModel(Bytes.toBytes(COLUMN_1), 2L, Bytes.toBytes(VALUE_2));
|
Bytes.toBytes(VALUE_1)));
|
||||||
rowModel.addCell(cellOne);
|
|
||||||
rowModel.addCell(cellTwo);
|
|
||||||
cellSetModel.addRow(rowModel);
|
cellSetModel.addRow(rowModel);
|
||||||
StringWriter writer = new StringWriter();
|
StringWriter writer = new StringWriter();
|
||||||
marshaller.marshal(cellSetModel, writer);
|
xmlMarshaller.marshal(cellSetModel, writer);
|
||||||
Response response = client.put(path, Constants.MIMETYPE_XML, Bytes.toBytes(writer.toString()));
|
|
||||||
assertEquals(response.getCode(), 200);
|
final String path = "/" + TABLE + "/" + ROW_1 + "/" + dummyColumn;
|
||||||
response = getValueXML(TABLE, ROW_1, COLUMN_1);
|
|
||||||
assertEquals(response.getCode(), 200);
|
Response response = client.put(path, Constants.MIMETYPE_XML,
|
||||||
assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type"));
|
Bytes.toBytes(writer.toString()));
|
||||||
CellSetModel cellSet = (CellSetModel) unmarshaller.unmarshal(new ByteArrayInputStream(response
|
assertEquals(response.getCode(), 404);
|
||||||
.getBody()));
|
}
|
||||||
assertTrue(cellSet.getRows().size() == 1);
|
|
||||||
assertTrue(cellSet.getRows().get(0).getCells().size() == 1);
|
@Test
|
||||||
CellModel cell = cellSet.getRows().get(0).getCells().get(0);
|
public void testMultiCellGetJson() throws IOException, JAXBException {
|
||||||
assertEquals(VALUE_2, Bytes.toString(cell.getValue()));
|
String path = "/" + TABLE + "/fakerow"; // deliberate nonexistent row
|
||||||
assertEquals(2L, cell.getTimestamp());
|
|
||||||
|
CellSetModel cellSetModel = new CellSetModel();
|
||||||
|
RowModel rowModel = new RowModel(ROW_1);
|
||||||
|
rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_1),
|
||||||
|
Bytes.toBytes(VALUE_1)));
|
||||||
|
rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_2),
|
||||||
|
Bytes.toBytes(VALUE_2)));
|
||||||
|
cellSetModel.addRow(rowModel);
|
||||||
|
rowModel = new RowModel(ROW_2);
|
||||||
|
rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_1),
|
||||||
|
Bytes.toBytes(VALUE_3)));
|
||||||
|
rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_2),
|
||||||
|
Bytes.toBytes(VALUE_4)));
|
||||||
|
cellSetModel.addRow(rowModel);
|
||||||
|
String jsonString = jsonMapper.writeValueAsString(cellSetModel);
|
||||||
|
|
||||||
|
Response response = client.put(path, Constants.MIMETYPE_JSON,
|
||||||
|
Bytes.toBytes(jsonString));
|
||||||
|
Thread.yield();
|
||||||
|
|
||||||
|
// make sure the fake row was not actually created
|
||||||
|
response = client.get(path, Constants.MIMETYPE_JSON);
|
||||||
|
assertEquals(response.getCode(), 404);
|
||||||
|
|
||||||
|
// check that all of the values were created
|
||||||
|
checkValueJSON(TABLE, ROW_1, COLUMN_1, VALUE_1);
|
||||||
|
checkValueJSON(TABLE, ROW_1, COLUMN_2, VALUE_2);
|
||||||
|
checkValueJSON(TABLE, ROW_2, COLUMN_1, VALUE_3);
|
||||||
|
checkValueJSON(TABLE, ROW_2, COLUMN_2, VALUE_4);
|
||||||
|
|
||||||
response = deleteRow(TABLE, ROW_1);
|
response = deleteRow(TABLE, ROW_1);
|
||||||
assertEquals(response.getCode(), 200);
|
assertEquals(response.getCode(), 200);
|
||||||
|
response = deleteRow(TABLE, ROW_2);
|
||||||
|
assertEquals(response.getCode(), 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMetrics() throws IOException, JAXBException {
|
||||||
|
final String path = "/" + TABLE + "/" + ROW_4 + "/" + COLUMN_1;
|
||||||
|
Response response = client.put(path, Constants.MIMETYPE_BINARY,
|
||||||
|
Bytes.toBytes(VALUE_4));
|
||||||
|
assertEquals(response.getCode(), 200);
|
||||||
|
Thread.yield();
|
||||||
|
response = client.get(path, Constants.MIMETYPE_JSON);
|
||||||
|
assertEquals(response.getCode(), 200);
|
||||||
|
assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type"));
|
||||||
|
response = deleteRow(TABLE, ROW_4);
|
||||||
|
assertEquals(response.getCode(), 200);
|
||||||
|
|
||||||
|
UserGroupInformation ugi = User.getCurrent().getUGI();
|
||||||
|
METRICS_ASSERT.assertCounterGt("requests", 2l,
|
||||||
|
RESTServlet.getInstance(conf, ugi).getMetrics().getSource());
|
||||||
|
|
||||||
|
METRICS_ASSERT.assertCounterGt("successfulGet", 0l,
|
||||||
|
RESTServlet.getInstance(conf, ugi).getMetrics().getSource());
|
||||||
|
|
||||||
|
METRICS_ASSERT.assertCounterGt("successfulPut", 0l,
|
||||||
|
RESTServlet.getInstance(conf, ugi).getMetrics().getSource());
|
||||||
|
|
||||||
|
METRICS_ASSERT.assertCounterGt("successfulDelete", 0l,
|
||||||
|
RESTServlet.getInstance(conf, ugi).getMetrics().getSource());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -776,7 +445,7 @@ public class TestRowResource {
|
||||||
rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_3), Bytes.toBytes(VALUE_2)));
|
rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_3), Bytes.toBytes(VALUE_2)));
|
||||||
cellSetModel.addRow(rowModel);
|
cellSetModel.addRow(rowModel);
|
||||||
StringWriter writer = new StringWriter();
|
StringWriter writer = new StringWriter();
|
||||||
marshaller.marshal(cellSetModel, writer);
|
xmlMarshaller.marshal(cellSetModel, writer);
|
||||||
|
|
||||||
Response response = client.put(path, Constants.MIMETYPE_XML, Bytes.toBytes(writer.toString()));
|
Response response = client.put(path, Constants.MIMETYPE_XML, Bytes.toBytes(writer.toString()));
|
||||||
Thread.yield();
|
Thread.yield();
|
||||||
|
@ -789,7 +458,7 @@ public class TestRowResource {
|
||||||
path = "/" + TABLE + "/" + ROW_1 + "/" + COLUMN_1 + "," + COLUMN_2 + "," + COLUMN_3;
|
path = "/" + TABLE + "/" + ROW_1 + "/" + COLUMN_1 + "," + COLUMN_2 + "," + COLUMN_3;
|
||||||
response = client.get(path, Constants.MIMETYPE_XML);
|
response = client.get(path, Constants.MIMETYPE_XML);
|
||||||
assertEquals(200, response.getCode());
|
assertEquals(200, response.getCode());
|
||||||
CellSetModel cellSet = (CellSetModel) unmarshaller.unmarshal(new ByteArrayInputStream(response
|
CellSetModel cellSet = (CellSetModel) xmlUnmarshaller.unmarshal(new ByteArrayInputStream(response
|
||||||
.getBody()));
|
.getBody()));
|
||||||
assertTrue(cellSet.getRows().size() == 1);
|
assertTrue(cellSet.getRows().size() == 1);
|
||||||
assertTrue(cellSet.getRows().get(0).getCells().size() == 3);
|
assertTrue(cellSet.getRows().get(0).getCells().size() == 3);
|
|
@ -28,12 +28,15 @@ import org.apache.hadoop.hbase.rest.client.Response;
|
||||||
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;
|
||||||
import org.apache.hadoop.hbase.rest.model.RowModel;
|
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.apache.hadoop.hbase.util.Bytes;
|
||||||
|
import org.codehaus.jackson.map.ObjectMapper;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.experimental.categories.Category;
|
import org.junit.experimental.categories.Category;
|
||||||
|
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
import javax.xml.bind.JAXBContext;
|
import javax.xml.bind.JAXBContext;
|
||||||
import javax.xml.bind.JAXBException;
|
import javax.xml.bind.JAXBException;
|
||||||
import javax.xml.bind.Marshaller;
|
import javax.xml.bind.Marshaller;
|
||||||
|
@ -151,7 +154,7 @@ public class TestMultiRowResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMultiCellGetJSONNotFound() throws IOException {
|
public void testMultiCellGetJSONNotFound() throws IOException, JAXBException {
|
||||||
String row_5_url = "/" + TABLE + "/" + ROW_1 + "/" + COLUMN_1;
|
String row_5_url = "/" + TABLE + "/" + ROW_1 + "/" + COLUMN_1;
|
||||||
|
|
||||||
StringBuilder path = new StringBuilder();
|
StringBuilder path = new StringBuilder();
|
||||||
|
@ -163,11 +166,15 @@ public class TestMultiRowResource {
|
||||||
path.append(ROW_2);
|
path.append(ROW_2);
|
||||||
|
|
||||||
client.post(row_5_url, Constants.MIMETYPE_BINARY, Bytes.toBytes(VALUE_1));
|
client.post(row_5_url, Constants.MIMETYPE_BINARY, Bytes.toBytes(VALUE_1));
|
||||||
|
|
||||||
Response response = client.get(path.toString(), Constants.MIMETYPE_JSON);
|
Response response = client.get(path.toString(), Constants.MIMETYPE_JSON);
|
||||||
|
assertEquals(response.getCode(), 200);
|
||||||
assertEquals(response.getCode(), 404);
|
ObjectMapper mapper = new JacksonProvider().locateMapper(CellSetModel.class,
|
||||||
|
MediaType.APPLICATION_JSON_TYPE);
|
||||||
|
CellSetModel cellSet = (CellSetModel) mapper.readValue(response.getBody(), CellSetModel.class);
|
||||||
|
assertEquals(1, cellSet.getRows().size());
|
||||||
|
assertEquals(ROW_1, Bytes.toString(cellSet.getRows().get(0).getKey()));
|
||||||
|
assertEquals(VALUE_1, Bytes.toString(cellSet.getRows().get(0).getCells().get(0).getValue()));
|
||||||
|
client.delete(row_5_url);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -281,7 +281,7 @@ public class TestRemoteTable {
|
||||||
gets.add(new Get(ROW_2));
|
gets.add(new Get(ROW_2));
|
||||||
results = remoteTable.get(gets);
|
results = remoteTable.get(gets);
|
||||||
assertNotNull(results);
|
assertNotNull(results);
|
||||||
assertEquals(0, results.length);
|
assertEquals(2, results.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Reference in New Issue