From 752a9d84bb3ff7451667de3cfaa74fe7feeecb83 Mon Sep 17 00:00:00 2001 From: Jing Zhao Date: Thu, 22 May 2014 07:30:18 +0000 Subject: [PATCH] HDFS-6438. DeleteSnapshot should be a DELETE request in WebHdfs. Contributed by Jing Zhao. git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1596772 13f79535-47bb-0310-9956-ffa450edef68 --- hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt | 2 + .../web/resources/NamenodeWebHdfsMethods.java | 32 +++-- .../hadoop/hdfs/web/WebHdfsFileSystem.java | 2 +- .../hdfs/web/resources/DeleteOpParam.java | 1 + .../hadoop/hdfs/web/resources/PutOpParam.java | 1 - .../hadoop-hdfs/src/site/apt/WebHDFS.apt.vm | 122 +++++++++++++++++- 6 files changed, 144 insertions(+), 16 deletions(-) diff --git a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt index 8d851e47215..66f657b113d 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt +++ b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt @@ -578,6 +578,8 @@ Release 2.5.0 - UNRELEASED HDFS-6433. Replace BytesMoved class with AtomicLong. (Benoy Antony via cnauroth) + HDFS-6438. DeleteSnapshot should be a DELETE request in WebHdfs. (jing9) + Release 2.4.1 - UNRELEASED INCOMPATIBLE CHANGES diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/web/resources/NamenodeWebHdfsMethods.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/web/resources/NamenodeWebHdfsMethods.java index 0daaa355d4a..0ffb813611e 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/web/resources/NamenodeWebHdfsMethods.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/web/resources/NamenodeWebHdfsMethods.java @@ -590,10 +590,6 @@ private Response put( org.apache.hadoop.fs.Path.class.getSimpleName(), snapshotPath); return Response.ok(js).type(MediaType.APPLICATION_JSON).build(); } - case DELETESNAPSHOT: { - np.deleteSnapshot(fullpath, snapshotName.getValue()); - return Response.ok().type(MediaType.APPLICATION_OCTET_STREAM).build(); - } case RENAMESNAPSHOT: { np.renameSnapshot(fullpath, oldSnapshotName.getValue(), snapshotName.getValue()); @@ -953,9 +949,12 @@ public Response deleteRoot( @QueryParam(DeleteOpParam.NAME) @DefaultValue(DeleteOpParam.DEFAULT) final DeleteOpParam op, @QueryParam(RecursiveParam.NAME) @DefaultValue(RecursiveParam.DEFAULT) - final RecursiveParam recursive + final RecursiveParam recursive, + @QueryParam(SnapshotNameParam.NAME) @DefaultValue(SnapshotNameParam.DEFAULT) + final SnapshotNameParam snapshotName ) throws IOException, InterruptedException { - return delete(ugi, delegation, username, doAsUser, ROOT, op, recursive); + return delete(ugi, delegation, username, doAsUser, ROOT, op, recursive, + snapshotName); } /** Handle HTTP DELETE request. */ @@ -974,17 +973,19 @@ public Response delete( @QueryParam(DeleteOpParam.NAME) @DefaultValue(DeleteOpParam.DEFAULT) final DeleteOpParam op, @QueryParam(RecursiveParam.NAME) @DefaultValue(RecursiveParam.DEFAULT) - final RecursiveParam recursive + final RecursiveParam recursive, + @QueryParam(SnapshotNameParam.NAME) @DefaultValue(SnapshotNameParam.DEFAULT) + final SnapshotNameParam snapshotName ) throws IOException, InterruptedException { - init(ugi, delegation, username, doAsUser, path, op, recursive); + init(ugi, delegation, username, doAsUser, path, op, recursive, snapshotName); return ugi.doAs(new PrivilegedExceptionAction() { @Override public Response run() throws IOException { try { return delete(ugi, delegation, username, doAsUser, - path.getAbsolutePath(), op, recursive); + path.getAbsolutePath(), op, recursive, snapshotName); } finally { reset(); } @@ -999,17 +1000,22 @@ private Response delete( final DoAsParam doAsUser, final String fullpath, final DeleteOpParam op, - final RecursiveParam recursive + final RecursiveParam recursive, + final SnapshotNameParam snapshotName ) throws IOException { final NameNode namenode = (NameNode)context.getAttribute("name.node"); + final NamenodeProtocols np = getRPCServer(namenode); switch(op.getValue()) { - case DELETE: - { - final boolean b = getRPCServer(namenode).delete(fullpath, recursive.getValue()); + case DELETE: { + final boolean b = np.delete(fullpath, recursive.getValue()); final String js = JsonUtil.toJsonString("boolean", b); return Response.ok(js).type(MediaType.APPLICATION_JSON).build(); } + case DELETESNAPSHOT: { + np.deleteSnapshot(fullpath, snapshotName.getValue()); + return Response.ok().type(MediaType.APPLICATION_OCTET_STREAM).build(); + } default: throw new UnsupportedOperationException(op + " is not supported"); } diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/web/WebHdfsFileSystem.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/web/WebHdfsFileSystem.java index 522bbf8b54d..bc791c644f2 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/web/WebHdfsFileSystem.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/web/WebHdfsFileSystem.java @@ -957,7 +957,7 @@ Path decodeResponse(Map json) { public void deleteSnapshot(final Path path, final String snapshotName) throws IOException { statistics.incrementWriteOps(1); - final HttpOpParam.Op op = PutOpParam.Op.DELETESNAPSHOT; + final HttpOpParam.Op op = DeleteOpParam.Op.DELETESNAPSHOT; new FsPathRunner(op, path, new SnapshotNameParam(snapshotName)).run(); } diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/web/resources/DeleteOpParam.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/web/resources/DeleteOpParam.java index 710e2e8992e..65275e0e500 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/web/resources/DeleteOpParam.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/web/resources/DeleteOpParam.java @@ -24,6 +24,7 @@ public class DeleteOpParam extends HttpOpParam { /** Delete operations. */ public static enum Op implements HttpOpParam.Op { DELETE(HttpURLConnection.HTTP_OK), + DELETESNAPSHOT(HttpURLConnection.HTTP_OK), NULL(HttpURLConnection.HTTP_NOT_IMPLEMENTED); diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/web/resources/PutOpParam.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/web/resources/PutOpParam.java index 64b7f8ca673..7fd2b717cc1 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/web/resources/PutOpParam.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/web/resources/PutOpParam.java @@ -47,7 +47,6 @@ public static enum Op implements HttpOpParam.Op { REMOVEXATTR(false, HttpURLConnection.HTTP_OK), CREATESNAPSHOT(false, HttpURLConnection.HTTP_OK), - DELETESNAPSHOT(false, HttpURLConnection.HTTP_OK), RENAMESNAPSHOT(false, HttpURLConnection.HTTP_OK), NULL(false, HttpURLConnection.HTTP_NOT_IMPLEMENTED); diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/site/apt/WebHDFS.apt.vm b/hadoop-hdfs-project/hadoop-hdfs/src/site/apt/WebHDFS.apt.vm index 48bcca3320e..94d5d0ba757 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/site/apt/WebHDFS.apt.vm +++ b/hadoop-hdfs-project/hadoop-hdfs/src/site/apt/WebHDFS.apt.vm @@ -102,6 +102,12 @@ WebHDFS REST API * {{{Cancel Delegation Token}<<>>}} (see {{{../../api/org/apache/hadoop/fs/FileSystem.html}FileSystem}}.cancelDelegationToken) + * {{{Create Snapshot}<<>>}} + (see {{{../../api/org/apache/hadoop/fs/FileSystem.html}FileSystem}}.createSnapshot) + + * {{{Rename Snapshot}<<>>}} + (see {{{../../api/org/apache/hadoop/fs/FileSystem.html}FileSystem}}.renameSnapshot) + * HTTP POST * {{{Append to a File}<<>>}} @@ -114,6 +120,9 @@ WebHDFS REST API * {{{Delete a File/Directory}<<>>}} (see {{{../../api/org/apache/hadoop/fs/FileSystem.html}FileSystem}}.delete) + + * {{{Delete Snapshot}<<>>}} + (see {{{../../api/org/apache/hadoop/fs/FileSystem.html}FileSystem}}.deleteSnapshot) ** {FileSystem URIs vs HTTP URLs} @@ -900,6 +909,75 @@ Transfer-Encoding: chunked {{{../../api/org/apache/hadoop/fs/FileSystem.html}FileSystem}}.getAclStatus +* {Snapshot Operations} + +** {Create Snapshot} + + * Submit a HTTP PUT request. + ++--------------------------------- +curl -i -X PUT "http://:/webhdfs/v1/?op=CREATESNAPSHOT[&snapshotname=]" ++--------------------------------- + + The client receives a response with a {{{Path JSON Schema}<<>> JSON object}}: + ++--------------------------------- +HTTP/1.1 200 OK +Content-Type: application/json +Transfer-Encoding: chunked + +{"Path": "/user/szetszwo/.snapshot/s1"} ++--------------------------------- + + [] + + See also: + {{{../../api/org/apache/hadoop/fs/FileSystem.html}FileSystem}}.createSnapshot + + +** {Delete Snapshot} + + * Submit a HTTP DELETE request. + ++--------------------------------- +curl -i -X DELETE "http://:/webhdfs/v1/?op=DELETESNAPSHOT&snapshotname=" ++--------------------------------- + + The client receives a response with zero content length: + ++--------------------------------- +HTTP/1.1 200 OK +Content-Length: 0 ++--------------------------------- + + [] + + See also: + {{{../../api/org/apache/hadoop/fs/FileSystem.html}FileSystem}}.deleteSnapshot + + +** {Rename Snapshot} + + * Submit a HTTP PUT request. + ++--------------------------------- +curl -i -X PUT "http://:/webhdfs/v1/?op=RENAMESNAPSHOT + &oldsnapshotname=&snapshotname=" ++--------------------------------- + + The client receives a response with zero content length: + ++--------------------------------- +HTTP/1.1 200 OK +Content-Length: 0 ++--------------------------------- + + [] + + See also: + {{{../../api/org/apache/hadoop/fs/FileSystem.html}FileSystem}}.renameSnapshot + + * {Delegation Token Operations} ** {Get Delegation Token} @@ -1839,6 +1917,26 @@ var tokenProperties = {{{Open and Read a File}<<>>}} +** {Old Snapshot Name} + +*----------------+-------------------------------------------------------------------+ +|| Name | <<>> | +*----------------+-------------------------------------------------------------------+ +|| Description | The old name of the snapshot to be renamed. | +*----------------+-------------------------------------------------------------------+ +|| Type | String | +*----------------+-------------------------------------------------------------------+ +|| Default Value | null | +*----------------+-------------------------------------------------------------------+ +|| Valid Values | An existing snapshot name. | +*----------------+-------------------------------------------------------------------+ +|| Syntax | Any string. | +*----------------+-------------------------------------------------------------------+ + + See also: + {{{Rename Snapshot}<<>>}} + + ** {Op} *----------------+-------------------------------------------------------------------+ @@ -1983,6 +2081,29 @@ var tokenProperties = {{{Set Replication Factor}<<>>}} +** {Snapshot Name} + +*----------------+-------------------------------------------------------------------+ +|| Name | <<>> | +*----------------+-------------------------------------------------------------------+ +|| Description | The name of the snapshot to be created/deleted. | +|| | Or the new name for snapshot rename. | +*----------------+-------------------------------------------------------------------+ +|| Type | String | +*----------------+-------------------------------------------------------------------+ +|| Default Value | null | +*----------------+-------------------------------------------------------------------+ +|| Valid Values | Any valid snapshot name. | +*----------------+-------------------------------------------------------------------+ +|| Syntax | Any string. | +*----------------+-------------------------------------------------------------------+ + + See also: + {{{Create Snapshot}<<>>}}, + {{{Delete Snapshot}<<>>}}, + {{{Rename Snapshot}<<>>}} + + ** {Sources} *----------------+-------------------------------------------------------------------+ @@ -2042,4 +2163,3 @@ var tokenProperties = See also: {{Authentication}} -