diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/webapp/WebApp.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/webapp/WebApp.java index e2d3df6..5bd926a 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/webapp/WebApp.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/webapp/WebApp.java @@ -122,6 +122,10 @@ public void joinThread() { public String name() { return this.name; } + public String wsName() { + return this.wsName; + } + void addServePathSpec(String path) { this.servePathSpecs.add(path); } public String[] getServePathSpecs() { diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebApp.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebApp.java index 34fe320..32e6b60 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebApp.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebApp.java @@ -21,6 +21,8 @@ import static org.apache.hadoop.yarn.util.StringHelper.pajoin; import java.net.InetSocketAddress; +import java.util.HashMap; +import java.util.Map; import org.apache.hadoop.ha.HAServiceProtocol.HAServiceState; import org.apache.hadoop.yarn.conf.YarnConfiguration; @@ -29,11 +31,17 @@ import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager; import org.apache.hadoop.yarn.server.resourcemanager.security.QueueACLsManager; import org.apache.hadoop.yarn.server.security.ApplicationACLsManager; +import org.apache.hadoop.yarn.webapp.DefaultWrapperServlet; import org.apache.hadoop.yarn.webapp.Dispatcher; import org.apache.hadoop.yarn.webapp.GenericExceptionHandler; import org.apache.hadoop.yarn.webapp.WebApp; import org.apache.hadoop.yarn.webapp.YarnWebParams; +import com.sun.jersey.api.container.filter.GZIPContentEncodingFilter; +import com.sun.jersey.api.core.ResourceConfig; +import com.sun.jersey.core.util.FeaturesAndProperties; +import com.sun.jersey.spi.container.servlet.ServletContainer; + /** * The RM webapp */ @@ -57,6 +65,7 @@ public void setup() { bind(ApplicationACLsManager.class).toInstance( rm.getApplicationACLsManager()); bind(QueueACLsManager.class).toInstance(rm.getQueueACLsManager()); + bind(RMWebApp.class).toInstance(this); } route("/", RmController.class); route(pajoin("/nodes", NODE_STATE), RmController.class, "nodes"); @@ -81,6 +90,34 @@ public void configureServlets() { configureRSServlets(); } + @Override + protected void configureRSServlets() { + // Add in the web services filters/serves if app has them. + // Using Jersey/guice integration module. If user has web services + // they must have also bound a default one in their webapp code. + if (this.wsName() != null) { + // There seems to be an issue with the guice/jersey integration + // where we have to list the stuff we don't want it to serve + // through the guicecontainer. In this case its everything except + // the the web services api prefix. We can't just change the filter + // from /* below - that doesn't work. + String regex = "(?!/" + this.wsName() + ")"; + serveRegex(regex).with(DefaultWrapperServlet.class); + + Map params = new HashMap(); + params.put(ResourceConfig.FEATURE_IMPLICIT_VIEWABLES, "true"); + params.put(ServletContainer.FEATURE_FILTER_FORWARD_ON_404, "true"); + params.put(FeaturesAndProperties.FEATURE_XMLROOTELEMENT_PROCESSING, + "true"); + params.put(ResourceConfig.PROPERTY_CONTAINER_REQUEST_FILTERS, + GZIPContentEncodingFilter.class.getName()); + params.put(ResourceConfig.PROPERTY_CONTAINER_RESPONSE_FILTERS, + GZIPContentEncodingFilter.class.getName()); + filter("/*").through(RMWebRSFilter.class, params); + } + + } + public boolean isStandbyMode() { if (rm.getRMContext().getHAServiceState() == HAServiceState.STANDBY) { standbyMode = true; diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebRSFilter.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebRSFilter.java new file mode 100644 index 0000000..86838ef --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebRSFilter.java @@ -0,0 +1,78 @@ +/** + * 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.yarn.server.resourcemanager.webapp; + + +import java.io.IOException; +import java.io.PrintWriter; + +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.hadoop.http.HtmlQuoting; + +import com.google.inject.Injector; +import com.sun.jersey.guice.spi.container.servlet.GuiceContainer; + +@Singleton +public class RMWebRSFilter extends GuiceContainer { + private Injector injector; + + @Inject + public RMWebRSFilter(Injector injector) { + super(injector); + this.injector = injector; + } + + @Override + public void doFilter(HttpServletRequest request, + HttpServletResponse response, FilterChain chain) throws IOException, + ServletException { + response.setCharacterEncoding("UTF-8"); + String uri = HtmlQuoting.quoteHtmlChars(request.getRequestURI()); + + if (uri == null) { + uri = "/"; + } + + RMWebApp rmWebApp = injector.getInstance(RMWebApp.class); + if (rmWebApp.isStandbyMode() + && !uri.equals("/" + rmWebApp.wsName() + "/v1/cluster/info")) { + String redirectPath = rmWebApp.getRedirectPath() + uri; + if (redirectPath != null && !redirectPath.isEmpty()) { + String redirectMsg = + "This is standby RM. Redirecting to the current active RM: " + + redirectPath; + response.addHeader("Refresh", "3; url=" + redirectPath); + PrintWriter out = response.getWriter(); + out.println(redirectMsg); + return; + } + } + + super.doFilter(request, response, chain); + + } + +} +