You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by wc...@apache.org on 2019/09/17 08:54:19 UTC
[hbase] branch branch-2.2 updated: HBASE-22846 Internal Error 500 when Using HBASE REST API to Create Na… (#524)
This is an automated email from the ASF dual-hosted git repository.
wchevreuil pushed a commit to branch branch-2.2
in repository https://gitbox.apache.org/repos/asf/hbase.git
The following commit(s) were added to refs/heads/branch-2.2 by this push:
new 81ac896 HBASE-22846 Internal Error 500 when Using HBASE REST API to Create Na… (#524)
81ac896 is described below
commit 81ac896299aaadc3b26a2087f91a75a2599c07c0
Author: Wellington Ramos Chevreuil <wc...@apache.org>
AuthorDate: Tue Sep 17 09:11:35 2019 +0100
HBASE-22846 Internal Error 500 when Using HBASE REST API to Create Na… (#524)
Signed-off-by: stack <st...@apache.org>
(cherry picked from commit f6ff970f397cc6cdef6608ec8de352b139ea11c6)
---
.../hbase/rest/NamespacesInstanceResource.java | 69 +++++-----------------
.../hbase/rest/model/NamespacesInstanceModel.java | 1 +
.../hbase/rest/TestNamespacesInstanceResource.java | 25 ++++++--
3 files changed, 37 insertions(+), 58 deletions(-)
diff --git a/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/NamespacesInstanceResource.java b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/NamespacesInstanceResource.java
index 3ff25f9..215abae 100644
--- a/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/NamespacesInstanceResource.java
+++ b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/NamespacesInstanceResource.java
@@ -135,36 +135,10 @@ public class NamespacesInstanceResource extends ResourceBase {
@Consumes({MIMETYPE_XML, MIMETYPE_JSON, MIMETYPE_PROTOBUF,
MIMETYPE_PROTOBUF_IETF})
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);
}
/**
- * 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.
* @param model properties used for create.
* @param uriInfo (JAX-RS context variable) request URL
@@ -175,39 +149,26 @@ public class NamespacesInstanceResource extends ResourceBase {
MIMETYPE_PROTOBUF_IETF})
public Response post(final NamespacesInstanceModel model,
final @Context UriInfo uriInfo) {
-
- if (LOG.isTraceEnabled()) {
- LOG.trace("POST " + uriInfo.getAbsolutePath());
- }
- servlet.getMetrics().incrementRequests(1);
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) {
+
+ // Check that POST or PUT is valid and then update namespace.
+ private Response processUpdate(NamespacesInstanceModel model, final boolean updateExisting,
+ final UriInfo uriInfo) {
if (LOG.isTraceEnabled()) {
- LOG.trace("POST " + uriInfo.getAbsolutePath());
+ LOG.trace((updateExisting ? "PUT " : "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 + "'.");
+ 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);
- // Check that POST or PUT is valid and then update namespace.
- private Response processUpdate(final NamespacesInstanceModel model, final boolean updateExisting,
- final UriInfo uriInfo) {
if (servlet.isReadOnly()) {
servlet.getMetrics().incrementFailedPutRequests(1);
return Response.status(Response.Status.FORBIDDEN).type(MIMETYPE_TEXT)
@@ -265,7 +226,9 @@ public class NamespacesInstanceResource extends ResourceBase {
}
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{
diff --git a/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/model/NamespacesInstanceModel.java b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/model/NamespacesInstanceModel.java
index 022ec38..af3b0b0 100644
--- a/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/model/NamespacesInstanceModel.java
+++ b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/model/NamespacesInstanceModel.java
@@ -166,4 +166,5 @@ public class NamespacesInstanceModel implements Serializable, ProtobufMessageHan
}
return this;
}
+
}
diff --git a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestNamespacesInstanceResource.java b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestNamespacesInstanceResource.java
index e0beeab..53eeecb 100644
--- a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestNamespacesInstanceResource.java
+++ b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestNamespacesInstanceResource.java
@@ -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.RestTests;
import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.http.Header;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.ClassRule;
@@ -329,6 +330,12 @@ public class TestNamespacesInstanceResource {
jsonString = jsonMapper.writeValueAsString(model2);
response = client.post(namespacePath2, Constants.MIMETYPE_JSON, Bytes.toBytes(jsonString));
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.
nd1 = findNamespace(admin, NAMESPACE1);
@@ -379,8 +386,12 @@ public class TestNamespacesInstanceResource {
model4 = testNamespacesInstanceModel.buildTestModel(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.
- response = client.put(namespacePath3, Constants.MIMETYPE_BINARY, new byte[]{});
+ response = client.put(namespacePath3, nullHeaders, new byte[]{});
assertEquals(403, response.getCode());
response = client.put(namespacePath4, Constants.MIMETYPE_PROTOBUF,
model4.createProtobufOutput());
@@ -388,7 +399,7 @@ public class TestNamespacesInstanceResource {
// Test cannot create tables when in read only mode.
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());
response = client.put(namespacePath4, Constants.MIMETYPE_PROTOBUF,
model4.createProtobufOutput());
@@ -399,12 +410,16 @@ public class TestNamespacesInstanceResource {
assertNull(nd4);
conf.set("hbase.rest.readonly", "false");
- // Create namespace via no body and protobuf.
- response = client.post(namespacePath3, Constants.MIMETYPE_BINARY, new byte[]{});
+ // Create namespace with no body and binary content type.
+ response = client.post(namespacePath3, nullHeaders, new byte[]{});
assertEquals(201, response.getCode());
+ // Create namespace with protobuf content-type.
response = client.post(namespacePath4, Constants.MIMETYPE_PROTOBUF,
model4.createProtobufOutput());
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.
nd3 = findNamespace(admin, NAMESPACE3);
@@ -415,7 +430,7 @@ public class TestNamespacesInstanceResource {
checkNamespaceProperties(nd4, NAMESPACE4_PROPS);
// 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());
response = client.post(namespacePath4, Constants.MIMETYPE_PROTOBUF,
model4.createProtobufOutput());