浏览代码

YARN-3239. WebAppProxy does not support a final tracking url which has query fragments and params. Contributed by Jian He
(cherry picked from commit 1a68fc43464d3948418f453bb2f80df7ce773097)

(cherry picked from commit 257087417e424e628f090b6b648ccb3b9c880250)
(cherry picked from commit 49468108c203bf093acdc93c1798d90c480c3a17)

Jason Lowe 10 年之前
父节点
当前提交
a4b8897b30

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

@@ -85,6 +85,9 @@ Release 2.6.1 - UNRELEASED
     YARN-3238. Connection timeouts to nodemanagers are retried at
     multiple levels (Jason Lowe via xgong)
 
+    YARN-3239. WebAppProxy does not support a final tracking url which has
+    query fragments and params (Jian He via jlowe)
+
 Release 2.6.0 - 2014-11-18
 
   INCOMPATIBLE CHANGES

+ 16 - 7
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-web-proxy/src/main/java/org/apache/hadoop/yarn/server/webproxy/WebAppProxyServlet.java

@@ -36,6 +36,7 @@ import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.UriBuilder;
 
 import org.apache.commons.httpclient.Header;
 import org.apache.commons.httpclient.HostConfiguration;
@@ -58,6 +59,8 @@ import org.apache.hadoop.yarn.util.TrackingUriPlugin;
 import org.apache.hadoop.yarn.webapp.MimeType;
 import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
 import org.apache.hadoop.yarn.webapp.util.WebAppUtils;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.utils.URLEncodedUtils;
 
 public class WebAppProxyServlet extends HttpServlet {
   private static final long serialVersionUID = 1L;
@@ -322,13 +325,19 @@ public class WebAppProxyServlet extends HttpServlet {
             req.getQueryString(), true), runningUser, id);
         return;
       }
-      URI toFetch = new URI(trackingUri.getScheme(), 
-          trackingUri.getAuthority(),
-          StringHelper.ujoin(trackingUri.getPath(), rest), req.getQueryString(),
-          null);
-      
-      LOG.info(req.getRemoteUser()+" is accessing unchecked "+toFetch+
-          " which is the app master GUI of "+appId+" owned by "+runningUser);
+
+      // Append the user-provided path and query parameter to the original
+      // tracking url.
+      List<NameValuePair> queryPairs =
+          URLEncodedUtils.parse(req.getQueryString(), null);
+      UriBuilder builder = UriBuilder.fromUri(trackingUri);
+      for (NameValuePair pair : queryPairs) {
+        builder.queryParam(pair.getName(), pair.getValue());
+      }
+      URI toFetch = builder.path(rest).build();
+
+      LOG.info(remoteUser+" is accessing unchecked "+toFetch+
+        " which is the app master GUI of "+appId+" owned by "+runningUser);
 
       switch(applicationReport.getYarnApplicationState()) {
       case KILLED:

+ 22 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-web-proxy/src/test/java/org/apache/hadoop/yarn/server/webproxy/TestWebAppProxyServlet.java

@@ -84,7 +84,7 @@ public class TestWebAppProxyServlet {
     Context context = new Context();
     context.setContextPath("/foo");
     server.setHandler(context);
-    context.addServlet(new ServletHolder(TestServlet.class), "/bar/");
+    context.addServlet(new ServletHolder(TestServlet.class), "/bar");
     server.getConnectors()[0].setHost("localhost");
     server.start();
     originalPort = server.getConnectors()[0].getLocalPort();
@@ -183,6 +183,19 @@ public class TestWebAppProxyServlet {
       proxyConn.setRequestProperty("Cookie", "checked_application_0_0000=true");
       proxyConn.connect();
       assertEquals(HttpURLConnection.HTTP_OK, proxyConn.getResponseCode());
+
+      // test user-provided path and query parameter can be appended to the
+      // original tracking url
+      appReportFetcher.answer = 5;
+      URL clientUrl = new URL("http://localhost:" + proxyPort
+        + "/proxy/application_00_0/test/tez?x=y&h=p");
+      proxyConn = (HttpURLConnection) clientUrl.openConnection();
+      proxyConn.connect();
+      LOG.info("" + proxyConn.getURL());
+      LOG.info("ProxyConn.getHeaderField(): " +  proxyConn.getHeaderField("Location"));
+      assertEquals("http://localhost:" + originalPort
+          + "/foo/bar/test/tez?a=b&x=y&h=p#main", proxyConn.getURL().toString());
+
     } finally {
       proxy.close();
     }
@@ -352,6 +365,14 @@ public class TestWebAppProxyServlet {
         return result;
       } else if (answer == 4) {
         throw new ApplicationNotFoundException("Application is not found");
+      } else if (answer == 5) {
+        // test user-provided path and query parameter can be appended to the
+        // original tracking url
+        ApplicationReport result = getDefaultApplicationReport(appId);
+        result.setOriginalTrackingUrl("localhost:" + originalPort
+            + "/foo/bar?a=b#main");
+        result.setYarnApplicationState(YarnApplicationState.FINISHED);
+        return result;
       }
       return null;
     }