Browse Source

YARN-3654. ContainerLogsPage web UI should not have meta-refresh. Contributed by Xuan Gong
(cherry picked from commit 6329bd00fa1f17cc9555efa496ea7607ad93e0ce)

Jian He 10 years ago
parent
commit
7c3895c8f6

+ 3 - 0
hadoop-yarn-project/CHANGES.txt

@@ -381,6 +381,9 @@ Release 2.8.0 - UNRELEASED
     YARN-2821. Fixed a problem that DistributedShell AM may hang if restarted.
     (Varun Vasudev via jianhe)
 
+    YARN-3654. ContainerLogsPage web UI should not have meta-refresh. (Xuan Gong
+    via jianhe)
+
 Release 2.7.1 - UNRELEASED
 
   INCOMPATIBLE CHANGES

+ 0 - 3
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/ContainerLogsPage.java

@@ -59,9 +59,6 @@ public class ContainerLogsPage extends NMView {
       if (redirectUrl.equals("false")) {
         set(TITLE, join("Failed redirect for ", $(CONTAINER_ID)));
         //Error getting redirect url. Fall through.
-      } else {
-        set(TITLE, join("Redirecting to log server for ", $(CONTAINER_ID)));
-        html.meta_http("refresh", "1; url=" + redirectUrl);
       }
     }
     

+ 1 - 39
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/NMController.java

@@ -20,29 +20,16 @@ package org.apache.hadoop.yarn.server.nodemanager.webapp;
 
 import static org.apache.hadoop.yarn.util.StringHelper.join;
 
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.yarn.api.records.ApplicationId;
-import org.apache.hadoop.yarn.api.records.ContainerId;
-import org.apache.hadoop.yarn.conf.YarnConfiguration;
-import org.apache.hadoop.yarn.server.nodemanager.Context;
-import org.apache.hadoop.yarn.server.nodemanager.containermanager.application.Application;
-import org.apache.hadoop.yarn.util.ConverterUtils;
 import org.apache.hadoop.yarn.webapp.Controller;
 import org.apache.hadoop.yarn.webapp.YarnWebParams;
 
 import com.google.inject.Inject;
 
 public class NMController extends Controller implements YarnWebParams {
-
-  private Context nmContext;
-  private Configuration nmConf;
   
   @Inject
-  public NMController(Configuration nmConf, RequestContext requestContext,
-      Context nmContext) {
+  public NMController(RequestContext requestContext) {
     super(requestContext);
-    this.nmContext = nmContext;
-    this.nmConf = nmConf;
   }
 
   @Override
@@ -80,31 +67,6 @@ public class NMController extends Controller implements YarnWebParams {
   }
 
   public void logs() {
-    String containerIdStr = $(CONTAINER_ID);
-    ContainerId containerId = null;
-    try {
-      containerId = ConverterUtils.toContainerId(containerIdStr);
-    } catch (IllegalArgumentException e) {
-      render(ContainerLogsPage.class);
-      return;
-    }
-    ApplicationId appId =
-        containerId.getApplicationAttemptId().getApplicationId();
-    Application app = nmContext.getApplications().get(appId);
-    if (app == null
-        && nmConf.getBoolean(YarnConfiguration.LOG_AGGREGATION_ENABLED,
-            YarnConfiguration.DEFAULT_LOG_AGGREGATION_ENABLED)) {
-      String logServerUrl = nmConf.get(YarnConfiguration.YARN_LOG_SERVER_URL);
-      String redirectUrl = null;
-      if (logServerUrl == null || logServerUrl.isEmpty()) {
-        redirectUrl = "false";
-      } else {
-        redirectUrl =
-            url(logServerUrl, nmContext.getNodeId().toString(), containerIdStr,
-                containerIdStr, $(APP_OWNER));
-      }
-      set(ContainerLogsPage.REDIRECT_URL, redirectUrl);
-    }
     render(ContainerLogsPage.class);
   }
 }

+ 118 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/NMWebAppFilter.java

@@ -0,0 +1,118 @@
+/**
+ * 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.nodemanager.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.conf.Configuration;
+import org.apache.hadoop.http.HtmlQuoting;
+import org.apache.hadoop.yarn.api.records.ApplicationId;
+import org.apache.hadoop.yarn.api.records.ContainerId;
+import org.apache.hadoop.yarn.conf.YarnConfiguration;
+import org.apache.hadoop.yarn.server.nodemanager.Context;
+import org.apache.hadoop.yarn.server.nodemanager.containermanager.application.Application;
+import org.apache.hadoop.yarn.webapp.Controller.RequestContext;
+import com.google.inject.Injector;
+import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;
+
+@Singleton
+public class NMWebAppFilter extends GuiceContainer{
+
+  private Injector injector;
+  private Context nmContext;
+
+  private static final long serialVersionUID = 1L;
+
+  @Inject
+  public NMWebAppFilter(Injector injector, Context nmContext) {
+    super(injector);
+    this.injector = injector;
+    this.nmContext = nmContext;
+  }
+
+  @Override
+  public void doFilter(HttpServletRequest request,
+      HttpServletResponse response, FilterChain chain) throws IOException,
+      ServletException {
+    String uri = HtmlQuoting.quoteHtmlChars(request.getRequestURI());
+    String redirectPath = containerLogPageRedirectPath(uri);
+    if (redirectPath != null) {
+      String redirectMsg =
+          "Redirecting to log server" + " : " + redirectPath;
+      PrintWriter out = response.getWriter();
+      out.println(redirectMsg);
+      response.setHeader("Location", redirectPath);
+      response.setStatus(HttpServletResponse.SC_TEMPORARY_REDIRECT);
+      return;
+    }
+    super.doFilter(request, response, chain);
+  }
+
+  private String containerLogPageRedirectPath(String uri) {
+    String redirectPath = null;
+    if (!uri.contains("/ws/v1/node") && uri.contains("/containerlogs")) {
+      String[] parts = uri.split("/");
+      String containerIdStr = parts[3];
+      String appOwner = parts[4];
+      if (containerIdStr != null && !containerIdStr.isEmpty()) {
+        ContainerId containerId = null;
+        try {
+          containerId = ContainerId.fromString(containerIdStr);
+        } catch (IllegalArgumentException ex) {
+          return redirectPath;
+        }
+        ApplicationId appId =
+            containerId.getApplicationAttemptId().getApplicationId();
+        Application app = nmContext.getApplications().get(appId);
+        Configuration nmConf = nmContext.getLocalDirsHandler().getConfig();
+        if (app == null
+            && nmConf.getBoolean(YarnConfiguration.LOG_AGGREGATION_ENABLED,
+              YarnConfiguration.DEFAULT_LOG_AGGREGATION_ENABLED)) {
+          String logServerUrl =
+              nmConf.get(YarnConfiguration.YARN_LOG_SERVER_URL);
+          if (logServerUrl != null && !logServerUrl.isEmpty()) {
+            StringBuilder sb = new StringBuilder();
+            sb.append(logServerUrl);
+            sb.append("/");
+            sb.append(nmContext.getNodeId().toString());
+            sb.append("/");
+            sb.append(containerIdStr);
+            sb.append("/");
+            sb.append(containerIdStr);
+            sb.append("/");
+            sb.append(appOwner);
+            redirectPath = sb.toString();
+          } else {
+            injector.getInstance(RequestContext.class).set(
+              ContainerLogsPage.REDIRECT_URL, "false");
+          }
+        }
+      }
+    }
+    return redirectPath;
+  }
+}

+ 6 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/WebServer.java

@@ -22,7 +22,6 @@ import static org.apache.hadoop.yarn.util.StringHelper.pajoin;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.hadoop.http.HttpConfig;
 import org.apache.hadoop.service.AbstractService;
 import org.apache.hadoop.yarn.conf.YarnConfiguration;
 import org.apache.hadoop.yarn.exceptions.YarnRuntimeException;
@@ -36,6 +35,8 @@ import org.apache.hadoop.yarn.webapp.WebApps;
 import org.apache.hadoop.yarn.webapp.YarnWebParams;
 import org.apache.hadoop.yarn.webapp.util.WebAppUtils;
 
+import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;
+
 public class WebServer extends AbstractService {
 
   private static final Log LOG = LogFactory.getLog(WebServer.class);
@@ -129,5 +130,9 @@ public class WebServer extends AbstractService {
       route("/errors-and-warnings", NMController.class, "errorsAndWarnings");
     }
 
+    @Override
+    protected Class<? extends GuiceContainer> getWebAppFilterClass() {
+      return NMWebAppFilter.class;
+    }
   }
 }