Return-Path: X-Original-To: apmail-hadoop-hdfs-commits-archive@minotaur.apache.org Delivered-To: apmail-hadoop-hdfs-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id CAC43DD0B for ; Wed, 27 Jun 2012 16:07:08 +0000 (UTC) Received: (qmail 80614 invoked by uid 500); 27 Jun 2012 16:07:08 -0000 Delivered-To: apmail-hadoop-hdfs-commits-archive@hadoop.apache.org Received: (qmail 80586 invoked by uid 500); 27 Jun 2012 16:07:08 -0000 Mailing-List: contact hdfs-commits-help@hadoop.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: hdfs-dev@hadoop.apache.org Delivered-To: mailing list hdfs-commits@hadoop.apache.org Received: (qmail 80577 invoked by uid 99); 27 Jun 2012 16:07:08 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 27 Jun 2012 16:07:08 +0000 X-ASF-Spam-Status: No, hits=-1998.0 required=5.0 tests=ALL_TRUSTED,FB_GET_MEDS X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 27 Jun 2012 16:07:03 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 97D172388962; Wed, 27 Jun 2012 16:06:43 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1354599 [1/2] - in /hadoop/common/trunk/hadoop-hdfs-project: hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/client/ hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/ hadoop-hdfs-httpfs/src/main/java/org/apache/... Date: Wed, 27 Jun 2012 16:06:41 -0000 To: hdfs-commits@hadoop.apache.org From: tucu@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120627160643.97D172388962@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: tucu Date: Wed Jun 27 16:06:37 2012 New Revision: 1354599 URL: http://svn.apache.org/viewvc?rev=1354599&view=rev Log: HDFS-3481. Refactor HttpFS handling of JAX-RS query string parameters (tucu) Added: hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/HttpFSParametersProvider.java hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/Parameters.java hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/ParametersProvider.java hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/lib/wsrs/TestParam.java hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/resources/httpfs-log4j.properties Removed: hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/HttpFSParams.java hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/lib/wsrs/TestBooleanParam.java hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/lib/wsrs/TestByteParam.java hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/lib/wsrs/TestEnumParam.java hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/lib/wsrs/TestIntegerParam.java hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/lib/wsrs/TestLongParam.java hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/lib/wsrs/TestShortParam.java hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/lib/wsrs/TestStringParam.java Modified: hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/client/HttpFSFileSystem.java hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/CheckUploadContentTypeFilter.java hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/HttpFSExceptionProvider.java hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/HttpFSServer.java hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/BooleanParam.java hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/ByteParam.java hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/EnumParam.java hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/IntegerParam.java hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/LongParam.java hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/Param.java hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/ShortParam.java hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/StringParam.java hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/fs/http/client/TestHttpFSFileSystem.java hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/fs/http/server/TestCheckUploadContentTypeFilter.java hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt Modified: hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/client/HttpFSFileSystem.java URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/client/HttpFSFileSystem.java?rev=1354599&r1=1354598&r2=1354599&view=diff ============================================================================== --- hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/client/HttpFSFileSystem.java (original) +++ hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/client/HttpFSFileSystem.java Wed Jun 27 16:06:37 2012 @@ -154,41 +154,33 @@ public class HttpFSFileSystem extends Fi public static final int HTTP_TEMPORARY_REDIRECT = 307; + private static final String HTTP_GET = "GET"; + private static final String HTTP_PUT = "PUT"; + private static final String HTTP_POST = "POST"; + private static final String HTTP_DELETE = "DELETE"; - /** - * Get operations. - */ - public enum GetOpValues { - OPEN, GETFILESTATUS, LISTSTATUS, GETHOMEDIRECTORY, GETCONTENTSUMMARY, GETFILECHECKSUM, - GETDELEGATIONTOKEN, GETFILEBLOCKLOCATIONS, INSTRUMENTATION - } + public enum Operation { + OPEN(HTTP_GET), GETFILESTATUS(HTTP_GET), LISTSTATUS(HTTP_GET), + GETHOMEDIRECTORY(HTTP_GET), GETCONTENTSUMMARY(HTTP_GET), + GETFILECHECKSUM(HTTP_GET), GETFILEBLOCKLOCATIONS(HTTP_GET), + INSTRUMENTATION(HTTP_GET), + APPEND(HTTP_POST), + CREATE(HTTP_PUT), MKDIRS(HTTP_PUT), RENAME(HTTP_PUT), SETOWNER(HTTP_PUT), + SETPERMISSION(HTTP_PUT), SETREPLICATION(HTTP_PUT), SETTIMES(HTTP_PUT), + DELETE(HTTP_DELETE); - /** - * Post operations. - */ - public static enum PostOpValues { - APPEND - } + private String httpMethod; - /** - * Put operations. - */ - public static enum PutOpValues { - CREATE, MKDIRS, RENAME, SETOWNER, SETPERMISSION, SETREPLICATION, SETTIMES, - RENEWDELEGATIONTOKEN, CANCELDELEGATIONTOKEN - } + Operation(String httpMethod) { + this.httpMethod = httpMethod; + } + + public String getMethod() { + return httpMethod; + } - /** - * Delete operations. - */ - public static enum DeleteOpValues { - DELETE } - private static final String HTTP_GET = "GET"; - private static final String HTTP_PUT = "PUT"; - private static final String HTTP_POST = "POST"; - private static final String HTTP_DELETE = "DELETE"; private AuthenticatedURL.Token authToken = new AuthenticatedURL.Token(); private URI uri; @@ -402,10 +394,12 @@ public class HttpFSFileSystem extends Fi @Override public FSDataInputStream open(Path f, int bufferSize) throws IOException { Map params = new HashMap(); - params.put(OP_PARAM, GetOpValues.OPEN.toString()); - HttpURLConnection conn = getConnection(HTTP_GET, params, f, true); + params.put(OP_PARAM, Operation.OPEN.toString()); + HttpURLConnection conn = getConnection(Operation.OPEN.getMethod(), params, + f, true); validateResponse(conn, HttpURLConnection.HTTP_OK); - return new FSDataInputStream(new HttpFSDataInputStream(conn.getInputStream(), bufferSize)); + return new FSDataInputStream( + new HttpFSDataInputStream(conn.getInputStream(), bufferSize)); } /** @@ -508,15 +502,18 @@ public class HttpFSFileSystem extends Fi * @see #setPermission(Path, FsPermission) */ @Override - public FSDataOutputStream create(Path f, FsPermission permission, boolean overwrite, int bufferSize, - short replication, long blockSize, Progressable progress) throws IOException { + public FSDataOutputStream create(Path f, FsPermission permission, + boolean overwrite, int bufferSize, + short replication, long blockSize, + Progressable progress) throws IOException { Map params = new HashMap(); - params.put(OP_PARAM, PutOpValues.CREATE.toString()); + params.put(OP_PARAM, Operation.CREATE.toString()); params.put(OVERWRITE_PARAM, Boolean.toString(overwrite)); params.put(REPLICATION_PARAM, Short.toString(replication)); params.put(BLOCKSIZE_PARAM, Long.toString(blockSize)); params.put(PERMISSION_PARAM, permissionToString(permission)); - return uploadData(HTTP_PUT, f, params, bufferSize, HttpURLConnection.HTTP_CREATED); + return uploadData(Operation.CREATE.getMethod(), f, params, bufferSize, + HttpURLConnection.HTTP_CREATED); } @@ -532,10 +529,12 @@ public class HttpFSFileSystem extends Fi * @throws IOException */ @Override - public FSDataOutputStream append(Path f, int bufferSize, Progressable progress) throws IOException { + public FSDataOutputStream append(Path f, int bufferSize, + Progressable progress) throws IOException { Map params = new HashMap(); - params.put(OP_PARAM, PostOpValues.APPEND.toString()); - return uploadData(HTTP_POST, f, params, bufferSize, HttpURLConnection.HTTP_OK); + params.put(OP_PARAM, Operation.APPEND.toString()); + return uploadData(Operation.APPEND.getMethod(), f, params, bufferSize, + HttpURLConnection.HTTP_OK); } /** @@ -545,9 +544,10 @@ public class HttpFSFileSystem extends Fi @Override public boolean rename(Path src, Path dst) throws IOException { Map params = new HashMap(); - params.put(OP_PARAM, PutOpValues.RENAME.toString()); + params.put(OP_PARAM, Operation.RENAME.toString()); params.put(DESTINATION_PARAM, dst.toString()); - HttpURLConnection conn = getConnection(HTTP_PUT, params, src, true); + HttpURLConnection conn = getConnection(Operation.RENAME.getMethod(), + params, src, true); validateResponse(conn, HttpURLConnection.HTTP_OK); JSONObject json = (JSONObject) jsonParse(conn); return (Boolean) json.get(RENAME_JSON); @@ -580,9 +580,10 @@ public class HttpFSFileSystem extends Fi @Override public boolean delete(Path f, boolean recursive) throws IOException { Map params = new HashMap(); - params.put(OP_PARAM, DeleteOpValues.DELETE.toString()); + params.put(OP_PARAM, Operation.DELETE.toString()); params.put(RECURSIVE_PARAM, Boolean.toString(recursive)); - HttpURLConnection conn = getConnection(HTTP_DELETE, params, f, true); + HttpURLConnection conn = getConnection(Operation.DELETE.getMethod(), + params, f, true); validateResponse(conn, HttpURLConnection.HTTP_OK); JSONObject json = (JSONObject) jsonParse(conn); return (Boolean) json.get(DELETE_JSON); @@ -601,8 +602,9 @@ public class HttpFSFileSystem extends Fi @Override public FileStatus[] listStatus(Path f) throws IOException { Map params = new HashMap(); - params.put(OP_PARAM, GetOpValues.LISTSTATUS.toString()); - HttpURLConnection conn = getConnection(HTTP_GET, params, f, true); + params.put(OP_PARAM, Operation.LISTSTATUS.toString()); + HttpURLConnection conn = getConnection(Operation.LISTSTATUS.getMethod(), + params, f, true); validateResponse(conn, HttpURLConnection.HTTP_OK); JSONObject json = (JSONObject) jsonParse(conn); json = (JSONObject) json.get(FILE_STATUSES_JSON); @@ -647,9 +649,10 @@ public class HttpFSFileSystem extends Fi @Override public boolean mkdirs(Path f, FsPermission permission) throws IOException { Map params = new HashMap(); - params.put(OP_PARAM, PutOpValues.MKDIRS.toString()); + params.put(OP_PARAM, Operation.MKDIRS.toString()); params.put(PERMISSION_PARAM, permissionToString(permission)); - HttpURLConnection conn = getConnection(HTTP_PUT, params, f, true); + HttpURLConnection conn = getConnection(Operation.MKDIRS.getMethod(), + params, f, true); validateResponse(conn, HttpURLConnection.HTTP_OK); JSONObject json = (JSONObject) jsonParse(conn); return (Boolean) json.get(MKDIRS_JSON); @@ -668,8 +671,9 @@ public class HttpFSFileSystem extends Fi @Override public FileStatus getFileStatus(Path f) throws IOException { Map params = new HashMap(); - params.put(OP_PARAM, GetOpValues.GETFILESTATUS.toString()); - HttpURLConnection conn = getConnection(HTTP_GET, params, f, true); + params.put(OP_PARAM, Operation.GETFILESTATUS.toString()); + HttpURLConnection conn = getConnection(Operation.GETFILESTATUS.getMethod(), + params, f, true); validateResponse(conn, HttpURLConnection.HTTP_OK); JSONObject json = (JSONObject) jsonParse(conn); json = (JSONObject) json.get(FILE_STATUS_JSON); @@ -684,9 +688,11 @@ public class HttpFSFileSystem extends Fi @Override public Path getHomeDirectory() { Map params = new HashMap(); - params.put(OP_PARAM, GetOpValues.GETHOMEDIRECTORY.toString()); + params.put(OP_PARAM, Operation.GETHOMEDIRECTORY.toString()); try { - HttpURLConnection conn = getConnection(HTTP_GET, params, new Path(getUri().toString(), "/"), false); + HttpURLConnection conn = + getConnection(Operation.GETHOMEDIRECTORY.getMethod(), params, + new Path(getUri().toString(), "/"), false); validateResponse(conn, HttpURLConnection.HTTP_OK); JSONObject json = (JSONObject) jsonParse(conn); return new Path((String) json.get(HOME_DIR_JSON)); @@ -704,12 +710,14 @@ public class HttpFSFileSystem extends Fi * @param groupname If it is null, the original groupname remains unchanged. */ @Override - public void setOwner(Path p, String username, String groupname) throws IOException { + public void setOwner(Path p, String username, String groupname) + throws IOException { Map params = new HashMap(); - params.put(OP_PARAM, PutOpValues.SETOWNER.toString()); + params.put(OP_PARAM, Operation.SETOWNER.toString()); params.put(OWNER_PARAM, username); params.put(GROUP_PARAM, groupname); - HttpURLConnection conn = getConnection(HTTP_PUT, params, p, true); + HttpURLConnection conn = getConnection(Operation.SETOWNER.getMethod(), + params, p, true); validateResponse(conn, HttpURLConnection.HTTP_OK); } @@ -722,9 +730,9 @@ public class HttpFSFileSystem extends Fi @Override public void setPermission(Path p, FsPermission permission) throws IOException { Map params = new HashMap(); - params.put(OP_PARAM, PutOpValues.SETPERMISSION.toString()); + params.put(OP_PARAM, Operation.SETPERMISSION.toString()); params.put(PERMISSION_PARAM, permissionToString(permission)); - HttpURLConnection conn = getConnection(HTTP_PUT, params, p, true); + HttpURLConnection conn = getConnection(Operation.SETPERMISSION.getMethod(), params, p, true); validateResponse(conn, HttpURLConnection.HTTP_OK); } @@ -742,10 +750,11 @@ public class HttpFSFileSystem extends Fi @Override public void setTimes(Path p, long mtime, long atime) throws IOException { Map params = new HashMap(); - params.put(OP_PARAM, PutOpValues.SETTIMES.toString()); + params.put(OP_PARAM, Operation.SETTIMES.toString()); params.put(MODIFICATION_TIME_PARAM, Long.toString(mtime)); params.put(ACCESS_TIME_PARAM, Long.toString(atime)); - HttpURLConnection conn = getConnection(HTTP_PUT, params, p, true); + HttpURLConnection conn = getConnection(Operation.SETTIMES.getMethod(), + params, p, true); validateResponse(conn, HttpURLConnection.HTTP_OK); } @@ -761,11 +770,13 @@ public class HttpFSFileSystem extends Fi * @throws IOException */ @Override - public boolean setReplication(Path src, short replication) throws IOException { + public boolean setReplication(Path src, short replication) + throws IOException { Map params = new HashMap(); - params.put(OP_PARAM, PutOpValues.SETREPLICATION.toString()); + params.put(OP_PARAM, Operation.SETREPLICATION.toString()); params.put(REPLICATION_PARAM, Short.toString(replication)); - HttpURLConnection conn = getConnection(HTTP_PUT, params, src, true); + HttpURLConnection conn = + getConnection(Operation.SETREPLICATION.getMethod(), params, src, true); validateResponse(conn, HttpURLConnection.HTTP_OK); JSONObject json = (JSONObject) jsonParse(conn); return (Boolean) json.get(SET_REPLICATION_JSON); @@ -814,10 +825,12 @@ public class HttpFSFileSystem extends Fi @Override public ContentSummary getContentSummary(Path f) throws IOException { Map params = new HashMap(); - params.put(OP_PARAM, GetOpValues.GETCONTENTSUMMARY.toString()); - HttpURLConnection conn = getConnection(HTTP_GET, params, f, true); + params.put(OP_PARAM, Operation.GETCONTENTSUMMARY.toString()); + HttpURLConnection conn = + getConnection(Operation.GETCONTENTSUMMARY.getMethod(), params, f, true); validateResponse(conn, HttpURLConnection.HTTP_OK); - JSONObject json = (JSONObject) ((JSONObject) jsonParse(conn)).get(CONTENT_SUMMARY_JSON); + JSONObject json = + (JSONObject) ((JSONObject) jsonParse(conn)).get(CONTENT_SUMMARY_JSON); return new ContentSummary((Long) json.get(CONTENT_SUMMARY_LENGTH_JSON), (Long) json.get(CONTENT_SUMMARY_FILE_COUNT_JSON), (Long) json.get(CONTENT_SUMMARY_DIRECTORY_COUNT_JSON), @@ -830,10 +843,12 @@ public class HttpFSFileSystem extends Fi @Override public FileChecksum getFileChecksum(Path f) throws IOException { Map params = new HashMap(); - params.put(OP_PARAM, GetOpValues.GETFILECHECKSUM.toString()); - HttpURLConnection conn = getConnection(HTTP_GET, params, f, true); + params.put(OP_PARAM, Operation.GETFILECHECKSUM.toString()); + HttpURLConnection conn = + getConnection(Operation.GETFILECHECKSUM.getMethod(), params, f, true); validateResponse(conn, HttpURLConnection.HTTP_OK); - final JSONObject json = (JSONObject) ((JSONObject) jsonParse(conn)).get(FILE_CHECKSUM_JSON); + final JSONObject json = + (JSONObject) ((JSONObject) jsonParse(conn)).get(FILE_CHECKSUM_JSON); return new FileChecksum() { @Override public String getAlgorithmName() { Modified: hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/CheckUploadContentTypeFilter.java URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/CheckUploadContentTypeFilter.java?rev=1354599&r1=1354598&r2=1354599&view=diff ============================================================================== --- hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/CheckUploadContentTypeFilter.java (original) +++ hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/CheckUploadContentTypeFilter.java Wed Jun 27 16:06:37 2012 @@ -30,7 +30,6 @@ import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; -import java.net.InetAddress; import java.util.HashSet; import java.util.Set; @@ -43,8 +42,8 @@ public class CheckUploadContentTypeFilte private static final Set UPLOAD_OPERATIONS = new HashSet(); static { - UPLOAD_OPERATIONS.add(HttpFSFileSystem.PostOpValues.APPEND.toString()); - UPLOAD_OPERATIONS.add(HttpFSFileSystem.PutOpValues.CREATE.toString()); + UPLOAD_OPERATIONS.add(HttpFSFileSystem.Operation.APPEND.toString()); + UPLOAD_OPERATIONS.add(HttpFSFileSystem.Operation.CREATE.toString()); } /** @@ -82,7 +81,7 @@ public class CheckUploadContentTypeFilte if (method.equals("PUT") || method.equals("POST")) { String op = httpReq.getParameter(HttpFSFileSystem.OP_PARAM); if (op != null && UPLOAD_OPERATIONS.contains(op.toUpperCase())) { - if ("true".equalsIgnoreCase(httpReq.getParameter(HttpFSParams.DataParam.NAME))) { + if ("true".equalsIgnoreCase(httpReq.getParameter(HttpFSParametersProvider.DataParam.NAME))) { String contentType = httpReq.getContentType(); contentTypeOK = HttpFSFileSystem.UPLOAD_CONTENT_TYPE.equalsIgnoreCase(contentType); Modified: hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/HttpFSExceptionProvider.java URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/HttpFSExceptionProvider.java?rev=1354599&r1=1354598&r2=1354599&view=diff ============================================================================== --- hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/HttpFSExceptionProvider.java (original) +++ hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/HttpFSExceptionProvider.java Wed Jun 27 16:06:37 2012 @@ -18,6 +18,7 @@ package org.apache.hadoop.fs.http.server; +import com.sun.jersey.api.container.ContainerException; import org.apache.hadoop.lib.service.FileSystemAccessException; import org.apache.hadoop.lib.wsrs.ExceptionProvider; import org.slf4j.Logger; @@ -59,6 +60,9 @@ public class HttpFSExceptionProvider ext if (throwable instanceof FileSystemAccessException) { throwable = throwable.getCause(); } + if (throwable instanceof ContainerException) { + throwable = throwable.getCause(); + } if (throwable instanceof SecurityException) { status = Response.Status.UNAUTHORIZED; } else if (throwable instanceof FileNotFoundException) { @@ -67,6 +71,8 @@ public class HttpFSExceptionProvider ext status = Response.Status.INTERNAL_SERVER_ERROR; } else if (throwable instanceof UnsupportedOperationException) { status = Response.Status.BAD_REQUEST; + } else if (throwable instanceof IllegalArgumentException) { + status = Response.Status.BAD_REQUEST; } else { status = Response.Status.INTERNAL_SERVER_ERROR; } Added: hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/HttpFSParametersProvider.java URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/HttpFSParametersProvider.java?rev=1354599&view=auto ============================================================================== --- hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/HttpFSParametersProvider.java (added) +++ hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/HttpFSParametersProvider.java Wed Jun 27 16:06:37 2012 @@ -0,0 +1,398 @@ +/** + * 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.fs.http.server; + +import org.apache.hadoop.fs.http.client.HttpFSFileSystem; +import org.apache.hadoop.fs.http.client.HttpFSFileSystem.Operation; +import org.apache.hadoop.lib.wsrs.BooleanParam; +import org.apache.hadoop.lib.wsrs.EnumParam; +import org.apache.hadoop.lib.wsrs.LongParam; +import org.apache.hadoop.lib.wsrs.Param; +import org.apache.hadoop.lib.wsrs.ParametersProvider; +import org.apache.hadoop.lib.wsrs.ShortParam; +import org.apache.hadoop.lib.wsrs.StringParam; +import org.apache.hadoop.lib.wsrs.UserProvider; +import org.slf4j.MDC; + +import javax.ws.rs.ext.Provider; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Pattern; + +/** + * HttpFS ParametersProvider. + */ +@Provider +public class HttpFSParametersProvider extends ParametersProvider { + + private static final Map>[]> PARAMS_DEF = + new HashMap>[]>(); + + static { + PARAMS_DEF.put(Operation.OPEN, + new Class[]{DoAsParam.class, OffsetParam.class, LenParam.class}); + PARAMS_DEF.put(Operation.GETFILESTATUS, new Class[]{DoAsParam.class}); + PARAMS_DEF.put(Operation.LISTSTATUS, + new Class[]{DoAsParam.class, FilterParam.class}); + PARAMS_DEF.put(Operation.GETHOMEDIRECTORY, new Class[]{DoAsParam.class}); + PARAMS_DEF.put(Operation.GETCONTENTSUMMARY, new Class[]{DoAsParam.class}); + PARAMS_DEF.put(Operation.GETFILECHECKSUM, new Class[]{DoAsParam.class}); + PARAMS_DEF.put(Operation.GETFILEBLOCKLOCATIONS, + new Class[]{DoAsParam.class}); + PARAMS_DEF.put(Operation.INSTRUMENTATION, new Class[]{DoAsParam.class}); + PARAMS_DEF.put(Operation.APPEND, + new Class[]{DoAsParam.class, DataParam.class}); + PARAMS_DEF.put(Operation.CREATE, + new Class[]{DoAsParam.class, PermissionParam.class, OverwriteParam.class, + ReplicationParam.class, BlockSizeParam.class, DataParam.class}); + PARAMS_DEF.put(Operation.MKDIRS, + new Class[]{DoAsParam.class, PermissionParam.class}); + PARAMS_DEF.put(Operation.RENAME, + new Class[]{DoAsParam.class, DestinationParam.class}); + PARAMS_DEF.put(Operation.SETOWNER, + new Class[]{DoAsParam.class, OwnerParam.class, GroupParam.class}); + PARAMS_DEF.put(Operation.SETPERMISSION, + new Class[]{DoAsParam.class, PermissionParam.class}); + PARAMS_DEF.put(Operation.SETREPLICATION, + new Class[]{DoAsParam.class, ReplicationParam.class}); + PARAMS_DEF.put(Operation.SETTIMES, + new Class[]{DoAsParam.class, ModifiedTimeParam.class, + AccessTimeParam.class}); + PARAMS_DEF.put(Operation.DELETE, + new Class[]{DoAsParam.class, RecursiveParam.class}); + } + + public HttpFSParametersProvider() { + super(HttpFSFileSystem.OP_PARAM, HttpFSFileSystem.Operation.class, + PARAMS_DEF); + } + + /** + * Class for access-time parameter. + */ + public static class AccessTimeParam extends LongParam { + + /** + * Parameter name. + */ + public static final String NAME = HttpFSFileSystem.ACCESS_TIME_PARAM; + /** + * Constructor. + */ + public AccessTimeParam() { + super(NAME, -1l); + } + } + + /** + * Class for block-size parameter. + */ + public static class BlockSizeParam extends LongParam { + + /** + * Parameter name. + */ + public static final String NAME = HttpFSFileSystem.BLOCKSIZE_PARAM; + + /** + * Constructor. + */ + public BlockSizeParam() { + super(NAME, -1l); + } + } + + /** + * Class for data parameter. + */ + public static class DataParam extends BooleanParam { + + /** + * Parameter name. + */ + public static final String NAME = "data"; + + /** + * Constructor. + */ + public DataParam() { + super(NAME, false); + } + } + + /** + * Class for operation parameter. + */ + public static class OperationParam extends EnumParam { + + /** + * Parameter name. + */ + public static final String NAME = HttpFSFileSystem.OP_PARAM; + /** + * Constructor. + */ + public OperationParam(String operation) { + super(NAME, HttpFSFileSystem.Operation.class, + HttpFSFileSystem.Operation.valueOf(operation.toUpperCase())); + } + } + + /** + * Class for delete's recursive parameter. + */ + public static class RecursiveParam extends BooleanParam { + + /** + * Parameter name. + */ + public static final String NAME = HttpFSFileSystem.RECURSIVE_PARAM; + + /** + * Constructor. + */ + public RecursiveParam() { + super(NAME, false); + } + } + + /** + * Class for do-as parameter. + */ + public static class DoAsParam extends StringParam { + + /** + * Parameter name. + */ + public static final String NAME = HttpFSFileSystem.DO_AS_PARAM; + + /** + * Constructor. + */ + public DoAsParam() { + super(NAME, null, UserProvider.USER_PATTERN); + } + + /** + * Delegates to parent and then adds do-as user to + * MDC context for logging purposes. + * + * + * @param str parameter value. + * + * @return parsed parameter + */ + @Override + public String parseParam(String str) { + String doAs = super.parseParam(str); + MDC.put(getName(), (doAs != null) ? doAs : "-"); + return doAs; + } + } + + /** + * Class for filter parameter. + */ + public static class FilterParam extends StringParam { + + /** + * Parameter name. + */ + public static final String NAME = "filter"; + + /** + * Constructor. + */ + public FilterParam() { + super(NAME, null); + } + + } + + /** + * Class for group parameter. + */ + public static class GroupParam extends StringParam { + + /** + * Parameter name. + */ + public static final String NAME = HttpFSFileSystem.GROUP_PARAM; + + /** + * Constructor. + */ + public GroupParam() { + super(NAME, null, UserProvider.USER_PATTERN); + } + + } + + /** + * Class for len parameter. + */ + public static class LenParam extends LongParam { + + /** + * Parameter name. + */ + public static final String NAME = "len"; + + /** + * Constructor. + */ + public LenParam() { + super(NAME, -1l); + } + } + + /** + * Class for modified-time parameter. + */ + public static class ModifiedTimeParam extends LongParam { + + /** + * Parameter name. + */ + public static final String NAME = HttpFSFileSystem.MODIFICATION_TIME_PARAM; + + /** + * Constructor. + */ + public ModifiedTimeParam() { + super(NAME, -1l); + } + } + + /** + * Class for offset parameter. + */ + public static class OffsetParam extends LongParam { + + /** + * Parameter name. + */ + public static final String NAME = "offset"; + + /** + * Constructor. + */ + public OffsetParam() { + super(NAME, 0l); + } + } + + /** + * Class for overwrite parameter. + */ + public static class OverwriteParam extends BooleanParam { + + /** + * Parameter name. + */ + public static final String NAME = HttpFSFileSystem.OVERWRITE_PARAM; + + /** + * Constructor. + */ + public OverwriteParam() { + super(NAME, true); + } + } + + /** + * Class for owner parameter. + */ + public static class OwnerParam extends StringParam { + + /** + * Parameter name. + */ + public static final String NAME = HttpFSFileSystem.OWNER_PARAM; + + /** + * Constructor. + */ + public OwnerParam() { + super(NAME, null, UserProvider.USER_PATTERN); + } + + } + + /** + * Class for permission parameter. + */ + public static class PermissionParam extends StringParam { + + /** + * Parameter name. + */ + public static final String NAME = HttpFSFileSystem.PERMISSION_PARAM; + + /** + * Symbolic Unix permissions regular expression pattern. + */ + private static final Pattern PERMISSION_PATTERN = + Pattern.compile(HttpFSFileSystem.DEFAULT_PERMISSION + + "|[0-1]?[0-7][0-7][0-7]"); + + /** + * Constructor. + */ + public PermissionParam() { + super(NAME, HttpFSFileSystem.DEFAULT_PERMISSION, PERMISSION_PATTERN); + } + + } + + /** + * Class for replication parameter. + */ + public static class ReplicationParam extends ShortParam { + + /** + * Parameter name. + */ + public static final String NAME = HttpFSFileSystem.REPLICATION_PARAM; + + /** + * Constructor. + */ + public ReplicationParam() { + super(NAME, (short) -1); + } + } + + /** + * Class for to-path parameter. + */ + public static class DestinationParam extends StringParam { + + /** + * Parameter name. + */ + public static final String NAME = HttpFSFileSystem.DESTINATION_PARAM; + + /** + * Constructor. + */ + public DestinationParam() { + super(NAME, null); + } + } +} Modified: hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/HttpFSServer.java URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/HttpFSServer.java?rev=1354599&r1=1354598&r2=1354599&view=diff ============================================================================== --- hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/HttpFSServer.java (original) +++ hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/HttpFSServer.java Wed Jun 27 16:06:37 2012 @@ -21,26 +21,22 @@ package org.apache.hadoop.fs.http.server import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.http.client.HttpFSFileSystem; -import org.apache.hadoop.fs.http.server.HttpFSParams.AccessTimeParam; -import org.apache.hadoop.fs.http.server.HttpFSParams.BlockSizeParam; -import org.apache.hadoop.fs.http.server.HttpFSParams.DataParam; -import org.apache.hadoop.fs.http.server.HttpFSParams.DeleteOpParam; -import org.apache.hadoop.fs.http.server.HttpFSParams.DeleteRecursiveParam; -import org.apache.hadoop.fs.http.server.HttpFSParams.DoAsParam; -import org.apache.hadoop.fs.http.server.HttpFSParams.FilterParam; -import org.apache.hadoop.fs.http.server.HttpFSParams.FsPathParam; -import org.apache.hadoop.fs.http.server.HttpFSParams.GetOpParam; -import org.apache.hadoop.fs.http.server.HttpFSParams.GroupParam; -import org.apache.hadoop.fs.http.server.HttpFSParams.LenParam; -import org.apache.hadoop.fs.http.server.HttpFSParams.ModifiedTimeParam; -import org.apache.hadoop.fs.http.server.HttpFSParams.OffsetParam; -import org.apache.hadoop.fs.http.server.HttpFSParams.OverwriteParam; -import org.apache.hadoop.fs.http.server.HttpFSParams.OwnerParam; -import org.apache.hadoop.fs.http.server.HttpFSParams.PermissionParam; -import org.apache.hadoop.fs.http.server.HttpFSParams.PostOpParam; -import org.apache.hadoop.fs.http.server.HttpFSParams.PutOpParam; -import org.apache.hadoop.fs.http.server.HttpFSParams.ReplicationParam; -import org.apache.hadoop.fs.http.server.HttpFSParams.ToPathParam; +import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.OperationParam; +import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.AccessTimeParam; +import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.BlockSizeParam; +import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.DataParam; +import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.RecursiveParam; +import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.DoAsParam; +import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.FilterParam; +import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.GroupParam; +import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.LenParam; +import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.ModifiedTimeParam; +import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.OffsetParam; +import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.OverwriteParam; +import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.OwnerParam; +import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.PermissionParam; +import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.ReplicationParam; +import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.DestinationParam; import org.apache.hadoop.lib.service.FileSystemAccess; import org.apache.hadoop.lib.service.FileSystemAccessException; import org.apache.hadoop.lib.service.Groups; @@ -49,6 +45,7 @@ import org.apache.hadoop.lib.service.Pro import org.apache.hadoop.lib.servlet.FileSystemReleaseFilter; import org.apache.hadoop.lib.servlet.HostnameFilter; import org.apache.hadoop.lib.wsrs.InputStreamEntity; +import org.apache.hadoop.lib.wsrs.Parameters; import org.apache.hadoop.security.authentication.server.AuthenticationToken; import org.json.simple.JSONObject; import org.slf4j.Logger; @@ -57,7 +54,6 @@ import org.slf4j.MDC; import javax.ws.rs.Consumes; 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; @@ -90,39 +86,6 @@ public class HttpFSServer { private static Logger AUDIT_LOG = LoggerFactory.getLogger("httpfsaudit"); /** - * Special binding for '/' as it is not handled by the wildcard binding. - * - * @param user principal making the request. - * @param op GET operation, default value is @link org.apache.hadoop.fs.http.client.HttpFSFileSystem.GetOpValues#OPEN}. - * @param filter Glob filter, default value is none. Used only if the - * operation is @link org.apache.hadoop.fs.http.client.HttpFSFileSystem.GetOpValues#LISTSTATUS} - * @param doAs user being impersonated, defualt value is none. It can be used - * only if the current user is a HttpFSServer proxyuser. - * - * @return the request response - * - * @throws IOException thrown if an IO error occurred. Thrown exceptions are - * handled by {@link HttpFSExceptionProvider}. - * @throws FileSystemAccessException thrown if a FileSystemAccess releated error occurred. Thrown - * exceptions are handled by {@link HttpFSExceptionProvider}. - */ - @GET - @Path("/") - @Produces(MediaType.APPLICATION_JSON) - public Response root(@Context Principal user, - @QueryParam(GetOpParam.NAME) GetOpParam op, - @QueryParam(FilterParam.NAME) @DefaultValue(FilterParam.DEFAULT) FilterParam filter, - @QueryParam(DoAsParam.NAME) @DefaultValue(DoAsParam.DEFAULT) DoAsParam doAs) - throws IOException, FileSystemAccessException { - return get(user, new FsPathParam(""), op, new OffsetParam(OffsetParam.DEFAULT), - new LenParam(LenParam.DEFAULT), filter, doAs, - new OverwriteParam(OverwriteParam.DEFAULT), - new BlockSizeParam(BlockSizeParam.DEFAULT), - new PermissionParam(PermissionParam.DEFAULT), - new ReplicationParam(ReplicationParam.DEFAULT)); - } - - /** * Resolves the effective user that will be used to request a FileSystemAccess filesystem. *

* If the doAs-user is NULL or the same as the user, it returns the user. @@ -207,402 +170,405 @@ public class HttpFSServer { return fs; } + private void enforceRootPath(HttpFSFileSystem.Operation op, String path) { + if (!path.equals("/")) { + throw new UnsupportedOperationException( + MessageFormat.format("Operation [{0}], invalid path [{1}], must be '/'", + op, path)); + } + } + /** - * Binding to handle all GET requests, supported operations are - * @link org.apache.hadoop.fs.http.client.HttpFSFileSystem.GetOpValues}. - *

- * The @link org.apache.hadoop.fs.http.client.HttpFSFileSystem.GetOpValues#INSTRUMENTATION} operation is available only - * to users that are in HttpFSServer's admin group (see {@link HttpFSServer}. It returns - * HttpFSServer instrumentation data. The specified path must be '/'. + * Special binding for '/' as it is not handled by the wildcard binding. * - * @param user principal making the request. - * @param path path for the GET request. - * @param op GET operation, default value is @link org.apache.hadoop.fs.http.client.HttpFSFileSystem.GetOpValues#OPEN}. - * @param offset of the file being fetch, used only with - * @link org.apache.hadoop.fs.http.client.HttpFSFileSystem.GetOpValues#OPEN} operations. - * @param len amounts of bytes, used only with @link org.apache.hadoop.fs.http.client.HttpFSFileSystem.GetOpValues#OPEN} - * operations. - * @param filter Glob filter, default value is none. Used only if the - * operation is @link org.apache.hadoop.fs.http.client.HttpFSFileSystem.GetOpValues#LISTSTATUS} - * @param doAs user being impersonated, defualt value is none. It can be used - * only if the current user is a HttpFSServer proxyuser. - * @param override default is true. Used only for - * @link org.apache.hadoop.fs.http.client.HttpFSFileSystem.PutOpValues#CREATE} operations. - * @param blockSize block size to set, used only by - * @link org.apache.hadoop.fs.http.client.HttpFSFileSystem.PutOpValues#CREATE} operations. - * @param permission permission to set, used only by - * @link org.apache.hadoop.fs.http.client.HttpFSFileSystem.PutOpValues#SETPERMISSION}. - * @param replication replication factor to set, used only by - * @link org.apache.hadoop.fs.http.client.HttpFSFileSystem.PutOpValues#SETREPLICATION}. + * @param user the principal of the user making the request. + * @param op the HttpFS operation of the request. + * @param params the HttpFS parameters of the request. * * @return the request response. * * @throws IOException thrown if an IO error occurred. Thrown exceptions are * handled by {@link HttpFSExceptionProvider}. - * @throws FileSystemAccessException thrown if a FileSystemAccess releated error occurred. Thrown - * exceptions are handled by {@link HttpFSExceptionProvider}. + * @throws FileSystemAccessException thrown if a FileSystemAccess releated + * error occurred. Thrown exceptions are handled by + * {@link HttpFSExceptionProvider}. */ @GET - @Path("{path:.*}") - @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_JSON}) - public Response get(@Context Principal user, - @PathParam("path") @DefaultValue("") FsPathParam path, - @QueryParam(GetOpParam.NAME) GetOpParam op, - @QueryParam(OffsetParam.NAME) @DefaultValue(OffsetParam.DEFAULT) OffsetParam offset, - @QueryParam(LenParam.NAME) @DefaultValue(LenParam.DEFAULT) LenParam len, - @QueryParam(FilterParam.NAME) @DefaultValue(FilterParam.DEFAULT) FilterParam filter, - @QueryParam(DoAsParam.NAME) @DefaultValue(DoAsParam.DEFAULT) DoAsParam doAs, - - //these params are only for createHandle operation acceptance purposes - @QueryParam(OverwriteParam.NAME) @DefaultValue(OverwriteParam.DEFAULT) OverwriteParam override, - @QueryParam(BlockSizeParam.NAME) @DefaultValue(BlockSizeParam.DEFAULT) BlockSizeParam blockSize, - @QueryParam(PermissionParam.NAME) @DefaultValue(PermissionParam.DEFAULT) - PermissionParam permission, - @QueryParam(ReplicationParam.NAME) @DefaultValue(ReplicationParam.DEFAULT) - ReplicationParam replication - ) + @Path("/") + @Produces(MediaType.APPLICATION_JSON) + public Response getRoot(@Context Principal user, + @QueryParam(OperationParam.NAME) OperationParam op, + @Context Parameters params) throws IOException, FileSystemAccessException { - Response response = null; - if (op == null) { - throw new UnsupportedOperationException(MessageFormat.format("Missing [{0}] parameter", GetOpParam.NAME)); - } else { - path.makeAbsolute(); - MDC.put(HttpFSFileSystem.OP_PARAM, op.value().name()); - switch (op.value()) { - case OPEN: { - //Invoking the command directly using an unmanaged FileSystem that is released by the - //FileSystemReleaseFilter - FSOperations.FSOpen command = new FSOperations.FSOpen(path.value()); - FileSystem fs = createFileSystem(user, doAs.value()); - InputStream is = command.execute(fs); - AUDIT_LOG.info("[{}] offset [{}] len [{}]", new Object[]{path, offset, len}); - InputStreamEntity entity = new InputStreamEntity(is, offset.value(), len.value()); - response = Response.ok(entity).type(MediaType.APPLICATION_OCTET_STREAM).build(); - break; - } - case GETFILESTATUS: { - FSOperations.FSFileStatus command = new FSOperations.FSFileStatus(path.value()); - Map json = fsExecute(user, doAs.value(), command); - AUDIT_LOG.info("[{}]", path); - response = Response.ok(json).type(MediaType.APPLICATION_JSON).build(); - break; - } - case LISTSTATUS: { - FSOperations.FSListStatus command = new FSOperations.FSListStatus(path.value(), filter.value()); - Map json = fsExecute(user, doAs.value(), command); - if (filter.value() == null) { - AUDIT_LOG.info("[{}]", path); - } else { - AUDIT_LOG.info("[{}] filter [{}]", path, filter.value()); - } - response = Response.ok(json).type(MediaType.APPLICATION_JSON).build(); - break; - } - case GETHOMEDIRECTORY: { - FSOperations.FSHomeDir command = new FSOperations.FSHomeDir(); - JSONObject json = fsExecute(user, doAs.value(), command); - AUDIT_LOG.info(""); - response = Response.ok(json).type(MediaType.APPLICATION_JSON).build(); - break; - } - case INSTRUMENTATION: { - if (!path.value().equals("/")) { - throw new UnsupportedOperationException( - MessageFormat.format("Invalid path for {0}={1}, must be '/'", - GetOpParam.NAME, HttpFSFileSystem.GetOpValues.INSTRUMENTATION)); - } - Groups groups = HttpFSServerWebApp.get().get(Groups.class); - List userGroups = groups.getGroups(user.getName()); - if (!userGroups.contains(HttpFSServerWebApp.get().getAdminGroup())) { - throw new AccessControlException("User not in HttpFSServer admin group"); - } - Instrumentation instrumentation = HttpFSServerWebApp.get().get(Instrumentation.class); - Map snapshot = instrumentation.getSnapshot(); - response = Response.ok(snapshot).build(); - break; - } - case GETCONTENTSUMMARY: { - FSOperations.FSContentSummary command = new FSOperations.FSContentSummary(path.value()); - Map json = fsExecute(user, doAs.value(), command); - AUDIT_LOG.info("[{}]", path); - response = Response.ok(json).type(MediaType.APPLICATION_JSON).build(); - break; - } - case GETFILECHECKSUM: { - FSOperations.FSFileChecksum command = new FSOperations.FSFileChecksum(path.value()); - Map json = fsExecute(user, doAs.value(), command); - AUDIT_LOG.info("[{}]", path); - response = Response.ok(json).type(MediaType.APPLICATION_JSON).build(); - break; - } - case GETDELEGATIONTOKEN: { - response = Response.status(Response.Status.BAD_REQUEST).build(); - break; - } - case GETFILEBLOCKLOCATIONS: { - response = Response.status(Response.Status.BAD_REQUEST).build(); - break; - } - } - return response; - } + return get(user, "", op, params); + } + + private String makeAbsolute(String path) { + return "/" + ((path != null) ? path : ""); } /** - * Creates the URL for an upload operation (create or append). + * Binding to handle GET requests, supported operations are * - * @param uriInfo uri info of the request. - * @param uploadOperation operation for the upload URL. + * @param user the principal of the user making the request. + * @param path the path for operation. + * @param op the HttpFS operation of the request. + * @param params the HttpFS parameters of the request. * - * @return the URI for uploading data. + * @return the request response. + * + * @throws IOException thrown if an IO error occurred. Thrown exceptions are + * handled by {@link HttpFSExceptionProvider}. + * @throws FileSystemAccessException thrown if a FileSystemAccess releated + * error occurred. Thrown exceptions are handled by + * {@link HttpFSExceptionProvider}. */ - protected URI createUploadRedirectionURL(UriInfo uriInfo, Enum uploadOperation) { - UriBuilder uriBuilder = uriInfo.getRequestUriBuilder(); - uriBuilder = uriBuilder.replaceQueryParam(PutOpParam.NAME, uploadOperation). - queryParam(DataParam.NAME, Boolean.TRUE); - return uriBuilder.build(null); + @GET + @Path("{path:.*}") + @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_JSON}) + public Response get(@Context Principal user, + @PathParam("path") String path, + @QueryParam(OperationParam.NAME) OperationParam op, + @Context Parameters params) + throws IOException, FileSystemAccessException { + Response response; + path = makeAbsolute(path); + MDC.put(HttpFSFileSystem.OP_PARAM, op.value().name()); + String doAs = params.get(DoAsParam.NAME, DoAsParam.class); + switch (op.value()) { + case OPEN: { + //Invoking the command directly using an unmanaged FileSystem that is + // released by the FileSystemReleaseFilter + FSOperations.FSOpen command = new FSOperations.FSOpen(path); + FileSystem fs = createFileSystem(user, doAs); + InputStream is = command.execute(fs); + Long offset = params.get(OffsetParam.NAME, OffsetParam.class); + Long len = params.get(LenParam.NAME, LenParam.class); + AUDIT_LOG.info("[{}] offset [{}] len [{}]", + new Object[]{path, offset, len}); + InputStreamEntity entity = new InputStreamEntity(is, offset, len); + response = + Response.ok(entity).type(MediaType.APPLICATION_OCTET_STREAM).build(); + break; + } + case GETFILESTATUS: { + FSOperations.FSFileStatus command = + new FSOperations.FSFileStatus(path); + Map json = fsExecute(user, doAs, command); + AUDIT_LOG.info("[{}]", path); + response = Response.ok(json).type(MediaType.APPLICATION_JSON).build(); + break; + } + case LISTSTATUS: { + String filter = params.get(FilterParam.NAME, FilterParam.class); + FSOperations.FSListStatus command = new FSOperations.FSListStatus( + path, filter); + Map json = fsExecute(user, doAs, command); + AUDIT_LOG.info("[{}] filter [{}]", path, + (filter != null) ? filter : "-"); + response = Response.ok(json).type(MediaType.APPLICATION_JSON).build(); + break; + } + case GETHOMEDIRECTORY: { + enforceRootPath(op.value(), path); + FSOperations.FSHomeDir command = new FSOperations.FSHomeDir(); + JSONObject json = fsExecute(user, doAs, command); + AUDIT_LOG.info(""); + response = Response.ok(json).type(MediaType.APPLICATION_JSON).build(); + break; + } + case INSTRUMENTATION: { + enforceRootPath(op.value(), path); + Groups groups = HttpFSServerWebApp.get().get(Groups.class); + List userGroups = groups.getGroups(user.getName()); + if (!userGroups.contains(HttpFSServerWebApp.get().getAdminGroup())) { + throw new AccessControlException( + "User not in HttpFSServer admin group"); + } + Instrumentation instrumentation = + HttpFSServerWebApp.get().get(Instrumentation.class); + Map snapshot = instrumentation.getSnapshot(); + response = Response.ok(snapshot).build(); + break; + } + case GETCONTENTSUMMARY: { + FSOperations.FSContentSummary command = + new FSOperations.FSContentSummary(path); + Map json = fsExecute(user, doAs, command); + AUDIT_LOG.info("[{}]", path); + response = Response.ok(json).type(MediaType.APPLICATION_JSON).build(); + break; + } + case GETFILECHECKSUM: { + FSOperations.FSFileChecksum command = + new FSOperations.FSFileChecksum(path); + Map json = fsExecute(user, doAs, command); + AUDIT_LOG.info("[{}]", path); + response = Response.ok(json).type(MediaType.APPLICATION_JSON).build(); + break; + } + case GETFILEBLOCKLOCATIONS: { + response = Response.status(Response.Status.BAD_REQUEST).build(); + break; + } + default: { + throw new IOException( + MessageFormat.format("Invalid HTTP GET operation [{0}]", + op.value())); + } + } + return response; } + /** - * Binding to handle all DELETE requests. + * Binding to handle DELETE requests. * - * @param user principal making the request. - * @param path path for the DELETE request. - * @param op DELETE operation, default value is @link org.apache.hadoop.fs.http.client.HttpFSFileSystem.DeleteOpValues#DELETE}. - * @param recursive indicates if the delete is recursive, default is false - * @param doAs user being impersonated, defualt value is none. It can be used - * only if the current user is a HttpFSServer proxyuser. + * @param user the principal of the user making the request. + * @param path the path for operation. + * @param op the HttpFS operation of the request. + * @param params the HttpFS parameters of the request. * * @return the request response. * * @throws IOException thrown if an IO error occurred. Thrown exceptions are * handled by {@link HttpFSExceptionProvider}. - * @throws FileSystemAccessException thrown if a FileSystemAccess releated error occurred. Thrown - * exceptions are handled by {@link HttpFSExceptionProvider}. + * @throws FileSystemAccessException thrown if a FileSystemAccess releated + * error occurred. Thrown exceptions are handled by + * {@link HttpFSExceptionProvider}. */ @DELETE @Path("{path:.*}") @Produces(MediaType.APPLICATION_JSON) public Response delete(@Context Principal user, - @PathParam("path") FsPathParam path, - @QueryParam(DeleteOpParam.NAME) DeleteOpParam op, - @QueryParam(DeleteRecursiveParam.NAME) @DefaultValue(DeleteRecursiveParam.DEFAULT) - DeleteRecursiveParam recursive, - @QueryParam(DoAsParam.NAME) @DefaultValue(DoAsParam.DEFAULT) DoAsParam doAs) + @PathParam("path") String path, + @QueryParam(OperationParam.NAME) OperationParam op, + @Context Parameters params) throws IOException, FileSystemAccessException { - Response response = null; - if (op == null) { - throw new UnsupportedOperationException(MessageFormat.format("Missing [{0}] parameter", DeleteOpParam.NAME)); - } + Response response; + path = makeAbsolute(path); + MDC.put(HttpFSFileSystem.OP_PARAM, op.value().name()); + String doAs = params.get(DoAsParam.NAME, DoAsParam.class); switch (op.value()) { case DELETE: { - path.makeAbsolute(); - MDC.put(HttpFSFileSystem.OP_PARAM, "DELETE"); + Boolean recursive = + params.get(RecursiveParam.NAME, RecursiveParam.class); AUDIT_LOG.info("[{}] recursive [{}]", path, recursive); - FSOperations.FSDelete command = new FSOperations.FSDelete(path.value(), recursive.value()); - JSONObject json = fsExecute(user, doAs.value(), command); + FSOperations.FSDelete command = + new FSOperations.FSDelete(path, recursive); + JSONObject json = fsExecute(user, doAs, command); response = Response.ok(json).type(MediaType.APPLICATION_JSON).build(); break; } + default: { + throw new IOException( + MessageFormat.format("Invalid HTTP DELETE operation [{0}]", + op.value())); + } } return response; } + /** + * Binding to handle POST requests. + * + * @param is the inputstream for the request payload. + * @param user the principal of the user making the request. + * @param uriInfo the of the request. + * @param path the path for operation. + * @param op the HttpFS operation of the request. + * @param params the HttpFS parameters of the request. + * + * @return the request response. + * + * @throws IOException thrown if an IO error occurred. Thrown exceptions are + * handled by {@link HttpFSExceptionProvider}. + * @throws FileSystemAccessException thrown if a FileSystemAccess releated + * error occurred. Thrown exceptions are handled by + * {@link HttpFSExceptionProvider}. + */ + @POST + @Path("{path:.*}") + @Consumes({"*/*"}) + @Produces({MediaType.APPLICATION_JSON}) + public Response post(InputStream is, + @Context Principal user, + @Context UriInfo uriInfo, + @PathParam("path") String path, + @QueryParam(OperationParam.NAME) OperationParam op, + @Context Parameters params) + throws IOException, FileSystemAccessException { + Response response; + path = makeAbsolute(path); + MDC.put(HttpFSFileSystem.OP_PARAM, op.value().name()); + String doAs = params.get(DoAsParam.NAME, DoAsParam.class); + switch (op.value()) { + case APPEND: { + boolean hasData = params.get(DataParam.NAME, DataParam.class); + if (!hasData) { + response = Response.temporaryRedirect( + createUploadRedirectionURL(uriInfo, + HttpFSFileSystem.Operation.APPEND)).build(); + } else { + FSOperations.FSAppend command = + new FSOperations.FSAppend(is, path); + fsExecute(user, doAs, command); + AUDIT_LOG.info("[{}]", path); + response = Response.ok().type(MediaType.APPLICATION_JSON).build(); + } + break; + } + default: { + throw new IOException( + MessageFormat.format("Invalid HTTP POST operation [{0}]", + op.value())); + } + } + return response; + } /** - * Binding to handle all PUT requests, supported operations are - * @link org.apache.hadoop.fs.http.client.HttpFSFileSystem.PutOpValues}. + * Creates the URL for an upload operation (create or append). * - * @param is request input stream, used only for - * @link org.apache.hadoop.fs.http.client.HttpFSFileSystem.PostOpValues#APPEND} operations. - * @param user principal making the request. - * @param uriInfo the request uriInfo. - * @param path path for the PUT request. - * @param op PUT operation, no default value. - * @param toPath new path, used only for - * {@link org.apache.hadoop.fs.http.client.HttpFSFileSystem.PutOpValues#RENAME} operations. - * @link org.apache.hadoop.fs.http.client.HttpFSFileSystem.PutOpValues#SETTIMES}. - * @param owner owner to set, used only for - * @link org.apache.hadoop.fs.http.client.HttpFSFileSystem.PutOpValues#SETOWNER} operations. - * @param group group to set, used only for - * @link org.apache.hadoop.fs.http.client.HttpFSFileSystem.PutOpValues#SETOWNER} operations. - * @param override default is true. Used only for - * @link org.apache.hadoop.fs.http.client.HttpFSFileSystem.PutOpValues#CREATE} operations. - * @param blockSize block size to set, used only by - * @link org.apache.hadoop.fs.http.client.HttpFSFileSystem.PutOpValues#CREATE} operations. - * @param permission permission to set, used only by - * @link org.apache.hadoop.fs.http.client.HttpFSFileSystem.PutOpValues#SETPERMISSION}. - * @param replication replication factor to set, used only by - * @link org.apache.hadoop.fs.http.client.HttpFSFileSystem.PutOpValues#SETREPLICATION}. - * @param modifiedTime modified time, in seconds since EPOC, used only by - * @link org.apache.hadoop.fs.http.client.HttpFSFileSystem.PutOpValues#SETTIMES}. - * @param accessTime accessed time, in seconds since EPOC, used only by - * @link org.apache.hadoop.fs.http.client.HttpFSFileSystem.PutOpValues#SETTIMES}. - * @param hasData indicates if the append request is uploading data or not - * (just getting the handle). - * @param doAs user being impersonated, defualt value is none. It can be used - * only if the current user is a HttpFSServer proxyuser. + * @param uriInfo uri info of the request. + * @param uploadOperation operation for the upload URL. + * + * @return the URI for uploading data. + */ + protected URI createUploadRedirectionURL(UriInfo uriInfo, Enum uploadOperation) { + UriBuilder uriBuilder = uriInfo.getRequestUriBuilder(); + uriBuilder = uriBuilder.replaceQueryParam(OperationParam.NAME, uploadOperation). + queryParam(DataParam.NAME, Boolean.TRUE); + return uriBuilder.build(null); + } + + + /** + * Binding to handle PUT requests. + * + * @param is the inputstream for the request payload. + * @param user the principal of the user making the request. + * @param uriInfo the of the request. + * @param path the path for operation. + * @param op the HttpFS operation of the request. + * @param params the HttpFS parameters of the request. * * @return the request response. * * @throws IOException thrown if an IO error occurred. Thrown exceptions are * handled by {@link HttpFSExceptionProvider}. - * @throws FileSystemAccessException thrown if a FileSystemAccess releated error occurred. Thrown - * exceptions are handled by {@link HttpFSExceptionProvider}. + * @throws FileSystemAccessException thrown if a FileSystemAccess releated + * error occurred. Thrown exceptions are handled by + * {@link HttpFSExceptionProvider}. */ @PUT @Path("{path:.*}") @Consumes({"*/*"}) @Produces({MediaType.APPLICATION_JSON}) public Response put(InputStream is, - @Context Principal user, - @Context UriInfo uriInfo, - @PathParam("path") FsPathParam path, - @QueryParam(PutOpParam.NAME) PutOpParam op, - @QueryParam(ToPathParam.NAME) @DefaultValue(ToPathParam.DEFAULT) ToPathParam toPath, - @QueryParam(OwnerParam.NAME) @DefaultValue(OwnerParam.DEFAULT) OwnerParam owner, - @QueryParam(GroupParam.NAME) @DefaultValue(GroupParam.DEFAULT) GroupParam group, - @QueryParam(OverwriteParam.NAME) @DefaultValue(OverwriteParam.DEFAULT) OverwriteParam override, - @QueryParam(BlockSizeParam.NAME) @DefaultValue(BlockSizeParam.DEFAULT) BlockSizeParam blockSize, - @QueryParam(PermissionParam.NAME) @DefaultValue(PermissionParam.DEFAULT) - PermissionParam permission, - @QueryParam(ReplicationParam.NAME) @DefaultValue(ReplicationParam.DEFAULT) - ReplicationParam replication, - @QueryParam(ModifiedTimeParam.NAME) @DefaultValue(ModifiedTimeParam.DEFAULT) - ModifiedTimeParam modifiedTime, - @QueryParam(AccessTimeParam.NAME) @DefaultValue(AccessTimeParam.DEFAULT) - AccessTimeParam accessTime, - @QueryParam(DataParam.NAME) @DefaultValue(DataParam.DEFAULT) DataParam hasData, - @QueryParam(DoAsParam.NAME) @DefaultValue(DoAsParam.DEFAULT) DoAsParam doAs) + @Context Principal user, + @Context UriInfo uriInfo, + @PathParam("path") String path, + @QueryParam(OperationParam.NAME) OperationParam op, + @Context Parameters params) throws IOException, FileSystemAccessException { - Response response = null; - if (op == null) { - throw new UnsupportedOperationException(MessageFormat.format("Missing [{0}] parameter", PutOpParam.NAME)); - } - path.makeAbsolute(); + Response response; + path = makeAbsolute(path); MDC.put(HttpFSFileSystem.OP_PARAM, op.value().name()); + String doAs = params.get(DoAsParam.NAME, DoAsParam.class); switch (op.value()) { case CREATE: { - if (!hasData.value()) { + boolean hasData = params.get(DataParam.NAME, DataParam.class); + if (!hasData) { response = Response.temporaryRedirect( - createUploadRedirectionURL(uriInfo, HttpFSFileSystem.PutOpValues.CREATE)).build(); + createUploadRedirectionURL(uriInfo, + HttpFSFileSystem.Operation.CREATE)).build(); } else { - FSOperations.FSCreate - command = new FSOperations.FSCreate(is, path.value(), permission.value(), override.value(), - replication.value(), blockSize.value()); - fsExecute(user, doAs.value(), command); - AUDIT_LOG.info("[{}] permission [{}] override [{}] replication [{}] blockSize [{}]", - new Object[]{path, permission, override, replication, blockSize}); + String permission = params.get(PermissionParam.NAME, + PermissionParam.class); + boolean override = params.get(OverwriteParam.NAME, + OverwriteParam.class); + short replication = params.get(ReplicationParam.NAME, + ReplicationParam.class); + long blockSize = params.get(BlockSizeParam.NAME, + BlockSizeParam.class); + FSOperations.FSCreate command = + new FSOperations.FSCreate(is, path, permission, override, + replication, blockSize); + fsExecute(user, doAs, command); + AUDIT_LOG.info( + "[{}] permission [{}] override [{}] replication [{}] blockSize [{}]", + new Object[]{path, permission, override, replication, blockSize}); response = Response.status(Response.Status.CREATED).build(); } break; } case MKDIRS: { - FSOperations.FSMkdirs command = new FSOperations.FSMkdirs(path.value(), permission.value()); - JSONObject json = fsExecute(user, doAs.value(), command); - AUDIT_LOG.info("[{}] permission [{}]", path, permission.value()); + String permission = params.get(PermissionParam.NAME, + PermissionParam.class); + FSOperations.FSMkdirs command = + new FSOperations.FSMkdirs(path, permission); + JSONObject json = fsExecute(user, doAs, command); + AUDIT_LOG.info("[{}] permission [{}]", path, permission); response = Response.ok(json).type(MediaType.APPLICATION_JSON).build(); break; } case RENAME: { - FSOperations.FSRename command = new FSOperations.FSRename(path.value(), toPath.value()); - JSONObject json = fsExecute(user, doAs.value(), command); + String toPath = params.get(DestinationParam.NAME, DestinationParam.class); + FSOperations.FSRename command = + new FSOperations.FSRename(path, toPath); + JSONObject json = fsExecute(user, doAs, command); AUDIT_LOG.info("[{}] to [{}]", path, toPath); response = Response.ok(json).type(MediaType.APPLICATION_JSON).build(); break; } case SETOWNER: { - FSOperations.FSSetOwner command = new FSOperations.FSSetOwner(path.value(), owner.value(), group.value()); - fsExecute(user, doAs.value(), command); - AUDIT_LOG.info("[{}] to (O/G)[{}]", path, owner.value() + ":" + group.value()); + String owner = params.get(OwnerParam.NAME, OwnerParam.class); + String group = params.get(GroupParam.NAME, GroupParam.class); + FSOperations.FSSetOwner command = + new FSOperations.FSSetOwner(path, owner, group); + fsExecute(user, doAs, command); + AUDIT_LOG.info("[{}] to (O/G)[{}]", path, owner + ":" + group); response = Response.ok().build(); break; } case SETPERMISSION: { - FSOperations.FSSetPermission command = new FSOperations.FSSetPermission(path.value(), permission.value()); - fsExecute(user, doAs.value(), command); - AUDIT_LOG.info("[{}] to [{}]", path, permission.value()); + String permission = params.get(PermissionParam.NAME, + PermissionParam.class); + FSOperations.FSSetPermission command = + new FSOperations.FSSetPermission(path, permission); + fsExecute(user, doAs, command); + AUDIT_LOG.info("[{}] to [{}]", path, permission); response = Response.ok().build(); break; } case SETREPLICATION: { - FSOperations.FSSetReplication command = new FSOperations.FSSetReplication(path.value(), replication.value()); - JSONObject json = fsExecute(user, doAs.value(), command); - AUDIT_LOG.info("[{}] to [{}]", path, replication.value()); + short replication = params.get(ReplicationParam.NAME, + ReplicationParam.class); + FSOperations.FSSetReplication command = + new FSOperations.FSSetReplication(path, replication); + JSONObject json = fsExecute(user, doAs, command); + AUDIT_LOG.info("[{}] to [{}]", path, replication); response = Response.ok(json).build(); break; } case SETTIMES: { - FSOperations.FSSetTimes - command = new FSOperations.FSSetTimes(path.value(), modifiedTime.value(), accessTime.value()); - fsExecute(user, doAs.value(), command); - AUDIT_LOG.info("[{}] to (M/A)[{}]", path, modifiedTime.value() + ":" + accessTime.value()); + long modifiedTime = params.get(ModifiedTimeParam.NAME, + ModifiedTimeParam.class); + long accessTime = params.get(AccessTimeParam.NAME, + AccessTimeParam.class); + FSOperations.FSSetTimes command = + new FSOperations.FSSetTimes(path, modifiedTime, accessTime); + fsExecute(user, doAs, command); + AUDIT_LOG.info("[{}] to (M/A)[{}]", path, + modifiedTime + ":" + accessTime); response = Response.ok().build(); break; } - case RENEWDELEGATIONTOKEN: { - response = Response.status(Response.Status.BAD_REQUEST).build(); - break; - } - case CANCELDELEGATIONTOKEN: { - response = Response.status(Response.Status.BAD_REQUEST).build(); - break; - } - } - return response; - } - - /** - * Binding to handle all OPST requests, supported operations are - * @link org.apache.hadoop.fs.http.client.HttpFSFileSystem.PostOpValues}. - * - * @param is request input stream, used only for - * @link org.apache.hadoop.fs.http.client.HttpFSFileSystem.PostOpValues#APPEND} operations. - * @param user principal making the request. - * @param uriInfo the request uriInfo. - * @param path path for the POST request. - * @param op POST operation, default is @link org.apache.hadoop.fs.http.client.HttpFSFileSystem.PostOpValues#APPEND}. - * @param hasData indicates if the append request is uploading data or not (just getting the handle). - * @param doAs user being impersonated, defualt value is none. It can be used - * only if the current user is a HttpFSServer proxyuser. - * - * @return the request response. - * - * @throws IOException thrown if an IO error occurred. Thrown exceptions are - * handled by {@link HttpFSExceptionProvider}. - * @throws FileSystemAccessException thrown if a FileSystemAccess releated error occurred. Thrown - * exceptions are handled by {@link HttpFSExceptionProvider}. - */ - @POST - @Path("{path:.*}") - @Consumes({"*/*"}) - @Produces({MediaType.APPLICATION_JSON}) - public Response post(InputStream is, - @Context Principal user, - @Context UriInfo uriInfo, - @PathParam("path") FsPathParam path, - @QueryParam(PostOpParam.NAME) PostOpParam op, - @QueryParam(DataParam.NAME) @DefaultValue(DataParam.DEFAULT) DataParam hasData, - @QueryParam(DoAsParam.NAME) @DefaultValue(DoAsParam.DEFAULT) DoAsParam doAs) - throws IOException, FileSystemAccessException { - Response response = null; - if (op == null) { - throw new UnsupportedOperationException(MessageFormat.format("Missing [{0}] parameter", PostOpParam.NAME)); - } - path.makeAbsolute(); - MDC.put(HttpFSFileSystem.OP_PARAM, op.value().name()); - switch (op.value()) { - case APPEND: { - if (!hasData.value()) { - response = Response.temporaryRedirect( - createUploadRedirectionURL(uriInfo, HttpFSFileSystem.PostOpValues.APPEND)).build(); - } else { - FSOperations.FSAppend command = new FSOperations.FSAppend(is, path.value()); - fsExecute(user, doAs.value(), command); - AUDIT_LOG.info("[{}]", path); - response = Response.ok().type(MediaType.APPLICATION_JSON).build(); - } - break; + default: { + throw new IOException( + MessageFormat.format("Invalid HTTP PUT operation [{0}]", + op.value())); } } return response; Modified: hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/BooleanParam.java URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/BooleanParam.java?rev=1354599&r1=1354598&r2=1354599&view=diff ============================================================================== --- hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/BooleanParam.java (original) +++ hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/BooleanParam.java Wed Jun 27 16:06:37 2012 @@ -22,15 +22,14 @@ import java.text.MessageFormat; public abstract class BooleanParam extends Param { - public BooleanParam(String name, String str) { - value = parseParam(name, str); + public BooleanParam(String name, Boolean defaultValue) { + super(name, defaultValue); } protected Boolean parse(String str) throws Exception { if (str.equalsIgnoreCase("true")) { return true; - } - if (str.equalsIgnoreCase("false")) { + } else if (str.equalsIgnoreCase("false")) { return false; } throw new IllegalArgumentException(MessageFormat.format("Invalid value [{0}], must be a boolean", str)); Modified: hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/ByteParam.java URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/ByteParam.java?rev=1354599&r1=1354598&r2=1354599&view=diff ============================================================================== --- hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/ByteParam.java (original) +++ hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/ByteParam.java Wed Jun 27 16:06:37 2012 @@ -20,8 +20,8 @@ package org.apache.hadoop.lib.wsrs; public abstract class ByteParam extends Param { - public ByteParam(String name, String str) { - value = parseParam(name, str); + public ByteParam(String name, Byte defaultValue) { + super(name, defaultValue); } protected Byte parse(String str) throws Exception { Modified: hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/EnumParam.java URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/EnumParam.java?rev=1354599&r1=1354598&r2=1354599&view=diff ============================================================================== --- hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/EnumParam.java (original) +++ hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/EnumParam.java Wed Jun 27 16:06:37 2012 @@ -25,9 +25,9 @@ import java.util.Arrays; public abstract class EnumParam> extends Param { Class klass; - public EnumParam(String label, String str, Class e) { + public EnumParam(String name, Class e, E defaultValue) { + super(name, defaultValue); klass = e; - value = parseParam(label, str); } protected E parse(String str) throws Exception { Modified: hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/IntegerParam.java URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/IntegerParam.java?rev=1354599&r1=1354598&r2=1354599&view=diff ============================================================================== --- hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/IntegerParam.java (original) +++ hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/IntegerParam.java Wed Jun 27 16:06:37 2012 @@ -20,8 +20,8 @@ package org.apache.hadoop.lib.wsrs; public abstract class IntegerParam extends Param { - public IntegerParam(String name, String str) { - value = parseParam(name, str); + public IntegerParam(String name, Integer defaultValue) { + super(name, defaultValue); } protected Integer parse(String str) throws Exception { Modified: hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/LongParam.java URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/LongParam.java?rev=1354599&r1=1354598&r2=1354599&view=diff ============================================================================== --- hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/LongParam.java (original) +++ hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/LongParam.java Wed Jun 27 16:06:37 2012 @@ -20,8 +20,8 @@ package org.apache.hadoop.lib.wsrs; public abstract class LongParam extends Param { - public LongParam(String name, String str) { - value = parseParam(name, str); + public LongParam(String name, Long defaultValue) { + super(name, defaultValue); } protected Long parse(String str) throws Exception { Modified: hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/Param.java URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/Param.java?rev=1354599&r1=1354598&r2=1354599&view=diff ============================================================================== --- hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/Param.java (original) +++ hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/Param.java Wed Jun 27 16:06:37 2012 @@ -23,32 +23,39 @@ import org.apache.hadoop.lib.util.Check; import java.text.MessageFormat; public abstract class Param { + private String name; protected T value; - public T parseParam(String name, String str) { - Check.notNull(name, "name"); + public Param(String name, T defaultValue) { + this.name = name; + this.value = defaultValue; + } + + public String getName() { + return name; + } + + public T parseParam(String str) { try { - return (str != null && str.trim().length() > 0) ? parse(str) : null; + value = (str != null && str.trim().length() > 0) ? parse(str) : value; } catch (Exception ex) { throw new IllegalArgumentException( MessageFormat.format("Parameter [{0}], invalid value [{1}], value must be [{2}]", name, str, getDomain())); } + return value; } public T value() { return value; } - protected void setValue(T value) { - this.value = value; - } - protected abstract String getDomain(); protected abstract T parse(String str) throws Exception; public String toString() { - return value.toString(); + return (value != null) ? value.toString() : "NULL"; } + } Added: hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/Parameters.java URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/Parameters.java?rev=1354599&view=auto ============================================================================== --- hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/Parameters.java (added) +++ hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/Parameters.java Wed Jun 27 16:06:37 2012 @@ -0,0 +1,51 @@ +/** + * 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.lib.wsrs; + +import java.util.Map; + +/** + * Class that contains all parsed JAX-RS parameters. + *

+ * Instances are created by the {@link ParametersProvider} class. + */ +public class Parameters { + private Map> params; + + /** + * Constructor that receives the request parsed parameters. + * + * @param params the request parsed parameters. + */ + public Parameters(Map> params) { + this.params = params; + } + + /** + * Returns the value of a request parsed parameter. + * + * @param name parameter name. + * @param klass class of the parameter, used for value casting. + * @return the value of the parameter. + */ + @SuppressWarnings("unchecked") + public > V get(String name, Class klass) { + return ((T)params.get(name)).value(); + } + +} Added: hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/ParametersProvider.java URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/ParametersProvider.java?rev=1354599&view=auto ============================================================================== --- hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/ParametersProvider.java (added) +++ hadoop/common/trunk/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/ParametersProvider.java Wed Jun 27 16:06:37 2012 @@ -0,0 +1,107 @@ +/** + * 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.lib.wsrs; + +import com.sun.jersey.api.core.HttpContext; +import com.sun.jersey.core.spi.component.ComponentContext; +import com.sun.jersey.core.spi.component.ComponentScope; +import com.sun.jersey.server.impl.inject.AbstractHttpContextInjectable; +import com.sun.jersey.spi.inject.Injectable; +import com.sun.jersey.spi.inject.InjectableProvider; + +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MultivaluedMap; +import java.lang.reflect.Type; +import java.text.MessageFormat; +import java.util.HashMap; +import java.util.Map; + +/** + * Jersey provider that parses the request parameters based on the + * given parameter definition. + */ +public class ParametersProvider + extends AbstractHttpContextInjectable + implements InjectableProvider { + + private String driverParam; + private Class enumClass; + private Map>[]> paramsDef; + + public ParametersProvider(String driverParam, Class enumClass, + Map>[]> paramsDef) { + this.driverParam = driverParam; + this.enumClass = enumClass; + this.paramsDef = paramsDef; + } + + @Override + @SuppressWarnings("unchecked") + public Parameters getValue(HttpContext httpContext) { + Map> map = new HashMap>(); + MultivaluedMap queryString = + httpContext.getRequest().getQueryParameters(); + String str = queryString.getFirst(driverParam); + if (str == null) { + throw new IllegalArgumentException( + MessageFormat.format("Missing Operation parameter [{0}]", + driverParam)); + } + Enum op; + try { + op = Enum.valueOf(enumClass, str.toUpperCase()); + } catch (IllegalArgumentException ex) { + throw new IllegalArgumentException( + MessageFormat.format("Invalid Operation [{0}]", str)); + } + if (!paramsDef.containsKey(op)) { + throw new IllegalArgumentException( + MessageFormat.format("Unsupported Operation [{0}]", op)); + } + for (Class> paramClass : paramsDef.get(op)) { + Param param; + try { + param = paramClass.newInstance(); + } catch (Exception ex) { + throw new UnsupportedOperationException( + MessageFormat.format( + "Param class [{0}] does not have default constructor", + paramClass.getName())); + } + try { + param.parseParam(queryString.getFirst(param.getName())); + } + catch (Exception ex) { + throw new IllegalArgumentException(ex.toString(), ex); + } + map.put(param.getName(), param); + } + return new Parameters(map); + } + + @Override + public ComponentScope getScope() { + return ComponentScope.PerRequest; + } + + @Override + public Injectable getInjectable(ComponentContext componentContext, Context context, Type type) { + return (type.equals(Parameters.class)) ? this : null; + } +}