You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by ae...@apache.org on 2015/07/28 20:14:09 UTC

[6/6] hadoop git commit: HDFS-8695. OzoneHandler : Add Bucket REST Interface. (aengineer)

HDFS-8695. OzoneHandler : Add Bucket REST Interface. (aengineer)


Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo
Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/c7851874
Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/c7851874
Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/c7851874

Branch: refs/heads/HDFS-7240
Commit: c78518749e431684cfc7685e1cf3299751b130e6
Parents: 188d283
Author: Anu Engineer <ae...@apache.org>
Authored: Tue Jul 28 11:13:13 2015 -0700
Committer: Anu Engineer <ae...@apache.org>
Committed: Tue Jul 28 11:13:13 2015 -0700

----------------------------------------------------------------------
 .../hadoop/ozone/web/exceptions/ErrorTable.java |   5 +
 .../hadoop/ozone/web/handlers/BucketArgs.java   |  10 -
 .../ozone/web/handlers/BucketHandler.java       | 193 +++++++++++++
 .../web/handlers/BucketProcessTemplate.java     | 278 +++++++++++++++++++
 .../apache/hadoop/ozone/web/headers/Header.java |  14 +-
 .../hadoop/ozone/web/interfaces/Bucket.java     | 133 +++++++++
 .../ozone/web/interfaces/StorageHandler.java    |  85 ++++++
 .../web/localstorage/LocalStorageHandler.java   | 109 ++++++++
 8 files changed, 815 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hadoop/blob/c7851874/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/exceptions/ErrorTable.java
----------------------------------------------------------------------
diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/exceptions/ErrorTable.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/exceptions/ErrorTable.java
index a51dac5..7e75cf0 100644
--- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/exceptions/ErrorTable.java
+++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/exceptions/ErrorTable.java
@@ -58,6 +58,7 @@ public final class ErrorTable {
       new OzoneException(HTTP_BAD_REQUEST, "malformedACL",
                          "Invalid ACL specified.");
 
+
   public static final OzoneException INVALID_VOLUME_NAME =
       new OzoneException(HTTP_BAD_REQUEST, "invalidVolumeName",
                          "Invalid volume name.");
@@ -81,6 +82,10 @@ public final class ErrorTable {
       new OzoneException(HTTP_BAD_REQUEST, "malformedBucketVersion",
                          "Malformed bucket version or version not unique.");
 
+  public static final OzoneException MALFORMED_STORAGE_TYPE =
+      new OzoneException(HTTP_BAD_REQUEST, "malformedStorageType",
+                         "Invalid storage Type specified.");
+
   public static final OzoneException MALFORMED_STORAGE_CLASS =
       new OzoneException(HTTP_BAD_REQUEST, "malformedStorageClass",
                          "Invalid storage class specified.");

http://git-wip-us.apache.org/repos/asf/hadoop/blob/c7851874/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/handlers/BucketArgs.java
----------------------------------------------------------------------
diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/handlers/BucketArgs.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/handlers/BucketArgs.java
index 315ae3f..d62c72d 100644
--- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/handlers/BucketArgs.java
+++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/handlers/BucketArgs.java
@@ -164,16 +164,6 @@ public class BucketArgs extends VolumeArgs {
     return versioning;
   }
 
-  /**
-   * Converts a valid String to Enum for ease of use.
-   *
-   * @param version version string.
-   */
-  public void setVersioning(String version) {
-    if (version != null) {
-      this.versioning = OzoneConsts.Versioning.valueOf(version.toUpperCase());
-    }
-  }
 
   /**
    * SetVersioning Info.

http://git-wip-us.apache.org/repos/asf/hadoop/blob/c7851874/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/handlers/BucketHandler.java
----------------------------------------------------------------------
diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/handlers/BucketHandler.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/handlers/BucketHandler.java
new file mode 100644
index 0000000..2005367
--- /dev/null
+++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/handlers/BucketHandler.java
@@ -0,0 +1,193 @@
+/*
+ *
+ *  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.web.handlers;
+
+import org.apache.hadoop.ozone.web.exceptions.ErrorTable;
+import org.apache.hadoop.ozone.web.exceptions.OzoneException;
+import org.apache.hadoop.ozone.web.headers.Header;
+import org.apache.hadoop.ozone.web.interfaces.Bucket;
+import org.apache.hadoop.ozone.web.interfaces.StorageHandler;
+import org.apache.hadoop.ozone.web.utils.OzoneConsts;
+import org.apache.hadoop.ozone.web.utils.OzoneUtils;
+
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Request;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import java.io.IOException;
+
+import static java.net.HttpURLConnection.HTTP_CREATED;
+import static java.net.HttpURLConnection.HTTP_OK;
+
+
+/**
+ * Bucket Class handles all ozone Bucket related actions.
+ */
+public class BucketHandler implements Bucket {
+  /**
+   * createBucket call handles the POST request for Creating a Bucket.
+   *
+   * @param volume - Volume name
+   * @param bucket - Bucket Name
+   * @param req - Http request
+   * @param info - Uri Info
+   * @param headers - Http headers
+   *
+   * @return Response
+   *
+   * @throws OzoneException
+   */
+  @Override
+  public Response createBucket(String volume, String bucket, Request req,
+                               UriInfo info, HttpHeaders headers)
+      throws OzoneException {
+    return new BucketProcessTemplate() {
+      @Override
+      public Response doProcess(BucketArgs args)
+          throws OzoneException, IOException {
+        StorageHandler fs = StorageHandlerBuilder.getStorageHandler();
+        getAclsFromHeaders(args, false);
+        args.setVersioning(getVersioning(args));
+        args.setStorageType(getStorageType(args));
+        fs.createBucket(args);
+        return OzoneUtils.getResponse(args, HTTP_CREATED, "");
+      }
+    }.handleCall(volume, bucket, req, info, headers);
+  }
+
+  /**
+   * updateBucket call handles the PUT request for updating a Bucket.
+   *
+   * There are only three possible actions currently with updateBucket.
+   * They are add/remove on ACLS, Bucket Versioning and  StorageType.
+   *  if you make a call with any other action, update just returns 200 OK.
+   *
+   * @param volume - Storage volume name
+   * @param bucket - Bucket name
+   * @param req - Http request
+   * @param info - Uri Info
+   * @param headers - Http headers
+   *
+   * @return Response
+   *
+   * @throws OzoneException
+   */
+  @Override
+  public Response updateBucket(String volume, String bucket, Request req,
+                               UriInfo info, HttpHeaders headers)
+      throws OzoneException {
+    return new BucketProcessTemplate() {
+      @Override
+      public Response doProcess(BucketArgs args)
+          throws OzoneException, IOException {
+        StorageHandler fs = StorageHandlerBuilder.getStorageHandler();
+        getAclsFromHeaders(args, true);
+        args.setVersioning(getVersioning(args));
+        args.setStorageType(getStorageType(args));
+
+        if ((args.getAddAcls() != null) || (args.getRemoveAcls() != null)) {
+          fs.setBucketAcls(args);
+        }
+
+        if (args.getVersioning() != OzoneConsts.Versioning.NOT_DEFINED) {
+          fs.setBucketVersioning(args);
+        }
+
+        if (args.getStorageType() != null) {
+          fs.setBucketStorageClass(args);
+        }
+        return OzoneUtils.getResponse(args, HTTP_OK, "");
+      }
+    }.handleCall(volume, bucket, req, info, headers);
+  }
+
+  /**
+   * Deletes an empty bucket.
+   *
+   * @param volume Volume name
+   * @param bucket Bucket Name
+   * @param req - Http request
+   * @param info - Uri Info
+   * @param headers - Http headers
+   *
+   * @return Response
+   *
+   * @throws OzoneException
+   */
+  @Override
+  public Response deleteBucket(String volume, String bucket, Request req,
+                               UriInfo info, HttpHeaders headers)
+      throws OzoneException {
+    return new BucketProcessTemplate() {
+      @Override
+      public Response doProcess(BucketArgs args)
+          throws OzoneException, IOException {
+        StorageHandler fs = StorageHandlerBuilder.getStorageHandler();
+        fs.deleteBucket(args);
+        return OzoneUtils.getResponse(args, HTTP_OK, "");
+      }
+    }.handleCall(volume, bucket, req, info, headers);
+  }
+
+  /**
+   * List Buckets allows the user to list the bucket.
+   *
+   * @param volume - Storage Volume Name
+   * @param bucket - Bucket Name
+   * @param info - Uri Info
+   * @param prefix - Prefix for the keys to be fetched
+   * @param maxKeys - MaxNumber of Keys to Return
+   * @param startPage - Continuation Token
+   * @param req - Http request
+   * @param headers - Http headers
+   *
+   * @return - Json Body
+   *
+   * @throws OzoneException
+   */
+  @Override
+  public Response listBucket(String volume, String bucket, final String info,
+                             final String prefix, final int maxKeys,
+                             final String startPage, Request req,
+                             UriInfo uriInfo, HttpHeaders headers)
+      throws OzoneException {
+    return new BucketProcessTemplate() {
+      @Override
+      public Response doProcess(BucketArgs args)
+          throws OzoneException, IOException {
+        switch (info) {
+          //TODO : Enable when Object support is enabled.
+          //          case Header.OZONE_LIST_QUERY_KEY:
+          //            ListArgs listArgs = new ListArgs(args, prefix,
+          // maxKeys, startPage);
+          //            return getBucketKeysList(listArgs);
+          case Header.OZONE_LIST_QUERY_BUCKET:
+            return getBucketInfoResponse(args);
+          default:
+            OzoneException ozException =
+                ErrorTable.newError(ErrorTable.INVALID_QUERY_PARAM, args);
+            ozException.setMessage("Unrecognized query param : " + info);
+            throw ozException;
+        }
+      }
+    }.handleCall(volume, bucket, req, uriInfo, headers);
+  }
+}

http://git-wip-us.apache.org/repos/asf/hadoop/blob/c7851874/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/handlers/BucketProcessTemplate.java
----------------------------------------------------------------------
diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/handlers/BucketProcessTemplate.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/handlers/BucketProcessTemplate.java
new file mode 100644
index 0000000..73827db
--- /dev/null
+++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/handlers/BucketProcessTemplate.java
@@ -0,0 +1,278 @@
+/*
+ * 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.web.handlers;
+
+
+import org.apache.hadoop.fs.StorageType;
+import org.apache.hadoop.ozone.web.exceptions.ErrorTable;
+import org.apache.hadoop.ozone.web.exceptions.OzoneException;
+import org.apache.hadoop.ozone.web.headers.Header;
+import org.apache.hadoop.ozone.web.interfaces.StorageHandler;
+import org.apache.hadoop.ozone.web.interfaces.UserAuth;
+import org.apache.hadoop.ozone.web.response.BucketInfo;
+import org.apache.hadoop.ozone.web.utils.OzoneConsts;
+import org.apache.hadoop.ozone.web.utils.OzoneUtils;
+
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Request;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import java.io.IOException;
+import java.nio.file.DirectoryNotEmptyException;
+import java.nio.file.FileAlreadyExistsException;
+import java.nio.file.NoSuchFileException;
+import java.util.LinkedList;
+import java.util.List;
+
+import static java.net.HttpURLConnection.HTTP_OK;
+
+
+/**
+ * This class abstracts way the repetitive tasks in
+ * Bucket handling code.
+ */
+public abstract class BucketProcessTemplate {
+
+  /**
+   * This function serves as the common error handling function
+   * for all bucket related operations.
+   *
+   * @param volume - Volume Name
+   * @param bucket - Bucket Name
+   * @param request - Http Request
+   * @param uriInfo - Http Uri
+   * @param headers - Http Headers
+   *
+   * @return Response
+   *
+   * @throws OzoneException
+   */
+  public Response handleCall(String volume, String bucket, Request request,
+                             UriInfo uriInfo, HttpHeaders headers)
+      throws OzoneException {
+    // TODO : Add logging
+    String reqID = OzoneUtils.getRequestID();
+    String hostName = OzoneUtils.getHostName();
+    try {
+      OzoneUtils.validate(request, headers, reqID, bucket, hostName);
+      OzoneUtils.verifyBucketName(bucket);
+
+      UserAuth auth = UserHandlerBuilder.getAuthHandler();
+      UserArgs userArgs =
+          new UserArgs(reqID, hostName, request, uriInfo, headers);
+      userArgs.setUserName(auth.getUser(userArgs));
+
+      BucketArgs args = new BucketArgs(volume, bucket, userArgs);
+      return doProcess(args);
+    } catch (IllegalArgumentException argExp) {
+      OzoneException ex = ErrorTable
+          .newError(ErrorTable.INVALID_BUCKET_NAME, reqID, bucket, hostName);
+      ex.setMessage(argExp.getMessage());
+      throw ex;
+    } catch (IOException fsExp) {
+      handleIOException(bucket, reqID, hostName, fsExp);
+    }
+    return null;
+  }
+
+  /**
+   * Reads ACLs from headers and throws appropriate exception if needed.
+   *
+   * @param args - bucketArgs
+   *
+   * @throws OzoneException
+   */
+  void getAclsFromHeaders(BucketArgs args, boolean parseRemoveACL)
+      throws OzoneException {
+    try {
+      List<String> acls = getAcls(args, Header.OZONE_ACL_REMOVE);
+      if (acls != null && !acls.isEmpty()) {
+        args.removeAcls(acls);
+      }
+      if ((!parseRemoveACL) && args.getRemoveAcls() != null) {
+        OzoneException ex = ErrorTable.newError(ErrorTable.MALFORMED_ACL, args);
+        ex.setMessage("Invalid Remove ACLs");
+        throw ex;
+      }
+
+      acls = getAcls(args, Header.OZONE_ACL_ADD);
+      if (acls != null && !acls.isEmpty()) {
+        args.addAcls(acls);
+      }
+    } catch (IllegalArgumentException ex) {
+      throw ErrorTable.newError(ErrorTable.MALFORMED_ACL, args, ex);
+    }
+  }
+
+  /**
+   * Converts FileSystem IO exceptions to OZONE exceptions.
+   *
+   * @param bucket Name of the bucket
+   * @param reqID Request ID
+   * @param hostName Machine Name
+   * @param fsExp Exception
+   *
+   * @throws OzoneException
+   */
+  void handleIOException(String bucket, String reqID, String hostName,
+                         IOException fsExp) throws OzoneException {
+
+    if (fsExp instanceof FileAlreadyExistsException) {
+      throw ErrorTable
+          .newError(ErrorTable.BUCKET_ALREADY_EXISTS, reqID, bucket, hostName);
+    }
+
+    if (fsExp instanceof DirectoryNotEmptyException) {
+      throw ErrorTable
+          .newError(ErrorTable.BUCKET_NOT_EMPTY, reqID, bucket, hostName);
+    }
+
+    if (fsExp instanceof NoSuchFileException) {
+      throw ErrorTable
+          .newError(ErrorTable.INVALID_BUCKET_NAME, reqID, bucket, hostName);
+    }
+
+    // default we don't handle this exception yet.
+
+    throw ErrorTable.newError(ErrorTable.SERVER_ERROR, reqID, bucket, hostName);
+  }
+
+  /**
+   * Abstract function that gets implemented in the BucketHandler functions.
+   * This function will just deal with the core file system related logic
+   * and will rely on handleCall function for repetitive error checks
+   *
+   * @param args - parsed bucket args, name, userName, ACLs etc
+   *
+   * @return Response
+   *
+   * @throws OzoneException
+   * @throws IOException
+   */
+  public abstract Response doProcess(BucketArgs args)
+      throws OzoneException, IOException;
+
+
+  /**
+   * Returns the ACL String if available.
+   * This function ignores all ACLs that are not prefixed with either
+   * ADD or Remove
+   *
+   * @param args - BucketArgs
+   * @param tag - Tag for different type of acls
+   *
+   * @return List of ACLs
+   *
+   * @throws OzoneException
+   */
+  List<String> getAcls(BucketArgs args, String tag) throws OzoneException {
+    List<String> aclStrings =
+        args.getHeaders().getRequestHeader(Header.OZONE_ACLS);
+    List<String> filteredSet = null;
+    if (aclStrings != null) {
+      filteredSet = new LinkedList<>();
+      for (String s : aclStrings) {
+        if (s.startsWith(tag)) {
+          filteredSet.add(s.replaceFirst(tag, ""));
+        }
+      }
+    }
+    return filteredSet;
+  }
+
+  /**
+   * Returns bucket versioning Info.
+   *
+   * @param args - BucketArgs
+   *
+   * @return - String
+   *
+   * @throws OzoneException
+   */
+  OzoneConsts.Versioning getVersioning(BucketArgs args) throws OzoneException {
+
+    List<String> versionStrings =
+        args.getHeaders().getRequestHeader(Header.OZONE_BUCKET_VERSIONING);
+    if (versionStrings == null) {
+      return null;
+    }
+
+    if (versionStrings.size() > 1) {
+      OzoneException ex =
+          ErrorTable.newError(ErrorTable.MALFORMED_BUCKET_VERSION, args);
+      ex.setMessage("Exactly one bucket version header required");
+      throw ex;
+    }
+
+    String version = versionStrings.get(0);
+    try {
+      return OzoneConsts.Versioning.valueOf(version);
+    } catch (IllegalArgumentException ex) {
+      throw ErrorTable.newError(ErrorTable.MALFORMED_BUCKET_VERSION, args, ex);
+    }
+  }
+
+
+  /**
+   * Returns Storage Class if Available or returns Default.
+   *
+   * @param args - bucketArgs
+   *
+   * @return StorageType
+   *
+   * @throws OzoneException
+   */
+  StorageType getStorageType(BucketArgs args) throws OzoneException {
+
+    try {
+      List<String> storageClassString =
+          args.getHeaders().getRequestHeader(Header.OZONE_STORAGE_CLASS);
+      if (storageClassString == null) {
+        return null;
+      }
+      if (storageClassString.size() > 1) {
+        OzoneException ex =
+            ErrorTable.newError(ErrorTable.MALFORMED_STORAGE_TYPE, args);
+        ex.setMessage("Exactly one storage class header required");
+        throw ex;
+      }
+      return StorageType.valueOf(storageClassString.get(0).toUpperCase());
+    } catch (IllegalArgumentException ex) {
+      throw ErrorTable.newError(ErrorTable.MALFORMED_STORAGE_TYPE, args, ex);
+    }
+  }
+
+  /**
+   * Returns BucketInfo response.
+   *
+   * @param args - BucketArgs
+   *
+   * @return BucketInfo
+   *
+   * @throws IOException
+   * @throws OzoneException
+   */
+  Response getBucketInfoResponse(BucketArgs args)
+      throws IOException, OzoneException {
+    StorageHandler fs = StorageHandlerBuilder.getStorageHandler();
+    BucketInfo info = fs.getBucketInfo(args);
+    return OzoneUtils.getResponse(args, HTTP_OK, info.toJsonString());
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/hadoop/blob/c7851874/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/headers/Header.java
----------------------------------------------------------------------
diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/headers/Header.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/headers/Header.java
index 6400b44..a804235 100644
--- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/headers/Header.java
+++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/headers/Header.java
@@ -38,12 +38,22 @@ public final class Header {
 
   public static final String OZONE_LIST_QUERY_SERVICE = "service";
   public static final String OZONE_LIST_QUERY_VOLUME = "volume";
-  public static final String OZONE_LIST_QUERY_BUCKET ="bucket";
-  public static final String OZONE_LIST_QUERY_KEY ="key";
+  public static final String OZONE_LIST_QUERY_BUCKET = "bucket";
+  public static final String OZONE_LIST_QUERY_KEY = "key";
 
   public static final String OZONE_REQUEST_ID = "x-ozone-request-id";
   public static final String OZONE_SERVER_NAME = "x-ozone-server-name";
 
+  public static final String OZONE_STORAGE_CLASS = "x-ozone-storage-type";
+
+  public static final String OZONE_BUCKET_VERSIONING =
+      "x-ozone-bucket-versioning";
+
+  public static final String OZONE_ACLS = "x-ozone-acls";
+  public static final String OZONE_ACL_ADD = "ADD";
+  public static final String OZONE_ACL_REMOVE = "REMOVE";
+
+
   private Header() {
     // Never constructed.
   }

http://git-wip-us.apache.org/repos/asf/hadoop/blob/c7851874/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/interfaces/Bucket.java
----------------------------------------------------------------------
diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/interfaces/Bucket.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/interfaces/Bucket.java
new file mode 100644
index 0000000..36141e3
--- /dev/null
+++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/interfaces/Bucket.java
@@ -0,0 +1,133 @@
+/*
+ * 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.web.interfaces;
+
+import org.apache.hadoop.ozone.web.exceptions.OzoneException;
+import org.apache.hadoop.ozone.web.headers.Header;
+
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Request;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+/**
+ * Bucket Interface acts as the HTTP entry point for
+ * bucket related functionality.
+ */
+@Path("/{volume}/{bucket}")
+public interface Bucket {
+  /**
+   * createBucket call handles the POST request for Creating a Bucket.
+   *
+   * @param volume - Volume name
+   * @param bucket - Bucket Name
+   * @param req - Http request
+   * @param info - Uri Info
+   * @param headers - Http headers
+   *
+   * @return Response
+   *
+   * @throws OzoneException
+   */
+  @POST
+  Response createBucket(@PathParam("volume") String volume,
+                        @PathParam("bucket") String bucket,
+                        @Context Request req, @Context UriInfo info,
+                        @Context HttpHeaders headers) throws OzoneException;
+
+  /**
+   * updateBucket call handles the PUT request for updating a Bucket.
+   *
+   * @param volume - Volume name
+   * @param bucket - Bucket name
+   * @param req - Http request
+   * @param info - Uri Info
+   * @param headers - Http headers
+   *
+   * @return Response
+   *
+   * @throws OzoneException
+   */
+  @PUT
+  Response updateBucket(@PathParam("volume") String volume,
+                        @PathParam("bucket") String bucket,
+                        @Context Request req, @Context UriInfo info,
+                        @Context HttpHeaders headers) throws OzoneException;
+
+  /**
+   * Deletes an empty bucket.
+   *
+   * @param volume Volume name
+   * @param bucket Bucket Name
+   * @param req - Http request
+   * @param info - Uri Info
+   * @param headers - Http headers
+   *
+   * @return Response
+   *
+   * @throws OzoneException
+   */
+  @DELETE
+  Response deleteBucket(@PathParam("volume") String volume,
+                        @PathParam("bucket") String bucket,
+                        @Context Request req, @Context UriInfo info,
+                        @Context HttpHeaders headers) throws OzoneException;
+
+  /**
+   * List Buckets lists the contents of a bucket.
+   *
+   * @param volume - Storage Volume Name
+   * @param bucket - Bucket Name
+   * @param info - Information type needed
+   * @param prefix - Prefix for the keys to be fetched
+   * @param maxKeys - MaxNumber of Keys to Return
+   * @param startPage - Continuation Token
+   * @param req - Http request
+   * @param headers - Http headers
+   *
+   * @return - Json Body
+   *
+   * @throws OzoneException
+   */
+
+  @GET
+  @Produces(MediaType.APPLICATION_JSON)
+  Response listBucket(@PathParam("volume") String volume,
+                      @PathParam("bucket") String bucket,
+                      @DefaultValue(Header.OZONE_LIST_QUERY_KEY)
+                      @QueryParam("info") String info,
+                      @QueryParam("prefix") String prefix,
+                      @DefaultValue("1000") @QueryParam("max-keys") int maxKeys,
+                      @QueryParam("start-page") String startPage,
+                      @Context Request req, @Context UriInfo uriInfo,
+                      @Context HttpHeaders headers) throws OzoneException;
+
+
+}

http://git-wip-us.apache.org/repos/asf/hadoop/blob/c7851874/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/interfaces/StorageHandler.java
----------------------------------------------------------------------
diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/interfaces/StorageHandler.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/interfaces/StorageHandler.java
index 043b59e..6759888 100644
--- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/interfaces/StorageHandler.java
+++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/interfaces/StorageHandler.java
@@ -20,8 +20,11 @@ package org.apache.hadoop.ozone.web.interfaces;
 
 import org.apache.hadoop.classification.InterfaceAudience;
 import org.apache.hadoop.ozone.web.exceptions.OzoneException;
+import org.apache.hadoop.ozone.web.handlers.BucketArgs;
 import org.apache.hadoop.ozone.web.handlers.UserArgs;
 import org.apache.hadoop.ozone.web.handlers.VolumeArgs;
+import org.apache.hadoop.ozone.web.response.BucketInfo;
+import org.apache.hadoop.ozone.web.response.ListBuckets;
 import org.apache.hadoop.ozone.web.response.ListVolumes;
 import org.apache.hadoop.ozone.web.response.VolumeInfo;
 
@@ -121,4 +124,86 @@ public interface StorageHandler {
    * @throws OzoneException
    */
   VolumeInfo getVolumeInfo(VolumeArgs args) throws IOException, OzoneException;
+
+  /**
+   * Creates a Bucket in specified Volume.
+   *
+   * @param args BucketArgs- BucketName, UserName and Acls
+   *
+   * @throws IOException
+   */
+  void createBucket(BucketArgs args) throws IOException, OzoneException;
+
+  /**
+   * Adds or Removes ACLs from a Bucket.
+   *
+   * @param args - BucketArgs
+   *
+   * @throws IOException
+   */
+  void setBucketAcls(BucketArgs args) throws IOException, OzoneException;
+
+  /**
+   * Enables or disables Bucket Versioning.
+   *
+   * @param args - BucketArgs
+   *
+   * @throws IOException
+   */
+  void setBucketVersioning(BucketArgs args) throws IOException, OzoneException;
+
+  /**
+   * Sets the Storage Class of a Bucket.
+   *
+   * @param args - BucketArgs
+   *
+   * @throws IOException
+   */
+  void setBucketStorageClass(BucketArgs args)
+      throws IOException, OzoneException;
+
+  /**
+   * Deletes a bucket if it is empty.
+   *
+   * @param args Bucket args structure
+   *
+   * @throws IOException
+   */
+  void deleteBucket(BucketArgs args) throws IOException, OzoneException;
+
+  /**
+   * true if the bucket exists and user has read access
+   * to the bucket else throws Exception.
+   *
+   * @param args Bucket args structure
+   *
+   * @throws IOException
+   */
+  void checkBucketAccess(BucketArgs args) throws IOException, OzoneException;
+
+
+  /**
+   * Returns all Buckets of a specified Volume.
+   *
+   * @param args --User Args
+   *
+   * @return ListAllBuckets
+   *
+   * @throws OzoneException
+   */
+  ListBuckets listBuckets(VolumeArgs args) throws IOException, OzoneException;
+
+
+  /**
+   * Returns Bucket's Metadata as a String.
+   *
+   * @param args Bucket args structure
+   *
+   * @return Info about the bucket
+   *
+   * @throws IOException
+   */
+  BucketInfo getBucketInfo(BucketArgs args) throws IOException, OzoneException;
+
+
 }

http://git-wip-us.apache.org/repos/asf/hadoop/blob/c7851874/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/localstorage/LocalStorageHandler.java
----------------------------------------------------------------------
diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/localstorage/LocalStorageHandler.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/localstorage/LocalStorageHandler.java
index 939ed1e..e00a66f 100644
--- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/localstorage/LocalStorageHandler.java
+++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/localstorage/LocalStorageHandler.java
@@ -20,10 +20,13 @@ package org.apache.hadoop.ozone.web.localstorage;
 
 import org.apache.hadoop.classification.InterfaceAudience;
 import org.apache.hadoop.ozone.web.exceptions.OzoneException;
+import org.apache.hadoop.ozone.web.handlers.BucketArgs;
 import org.apache.hadoop.ozone.web.handlers.UserArgs;
 import org.apache.hadoop.ozone.web.handlers.VolumeArgs;
 import org.apache.hadoop.ozone.web.interfaces.StorageHandler;
 import org.apache.hadoop.ozone.web.request.OzoneQuota;
+import org.apache.hadoop.ozone.web.response.BucketInfo;
+import org.apache.hadoop.ozone.web.response.ListBuckets;
 import org.apache.hadoop.ozone.web.response.ListVolumes;
 import org.apache.hadoop.ozone.web.response.VolumeInfo;
 
@@ -158,4 +161,110 @@ public class LocalStorageHandler implements StorageHandler {
     return oz.listVolumes(args);
   }
 
+  /**
+   * true if the bucket exists and user has read access
+   * to the bucket else throws Exception.
+   *
+   * @param args Bucket args structure
+   *
+   * @throws IOException
+   */
+  @Override
+  public void checkBucketAccess(BucketArgs args)
+      throws IOException, OzoneException {
+
+  }
+
+  /**
+   * Creates a Bucket in specified Volume.
+   *
+   * @param args BucketArgs- BucketName, UserName and Acls
+   *
+   * @throws IOException
+   */
+  @Override
+  public void createBucket(BucketArgs args) throws IOException, OzoneException {
+
+  }
+
+  /**
+   * Adds or Removes ACLs from a Bucket.
+   *
+   * @param args - BucketArgs
+   *
+   * @throws IOException
+   */
+  @Override
+  public void setBucketAcls(BucketArgs args)
+      throws IOException, OzoneException {
+
+  }
+
+  /**
+   * Enables or disables Bucket Versioning.
+   *
+   * @param args - BucketArgs
+   *
+   * @throws IOException
+   */
+  @Override
+  public void setBucketVersioning(BucketArgs args)
+      throws IOException, OzoneException {
+
+  }
+
+  /**
+   * Sets the Storage Class of a Bucket.
+   *
+   * @param args - BucketArgs
+   *
+   * @throws IOException
+   */
+  @Override
+  public void setBucketStorageClass(BucketArgs args)
+      throws IOException, OzoneException {
+
+  }
+
+  /**
+   * Deletes a bucket if it is empty.
+   *
+   * @param args Bucket args structure
+   *
+   * @throws IOException
+   */
+  @Override
+  public void deleteBucket(BucketArgs args) throws IOException, OzoneException {
+
+  }
+
+  /**
+   * Returns all Buckets of a specified Volume.
+   *
+   * @param args --User Args
+   *
+   * @return ListAllBuckets
+   *
+   * @throws OzoneException
+   */
+  @Override
+  public ListBuckets listBuckets(VolumeArgs args)
+      throws IOException, OzoneException {
+    return null;
+  }
+
+  /**
+   * Returns Bucket's Metadata as a String.
+   *
+   * @param args Bucket args structure
+   *
+   * @return Info about the bucket
+   *
+   * @throws IOException
+   */
+  @Override
+  public BucketInfo getBucketInfo(BucketArgs args)
+      throws IOException, OzoneException {
+    return null;
+  }
 }