From ec075791dab032d434b1697107de14bc5db8c087 Mon Sep 17 00:00:00 2001 From: Bharat Viswanadham Date: Tue, 2 Oct 2018 20:13:59 -0700 Subject: [PATCH] HDDS-520. Implement HeadBucket REST endpoint. Contributed by Bharat Viswanadham. --- .../apache/hadoop/ozone/s3/EndpointBase.java | 15 +++ .../hadoop/ozone/s3/bucket/HeadBucket.java | 67 +++++++++++++ .../ozone/s3/bucket/TestHeadBucket.java | 95 +++++++++++++++++++ 3 files changed, 177 insertions(+) create mode 100644 hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/bucket/HeadBucket.java create mode 100644 hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/bucket/TestHeadBucket.java diff --git a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/EndpointBase.java b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/EndpointBase.java index f20d18278fa..007cca23a77 100644 --- a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/EndpointBase.java +++ b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/EndpointBase.java @@ -42,6 +42,7 @@ public class EndpointBase { LoggerFactory.getLogger(EndpointBase.class); @Inject private OzoneClient client; + private String requestId; protected OzoneBucket getBucket(String volumeName, String bucketName) throws IOException { @@ -84,4 +85,18 @@ public class EndpointBase { public void setClient(OzoneClient ozoneClient) { this.client = ozoneClient; } + + /** + * Set the requestId. + * @param id + */ + protected void setRequestId(String id) { + this.requestId = id; + } + + @VisibleForTesting + public String getRequestId() { + return requestId; + } + } diff --git a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/bucket/HeadBucket.java b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/bucket/HeadBucket.java new file mode 100644 index 00000000000..296ce3c99af --- /dev/null +++ b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/bucket/HeadBucket.java @@ -0,0 +1,67 @@ +/* + * 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.ozone.s3.bucket; + +import org.apache.hadoop.ozone.s3.EndpointBase; +import org.apache.hadoop.ozone.s3.exception.OS3Exception; +import org.apache.hadoop.ozone.s3.exception.S3ErrorTable; +import org.apache.hadoop.ozone.s3.exception.S3ErrorTable.Resource; +import org.apache.hadoop.ozone.web.utils.OzoneUtils; +import org.apache.http.HttpStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.ws.rs.HEAD; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.core.Response; +import java.io.IOException; + +/** + * Finds the bucket exists or not. + */ +@Path("/{volume}/{bucket}") +public class HeadBucket extends EndpointBase { + + private static final Logger LOG = + LoggerFactory.getLogger(HeadBucket.class); + + @HEAD + public Response head(@PathParam("volume") String volumeName, + @PathParam("bucket") String bucketName) + throws Exception { + setRequestId(OzoneUtils.getRequestID()); + try { + getVolume(volumeName).getBucket(bucketName); + // Not sure what kind of error, we need to show for volume not exist + // to end user. As right now we throw run time exception. + } catch (IOException ex) { + LOG.error("Exception occurred in headBucket", ex); + if (ex.getMessage().contains("NOT_FOUND")) { + OS3Exception os3Exception = S3ErrorTable.newError(S3ErrorTable + .NO_SUCH_BUCKET, getRequestId(), Resource.BUCKET); + throw os3Exception; + } else { + throw ex; + } + } + return Response.ok().status(HttpStatus.SC_OK).header("x-amz-request-id", + getRequestId()).build(); + } +} diff --git a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/bucket/TestHeadBucket.java b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/bucket/TestHeadBucket.java new file mode 100644 index 00000000000..8069b11752b --- /dev/null +++ b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/bucket/TestHeadBucket.java @@ -0,0 +1,95 @@ +/* + * 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.ozone.s3.bucket; + +import org.apache.hadoop.ozone.client.ObjectStore; +import org.apache.hadoop.ozone.client.OzoneClientStub; +import org.apache.hadoop.ozone.client.OzoneVolume; +import org.apache.hadoop.ozone.s3.exception.OS3Exception; +import org.apache.hadoop.ozone.s3.exception.S3ErrorTable; +import org.junit.Before; +import org.junit.Test; + +import javax.ws.rs.core.Response; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +/** + * This class test HeadBucket functionality. + */ +public class TestHeadBucket { + + private String volumeName = "myVolume"; + private String bucketName = "myBucket"; + private OzoneClientStub clientStub; + private ObjectStore objectStoreStub; + private HeadBucket headBucket; + + @Before + public void setup() throws Exception { + + //Create client stub and object store stub. + clientStub = new OzoneClientStub(); + objectStoreStub = clientStub.getObjectStore(); + + // Create volume and bucket + objectStoreStub.createVolume(volumeName); + + OzoneVolume volumeStub = objectStoreStub.getVolume(volumeName); + volumeStub.createBucket(bucketName); + + // Create HeadBucket and setClient to OzoneClientStub + headBucket = new HeadBucket(); + headBucket.setClient(clientStub); + + + } + + @Test + public void testHeadBucket() throws Exception { + + Response response = headBucket.head(volumeName, bucketName); + assertEquals(200, response.getStatus()); + assertEquals(headBucket.getRequestId(), response.getHeaderString( + "x-amz-request-id")); + } + + @Test + public void testHeadFail() { + try { + headBucket.head(volumeName, "unknownbucket"); + } catch (Exception ex) { + if (ex instanceof OS3Exception) { + assertEquals(S3ErrorTable.NO_SUCH_BUCKET.getCode(), + ((OS3Exception) ex).getCode()); + assertEquals(S3ErrorTable.NO_SUCH_BUCKET.getErrorMessage(), ( + (OS3Exception) ex).getErrorMessage()); + assertEquals(S3ErrorTable.NO_SUCH_BUCKET.getResource(), ( + (OS3Exception) ex).getResource()); + assertEquals(headBucket.getRequestId(), ( + (OS3Exception) ex).getRequestId()); + } else { + fail("testHeadFail failed"); + } + } + } +}