HBASE-22846 Internal Error 500 when Using HBASE REST API to Create Na… (#524)
Signed-off-by: stack <stack@apache.org>
(cherry picked from commit f6ff970f39
)
This commit is contained in:
parent
bcad0d9f98
commit
9198525501
|
@ -136,35 +136,9 @@ public class NamespacesInstanceResource extends ResourceBase {
|
||||||
@Consumes({MIMETYPE_XML, MIMETYPE_JSON, MIMETYPE_PROTOBUF,
|
@Consumes({MIMETYPE_XML, MIMETYPE_JSON, MIMETYPE_PROTOBUF,
|
||||||
MIMETYPE_PROTOBUF_IETF})
|
MIMETYPE_PROTOBUF_IETF})
|
||||||
public Response put(final NamespacesInstanceModel model, final @Context UriInfo uriInfo) {
|
public Response put(final NamespacesInstanceModel model, final @Context UriInfo uriInfo) {
|
||||||
if (LOG.isTraceEnabled()) {
|
|
||||||
LOG.trace("PUT " + uriInfo.getAbsolutePath());
|
|
||||||
}
|
|
||||||
servlet.getMetrics().incrementRequests(1);
|
|
||||||
return processUpdate(model, true, uriInfo);
|
return processUpdate(model, true, uriInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Build a response for PUT alter namespace with no properties specified.
|
|
||||||
* @param message value not used.
|
|
||||||
* @param headers value not used.
|
|
||||||
* @return response code.
|
|
||||||
*/
|
|
||||||
@PUT
|
|
||||||
public Response putNoBody(final byte[] message,
|
|
||||||
final @Context UriInfo uriInfo, final @Context HttpHeaders headers) {
|
|
||||||
if (LOG.isTraceEnabled()) {
|
|
||||||
LOG.trace("PUT " + uriInfo.getAbsolutePath());
|
|
||||||
}
|
|
||||||
servlet.getMetrics().incrementRequests(1);
|
|
||||||
try{
|
|
||||||
NamespacesInstanceModel model = new NamespacesInstanceModel(namespace);
|
|
||||||
return processUpdate(model, true, uriInfo);
|
|
||||||
}catch(IOException ioe){
|
|
||||||
servlet.getMetrics().incrementFailedPutRequests(1);
|
|
||||||
throw new RuntimeException("Cannot retrieve info for '" + namespace + "'.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build a response for POST create namespace with properties specified.
|
* Build a response for POST create namespace with properties specified.
|
||||||
* @param model properties used for create.
|
* @param model properties used for create.
|
||||||
|
@ -176,39 +150,26 @@ public class NamespacesInstanceResource extends ResourceBase {
|
||||||
MIMETYPE_PROTOBUF_IETF})
|
MIMETYPE_PROTOBUF_IETF})
|
||||||
public Response post(final NamespacesInstanceModel model,
|
public Response post(final NamespacesInstanceModel model,
|
||||||
final @Context UriInfo uriInfo) {
|
final @Context UriInfo uriInfo) {
|
||||||
|
|
||||||
if (LOG.isTraceEnabled()) {
|
|
||||||
LOG.trace("POST " + uriInfo.getAbsolutePath());
|
|
||||||
}
|
|
||||||
servlet.getMetrics().incrementRequests(1);
|
|
||||||
return processUpdate(model, false, uriInfo);
|
return processUpdate(model, false, uriInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Build a response for POST create namespace with no properties specified.
|
|
||||||
* @param message value not used.
|
|
||||||
* @param headers value not used.
|
|
||||||
* @return response code.
|
|
||||||
*/
|
|
||||||
@POST
|
|
||||||
public Response postNoBody(final byte[] message,
|
|
||||||
final @Context UriInfo uriInfo, final @Context HttpHeaders headers) {
|
|
||||||
if (LOG.isTraceEnabled()) {
|
|
||||||
LOG.trace("POST " + uriInfo.getAbsolutePath());
|
|
||||||
}
|
|
||||||
servlet.getMetrics().incrementRequests(1);
|
|
||||||
try{
|
|
||||||
NamespacesInstanceModel model = new NamespacesInstanceModel(namespace);
|
|
||||||
return processUpdate(model, false, uriInfo);
|
|
||||||
}catch(IOException ioe){
|
|
||||||
servlet.getMetrics().incrementFailedPutRequests(1);
|
|
||||||
throw new RuntimeException("Cannot retrieve info for '" + namespace + "'.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that POST or PUT is valid and then update namespace.
|
// Check that POST or PUT is valid and then update namespace.
|
||||||
private Response processUpdate(final NamespacesInstanceModel model, final boolean updateExisting,
|
private Response processUpdate(NamespacesInstanceModel model, final boolean updateExisting,
|
||||||
final UriInfo uriInfo) {
|
final UriInfo uriInfo) {
|
||||||
|
if (LOG.isTraceEnabled()) {
|
||||||
|
LOG.trace((updateExisting ? "PUT " : "POST ") + uriInfo.getAbsolutePath());
|
||||||
|
}
|
||||||
|
if (model == null) {
|
||||||
|
try {
|
||||||
|
model = new NamespacesInstanceModel(namespace);
|
||||||
|
} catch(IOException ioe) {
|
||||||
|
servlet.getMetrics().incrementFailedPutRequests(1);
|
||||||
|
throw new RuntimeException("Cannot retrieve info for '" + namespace + "'.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
servlet.getMetrics().incrementRequests(1);
|
||||||
|
|
||||||
if (servlet.isReadOnly()) {
|
if (servlet.isReadOnly()) {
|
||||||
servlet.getMetrics().incrementFailedPutRequests(1);
|
servlet.getMetrics().incrementFailedPutRequests(1);
|
||||||
return Response.status(Response.Status.FORBIDDEN).type(MIMETYPE_TEXT)
|
return Response.status(Response.Status.FORBIDDEN).type(MIMETYPE_TEXT)
|
||||||
|
@ -266,7 +227,9 @@ public class NamespacesInstanceResource extends ResourceBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
servlet.getMetrics().incrementSucessfulPutRequests(1);
|
servlet.getMetrics().incrementSucessfulPutRequests(1);
|
||||||
return Response.created(uriInfo.getAbsolutePath()).build();
|
|
||||||
|
return updateExisting ? Response.ok(uriInfo.getAbsolutePath()).build() :
|
||||||
|
Response.created(uriInfo.getAbsolutePath()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean doesNamespaceExist(Admin admin, String namespaceName) throws IOException{
|
private boolean doesNamespaceExist(Admin admin, String namespaceName) throws IOException{
|
||||||
|
|
|
@ -166,4 +166,5 @@ public class NamespacesInstanceModel implements Serializable, ProtobufMessageHan
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,7 @@ import org.apache.hadoop.hbase.rest.model.TestNamespacesInstanceModel;
|
||||||
import org.apache.hadoop.hbase.testclassification.MediumTests;
|
import org.apache.hadoop.hbase.testclassification.MediumTests;
|
||||||
import org.apache.hadoop.hbase.testclassification.RestTests;
|
import org.apache.hadoop.hbase.testclassification.RestTests;
|
||||||
import org.apache.hadoop.hbase.util.Bytes;
|
import org.apache.hadoop.hbase.util.Bytes;
|
||||||
|
import org.apache.http.Header;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.ClassRule;
|
import org.junit.ClassRule;
|
||||||
|
@ -329,6 +330,12 @@ public class TestNamespacesInstanceResource {
|
||||||
jsonString = jsonMapper.writeValueAsString(model2);
|
jsonString = jsonMapper.writeValueAsString(model2);
|
||||||
response = client.post(namespacePath2, Constants.MIMETYPE_JSON, Bytes.toBytes(jsonString));
|
response = client.post(namespacePath2, Constants.MIMETYPE_JSON, Bytes.toBytes(jsonString));
|
||||||
assertEquals(201, response.getCode());
|
assertEquals(201, response.getCode());
|
||||||
|
//check passing null content-type with a payload returns 415
|
||||||
|
Header[] nullHeaders = null;
|
||||||
|
response = client.post(namespacePath1, nullHeaders, toXML(model1));
|
||||||
|
assertEquals(415, response.getCode());
|
||||||
|
response = client.post(namespacePath1, nullHeaders, Bytes.toBytes(jsonString));
|
||||||
|
assertEquals(415, response.getCode());
|
||||||
|
|
||||||
// Check that created namespaces correctly.
|
// Check that created namespaces correctly.
|
||||||
nd1 = findNamespace(admin, NAMESPACE1);
|
nd1 = findNamespace(admin, NAMESPACE1);
|
||||||
|
@ -379,8 +386,12 @@ public class TestNamespacesInstanceResource {
|
||||||
model4 = testNamespacesInstanceModel.buildTestModel(NAMESPACE4, NAMESPACE4_PROPS);
|
model4 = testNamespacesInstanceModel.buildTestModel(NAMESPACE4, NAMESPACE4_PROPS);
|
||||||
testNamespacesInstanceModel.checkModel(model4, NAMESPACE4, NAMESPACE4_PROPS);
|
testNamespacesInstanceModel.checkModel(model4, NAMESPACE4, NAMESPACE4_PROPS);
|
||||||
|
|
||||||
|
//Defines null headers for use in tests where no body content is provided, so that we set
|
||||||
|
// no content-type in the request
|
||||||
|
Header[] nullHeaders = null;
|
||||||
|
|
||||||
// Test cannot PUT (alter) non-existent namespace.
|
// Test cannot PUT (alter) non-existent namespace.
|
||||||
response = client.put(namespacePath3, Constants.MIMETYPE_BINARY, new byte[]{});
|
response = client.put(namespacePath3, nullHeaders, new byte[]{});
|
||||||
assertEquals(403, response.getCode());
|
assertEquals(403, response.getCode());
|
||||||
response = client.put(namespacePath4, Constants.MIMETYPE_PROTOBUF,
|
response = client.put(namespacePath4, Constants.MIMETYPE_PROTOBUF,
|
||||||
model4.createProtobufOutput());
|
model4.createProtobufOutput());
|
||||||
|
@ -388,7 +399,7 @@ public class TestNamespacesInstanceResource {
|
||||||
|
|
||||||
// Test cannot create tables when in read only mode.
|
// Test cannot create tables when in read only mode.
|
||||||
conf.set("hbase.rest.readonly", "true");
|
conf.set("hbase.rest.readonly", "true");
|
||||||
response = client.post(namespacePath3, Constants.MIMETYPE_BINARY, new byte[]{});
|
response = client.post(namespacePath3, nullHeaders, new byte[]{});
|
||||||
assertEquals(403, response.getCode());
|
assertEquals(403, response.getCode());
|
||||||
response = client.put(namespacePath4, Constants.MIMETYPE_PROTOBUF,
|
response = client.put(namespacePath4, Constants.MIMETYPE_PROTOBUF,
|
||||||
model4.createProtobufOutput());
|
model4.createProtobufOutput());
|
||||||
|
@ -399,12 +410,16 @@ public class TestNamespacesInstanceResource {
|
||||||
assertNull(nd4);
|
assertNull(nd4);
|
||||||
conf.set("hbase.rest.readonly", "false");
|
conf.set("hbase.rest.readonly", "false");
|
||||||
|
|
||||||
// Create namespace via no body and protobuf.
|
// Create namespace with no body and binary content type.
|
||||||
response = client.post(namespacePath3, Constants.MIMETYPE_BINARY, new byte[]{});
|
response = client.post(namespacePath3, nullHeaders, new byte[]{});
|
||||||
assertEquals(201, response.getCode());
|
assertEquals(201, response.getCode());
|
||||||
|
// Create namespace with protobuf content-type.
|
||||||
response = client.post(namespacePath4, Constants.MIMETYPE_PROTOBUF,
|
response = client.post(namespacePath4, Constants.MIMETYPE_PROTOBUF,
|
||||||
model4.createProtobufOutput());
|
model4.createProtobufOutput());
|
||||||
assertEquals(201, response.getCode());
|
assertEquals(201, response.getCode());
|
||||||
|
//check setting unsupported content-type returns 415
|
||||||
|
response = client.post(namespacePath3, Constants.MIMETYPE_BINARY, new byte[]{});
|
||||||
|
assertEquals(415, response.getCode());
|
||||||
|
|
||||||
// Check that created namespaces correctly.
|
// Check that created namespaces correctly.
|
||||||
nd3 = findNamespace(admin, NAMESPACE3);
|
nd3 = findNamespace(admin, NAMESPACE3);
|
||||||
|
@ -415,7 +430,7 @@ public class TestNamespacesInstanceResource {
|
||||||
checkNamespaceProperties(nd4, NAMESPACE4_PROPS);
|
checkNamespaceProperties(nd4, NAMESPACE4_PROPS);
|
||||||
|
|
||||||
// Check cannot post tables that already exist.
|
// Check cannot post tables that already exist.
|
||||||
response = client.post(namespacePath3, Constants.MIMETYPE_BINARY, new byte[]{});
|
response = client.post(namespacePath3, nullHeaders, new byte[]{});
|
||||||
assertEquals(403, response.getCode());
|
assertEquals(403, response.getCode());
|
||||||
response = client.post(namespacePath4, Constants.MIMETYPE_PROTOBUF,
|
response = client.post(namespacePath4, Constants.MIMETYPE_PROTOBUF,
|
||||||
model4.createProtobufOutput());
|
model4.createProtobufOutput());
|
||||||
|
|
Loading…
Reference in New Issue