YARN-4990. Re-direction of a particular log file within in a container in NM UI 
does not redirect properly. Contributed by Xuan Gong.


Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo
Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/736f54b7
Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/736f54b7
Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/736f54b7

Branch: refs/heads/YARN-5734
Commit: 736f54b727c3f0ecc8fb9a594f2281c240c89cb8
Parents: f6e80ac
Author: Junping Du <junping...@apache.org>
Authored: Wed Dec 21 14:14:42 2016 -0800
Committer: Junping Du <junping...@apache.org>
Committed: Wed Dec 21 14:14:42 2016 -0800

----------------------------------------------------------------------
 .../nodemanager/webapp/NMWebAppFilter.java      |   8 +
 .../nodemanager/webapp/TestNMWebFilter.java     | 176 +++++++++++++++++++
 2 files changed, 184 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hadoop/blob/736f54b7/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/NMWebAppFilter.java
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/NMWebAppFilter.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/NMWebAppFilter.java
index d2f5849..7b4c2a9 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/NMWebAppFilter.java
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/NMWebAppFilter.java
@@ -79,6 +79,10 @@ public class NMWebAppFilter extends GuiceContainer{
       String[] parts = uri.split("/");
       String containerIdStr = parts[3];
       String appOwner = parts[4];
+      String logType = null;
+      if (parts.length > 5) {
+        logType = parts[5];
+      }
       if (containerIdStr != null && !containerIdStr.isEmpty()) {
         ContainerId containerId = null;
         try {
@@ -106,6 +110,10 @@ public class NMWebAppFilter extends GuiceContainer{
             sb.append(containerIdStr);
             sb.append("/");
             sb.append(appOwner);
+            if (logType != null && !logType.isEmpty()) {
+              sb.append("/");
+              sb.append(logType);
+            }
             redirectPath =
                 WebAppUtils.appendQueryParams(request, sb.toString());
           } else {

http://git-wip-us.apache.org/repos/asf/hadoop/blob/736f54b7/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/webapp/TestNMWebFilter.java
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/webapp/TestNMWebFilter.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/webapp/TestNMWebFilter.java
new file mode 100644
index 0000000..5dbe244
--- /dev/null
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/webapp/TestNMWebFilter.java
@@ -0,0 +1,176 @@
+/**
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import com.google.inject.Injector;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.HttpURLConnection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
+import org.apache.hadoop.yarn.api.records.ApplicationId;
+import org.apache.hadoop.yarn.api.records.ContainerId;
+import org.apache.hadoop.yarn.api.records.NodeId;
+import org.apache.hadoop.yarn.conf.YarnConfiguration;
+import org.apache.hadoop.yarn.server.nodemanager.LocalDirsHandlerService;
+import org.apache.hadoop.yarn.server.nodemanager.NodeManager.NMContext;
+import 
org.apache.hadoop.yarn.server.nodemanager.containermanager.application.Application;
+import org.glassfish.grizzly.servlet.HttpServletResponseImpl;
+import org.junit.Test;
+
+/**
+ * Basic sanity Tests for NMWebFilter.
+ *
+ */
+public class TestNMWebFilter {
+
+  private static final String LOG_SERVER_URI = "log-server:1999/logs";
+  private static final String USER = "testUser";
+
+  @Test(timeout = 5000)
+  public void testRedirection() throws Exception {
+    ApplicationId appId = ApplicationId.newInstance(
+        System.currentTimeMillis(), 1);
+    ApplicationAttemptId attemptId = ApplicationAttemptId.newInstance(
+        appId, 1);
+    ContainerId containerId = ContainerId.newContainerId(attemptId, 1);
+
+    NMContext mockNMContext = mock(NMContext.class);
+    ConcurrentMap<ApplicationId, Application> applications
+        = new ConcurrentHashMap<>();
+    when(mockNMContext.getApplications()).thenReturn(applications);
+    LocalDirsHandlerService mockLocalDirsHandlerService = mock(
+        LocalDirsHandlerService.class);
+    Configuration conf = new Configuration();
+    conf.setBoolean(YarnConfiguration.LOG_AGGREGATION_ENABLED, true);
+    conf.set(YarnConfiguration.YARN_LOG_SERVER_URL,
+        "http://"; + LOG_SERVER_URI);
+    when(mockLocalDirsHandlerService.getConfig()).thenReturn(conf);
+    when(mockNMContext.getLocalDirsHandler()).thenReturn(
+        mockLocalDirsHandlerService);
+    NodeId nodeId = NodeId.newInstance("testNM", 9999);
+    when(mockNMContext.getNodeId()).thenReturn(nodeId);
+
+    Injector mockInjector = mock(Injector.class);
+    NMWebAppFilter testFilter = new NMWebAppFilter(
+        mockInjector, mockNMContext);
+
+    HttpServletResponseForTest response = new HttpServletResponseForTest();
+    // dummy filter
+    FilterChain chain = new FilterChain() {
+      @Override
+      public void doFilter(ServletRequest servletRequest,
+          ServletResponse servletResponse) throws IOException,
+          ServletException {
+        // Do Nothing
+      }
+    };
+
+    String uri = "testNM:8042/node/containerlogs/"
+            + containerId.toString() + "/" + USER;
+    HttpServletRequest request = mock(HttpServletRequest.class);
+    when(request.getRequestURI()).thenReturn(uri);
+    testFilter.doFilter(request, response, chain);
+    assertEquals(HttpServletResponse.SC_TEMPORARY_REDIRECT, response.status);
+    String redirect = response.getHeader("Location");
+    assertTrue(redirect.contains(LOG_SERVER_URI));
+    assertTrue(redirect.contains(nodeId.toString()));
+    assertTrue(redirect.contains(containerId.toString()));
+    assertTrue(redirect.contains(USER));
+
+    String logType = "syslog";
+    uri = "testNM:8042/node/containerlogs/" + containerId.toString()
+        + "/" + USER + "/" + logType + "/?start=10";
+    HttpServletRequest request2 = mock(HttpServletRequest.class);
+    when(request2.getRequestURI()).thenReturn(uri);
+    when(request2.getQueryString()).thenReturn("start=10");
+    testFilter.doFilter(request2, response, chain);
+    assertEquals(HttpServletResponse.SC_TEMPORARY_REDIRECT, response.status);
+    redirect = response.getHeader("Location");
+    assertTrue(redirect.contains(LOG_SERVER_URI));
+    assertTrue(redirect.contains(nodeId.toString()));
+    assertTrue(redirect.contains(containerId.toString()));
+    assertTrue(redirect.contains(USER));
+    assertTrue(redirect.contains(logType));
+    assertTrue(redirect.contains("start=10"));
+  }
+
+  private class HttpServletResponseForTest extends HttpServletResponseImpl {
+    String redirectLocation = "";
+    int status;
+    private String contentType;
+    private final Map<String, String> headers = new HashMap<>(1);
+    private StringWriter body;
+
+    public String getRedirect() {
+      return redirectLocation;
+    }
+
+    @Override
+    public void sendRedirect(String location) throws IOException {
+      redirectLocation = location;
+    }
+
+    @Override
+    public String encodeRedirectURL(String url) {
+      return url;
+    }
+
+    @Override
+    public void setStatus(int status) {
+      this.status = status;
+    }
+
+    @Override
+    public void setContentType(String type) {
+      this.contentType = type;
+    }
+
+    @Override
+    public void setHeader(String name, String value) {
+      headers.put(name, value);
+    }
+
+    public String getHeader(String name) {
+      return headers.get(name);
+    }
+
+    @Override
+    public PrintWriter getWriter() throws IOException {
+      body = new StringWriter();
+      return new PrintWriter(body);
+    }
+  }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: common-commits-unsubscr...@hadoop.apache.org
For additional commands, e-mail: common-commits-h...@hadoop.apache.org

Reply via email to