HADOOP-7594. Support HTTP REST in HttpServer.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1163858 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
2b016dac82
commit
19523b6a2b
|
@ -350,6 +350,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
|
||||
|
|
|
@ -92,6 +92,28 @@
|
|||
<artifactId>jetty-util</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>asm</groupId>
|
||||
<artifactId>asm</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey</groupId>
|
||||
<artifactId>jersey-core</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey</groupId>
|
||||
<artifactId>jersey-json</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey</groupId>
|
||||
<artifactId>jersey-server</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>tomcat</groupId>
|
||||
<artifactId>jasper-compiler</artifactId>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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<String, String[]> params = request.getParameterMap();
|
||||
SortedSet<String> keys = new TreeSet(params.keySet());
|
||||
SortedSet<String> keys = new TreeSet<String>(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<String> sortedKeys = new TreeSet();
|
||||
SortedSet<String> sortedKeys = new TreeSet<String>();
|
||||
Enumeration<String> 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<String, Object> parse(String jsonString) {
|
||||
return (Map<String, Object>)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<String, Object> m = parse(js);
|
||||
LOG.info("m=" + m);
|
||||
assertEquals("foo", m.get(JerseyResource.PATH));
|
||||
assertEquals("bar", m.get(JerseyResource.OP));
|
||||
LOG.info("END testJersey()");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<String, Object> m = new TreeMap<String, Object>();
|
||||
m.put(PATH, path);
|
||||
m.put(OP, op);
|
||||
final String js = JSON.toString(m);
|
||||
return Response.ok(js).type(MediaType.APPLICATION_JSON).build();
|
||||
}
|
||||
}
|
|
@ -168,6 +168,28 @@
|
|||
<artifactId>jetty-util</artifactId>
|
||||
<version>6.1.26</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>asm</groupId>
|
||||
<artifactId>asm</artifactId>
|
||||
<version>3.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey</groupId>
|
||||
<artifactId>jersey-core</artifactId>
|
||||
<version>1.8</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey</groupId>
|
||||
<artifactId>jersey-json</artifactId>
|
||||
<version>1.8</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey</groupId>
|
||||
<artifactId>jersey-server</artifactId>
|
||||
<version>1.8</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>tomcat</groupId>
|
||||
<artifactId>jasper-compiler</artifactId>
|
||||
|
|
Loading…
Reference in New Issue