diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/webapp/util/WebAppUtils.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/webapp/util/WebAppUtils.java index 459c110..1d467de 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/webapp/util/WebAppUtils.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/webapp/util/WebAppUtils.java @@ -81,6 +81,17 @@ public static void setNMWebAppHostNameAndPort(Configuration conf, public static String getRMWebAppURLWithScheme(Configuration conf) { return getHttpSchemePrefix(conf) + getRMWebAppURLWithoutScheme(conf); } + + public static List getRMHAWebappAddressesWithScheme(Configuration conf) { + List rmhaWebappAddresses = + RMHAUtils.getRMHAWebappAddresses(new YarnConfiguration(conf)); + List webappAddresses = new ArrayList<>(); + for (String webAddres : rmhaWebappAddresses) { + String urlWithScheme = getHttpSchemePrefix(conf) + webAddres; + webappAddresses.add(urlWithScheme); + } + return webappAddresses; + } public static String getRMWebAppURLWithoutScheme(Configuration conf) { if (YarnConfiguration.useHttps(conf)) { diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/RMServerUtils.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/RMServerUtils.java index 3d28bb7..ee5dca7 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/RMServerUtils.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/RMServerUtils.java @@ -20,11 +20,14 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; import java.util.EnumSet; import java.util.HashMap; import java.util.List; import java.util.Map; +import javax.ws.rs.core.MediaType; + import org.apache.commons.logging.Log; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.security.AccessControlException; @@ -40,10 +43,12 @@ import org.apache.hadoop.yarn.api.records.ResourceRequest; import org.apache.hadoop.yarn.api.records.YarnApplicationAttemptState; import org.apache.hadoop.yarn.api.records.YarnApplicationState; +import org.apache.hadoop.yarn.conf.HAUtil; import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.hadoop.yarn.exceptions.InvalidContainerReleaseException; import org.apache.hadoop.yarn.exceptions.InvalidResourceBlacklistRequestException; import org.apache.hadoop.yarn.exceptions.InvalidResourceRequestException; +import org.apache.hadoop.yarn.exceptions.YarnException; import org.apache.hadoop.yarn.exceptions.YarnRuntimeException; import org.apache.hadoop.yarn.security.YarnAuthorizationProvider; import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppState; @@ -53,6 +58,12 @@ import org.apache.hadoop.yarn.server.resourcemanager.scheduler.YarnScheduler; import org.apache.hadoop.yarn.server.utils.BuilderUtils; import org.apache.hadoop.yarn.util.resource.Resources; +import org.apache.hadoop.yarn.webapp.util.WebAppUtils; +import org.codehaus.jettison.json.JSONObject; + +import com.sun.jersey.api.client.Client; +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.WebResource; /** * Utility methods to aid serving RM data through the REST and RPC APIs @@ -276,4 +287,62 @@ public static void processRMProxyUsersConf(Configuration conf) { conf.set(entry.getKey(), entry.getValue()); } } + + /** + * Using REST api, finds any RM is running in the cluster. + * + * @param conf + * @return + * @throws YarnException + */ + public static boolean isActiveRMRunningInCluster(Configuration conf) + throws YarnException { + if (HAUtil.isHAEnabled(conf)) { + Collection rmhaIds = HAUtil.getRMHAIds(conf); + List rmhaWebappAddressesWithScheme = + WebAppUtils.getRMHAWebappAddressesWithScheme(conf); + + // Sanity check for configured web address size are inline with rm-ids. + if (rmhaIds.size() != rmhaWebappAddressesWithScheme.size()) { + throw new YarnException( + "Configured number of rm-ids are mismatch with number of web address"); + } + + for (String rmAddress : rmhaWebappAddressesWithScheme) { + if (isRMActive(rmAddress)) { + return true; + } + } + } else { + return isRMActive(WebAppUtils.getRMWebAppURLWithScheme(conf)); + } + return false; + } + + private static boolean isRMActive(String rmAddress) { + String rmHaState = getRMState(rmAddress); + if (rmHaState.equals("ACTIVE")) { + return true; + } + return false; + } + + public static String getRMState(String address) { + String rmHaState = "STOPPED"; + Client webServiceClient = Client.create(); + WebResource webResource = webServiceClient.resource(address); + + try { + ClientResponse response = + webResource.path("ws").path("v1").path("cluster").path("info") + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + rmHaState = + response.getEntity(JSONObject.class).getJSONObject("clusterInfo") + .getString("haState"); + + } catch (Exception e) { + // Ignore it. + } + return rmHaState; + } } diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java index 8bd8e21..e10c5b4 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java @@ -53,6 +53,7 @@ import org.apache.hadoop.yarn.event.AsyncDispatcher; import org.apache.hadoop.yarn.event.Dispatcher; import org.apache.hadoop.yarn.event.EventHandler; +import org.apache.hadoop.yarn.exceptions.YarnException; import org.apache.hadoop.yarn.exceptions.YarnRuntimeException; import org.apache.hadoop.yarn.server.resourcemanager.ahs.RMApplicationHistoryWriter; import org.apache.hadoop.yarn.server.resourcemanager.amlauncher.AMLauncherEventType; @@ -1264,6 +1265,11 @@ public static InetSocketAddress getBindAddress(Configuration conf) { * @throws Exception */ private static void deleteRMStateStore(Configuration conf) throws Exception { + if (RMServerUtils.isActiveRMRunningInCluster(conf)) { + throw new YarnException( + "Active RM is running in the cluster. -format-state-store should " + + "be run when ResourceManager is shutdown."); + } RMStateStore rmStore = RMStateStoreFactory.getStore(conf); rmStore.init(conf); rmStore.start(); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestRM.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestRM.java index 77d8cdf..e83c6d9 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestRM.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestRM.java @@ -19,6 +19,9 @@ package org.apache.hadoop.yarn.server.resourcemanager; import org.junit.Before; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.argThat; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doAnswer; @@ -749,4 +752,20 @@ protected Dispatcher createDispatcher() { // app is killed, not launching a new attempt rm1.waitForState(app1.getApplicationId(), RMAppState.KILLED); } + + @Test + public void testRMServerUtils() throws Exception { + conf.set(YarnConfiguration.RM_WEBAPP_ADDRESS, "127.0.0.1:1234"); + conf.setBoolean(MockRM.ENABLE_WEBAPP, true); + + // When no RM is running + assertFalse(RMServerUtils.isActiveRMRunningInCluster(conf)); + + // Start RM + MockRM rm = new MockRM(conf); + rm.start(); + + assertTrue(RMServerUtils.isActiveRMRunningInCluster(conf)); + } + } -- 1.9.2.msysgit.0