From 05dbca229fc08599fa33182cc90c5c2a876bcf67 Mon Sep 17 00:00:00 2001 From: Tsz-wo Sze Date: Wed, 31 Aug 2011 23:01:16 +0000 Subject: [PATCH] svn merge -c 1163858 from trunk. git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-0.23@1163860 13f79535-47bb-0310-9956-ffa450edef68 --- .../hadoop-common/CHANGES.txt | 2 + hadoop-common-project/hadoop-common/pom.xml | 22 +++++++ .../org/apache/hadoop/http/HttpServer.java | 24 +++++-- .../apache/hadoop/http/TestHttpServer.java | 23 ++++++- .../hadoop/http/resource/JerseyResource.java | 64 +++++++++++++++++++ hadoop-project/pom.xml | 22 +++++++ 6 files changed, 149 insertions(+), 8 deletions(-) create mode 100644 hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/resource/JerseyResource.java diff --git a/hadoop-common-project/hadoop-common/CHANGES.txt b/hadoop-common-project/hadoop-common/CHANGES.txt index de8a61ccd7d..350e5269cd5 100644 --- a/hadoop-common-project/hadoop-common/CHANGES.txt +++ b/hadoop-common-project/hadoop-common/CHANGES.txt @@ -348,6 +348,8 @@ Release 0.23.0 - Unreleased HADOOP-7579. Rename package names from alfredo to auth. (Alejandro Abdelnur via szetszwo) + HADOOP-7594. Support HTTP REST in HttpServer. (szetszwo) + OPTIMIZATIONS HADOOP-7333. Performance improvement in PureJavaCrc32. (Eric Caspole diff --git a/hadoop-common-project/hadoop-common/pom.xml b/hadoop-common-project/hadoop-common/pom.xml index f99fb1fb914..26d004614f4 100644 --- a/hadoop-common-project/hadoop-common/pom.xml +++ b/hadoop-common-project/hadoop-common/pom.xml @@ -92,6 +92,28 @@ jetty-util compile + + + asm + asm + compile + + + com.sun.jersey + jersey-core + compile + + + com.sun.jersey + jersey-json + compile + + + com.sun.jersey + jersey-server + compile + + tomcat jasper-compiler diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer.java index 0aaa964313b..00cdf32746f 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer.java @@ -48,16 +48,12 @@ import org.apache.hadoop.classification.InterfaceStability; import org.apache.hadoop.conf.ConfServlet; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.CommonConfigurationKeys; -import org.apache.hadoop.http.AdminAuthorizedServlet; -import org.apache.hadoop.http.FilterContainer; -import org.apache.hadoop.http.FilterInitializer; -import org.apache.hadoop.http.HtmlQuoting; import org.apache.hadoop.jmx.JMXJsonServlet; import org.apache.hadoop.log.LogLevel; import org.apache.hadoop.metrics.MetricsServlet; import org.apache.hadoop.security.Krb5AndCertsSslSocketConnector; -import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.security.Krb5AndCertsSslSocketConnector.MODE; +import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.security.authorize.AccessControlList; import org.apache.hadoop.util.ReflectionUtils; import org.mortbay.io.Buffer; @@ -79,6 +75,8 @@ import org.mortbay.jetty.webapp.WebAppContext; import org.mortbay.thread.QueuedThreadPool; import org.mortbay.util.MultiException; +import com.sun.jersey.spi.container.servlet.ServletContainer; + /** * Create a Jetty embedded server to answer http requests. The primary goal * is to serve up status information for the server. @@ -325,6 +323,22 @@ public class HttpServer implements FilterContainer { webAppContext.setAttribute(name, value); } + /** + * Add a Jersey resource package. + * @param packageName The Java package name containing the Jersey resource. + * @param pathSpec The path spec for the servlet + */ + public void addJerseyResourcePackage(final String packageName, + final String pathSpec) { + LOG.info("addJerseyResourcePackage: packageName=" + packageName + + ", pathSpec=" + pathSpec); + final ServletHolder sh = new ServletHolder(ServletContainer.class); + sh.setInitParameter("com.sun.jersey.config.property.resourceConfigClass", + "com.sun.jersey.api.core.PackagesResourceConfig"); + sh.setInitParameter("com.sun.jersey.config.property.packages", packageName); + webAppContext.addServlet(sh, pathSpec); + } + /** * Add a servlet in the server. * @param name The name of the servlet (can be passed as null) diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpServer.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpServer.java index 38c70b910c8..bf2f3fecc69 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpServer.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpServer.java @@ -50,6 +50,7 @@ import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.CommonConfigurationKeys; import org.apache.hadoop.http.HttpServer.QuotingInputFilter.RequestQuoter; +import org.apache.hadoop.http.resource.JerseyResource; import org.apache.hadoop.security.Groups; import org.apache.hadoop.security.ShellBasedUnixGroupsMapping; import org.apache.hadoop.security.authorize.AccessControlList; @@ -57,6 +58,7 @@ import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.mockito.Mockito; +import org.mortbay.util.ajax.JSON; public class TestHttpServer extends HttpServerFunctionalTest { static final Log LOG = LogFactory.getLog(TestHttpServer.class); @@ -73,7 +75,7 @@ public class TestHttpServer extends HttpServerFunctionalTest { ) throws ServletException, IOException { PrintWriter out = response.getWriter(); Map params = request.getParameterMap(); - SortedSet keys = new TreeSet(params.keySet()); + SortedSet keys = new TreeSet(params.keySet()); for(String key: keys) { out.print(key); out.print(':'); @@ -99,7 +101,7 @@ public class TestHttpServer extends HttpServerFunctionalTest { HttpServletResponse response ) throws ServletException, IOException { PrintWriter out = response.getWriter(); - SortedSet sortedKeys = new TreeSet(); + SortedSet sortedKeys = new TreeSet(); Enumeration keys = request.getParameterNames(); while(keys.hasMoreElements()) { sortedKeys.add(keys.nextElement()); @@ -116,7 +118,6 @@ public class TestHttpServer extends HttpServerFunctionalTest { @SuppressWarnings("serial") public static class HtmlContentServlet extends HttpServlet { - @SuppressWarnings("unchecked") @Override public void doGet(HttpServletRequest request, HttpServletResponse response @@ -135,6 +136,8 @@ public class TestHttpServer extends HttpServerFunctionalTest { server.addServlet("echo", "/echo", EchoServlet.class); server.addServlet("echomap", "/echomap", EchoMapServlet.class); server.addServlet("htmlcontent", "/htmlcontent", HtmlContentServlet.class); + server.addJerseyResourcePackage( + JerseyResource.class.getPackage().getName(), "/jersey/*"); server.start(); baseUrl = getServerURL(server); LOG.info("HTTP server started: "+ baseUrl); @@ -405,4 +408,18 @@ public class TestHttpServer extends HttpServerFunctionalTest { values, parameterValues)); } + @SuppressWarnings("unchecked") + private static Map parse(String jsonString) { + return (Map)JSON.parse(jsonString); + } + + @Test public void testJersey() throws Exception { + LOG.info("BEGIN testJersey()"); + final String js = readOutput(new URL(baseUrl, "/jersey/foo?op=bar")); + final Map m = parse(js); + LOG.info("m=" + m); + assertEquals("foo", m.get(JerseyResource.PATH)); + assertEquals("bar", m.get(JerseyResource.OP)); + LOG.info("END testJersey()"); + } } diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/resource/JerseyResource.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/resource/JerseyResource.java new file mode 100644 index 00000000000..f1313e26ca9 --- /dev/null +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/resource/JerseyResource.java @@ -0,0 +1,64 @@ +/** + * 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.http.resource; + +import java.io.IOException; +import java.util.Map; +import java.util.TreeMap; + +import javax.ws.rs.DefaultValue; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.mortbay.util.ajax.JSON; + +/** + * A simple Jersey resource class TestHttpServer. + * The servlet simply puts the path and the op parameter in a map + * and return it in JSON format in the response. + */ +@Path("") +public class JerseyResource { + static final Log LOG = LogFactory.getLog(JerseyResource.class); + + public static final String PATH = "path"; + public static final String OP = "op"; + + @GET + @Path("{" + PATH + ":.*}") + @Produces({MediaType.APPLICATION_JSON}) + public Response get( + @PathParam(PATH) @DefaultValue("UNKNOWN_" + PATH) final String path, + @QueryParam(OP) @DefaultValue("UNKNOWN_" + OP) final String op + ) throws IOException { + LOG.info("get: " + PATH + "=" + path + ", " + OP + "=" + op); + + final Map m = new TreeMap(); + m.put(PATH, path); + m.put(OP, op); + final String js = JSON.toString(m); + return Response.ok(js).type(MediaType.APPLICATION_JSON).build(); + } +} diff --git a/hadoop-project/pom.xml b/hadoop-project/pom.xml index 5679dcbec69..bdb81f315c7 100644 --- a/hadoop-project/pom.xml +++ b/hadoop-project/pom.xml @@ -168,6 +168,28 @@ jetty-util 6.1.26 + + + asm + asm + 3.2 + + + com.sun.jersey + jersey-core + 1.8 + + + com.sun.jersey + jersey-json + 1.8 + + + com.sun.jersey + jersey-server + 1.8 + + tomcat jasper-compiler