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
|
||||
Shah via acmurthy)
|
||||
|
||||
MAPREDUCE-2999. Fix YARN webapp framework to properly filter servlet
|
||||
paths. (Thomas Graves via vinodkv)
|
||||
|
||||
Release 0.22.0 - Unreleased
|
||||
|
||||
INCOMPATIBLE CHANGES
|
||||
|
|
|
@ -84,6 +84,15 @@ public class Dispatcher extends HttpServlet {
|
|||
prepareToExit();
|
||||
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();
|
||||
if (method.equals("OPTIONS")) {
|
||||
doOptions(req, res);
|
||||
|
|
|
@ -26,6 +26,7 @@ import com.google.inject.Provides;
|
|||
import com.google.inject.servlet.GuiceFilter;
|
||||
import com.google.inject.servlet.ServletModule;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.hadoop.conf.Configuration;
|
||||
|
@ -44,6 +45,9 @@ public abstract class WebApp extends ServletModule {
|
|||
public enum HTTP { GET, POST, HEAD, PUT, DELETE };
|
||||
|
||||
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 HttpServer httpServer;
|
||||
private volatile GuiceFilter guiceFilter;
|
||||
|
@ -98,6 +102,22 @@ public abstract class WebApp extends ServletModule {
|
|||
|
||||
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) {
|
||||
router.setHostClass(cls);
|
||||
}
|
||||
|
@ -109,7 +129,10 @@ public abstract class WebApp extends ServletModule {
|
|||
@Override
|
||||
public void configureServlets() {
|
||||
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);
|
||||
String basePath = "/" + name;
|
||||
webapp.setRedirectPath(basePath);
|
||||
if (basePath.equals("/")) {
|
||||
webapp.addServePathSpec("/*");
|
||||
} else {
|
||||
webapp.addServePathSpec(basePath);
|
||||
webapp.addServePathSpec(basePath + "/*");
|
||||
}
|
||||
if (conf == null) {
|
||||
conf = new Configuration();
|
||||
}
|
||||
|
@ -142,7 +150,8 @@ public class WebApps {
|
|||
}
|
||||
}
|
||||
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);
|
||||
webapp.setConf(conf);
|
||||
webapp.setHttpServer(server);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
package org.apache.hadoop.yarn.webapp;
|
||||
|
||||
import org.apache.commons.lang.ArrayUtils;
|
||||
import org.apache.hadoop.yarn.MockApps;
|
||||
import org.apache.hadoop.yarn.webapp.Controller;
|
||||
import org.apache.hadoop.yarn.webapp.WebApp;
|
||||
|
@ -148,6 +149,32 @@ public class TestWebApp {
|
|||
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 {
|
||||
WebApp app = WebApps.$for("test", this).start();
|
||||
String baseUrl = baseUrl(app);
|
||||
|
|
|
@ -144,7 +144,7 @@ public class RMNodeImpl implements RMNode, EventHandler<RMNodeEvent> {
|
|||
this.httpPort = httpPort;
|
||||
this.totalCapability = capability;
|
||||
this.nodeAddress = hostName + ":" + cmPort;
|
||||
this.httpAddress = hostName + ":" + httpPort;;
|
||||
this.httpAddress = hostName + ":" + httpPort;
|
||||
this.node = node;
|
||||
this.nodeHealthStatus.setIsNodeHealthy(true);
|
||||
this.nodeHealthStatus.setHealthReport("Healthy");
|
||||
|
|
Loading…
Reference in New Issue