YARN-4820. ResourceManager web redirects in HA mode drops query parameters. Contributed by Varun Vasudev.

(cherry picked from commit 19b645c938)
This commit is contained in:
Junping Du 2016-03-23 19:34:30 -07:00
parent daf24eeb6b
commit c722262c75
2 changed files with 35 additions and 12 deletions

View File

@ -273,8 +273,8 @@ public class TestRMFailover extends ClientBaseWithFixes {
redirectURL = getRedirectURL(rm2Url + "/metrics"); redirectURL = getRedirectURL(rm2Url + "/metrics");
assertEquals(redirectURL,rm1Url + "/metrics"); assertEquals(redirectURL,rm1Url + "/metrics");
redirectURL = getRedirectURL(rm2Url + "/jmx"); redirectURL = getRedirectURL(rm2Url + "/jmx?param1=value1+x&param2=y");
assertEquals(redirectURL,rm1Url + "/jmx"); assertEquals(rm1Url + "/jmx?param1=value1+x&param2=y", redirectURL);
// standby RM links /conf, /stacks, /logLevel, /static, /logs, // standby RM links /conf, /stacks, /logLevel, /static, /logs,
// /cluster/cluster as well as webService // /cluster/cluster as well as webService
@ -327,8 +327,9 @@ public class TestRMFailover extends ClientBaseWithFixes {
// do not automatically follow the redirection // do not automatically follow the redirection
// otherwise we get too many redirections exception // otherwise we get too many redirections exception
conn.setInstanceFollowRedirects(false); conn.setInstanceFollowRedirects(false);
if(conn.getResponseCode() == HttpServletResponse.SC_TEMPORARY_REDIRECT) if(conn.getResponseCode() == HttpServletResponse.SC_TEMPORARY_REDIRECT) {
redirectUrl = conn.getHeaderField("Location"); redirectUrl = conn.getHeaderField("Location");
}
} catch (Exception e) { } catch (Exception e) {
// throw new RuntimeException(e); // throw new RuntimeException(e);
} }

View File

@ -25,6 +25,8 @@ import java.io.PrintWriter;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
@ -48,6 +50,8 @@ import org.apache.hadoop.yarn.util.Apps;
import org.apache.hadoop.yarn.util.ConverterUtils; import org.apache.hadoop.yarn.util.ConverterUtils;
import org.apache.hadoop.yarn.webapp.YarnWebParams; import org.apache.hadoop.yarn.webapp.YarnWebParams;
import org.apache.hadoop.yarn.webapp.util.WebAppUtils; import org.apache.hadoop.yarn.webapp.util.WebAppUtils;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -106,22 +110,40 @@ public class RMWebAppFilter extends GuiceContainer {
HttpServletResponse response, FilterChain chain) throws IOException, HttpServletResponse response, FilterChain chain) throws IOException,
ServletException { ServletException {
response.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8");
String uri = HtmlQuoting.quoteHtmlChars(request.getRequestURI()); String htmlEscapedUri = HtmlQuoting.quoteHtmlChars(request.getRequestURI());
if (uri == null) { if (htmlEscapedUri == null) {
uri = "/"; htmlEscapedUri = "/";
} }
String uriWithQueryString = htmlEscapedUri;
String htmlEscapedUriWithQueryString = htmlEscapedUri;
String queryString = request.getQueryString();
if (queryString != null && !queryString.isEmpty()) {
String reqEncoding = request.getCharacterEncoding();
if (reqEncoding == null || reqEncoding.isEmpty()) {
reqEncoding = "ISO-8859-1";
}
Charset encoding = Charset.forName(reqEncoding);
List<NameValuePair> params = URLEncodedUtils.parse(queryString, encoding);
String urlEncodedQueryString = URLEncodedUtils.format(params, encoding);
uriWithQueryString += "?" + urlEncodedQueryString;
htmlEscapedUriWithQueryString = HtmlQuoting.quoteHtmlChars(
request.getRequestURI() + "?" + urlEncodedQueryString);
}
RMWebApp rmWebApp = injector.getInstance(RMWebApp.class); RMWebApp rmWebApp = injector.getInstance(RMWebApp.class);
rmWebApp.checkIfStandbyRM(); rmWebApp.checkIfStandbyRM();
if (rmWebApp.isStandby() if (rmWebApp.isStandby()
&& shouldRedirect(rmWebApp, uri)) { && shouldRedirect(rmWebApp, htmlEscapedUri)) {
String redirectPath = rmWebApp.getRedirectPath(); String redirectPath = rmWebApp.getRedirectPath();
if (redirectPath != null && !redirectPath.isEmpty()) { if (redirectPath != null && !redirectPath.isEmpty()) {
redirectPath += uri; redirectPath += uriWithQueryString;
String redirectMsg = String redirectMsg = "This is standby RM. The redirect url is: "
"This is standby RM. The redirect url is: " + redirectPath; + htmlEscapedUriWithQueryString;
PrintWriter out = response.getWriter(); PrintWriter out = response.getWriter();
out.println(redirectMsg); out.println(redirectMsg);
response.setHeader("Location", redirectPath); response.setHeader("Location", redirectPath);
@ -142,7 +164,7 @@ public class RMWebAppFilter extends GuiceContainer {
int next = calculateExponentialTime(retryInterval); int next = calculateExponentialTime(retryInterval);
String redirectUrl = String redirectUrl =
appendOrReplaceParamter(path + uri, appendOrReplaceParamter(path + uriWithQueryString,
YarnWebParams.NEXT_REFRESH_INTERVAL + "=" + (retryInterval + 1)); YarnWebParams.NEXT_REFRESH_INTERVAL + "=" + (retryInterval + 1));
if (redirectUrl == null || next > MAX_SLEEP_TIME) { if (redirectUrl == null || next > MAX_SLEEP_TIME) {
doRetry = false; doRetry = false;
@ -161,7 +183,7 @@ public class RMWebAppFilter extends GuiceContainer {
} }
return; return;
} else if (ahsEnabled) { } else if (ahsEnabled) {
String ahsRedirectUrl = ahsRedirectPath(uri, rmWebApp); String ahsRedirectUrl = ahsRedirectPath(uriWithQueryString, rmWebApp);
if(ahsRedirectUrl != null) { if(ahsRedirectUrl != null) {
response.setHeader("Location", ahsRedirectUrl); response.setHeader("Location", ahsRedirectUrl);
response.setStatus(HttpServletResponse.SC_TEMPORARY_REDIRECT); response.setStatus(HttpServletResponse.SC_TEMPORARY_REDIRECT);