diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/ClientRMProxy.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/ClientRMProxy.java deleted file mode 100644 index 06bbc35..0000000 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/ClientRMProxy.java +++ /dev/null @@ -1,123 +0,0 @@ -/** -* 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.client; - -import java.io.IOException; -import java.net.InetSocketAddress; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.hadoop.classification.InterfaceAudience; -import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.security.SecurityUtil; -import org.apache.hadoop.security.UserGroupInformation; -import org.apache.hadoop.security.token.Token; -import org.apache.hadoop.security.token.TokenIdentifier; -import org.apache.hadoop.yarn.api.ApplicationClientProtocol; -import org.apache.hadoop.yarn.api.ApplicationMasterProtocol; -import org.apache.hadoop.yarn.conf.YarnConfiguration; -import org.apache.hadoop.yarn.security.AMRMTokenIdentifier; -import org.apache.hadoop.yarn.server.api.ResourceManagerAdministrationProtocol; - -import com.google.common.base.Preconditions; - -public class ClientRMProxy extends RMProxy { - private static final Log LOG = LogFactory.getLog(ClientRMProxy.class); - - private interface ClientRMProtocols extends ApplicationClientProtocol, - ApplicationMasterProtocol, ResourceManagerAdministrationProtocol { - // Add nothing - } - - static { - INSTANCE = new ClientRMProxy(); - } - - private ClientRMProxy(){ - super(); - } - - /** - * Create a proxy to the ResourceManager for the specified protocol. - * @param configuration Configuration with all the required information. - * @param protocol Client protocol for which proxy is being requested. - * @param Type of proxy. - * @return Proxy to the ResourceManager for the specified client protocol. - * @throws IOException - */ - public static T createRMProxy(final Configuration configuration, - final Class protocol) throws IOException { - // This method exists only to initiate this class' static INSTANCE. TODO: - // FIX if possible - return RMProxy.createRMProxy(configuration, protocol); - } - - private static void setupTokens(InetSocketAddress resourceManagerAddress) - throws IOException { - // It is assumed for now that the only AMRMToken in AM's UGI is for this - // cluster/RM. TODO: Fix later when we have some kind of cluster-ID as - // default service-address, see YARN-986. - for (Token token : UserGroupInformation - .getCurrentUser().getTokens()) { - if (token.getKind().equals(AMRMTokenIdentifier.KIND_NAME)) { - // This token needs to be directly provided to the AMs, so set the - // appropriate service-name. We'll need more infrastructure when we - // need to set it in HA case. - SecurityUtil.setTokenService(token, resourceManagerAddress); - } - } - } - - @InterfaceAudience.Private - @Override - protected InetSocketAddress getRMAddress(YarnConfiguration conf, - Class protocol) throws IOException { - if (protocol == ApplicationClientProtocol.class) { - return conf.getSocketAddr(YarnConfiguration.RM_ADDRESS, - YarnConfiguration.DEFAULT_RM_ADDRESS, - YarnConfiguration.DEFAULT_RM_PORT); - } else if (protocol == ResourceManagerAdministrationProtocol.class) { - return conf.getSocketAddr( - YarnConfiguration.RM_ADMIN_ADDRESS, - YarnConfiguration.DEFAULT_RM_ADMIN_ADDRESS, - YarnConfiguration.DEFAULT_RM_ADMIN_PORT); - } else if (protocol == ApplicationMasterProtocol.class) { - InetSocketAddress serviceAddr = - conf.getSocketAddr(YarnConfiguration.RM_SCHEDULER_ADDRESS, - YarnConfiguration.DEFAULT_RM_SCHEDULER_ADDRESS, - YarnConfiguration.DEFAULT_RM_SCHEDULER_PORT); - setupTokens(serviceAddr); - return serviceAddr; - } else { - String message = "Unsupported protocol found when creating the proxy " + - "connection to ResourceManager: " + - ((protocol != null) ? protocol.getClass().getName() : "null"); - LOG.error(message); - throw new IllegalStateException(message); - } - } - - @InterfaceAudience.Private - @Override - protected void checkAllowedProtocols(Class protocol) { - Preconditions.checkArgument( - protocol.isAssignableFrom(ClientRMProtocols.class), - "RM does not support this client protocol"); - } -} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/TestRMFailover.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/TestRMFailover.java index fed26d7..a8b0d37 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/TestRMFailover.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/TestRMFailover.java @@ -89,6 +89,7 @@ public static void setup() throws IOException { conf.setLong(YarnConfiguration.CLIENT_FAILOVER_SLEEPTIME_BASE_MS, 100L); conf.setBoolean(YarnConfiguration.YARN_MINICLUSTER_FIXED_PORTS, true); conf.setBoolean(YarnConfiguration.YARN_MINICLUSTER_USE_RPC, true); + conf.set(YarnConfiguration.PROXY_ADDRESS, "0.0.0.0:9099"); cluster = new MiniYARNCluster(TestRMFailover.class.getName(), 2, 1, 1, 1); cluster.init(conf); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/client/ClientRMProxy.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/client/ClientRMProxy.java new file mode 100644 index 0000000..06bbc35 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/client/ClientRMProxy.java @@ -0,0 +1,123 @@ +/** +* 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.client; + +import java.io.IOException; +import java.net.InetSocketAddress; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.security.SecurityUtil; +import org.apache.hadoop.security.UserGroupInformation; +import org.apache.hadoop.security.token.Token; +import org.apache.hadoop.security.token.TokenIdentifier; +import org.apache.hadoop.yarn.api.ApplicationClientProtocol; +import org.apache.hadoop.yarn.api.ApplicationMasterProtocol; +import org.apache.hadoop.yarn.conf.YarnConfiguration; +import org.apache.hadoop.yarn.security.AMRMTokenIdentifier; +import org.apache.hadoop.yarn.server.api.ResourceManagerAdministrationProtocol; + +import com.google.common.base.Preconditions; + +public class ClientRMProxy extends RMProxy { + private static final Log LOG = LogFactory.getLog(ClientRMProxy.class); + + private interface ClientRMProtocols extends ApplicationClientProtocol, + ApplicationMasterProtocol, ResourceManagerAdministrationProtocol { + // Add nothing + } + + static { + INSTANCE = new ClientRMProxy(); + } + + private ClientRMProxy(){ + super(); + } + + /** + * Create a proxy to the ResourceManager for the specified protocol. + * @param configuration Configuration with all the required information. + * @param protocol Client protocol for which proxy is being requested. + * @param Type of proxy. + * @return Proxy to the ResourceManager for the specified client protocol. + * @throws IOException + */ + public static T createRMProxy(final Configuration configuration, + final Class protocol) throws IOException { + // This method exists only to initiate this class' static INSTANCE. TODO: + // FIX if possible + return RMProxy.createRMProxy(configuration, protocol); + } + + private static void setupTokens(InetSocketAddress resourceManagerAddress) + throws IOException { + // It is assumed for now that the only AMRMToken in AM's UGI is for this + // cluster/RM. TODO: Fix later when we have some kind of cluster-ID as + // default service-address, see YARN-986. + for (Token token : UserGroupInformation + .getCurrentUser().getTokens()) { + if (token.getKind().equals(AMRMTokenIdentifier.KIND_NAME)) { + // This token needs to be directly provided to the AMs, so set the + // appropriate service-name. We'll need more infrastructure when we + // need to set it in HA case. + SecurityUtil.setTokenService(token, resourceManagerAddress); + } + } + } + + @InterfaceAudience.Private + @Override + protected InetSocketAddress getRMAddress(YarnConfiguration conf, + Class protocol) throws IOException { + if (protocol == ApplicationClientProtocol.class) { + return conf.getSocketAddr(YarnConfiguration.RM_ADDRESS, + YarnConfiguration.DEFAULT_RM_ADDRESS, + YarnConfiguration.DEFAULT_RM_PORT); + } else if (protocol == ResourceManagerAdministrationProtocol.class) { + return conf.getSocketAddr( + YarnConfiguration.RM_ADMIN_ADDRESS, + YarnConfiguration.DEFAULT_RM_ADMIN_ADDRESS, + YarnConfiguration.DEFAULT_RM_ADMIN_PORT); + } else if (protocol == ApplicationMasterProtocol.class) { + InetSocketAddress serviceAddr = + conf.getSocketAddr(YarnConfiguration.RM_SCHEDULER_ADDRESS, + YarnConfiguration.DEFAULT_RM_SCHEDULER_ADDRESS, + YarnConfiguration.DEFAULT_RM_SCHEDULER_PORT); + setupTokens(serviceAddr); + return serviceAddr; + } else { + String message = "Unsupported protocol found when creating the proxy " + + "connection to ResourceManager: " + + ((protocol != null) ? protocol.getClass().getName() : "null"); + LOG.error(message); + throw new IllegalStateException(message); + } + } + + @InterfaceAudience.Private + @Override + protected void checkAllowedProtocols(Class protocol) { + Preconditions.checkArgument( + protocol.isAssignableFrom(ClientRMProtocols.class), + "RM does not support this client protocol"); + } +} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java index d7f51e9..fa20027 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java @@ -152,6 +152,8 @@ protected ResourceTrackerService resourceTracker; private boolean recoveryEnabled; + private String webAppAddress; + /** End of Active services */ private Configuration conf; @@ -189,6 +191,8 @@ protected void serviceInit(Configuration conf) throws Exception { } createAndInitActiveServices(); + webAppAddress = WebAppUtils.getRMWebAppURLWithoutScheme(conf); + super.serviceInit(conf); } @@ -443,22 +447,12 @@ protected void serviceStart() throws Exception { throw e; } } - startWepApp(); - - if (getConfig().getBoolean(YarnConfiguration.IS_MINI_YARN_CLUSTER, false)) { - int port = webApp.port(); - WebAppUtils.setRMWebAppPort(conf, port); - } super.serviceStart(); } @Override protected void serviceStop() throws Exception { - if (webApp != null) { - webApp.stop(); - } - DefaultMetricsSystem.shutdown(); @@ -764,12 +758,17 @@ protected void startWepApp() { YarnConfiguration.RM_WEBAPP_SPNEGO_USER_NAME_KEY) .withHttpSpnegoKeytabKey( YarnConfiguration.RM_WEBAPP_SPNEGO_KEYTAB_FILE_KEY) - .at(WebAppUtils.getRMWebAppURLWithoutScheme(conf)); + .at(webAppAddress); String proxyHostAndPort = WebAppUtils.getProxyHostAndPort(conf); if(WebAppUtils.getResolvedRMWebAppURLWithoutScheme(conf). equals(proxyHostAndPort)) { - AppReportFetcher fetcher = new AppReportFetcher(conf, getClientRMService()); - builder.withServlet(ProxyUriUtils.PROXY_SERVLET_NAME, + AppReportFetcher fetcher; + if (HAUtil.isHAEnabled(conf)) { + fetcher = new AppReportFetcher(conf); + } else { + fetcher = new AppReportFetcher(conf, getClientRMService()); + } + builder.withServlet(ProxyUriUtils.PROXY_SERVLET_NAME, ProxyUriUtils.PROXY_PATH_SPEC, WebAppProxyServlet.class); builder.withAttribute(WebAppProxy.FETCHER_ATTRIBUTE, fetcher); String[] proxyParts = proxyHostAndPort.split(":"); @@ -866,6 +865,13 @@ protected void serviceStart() throws Exception { transitionToActive(); } + startWepApp(); + + if (getConfig().getBoolean(YarnConfiguration.IS_MINI_YARN_CLUSTER, false)) { + int port = webApp.port(); + WebAppUtils.setRMWebAppPort(conf, port); + } + super.serviceStart(); } @@ -876,6 +882,9 @@ protected void doSecureLogin() throws IOException { @Override protected void serviceStop() throws Exception { + if (webApp != null) { + webApp.stop(); + } super.serviceStop(); transitionToStandby(false); rmContext.setHAServiceState(HAServiceState.STOPPING); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-tests/src/test/java/org/apache/hadoop/yarn/server/TestEmbededWebApplicationProxy.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-tests/src/test/java/org/apache/hadoop/yarn/server/TestEmbededWebApplicationProxy.java new file mode 100644 index 0000000..7ac99a1 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-tests/src/test/java/org/apache/hadoop/yarn/server/TestEmbededWebApplicationProxy.java @@ -0,0 +1,73 @@ +/** +* 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; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.net.HttpURLConnection; +import java.net.URL; + +import org.apache.hadoop.ha.HAServiceProtocol; +import org.apache.hadoop.service.Service.STATE; +import org.junit.Assert; +import org.junit.Test; + + +public class TestEmbededWebApplicationProxy extends TestWebAppProxy{ + + @Test + public void testEmbeddedWebAppProxy() throws Exception{ + cluster = new MiniYARNCluster( + TestEmbededWebApplicationProxy.class.getName(), 2, 1, 1, 1); + cluster.init(conf); + cluster.start(); + int numTries = maxWaitTimes; + while ((cluster.getServiceState() != STATE.STARTED) && (numTries > 0)) { + numTries--; + try { + Thread.sleep(500); + } catch (Exception e) { + // Do nothing + } + } + Assert.assertEquals(STATE.STARTED, cluster.getServiceState()); + + cluster.getResourceManager(0).getRMContext().getRMAdminService() + .transitionToActive(req); + assertFalse("RM never turned active", -1 == cluster.getActiveRMIndex()); + URL wrongUrl = new URL("http://0.0.0.0:18088/proxy/" + fakeAppId); + HttpURLConnection proxyConn = (HttpURLConnection) wrongUrl + .openConnection(); + + proxyConn.connect(); + verifyExpectedException(proxyConn.getResponseMessage()); + + // Failover to the second RM + getRMAdminService(0).transitionToStandby(req); + getRMAdminService(1).transitionToActive(req); + assertEquals("Wrong ResourceManager is active", + HAServiceProtocol.HAServiceState.ACTIVE, + getRMAdminService(1).getServiceStatus().getState()); + assertTrue("NMs failed to connect to the RM", + cluster.waitForNodeManagersToConnect(5000)); + proxyConn.connect(); + verifyExpectedException(proxyConn.getResponseMessage()); + } +} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-tests/src/test/java/org/apache/hadoop/yarn/server/TestWebAppProxy.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-tests/src/test/java/org/apache/hadoop/yarn/server/TestWebAppProxy.java new file mode 100644 index 0000000..8966901 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-tests/src/test/java/org/apache/hadoop/yarn/server/TestWebAppProxy.java @@ -0,0 +1,104 @@ +/** +* 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; + +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.ha.HAServiceProtocol; +import org.apache.hadoop.yarn.api.records.ApplicationId; +import org.apache.hadoop.yarn.conf.HAUtil; +import org.apache.hadoop.yarn.conf.YarnConfiguration; +import org.apache.hadoop.yarn.exceptions.ApplicationNotFoundException; +import org.apache.hadoop.yarn.server.resourcemanager.AdminService; +import org.junit.AfterClass; +import org.junit.BeforeClass; + + +public class TestWebAppProxy { + + private static final String RM1_NODE_ID = "rm1"; + private static final int RM1_PORT_BASE = 10000; + private static final String RM2_NODE_ID = "rm2"; + private static final int RM2_PORT_BASE = 20000; + + protected static final HAServiceProtocol.StateChangeRequestInfo req = + new HAServiceProtocol.StateChangeRequestInfo( + HAServiceProtocol.RequestSource.REQUEST_BY_USER_FORCED); + + protected static Configuration conf; + protected static MiniYARNCluster cluster = null; + + protected static final int maxWaitTimes = 3; + protected static ApplicationId fakeAppId; + + private static void setConfForRM(String rmId, String prefix, String value) { + conf.set(HAUtil.addSuffix(prefix, rmId), value); + } + + private static void setRpcAddressForRM(String rmId, int base) { + setConfForRM(rmId, YarnConfiguration.RM_ADDRESS, "0.0.0.0:" + + (base + YarnConfiguration.DEFAULT_RM_PORT)); + setConfForRM(rmId, YarnConfiguration.RM_SCHEDULER_ADDRESS, "0.0.0.0:" + + (base + YarnConfiguration.DEFAULT_RM_SCHEDULER_PORT)); + setConfForRM(rmId, YarnConfiguration.RM_ADMIN_ADDRESS, "0.0.0.0:" + + (base + YarnConfiguration.DEFAULT_RM_ADMIN_PORT)); + setConfForRM(rmId, YarnConfiguration.RM_RESOURCE_TRACKER_ADDRESS, "0.0.0.0:" + + (base + YarnConfiguration.DEFAULT_RM_RESOURCE_TRACKER_PORT)); + setConfForRM(rmId, YarnConfiguration.RM_WEBAPP_ADDRESS, "0.0.0.0:" + + (base + YarnConfiguration.DEFAULT_RM_WEBAPP_PORT)); + setConfForRM(rmId, YarnConfiguration.RM_WEBAPP_HTTPS_ADDRESS, "0.0.0.0:" + + (base + YarnConfiguration.DEFAULT_RM_WEBAPP_HTTPS_PORT)); + } + + public static AdminService getRMAdminService(int index) { + return + cluster.getResourceManager(index).getRMContext().getRMAdminService(); + } + + @BeforeClass + public static void setup() throws IOException { + fakeAppId = ApplicationId.newInstance(System.currentTimeMillis(), 0); + conf = new YarnConfiguration(); + conf.setBoolean(YarnConfiguration.RM_HA_ENABLED, true); + conf.set(YarnConfiguration.RM_HA_IDS, RM1_NODE_ID + "," + RM2_NODE_ID); + setRpcAddressForRM(RM1_NODE_ID, RM1_PORT_BASE); + setRpcAddressForRM(RM2_NODE_ID, RM2_PORT_BASE); + + conf.setLong(YarnConfiguration.CLIENT_FAILOVER_SLEEPTIME_BASE_MS, 100L); + conf.setBoolean(YarnConfiguration.YARN_MINICLUSTER_FIXED_PORTS, true); + conf.setBoolean(YarnConfiguration.YARN_MINICLUSTER_USE_RPC, true); + + } + + @AfterClass + public static void teardown() throws IOException { + if (cluster != null) { + cluster.stop(); + } + } + + public void verifyExpectedException(String exceptionMessage){ + assertTrue(exceptionMessage.contains(ApplicationNotFoundException.class + .getName())); + assertTrue(exceptionMessage + .contains("Application with id '" + fakeAppId + "' " + + "doesn't exist in RM.")); + } +} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-tests/src/test/java/org/apache/hadoop/yarn/server/TestWebAppProxyInStandAloneMode.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-tests/src/test/java/org/apache/hadoop/yarn/server/TestWebAppProxyInStandAloneMode.java new file mode 100644 index 0000000..5c43177 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-tests/src/test/java/org/apache/hadoop/yarn/server/TestWebAppProxyInStandAloneMode.java @@ -0,0 +1,89 @@ +/** +* 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; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.net.HttpURLConnection; +import java.net.URL; + +import org.apache.hadoop.ha.HAServiceProtocol; +import org.apache.hadoop.service.Service.STATE; +import org.apache.hadoop.yarn.conf.YarnConfiguration; +import org.apache.hadoop.yarn.server.webproxy.WebAppProxyServer; +import org.junit.Assert; +import org.junit.Test; + +public class TestWebAppProxyInStandAloneMode extends TestWebAppProxy { + private WebAppProxyServer webAppProxyServer = new WebAppProxyServer(); + + @Test + public void testWebAppProxyInStandAloneMode() throws Exception { + try { + conf.set(YarnConfiguration.PROXY_ADDRESS, "0.0.0.0:9099"); + + cluster = new MiniYARNCluster( + TestWebAppProxyInStandAloneMode.class.getName(), 2, 1, 1, 1); + cluster.init(conf); + cluster.start(); + int numTries = maxWaitTimes; + while ((cluster.getServiceState() != STATE.STARTED) && (numTries > 0)) { + numTries--; + try { + Thread.sleep(500); + } catch (Exception e) { + // Do nothing + } + } + Assert.assertEquals(STATE.STARTED, cluster.getServiceState()); + + webAppProxyServer.init(conf); + + cluster.getResourceManager(0).getRMContext().getRMAdminService() + .transitionToActive(req); + assertFalse("RM never turned active", -1 == cluster.getActiveRMIndex()); + + // Start webAppProxyServer + Assert.assertEquals(STATE.INITED, webAppProxyServer.getServiceState()); + webAppProxyServer.start(); + Assert.assertEquals(STATE.STARTED, webAppProxyServer.getServiceState()); + + URL wrongUrl = new URL("http://0.0.0.0:9099/proxy/" + fakeAppId); + HttpURLConnection proxyConn = (HttpURLConnection) wrongUrl + .openConnection(); + + proxyConn.connect(); + verifyExpectedException(proxyConn.getResponseMessage()); + + // Failover to the second RM + getRMAdminService(0).transitionToStandby(req); + getRMAdminService(1).transitionToActive(req); + assertEquals("Wrong ResourceManager is active", + HAServiceProtocol.HAServiceState.ACTIVE, + getRMAdminService(1).getServiceStatus().getState()); + assertTrue("NMs failed to connect to the RM", + cluster.waitForNodeManagersToConnect(5000)); + proxyConn.connect(); + verifyExpectedException(proxyConn.getResponseMessage()); + } finally { + webAppProxyServer.stop(); + } + } +} \ No newline at end of file diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-web-proxy/src/main/java/org/apache/hadoop/yarn/server/webproxy/AppReportFetcher.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-web-proxy/src/main/java/org/apache/hadoop/yarn/server/webproxy/AppReportFetcher.java index 077783f..a03f112 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-web-proxy/src/main/java/org/apache/hadoop/yarn/server/webproxy/AppReportFetcher.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-web-proxy/src/main/java/org/apache/hadoop/yarn/server/webproxy/AppReportFetcher.java @@ -19,8 +19,6 @@ package org.apache.hadoop.yarn.server.webproxy; import java.io.IOException; -import java.net.InetSocketAddress; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; @@ -29,11 +27,11 @@ import org.apache.hadoop.yarn.api.protocolrecords.GetApplicationReportResponse; import org.apache.hadoop.yarn.api.records.ApplicationId; import org.apache.hadoop.yarn.api.records.ApplicationReport; -import org.apache.hadoop.yarn.conf.YarnConfiguration; +import org.apache.hadoop.yarn.client.ClientRMProxy; import org.apache.hadoop.yarn.exceptions.YarnException; +import org.apache.hadoop.yarn.exceptions.YarnRuntimeException; import org.apache.hadoop.yarn.factories.RecordFactory; import org.apache.hadoop.yarn.factory.providers.RecordFactoryProvider; -import org.apache.hadoop.yarn.ipc.YarnRPC; /** * This class abstracts away how ApplicationReports are fetched. @@ -50,16 +48,12 @@ */ public AppReportFetcher(Configuration conf) { this.conf = conf; - YarnRPC rpc = YarnRPC.create(this.conf); - InetSocketAddress rmAddress = conf.getSocketAddr( - YarnConfiguration.RM_ADDRESS, - YarnConfiguration.DEFAULT_RM_ADDRESS, - YarnConfiguration.DEFAULT_RM_PORT); - LOG.info("Connecting to ResourceManager at " + rmAddress); - applicationsManager = - (ApplicationClientProtocol) rpc.getProxy(ApplicationClientProtocol.class, - rmAddress, this.conf); - LOG.info("Connected to ResourceManager at " + rmAddress); + try { + applicationsManager = ClientRMProxy.createRMProxy(conf, + ApplicationClientProtocol.class); + } catch (IOException e) { + throw new YarnRuntimeException(e); + } } /**