MAPREDUCE-2999. Fix YARN webapp framework to properly filter servlet paths. Contributed by Thomas Graves.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1176469 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
6507a0bc35
commit
87b969c835
|
@ -1444,6 +1444,9 @@ Release 0.23.0 - Unreleased
|
||||||
MAPREDUCE-3067. Ensure exit-code is set correctly for containers. (Hitesh
|
MAPREDUCE-3067. Ensure exit-code is set correctly for containers. (Hitesh
|
||||||
Shah via acmurthy)
|
Shah via acmurthy)
|
||||||
|
|
||||||
|
MAPREDUCE-2999. Fix YARN webapp framework to properly filter servlet
|
||||||
|
paths. (Thomas Graves via vinodkv)
|
||||||
|
|
||||||
Release 0.22.0 - Unreleased
|
Release 0.22.0 - Unreleased
|
||||||
|
|
||||||
INCOMPATIBLE CHANGES
|
INCOMPATIBLE CHANGES
|
||||||
|
|
|
@ -84,6 +84,15 @@ public class Dispatcher extends HttpServlet {
|
||||||
prepareToExit();
|
prepareToExit();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// if they provide a redirectPath go there instead of going to
|
||||||
|
// "/" so that filters can differentiate the webapps.
|
||||||
|
if (uri.equals("/")) {
|
||||||
|
String redirectPath = webApp.getRedirectPath();
|
||||||
|
if (redirectPath != null && !redirectPath.isEmpty()) {
|
||||||
|
res.sendRedirect(redirectPath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
String method = req.getMethod();
|
String method = req.getMethod();
|
||||||
if (method.equals("OPTIONS")) {
|
if (method.equals("OPTIONS")) {
|
||||||
doOptions(req, res);
|
doOptions(req, res);
|
||||||
|
|
|
@ -26,6 +26,7 @@ import com.google.inject.Provides;
|
||||||
import com.google.inject.servlet.GuiceFilter;
|
import com.google.inject.servlet.GuiceFilter;
|
||||||
import com.google.inject.servlet.ServletModule;
|
import com.google.inject.servlet.ServletModule;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
|
@ -44,6 +45,9 @@ public abstract class WebApp extends ServletModule {
|
||||||
public enum HTTP { GET, POST, HEAD, PUT, DELETE };
|
public enum HTTP { GET, POST, HEAD, PUT, DELETE };
|
||||||
|
|
||||||
private volatile String name;
|
private volatile String name;
|
||||||
|
private volatile List<String> servePathSpecs = new ArrayList<String>();
|
||||||
|
// path to redirect to if user goes to "/"
|
||||||
|
private volatile String redirectPath;
|
||||||
private volatile Configuration conf;
|
private volatile Configuration conf;
|
||||||
private volatile HttpServer httpServer;
|
private volatile HttpServer httpServer;
|
||||||
private volatile GuiceFilter guiceFilter;
|
private volatile GuiceFilter guiceFilter;
|
||||||
|
@ -98,6 +102,22 @@ public abstract class WebApp extends ServletModule {
|
||||||
|
|
||||||
public String name() { return this.name; }
|
public String name() { return this.name; }
|
||||||
|
|
||||||
|
void addServePathSpec(String path) { this.servePathSpecs.add(path); }
|
||||||
|
|
||||||
|
public String[] getServePathSpecs() {
|
||||||
|
return this.servePathSpecs.toArray(new String[this.servePathSpecs.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a path to redirect the user to if they just go to "/". For
|
||||||
|
* instance "/" goes to "/yarn/apps". This allows the filters to
|
||||||
|
* more easily differentiate the different webapps.
|
||||||
|
* @param path the path to redirect to
|
||||||
|
*/
|
||||||
|
void setRedirectPath(String path) { this.redirectPath = path; }
|
||||||
|
|
||||||
|
public String getRedirectPath() { return this.redirectPath; }
|
||||||
|
|
||||||
void setHostClass(Class<?> cls) {
|
void setHostClass(Class<?> cls) {
|
||||||
router.setHostClass(cls);
|
router.setHostClass(cls);
|
||||||
}
|
}
|
||||||
|
@ -109,7 +129,10 @@ public abstract class WebApp extends ServletModule {
|
||||||
@Override
|
@Override
|
||||||
public void configureServlets() {
|
public void configureServlets() {
|
||||||
setup();
|
setup();
|
||||||
serve("/", "/__stop", StringHelper.join('/', name, '*')).with(Dispatcher.class);
|
serve("/", "/__stop").with(Dispatcher.class);
|
||||||
|
for (String path : this.servePathSpecs) {
|
||||||
|
serve(path).with(Dispatcher.class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -113,6 +113,14 @@ public class WebApps {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
webapp.setName(name);
|
webapp.setName(name);
|
||||||
|
String basePath = "/" + name;
|
||||||
|
webapp.setRedirectPath(basePath);
|
||||||
|
if (basePath.equals("/")) {
|
||||||
|
webapp.addServePathSpec("/*");
|
||||||
|
} else {
|
||||||
|
webapp.addServePathSpec(basePath);
|
||||||
|
webapp.addServePathSpec(basePath + "/*");
|
||||||
|
}
|
||||||
if (conf == null) {
|
if (conf == null) {
|
||||||
conf = new Configuration();
|
conf = new Configuration();
|
||||||
}
|
}
|
||||||
|
@ -142,7 +150,8 @@ public class WebApps {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HttpServer server =
|
HttpServer server =
|
||||||
new HttpServer(name, bindAddress, port, findPort, conf);
|
new HttpServer(name, bindAddress, port, findPort, conf,
|
||||||
|
webapp.getServePathSpecs());
|
||||||
server.addGlobalFilter("guice", GuiceFilter.class.getName(), null);
|
server.addGlobalFilter("guice", GuiceFilter.class.getName(), null);
|
||||||
webapp.setConf(conf);
|
webapp.setConf(conf);
|
||||||
webapp.setHttpServer(server);
|
webapp.setHttpServer(server);
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
package org.apache.hadoop.yarn.webapp;
|
package org.apache.hadoop.yarn.webapp;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.ArrayUtils;
|
||||||
import org.apache.hadoop.yarn.MockApps;
|
import org.apache.hadoop.yarn.MockApps;
|
||||||
import org.apache.hadoop.yarn.webapp.Controller;
|
import org.apache.hadoop.yarn.webapp.Controller;
|
||||||
import org.apache.hadoop.yarn.webapp.WebApp;
|
import org.apache.hadoop.yarn.webapp.WebApp;
|
||||||
|
@ -148,6 +149,32 @@ public class TestWebApp {
|
||||||
app.stop();
|
app.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test public void testServePaths() {
|
||||||
|
WebApp app = WebApps.$for("test", this).start();
|
||||||
|
assertEquals("/test", app.getRedirectPath());
|
||||||
|
String[] expectedPaths = { "/test", "/test/*" };
|
||||||
|
String[] pathSpecs = app.getServePathSpecs();
|
||||||
|
|
||||||
|
assertEquals(2, pathSpecs.length);
|
||||||
|
for(int i = 0; i < expectedPaths.length; i++) {
|
||||||
|
assertTrue(ArrayUtils.contains(pathSpecs, expectedPaths[i]));
|
||||||
|
}
|
||||||
|
app.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void testServePathsNoName() {
|
||||||
|
WebApp app = WebApps.$for("", this).start();
|
||||||
|
assertEquals("/", app.getRedirectPath());
|
||||||
|
String[] expectedPaths = { "/*" };
|
||||||
|
String[] pathSpecs = app.getServePathSpecs();
|
||||||
|
|
||||||
|
assertEquals(1, pathSpecs.length);
|
||||||
|
for(int i = 0; i < expectedPaths.length; i++) {
|
||||||
|
assertTrue(ArrayUtils.contains(pathSpecs, expectedPaths[i]));
|
||||||
|
}
|
||||||
|
app.stop();
|
||||||
|
}
|
||||||
|
|
||||||
@Test public void testDefaultRoutes() throws Exception {
|
@Test public void testDefaultRoutes() throws Exception {
|
||||||
WebApp app = WebApps.$for("test", this).start();
|
WebApp app = WebApps.$for("test", this).start();
|
||||||
String baseUrl = baseUrl(app);
|
String baseUrl = baseUrl(app);
|
||||||
|
|
|
@ -144,7 +144,7 @@ public class RMNodeImpl implements RMNode, EventHandler<RMNodeEvent> {
|
||||||
this.httpPort = httpPort;
|
this.httpPort = httpPort;
|
||||||
this.totalCapability = capability;
|
this.totalCapability = capability;
|
||||||
this.nodeAddress = hostName + ":" + cmPort;
|
this.nodeAddress = hostName + ":" + cmPort;
|
||||||
this.httpAddress = hostName + ":" + httpPort;;
|
this.httpAddress = hostName + ":" + httpPort;
|
||||||
this.node = node;
|
this.node = node;
|
||||||
this.nodeHealthStatus.setIsNodeHealthy(true);
|
this.nodeHealthStatus.setIsNodeHealthy(true);
|
||||||
this.nodeHealthStatus.setHealthReport("Healthy");
|
this.nodeHealthStatus.setHealthReport("Healthy");
|
||||||
|
|
Loading…
Reference in New Issue