|
@@ -21,23 +21,45 @@ package org.apache.hadoop.mapreduce.v2.app.webapp;
|
|
|
import static org.apache.hadoop.mapreduce.v2.app.webapp.AMParams.APP_ID;
|
|
|
import static org.junit.Assert.assertEquals;
|
|
|
|
|
|
+import java.io.ByteArrayOutputStream;
|
|
|
+import java.io.InputStream;
|
|
|
+import java.net.HttpURLConnection;
|
|
|
+import java.net.URL;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.Map;
|
|
|
import java.util.Map.Entry;
|
|
|
|
|
|
+import javax.net.ssl.SSLException;
|
|
|
+
|
|
|
+import junit.framework.Assert;
|
|
|
+
|
|
|
+import org.apache.commons.httpclient.HttpStatus;
|
|
|
+import org.apache.hadoop.conf.Configuration;
|
|
|
+import org.apache.hadoop.http.HttpConfig.Policy;
|
|
|
+import org.apache.hadoop.io.IOUtils;
|
|
|
import org.apache.hadoop.mapreduce.v2.api.records.JobId;
|
|
|
+import org.apache.hadoop.mapreduce.v2.api.records.JobState;
|
|
|
import org.apache.hadoop.mapreduce.v2.api.records.TaskId;
|
|
|
import org.apache.hadoop.mapreduce.v2.app.AppContext;
|
|
|
+import org.apache.hadoop.mapreduce.v2.app.MRApp;
|
|
|
import org.apache.hadoop.mapreduce.v2.app.MockAppContext;
|
|
|
import org.apache.hadoop.mapreduce.v2.app.MockJobs;
|
|
|
+import org.apache.hadoop.mapreduce.v2.app.client.ClientService;
|
|
|
+import org.apache.hadoop.mapreduce.v2.app.client.MRClientService;
|
|
|
import org.apache.hadoop.mapreduce.v2.app.job.Job;
|
|
|
import org.apache.hadoop.mapreduce.v2.app.job.Task;
|
|
|
import org.apache.hadoop.mapreduce.v2.app.job.TaskAttempt;
|
|
|
import org.apache.hadoop.mapreduce.v2.util.MRApps;
|
|
|
+import org.apache.hadoop.net.NetUtils;
|
|
|
+import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
|
|
+import org.apache.hadoop.yarn.server.webproxy.ProxyUriUtils;
|
|
|
+import org.apache.hadoop.yarn.server.webproxy.amfilter.AmFilterInitializer;
|
|
|
import org.apache.hadoop.yarn.webapp.WebApps;
|
|
|
import org.apache.hadoop.yarn.webapp.test.WebAppTests;
|
|
|
+import org.apache.hadoop.yarn.webapp.util.WebAppUtils;
|
|
|
import org.junit.Test;
|
|
|
|
|
|
+import com.google.common.net.HttpHeaders;
|
|
|
import com.google.inject.Injector;
|
|
|
|
|
|
public class TestAMWebApp {
|
|
@@ -147,7 +169,96 @@ public class TestAMWebApp {
|
|
|
WebAppTests.testPage(SingleCounterPage.class, AppContext.class,
|
|
|
appContext, params);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testMRWebAppSSLDisabled() throws Exception {
|
|
|
+ MRApp app = new MRApp(2, 2, true, this.getClass().getName(), true) {
|
|
|
+ @Override
|
|
|
+ protected ClientService createClientService(AppContext context) {
|
|
|
+ return new MRClientService(context);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ Configuration conf = new Configuration();
|
|
|
+ // MR is explicitly disabling SSL, even though setting as HTTPS_ONLY
|
|
|
+ conf.set(YarnConfiguration.YARN_HTTP_POLICY_KEY, Policy.HTTPS_ONLY.name());
|
|
|
+ Job job = app.submit(conf);
|
|
|
+
|
|
|
+ String hostPort =
|
|
|
+ NetUtils.getHostPortString(((MRClientService) app.getClientService())
|
|
|
+ .getWebApp().getListenerAddress());
|
|
|
+ // http:// should be accessible
|
|
|
+ URL httpUrl = new URL("http://" + hostPort);
|
|
|
+ HttpURLConnection conn = (HttpURLConnection) httpUrl.openConnection();
|
|
|
+ InputStream in = conn.getInputStream();
|
|
|
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
|
+ IOUtils.copyBytes(in, out, 1024);
|
|
|
+ Assert.assertTrue(out.toString().contains("MapReduce Application"));
|
|
|
+
|
|
|
+ // https:// is not accessible.
|
|
|
+ URL httpsUrl = new URL("https://" + hostPort);
|
|
|
+ try {
|
|
|
+ HttpURLConnection httpsConn =
|
|
|
+ (HttpURLConnection) httpsUrl.openConnection();
|
|
|
+ httpsConn.getInputStream();
|
|
|
+ Assert.fail("https:// is not accessible, expected to fail");
|
|
|
+ } catch (Exception e) {
|
|
|
+ Assert.assertTrue(e instanceof SSLException);
|
|
|
+ }
|
|
|
+
|
|
|
+ app.waitForState(job, JobState.SUCCEEDED);
|
|
|
+ app.verifyCompleted();
|
|
|
+ }
|
|
|
+
|
|
|
+ static String webProxyBase = null;
|
|
|
+ public static class TestAMFilterInitializer extends AmFilterInitializer {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected String getApplicationWebProxyBase() {
|
|
|
+ return webProxyBase;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testMRWebAppRedirection() throws Exception {
|
|
|
+
|
|
|
+ String[] schemePrefix =
|
|
|
+ { WebAppUtils.HTTP_PREFIX, WebAppUtils.HTTPS_PREFIX };
|
|
|
+ for (String scheme : schemePrefix) {
|
|
|
+ MRApp app = new MRApp(2, 2, true, this.getClass().getName(), true) {
|
|
|
+ @Override
|
|
|
+ protected ClientService createClientService(AppContext context) {
|
|
|
+ return new MRClientService(context);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ Configuration conf = new Configuration();
|
|
|
+ conf.set(YarnConfiguration.PROXY_ADDRESS, "9.9.9.9");
|
|
|
+ conf.set(YarnConfiguration.YARN_HTTP_POLICY_KEY, scheme
|
|
|
+ .equals(WebAppUtils.HTTPS_PREFIX) ? Policy.HTTPS_ONLY.name()
|
|
|
+ : Policy.HTTP_ONLY.name());
|
|
|
+ webProxyBase = "/proxy/" + app.getAppID();
|
|
|
+ conf.set("hadoop.http.filter.initializers",
|
|
|
+ TestAMFilterInitializer.class.getName());
|
|
|
+ Job job = app.submit(conf);
|
|
|
+ String hostPort =
|
|
|
+ NetUtils.getHostPortString(((MRClientService) app.getClientService())
|
|
|
+ .getWebApp().getListenerAddress());
|
|
|
+ URL httpUrl = new URL("http://" + hostPort + "/mapreduce");
|
|
|
+
|
|
|
+ HttpURLConnection conn = (HttpURLConnection) httpUrl.openConnection();
|
|
|
+ conn.setInstanceFollowRedirects(false);
|
|
|
+ conn.connect();
|
|
|
+ String expectedURL =
|
|
|
+ scheme + conf.get(YarnConfiguration.PROXY_ADDRESS)
|
|
|
+ + ProxyUriUtils.getPath(app.getAppID(), "/mapreduce");
|
|
|
+ Assert.assertEquals(expectedURL,
|
|
|
+ conn.getHeaderField(HttpHeaders.LOCATION));
|
|
|
+ Assert.assertEquals(HttpStatus.SC_MOVED_TEMPORARILY,
|
|
|
+ conn.getResponseCode());
|
|
|
+ app.waitForState(job, JobState.SUCCEEDED);
|
|
|
+ app.verifyCompleted();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
public static void main(String[] args) {
|
|
|
WebApps.$for("yarn", AppContext.class, new MockAppContext(0, 8, 88, 4)).
|
|
|
at(58888).inDevMode().start(new AMWebApp()).joinThread();
|