You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by jo...@apache.org on 2015/12/04 05:42:32 UTC
ambari git commit: AMBARI-14191 - Hosts In Maintenance Mode Should Be
Excluded From Service Check Candidates During Upgrades (jonathanhurley)
Repository: ambari
Updated Branches:
refs/heads/trunk fe65472ac -> f468e9bca
AMBARI-14191 - Hosts In Maintenance Mode Should Be Excluded From Service Check Candidates During Upgrades (jonathanhurley)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/f468e9bc
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/f468e9bc
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/f468e9bc
Branch: refs/heads/trunk
Commit: f468e9bcabd127f7882c9947fc4696a66c29602a
Parents: fe65472
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Thu Dec 3 14:19:36 2015 -0500
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Thu Dec 3 23:41:05 2015 -0500
----------------------------------------------------------------------
.../controller/ActionExecutionContext.java | 4 +-
.../AmbariCustomCommandExecutionHelper.java | 68 ++--
.../internal/UpgradeResourceProvider.java | 62 ++--
.../AmbariCustomCommandExecutionHelperTest.java | 328 +++++++++++--------
4 files changed, 267 insertions(+), 195 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/f468e9bc/ambari-server/src/main/java/org/apache/ambari/server/controller/ActionExecutionContext.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ActionExecutionContext.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ActionExecutionContext.java
index dc88a5f..923fd92 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ActionExecutionContext.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ActionExecutionContext.java
@@ -188,14 +188,14 @@ public class ActionExecutionContext {
* @return {@code true} if the action context should schedule even if maintenance mode is
* enabled
*/
- public boolean isIgnoreMaintenance() {
+ public boolean isMaintenanceModeIgnored() {
return ignoreMaintenance;
}
/**
* @param ignore {@code true} to ignore maintenace mode
*/
- public void setIgnoreMaintenance(boolean ignore) {
+ public void setMaintenanceModeIgnored(boolean ignore) {
ignoreMaintenance = ignore;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f468e9bc/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
index 1e2faf5..69709e5 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
@@ -42,13 +42,14 @@ import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.STACK_NAM
import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.STACK_VERSION;
import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.USER_LIST;
+import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Iterator;
import java.util.Set;
import java.util.TreeMap;
@@ -244,7 +245,9 @@ public class AmbariCustomCommandExecutionHelper {
String clusterName = stage.getClusterName();
final Cluster cluster = clusters.getCluster(clusterName);
+ // start with all hosts
Set<String> candidateHosts = new HashSet<String>(resourceFilter.getHostNames());
+
// Filter hosts that are in MS
Set<String> ignoredHosts = maintenanceStateHelper.filterHostsInMaintenanceState(
candidateHosts, new MaintenanceStateHelper.HostPredicate() {
@@ -259,20 +262,28 @@ public class AmbariCustomCommandExecutionHelper {
);
// Filter unhealthy hosts
- Set<String> filteredHosts = filterUnhealthHosts(candidateHosts, actionExecutionContext, resourceFilter);
+ Set<String> unhealthyHosts = getUnhealthyHosts(candidateHosts, actionExecutionContext, resourceFilter);
+ // log excluded hosts
if (!ignoredHosts.isEmpty()) {
- String message = String.format("Some hosts (%s) have been ignored " +
- "because components on them are in Maintenance state.",
- ignoredHosts);
- LOG.debug(message);
- } else if (!filteredHosts.isEmpty()) {
- String message = String.format("Some hosts (%s) have been ignored " +
- "because they are in unknown state",
- filteredHosts);
- LOG.warn(message);
+ if( LOG.isDebugEnabled() ){
+ LOG.debug(
+ "While building the {} custom command for {}/{}, the following hosts were excluded: unhealthy[{}], maintenance[{}]",
+ commandName, serviceName, componentName, StringUtils.join(unhealthyHosts, ','),
+ StringUtils.join(ignoredHosts, ','));
+ }
+ } else if (!unhealthyHosts.isEmpty()) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(
+ "While building the {} custom command for {}/{}, the following hosts were excluded: unhealthy[{}], maintenance[{}]",
+ commandName, serviceName, componentName, StringUtils.join(unhealthyHosts, ','),
+ StringUtils.join(ignoredHosts, ','));
+ }
} else if (candidateHosts.isEmpty()) {
- String message = "Invalid request : No hosts specified.";
+ String message = MessageFormat.format(
+ "While building the {0} custom command for {1}/{2}, there were no healthy eligible hosts",
+ commandName, serviceName, componentName);
+
throw new AmbariException(message);
}
@@ -433,9 +444,11 @@ public class AmbariCustomCommandExecutionHelper {
if (null == smokeTestRole) {
smokeTestRole = actionExecutionContext.getActionName();
}
+
long nowTimestamp = System.currentTimeMillis();
Map<String, String> actionParameters = actionExecutionContext.getParameters();
final Set<String> candidateHosts;
+
if (componentName != null) {
Map<String, ServiceComponentHost> components =
cluster.getService(serviceName)
@@ -445,6 +458,7 @@ public class AmbariCustomCommandExecutionHelper {
+ componentName + ", service = " + serviceName
+ ", cluster = " + clusterName);
}
+
List<String> candidateHostsList = resourceFilter.getHostNames();
if (candidateHostsList != null && !candidateHostsList.isEmpty()) {
candidateHosts = new HashSet<String>(candidateHostsList);
@@ -454,10 +468,12 @@ public class AmbariCustomCommandExecutionHelper {
} else { // TODO: this code branch looks unreliable(taking random component)
Map<String, ServiceComponent> components =
cluster.getService(serviceName).getServiceComponents();
+
if (components.isEmpty()) {
throw new AmbariException("Components not found, service = "
+ serviceName + ", cluster = " + clusterName);
}
+
ServiceComponent serviceComponent = components.values().iterator().next();
if (serviceComponent.getServiceComponentHosts().isEmpty()) {
throw new AmbariException("Hosts not found, component="
@@ -467,15 +483,13 @@ public class AmbariCustomCommandExecutionHelper {
candidateHosts = serviceComponent.getServiceComponentHosts().keySet();
}
- // Filter hosts that are in MS
+ // filter out hosts that are in maintenance mode
Set<String> ignoredHosts = new HashSet<String>();
-
- if (!actionExecutionContext.isIgnoreMaintenance()) {
+ if (!actionExecutionContext.isMaintenanceModeIgnored()) {
ignoredHosts.addAll(maintenanceStateHelper.filterHostsInMaintenanceState(
candidateHosts, new MaintenanceStateHelper.HostPredicate() {
@Override
- public boolean shouldHostBeRemoved(final String hostname)
- throws AmbariException {
+ public boolean shouldHostBeRemoved(final String hostname) throws AmbariException {
return !maintenanceStateHelper.isOperationAllowed(
cluster, actionExecutionContext.getOperationLevel(),
resourceFilter, serviceName, componentName, hostname);
@@ -484,15 +498,15 @@ public class AmbariCustomCommandExecutionHelper {
));
}
+ // pick a random healthy host from the remaining set, throwing an exception
+ // if there are none to choose from
String hostName = managementController.getHealthyHost(candidateHosts);
if (hostName == null) {
- String msg = String.format("Unable to find a healthy host " +
- "amongst the provided set of " +
- "hosts: %s. You may also see this message if " +
- "all healthy hosts are not appropriate for service check " +
- "due to maintenance state (these hosts are %s). ",
- candidateHosts, ignoredHosts);
- LOG.info(msg);
+ String message = MessageFormat.format(
+ "While building a service check command for {0}, there were no healthy eligible hosts: unhealthy[{1}], maintenance[{2}]",
+ serviceName, StringUtils.join(candidateHosts, ','), StringUtils.join(ignoredHosts, ','));
+
+ throw new AmbariException(message);
}
addServiceCheckAction(stage, hostName, smokeTestRole, nowTimestamp, serviceName, componentName,
@@ -567,7 +581,7 @@ public class AmbariCustomCommandExecutionHelper {
commandParams.put("dfs_type",serviceInfoInstance.getServiceType());
break;
}
- }
+ }
String commandTimeout = configs.getDefaultAgentTaskTimeout(false);
@@ -1088,7 +1102,7 @@ public class AmbariCustomCommandExecutionHelper {
commandParamsStage.put("dfs_type",serviceInfoInstance.getServiceType());
break;
}
- }
+ }
}
@@ -1226,7 +1240,7 @@ public class AmbariCustomCommandExecutionHelper {
* @return Set of excluded hosts
* @throws AmbariException
*/
- private Set<String> filterUnhealthHosts(Set<String> hosts,
+ private Set<String> getUnhealthyHosts(Set<String> hosts,
ActionExecutionContext actionExecutionContext,
RequestResourceFilter resourceFilter) throws AmbariException {
Set<String> removedHosts = new HashSet<String>();
http://git-wip-us.apache.org/repos/asf/ambari/blob/f468e9bc/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
index 2b53ab5..341a433 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
@@ -17,10 +17,25 @@
*/
package org.apache.ambari.server.controller.internal;
-import com.google.common.collect.Lists;
-import com.google.gson.Gson;
-import com.google.inject.Inject;
-import com.google.inject.Provider;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.HOOKS_FOLDER;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SERVICE_PACKAGE_FOLDER;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.VERSION;
+
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.Role;
import org.apache.ambari.server.RoleCommand;
@@ -93,24 +108,10 @@ import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.HOOKS_FOLDER;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SERVICE_PACKAGE_FOLDER;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.VERSION;
+import com.google.common.collect.Lists;
+import com.google.gson.Gson;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
/**
* Manages the ability to start and get status of upgrades.
@@ -1185,7 +1186,9 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
ActionExecutionContext actionContext = new ActionExecutionContext(cluster.getClusterName(),
"ru_execute_tasks", Collections.singletonList(filter), params);
- actionContext.setIgnoreMaintenance(true);
+ // hosts in maintenance mode are excluded from the upgrade
+ actionContext.setMaintenanceModeIgnored(false);
+
actionContext.setTimeout(Short.valueOf(s_configuration.getDefaultAgentTaskTimeout(false)));
actionContext.setRetryAllowed(allowRetry);
actionContext.setAutoSkipFailures(context.isComponentFailureAutoSkipped());
@@ -1281,10 +1284,12 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
ActionExecutionContext actionContext = new ActionExecutionContext(cluster.getClusterName(),
function, filters, commandParams);
actionContext.setTimeout(Short.valueOf(s_configuration.getDefaultAgentTaskTimeout(false)));
- actionContext.setIgnoreMaintenance(true);
actionContext.setRetryAllowed(allowRetry);
actionContext.setAutoSkipFailures(context.isComponentFailureAutoSkipped());
+ // hosts in maintenance mode are excluded from the upgrade
+ actionContext.setMaintenanceModeIgnored(false);
+
ExecuteCommandJson jsons = s_commandExecutionHelper.get().getCommandJson(actionContext,
cluster, context.getEffectiveStackId());
@@ -1339,10 +1344,13 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
"SERVICE_CHECK", filters, commandParams);
actionContext.setTimeout(Short.valueOf(s_configuration.getDefaultAgentTaskTimeout(false)));
- actionContext.setIgnoreMaintenance(true);
actionContext.setRetryAllowed(allowRetry);
actionContext.setAutoSkipFailures(context.isServiceCheckFailureAutoSkipped());
+ // hosts in maintenance mode are excluded from the upgrade and should not be
+ // candidates for service checks
+ actionContext.setMaintenanceModeIgnored(false);
+
ExecuteCommandJson jsons = s_commandExecutionHelper.get().getCommandJson(actionContext,
cluster, context.getEffectiveStackId());
@@ -1454,10 +1462,12 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
commandParams);
actionContext.setTimeout(Short.valueOf((short) -1));
- actionContext.setIgnoreMaintenance(true);
actionContext.setRetryAllowed(allowRetry);
actionContext.setAutoSkipFailures(context.isComponentFailureAutoSkipped());
+ // hosts in maintenance mode are excluded from the upgrade
+ actionContext.setMaintenanceModeIgnored(false);
+
ExecuteCommandJson jsons = s_commandExecutionHelper.get().getCommandJson(actionContext,
cluster, context.getEffectiveStackId());
http://git-wip-us.apache.org/repos/asf/ambari/blob/f468e9bc/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelperTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelperTest.java
index ba952c0..53630aa 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelperTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelperTest.java
@@ -27,8 +27,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
-import junit.framework.Assert;
-
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.actionmanager.ActionManager;
import org.apache.ambari.server.actionmanager.ExecutionCommandWrapper;
@@ -41,12 +39,14 @@ import org.apache.ambari.server.controller.internal.RequestOperationLevel;
import org.apache.ambari.server.controller.internal.RequestResourceFilter;
import org.apache.ambari.server.controller.internal.ServiceResourceProviderTest;
import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.metadata.ActionMetadata;
import org.apache.ambari.server.orm.GuiceJpaInitializer;
import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
import org.apache.ambari.server.security.authorization.AuthorizationException;
import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.state.Host;
import org.apache.ambari.server.state.HostState;
+import org.apache.ambari.server.state.MaintenanceState;
import org.apache.ambari.server.state.SecurityType;
import org.apache.ambari.server.state.State;
import org.apache.ambari.server.topology.TopologyManager;
@@ -65,6 +65,8 @@ import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.persist.PersistService;
+import junit.framework.Assert;
+
@RunWith(MockitoJUnitRunner.class)
public class AmbariCustomCommandExecutionHelperTest {
private Injector injector;
@@ -72,13 +74,13 @@ public class AmbariCustomCommandExecutionHelperTest {
private AmbariMetaInfo ambariMetaInfo;
private Clusters clusters;
private TopologyManager topologyManager;
-
-
+
+
private static final String REQUEST_CONTEXT_PROPERTY = "context";
-
+
@Captor ArgumentCaptor<Request> requestCapture;
@Mock ActionManager am;
-
+
@Before
public void setup() throws Exception {
InMemoryDefaultTestModule module = new InMemoryDefaultTestModule(){
@@ -89,8 +91,8 @@ public class AmbariCustomCommandExecutionHelperTest {
}
};
injector = Guice.createInjector(module);
-
-
+
+
injector.getInstance(GuiceJpaInitializer.class);
controller = injector.getInstance(AmbariManagementController.class);
clusters = injector.getInstance(Clusters.class);
@@ -105,49 +107,47 @@ public class AmbariCustomCommandExecutionHelperTest {
@SuppressWarnings("serial")
@Test
- public void testRefreshQueueCustomCommand() {
- try {
- createClusterFixture("HDP-2.0.6");
-
- Map<String, String> requestProperties = new HashMap<String, String>() {
- {
- put(REQUEST_CONTEXT_PROPERTY, "Refresh YARN Capacity Scheduler");
- put("command", "REFRESHQUEUES");
- }
- };
-
- ExecuteActionRequest actionRequest = new ExecuteActionRequest("c1",
- "REFRESHQUEUES", new HashMap<String, String>() {
- {
- put("forceRefreshConfigTags" , "capacity-scheduler");
- }
- }, false);
- actionRequest.getResourceFilters().add(new RequestResourceFilter("YARN", "RESOURCEMANAGER",Collections.singletonList("c6401")));
-
- controller.createAction(actionRequest, requestProperties);
-
- Mockito.verify(am, Mockito.times(1)).sendActions(requestCapture.capture(), any(ExecuteActionRequest.class));
-
- Request request = requestCapture.getValue();
- Assert.assertNotNull(request);
- Assert.assertNotNull(request.getStages());
- Assert.assertEquals(1, request.getStages().size());
- Stage stage = request.getStages().iterator().next();
-
- Assert.assertEquals(1, stage.getHosts().size());
-
- List<ExecutionCommandWrapper> commands = stage.getExecutionCommands("c6401");
- Assert.assertEquals(1, commands.size());
-
- ExecutionCommand command = commands.get(0).getExecutionCommand();
-
- Assert.assertNotNull(command.getForceRefreshConfigTags());
- Assert.assertEquals(1, command.getForceRefreshConfigTags().size());
- Assert.assertEquals("capacity-scheduler", command.getForceRefreshConfigTags().iterator().next());
-
- } catch (Exception e) {
- Assert.fail(e.getMessage());
- }
+ public void testRefreshQueueCustomCommand() throws Exception {
+ createClusterFixture("HDP-2.0.6");
+
+ Map<String, String> requestProperties = new HashMap<String, String>() {
+ {
+ put(REQUEST_CONTEXT_PROPERTY, "Refresh YARN Capacity Scheduler");
+ put("command", "REFRESHQUEUES");
+ }
+ };
+
+ ExecuteActionRequest actionRequest = new ExecuteActionRequest("c1", "REFRESHQUEUES",
+ new HashMap<String, String>() {
+ {
+ put("forceRefreshConfigTags", "capacity-scheduler");
+ }
+ }, false);
+ actionRequest.getResourceFilters().add(
+ new RequestResourceFilter("YARN", "RESOURCEMANAGER", Collections.singletonList("c6401")));
+
+ controller.createAction(actionRequest, requestProperties);
+
+ Mockito.verify(am, Mockito.times(1)).sendActions(requestCapture.capture(),
+ any(ExecuteActionRequest.class));
+
+ Request request = requestCapture.getValue();
+ Assert.assertNotNull(request);
+ Assert.assertNotNull(request.getStages());
+ Assert.assertEquals(1, request.getStages().size());
+ Stage stage = request.getStages().iterator().next();
+
+ Assert.assertEquals(1, stage.getHosts().size());
+
+ List<ExecutionCommandWrapper> commands = stage.getExecutionCommands("c6401");
+ Assert.assertEquals(1, commands.size());
+
+ ExecutionCommand command = commands.get(0).getExecutionCommand();
+
+ Assert.assertNotNull(command.getForceRefreshConfigTags());
+ Assert.assertEquals(1, command.getForceRefreshConfigTags().size());
+ Assert.assertEquals("capacity-scheduler",
+ command.getForceRefreshConfigTags().iterator().next());
}
@Test
@@ -171,7 +171,10 @@ public class AmbariCustomCommandExecutionHelperTest {
new RequestResourceFilter("GANGLIA", "GANGLIA_MONITOR", Collections.singletonList("c6402"))
),
new RequestOperationLevel(Resource.Type.Service, "c1", "GANGLIA", null, null),
- new HashMap<String, String>(){{}},
+ new HashMap<String, String>() {
+ {
+ }
+ },
false);
controller.createAction(actionRequest, requestProperties);
@@ -191,92 +194,134 @@ public class AmbariCustomCommandExecutionHelperTest {
}
@Test
- public void testHostsFilterUnhealthyHost(){
- try {
- createClusterFixture("HDP-2.0.6");
-
- // Set custom status to host
- clusters.getHost("c6402").setState(HostState.HEARTBEAT_LOST);
- Map<String, String> requestProperties = new HashMap<String, String>() {
- {
- put("context" , "Restart all components for GANGLIA");
- put("operation_level/level", "SERVICE");
- put("operation_level/service_name", "GANGLIA");
- put("operation_level/cluster_name", "c1");
- }
- };
-
- ExecuteActionRequest actionRequest = new ExecuteActionRequest(
- "c1", "RESTART", null,
- Arrays.asList(
- new RequestResourceFilter("GANGLIA", "GANGLIA_SERVER", Collections.singletonList("c6401")),
- new RequestResourceFilter("GANGLIA", "GANGLIA_MONITOR", Collections.singletonList("c6401")),
- new RequestResourceFilter("GANGLIA", "GANGLIA_MONITOR", Collections.singletonList("c6402"))
- ),
- new RequestOperationLevel(Resource.Type.Service, "c1", "GANGLIA", null, null),
- new HashMap<String, String>(){{}},
- false);
-
- controller.createAction(actionRequest, requestProperties);
-
- Mockito.verify(am, Mockito.times(1)).sendActions(requestCapture.capture(), any(ExecuteActionRequest.class));
-
- Request request = requestCapture.getValue();
- Assert.assertNotNull(request);
- Assert.assertNotNull(request.getStages());
- Assert.assertEquals(1, request.getStages().size());
- Stage stage = request.getStages().iterator().next();
-
- // Check if was generated command for one health host
- Assert.assertEquals(1, stage.getHostRoleCommands().size());
- }catch (Exception e) {
- Assert.fail(e.getMessage());
- }
+ public void testHostsFilterUnhealthyHost() throws Exception {
+ createClusterFixture("HDP-2.0.6");
+
+ // Set custom status to host
+ clusters.getHost("c6402").setState(HostState.HEARTBEAT_LOST);
+ Map<String, String> requestProperties = new HashMap<String, String>() {
+ {
+ put("context", "Restart all components for GANGLIA");
+ put("operation_level/level", "SERVICE");
+ put("operation_level/service_name", "GANGLIA");
+ put("operation_level/cluster_name", "c1");
+ }
+ };
+
+ ExecuteActionRequest actionRequest = new ExecuteActionRequest("c1", "RESTART", null,
+ Arrays.asList(
+ new RequestResourceFilter("GANGLIA", "GANGLIA_SERVER",
+ Collections.singletonList("c6401")),
+ new RequestResourceFilter("GANGLIA", "GANGLIA_MONITOR",
+ Collections.singletonList("c6401")),
+ new RequestResourceFilter("GANGLIA", "GANGLIA_MONITOR",
+ Collections.singletonList("c6402"))),
+ new RequestOperationLevel(Resource.Type.Service, "c1", "GANGLIA", null, null),
+ new HashMap<String, String>() {
+ {
+ }
+ }, false);
+
+ controller.createAction(actionRequest, requestProperties);
+
+ Mockito.verify(am, Mockito.times(1)).sendActions(requestCapture.capture(),
+ any(ExecuteActionRequest.class));
+
+ Request request = requestCapture.getValue();
+ Assert.assertNotNull(request);
+ Assert.assertNotNull(request.getStages());
+ Assert.assertEquals(1, request.getStages().size());
+ Stage stage = request.getStages().iterator().next();
+
+ // Check if was generated command for one health host
+ Assert.assertEquals(1, stage.getHostRoleCommands().size());
}
@Test
- public void testHostsFilterUnhealthyComponent(){
- try {
- createClusterFixture("HDP-2.0.6");
-
- // Set custom status to host
- clusters.getCluster("c1").getService("GANGLIA").getServiceComponent("GANGLIA_MONITOR").getServiceComponentHost("c6402")
- .setState(State.UNKNOWN);
- Map<String, String> requestProperties = new HashMap<String, String>() {
- {
- put("context" , "Restart all components for GANGLIA");
- put("operation_level/level", "SERVICE");
- put("operation_level/service_name", "GANGLIA");
- put("operation_level/cluster_name", "c1");
- }
- };
-
- ExecuteActionRequest actionRequest = new ExecuteActionRequest(
- "c1", "RESTART", null,
- Arrays.asList(
- new RequestResourceFilter("GANGLIA", "GANGLIA_SERVER", Collections.singletonList("c6401")),
- new RequestResourceFilter("GANGLIA", "GANGLIA_MONITOR", Collections.singletonList("c6401")),
- new RequestResourceFilter("GANGLIA", "GANGLIA_MONITOR", Collections.singletonList("c6402"))
- ),
- new RequestOperationLevel(Resource.Type.Host, "c1", "GANGLIA", null, null),
- new HashMap<String, String>(){{}},
- false);
-
- controller.createAction(actionRequest, requestProperties);
-
- Mockito.verify(am, Mockito.times(1)).sendActions(requestCapture.capture(), any(ExecuteActionRequest.class));
-
- Request request = requestCapture.getValue();
- Assert.assertNotNull(request);
- Assert.assertNotNull(request.getStages());
- Assert.assertEquals(1, request.getStages().size());
- Stage stage = request.getStages().iterator().next();
-
- // Check if was generated command for one health host
- Assert.assertEquals(1, stage.getHostRoleCommands().size());
- }catch (Exception e) {
- Assert.fail(e.getMessage());
- }
+ public void testHostsFilterUnhealthyComponent() throws Exception {
+ createClusterFixture("HDP-2.0.6");
+
+ // Set custom status to host
+ clusters.getCluster("c1").getService("GANGLIA").getServiceComponent(
+ "GANGLIA_MONITOR").getServiceComponentHost("c6402").setState(State.UNKNOWN);
+
+ Map<String, String> requestProperties = new HashMap<String, String>() {
+ {
+ put("context", "Restart all components for GANGLIA");
+ put("operation_level/level", "SERVICE");
+ put("operation_level/service_name", "GANGLIA");
+ put("operation_level/cluster_name", "c1");
+ }
+ };
+
+ ExecuteActionRequest actionRequest = new ExecuteActionRequest("c1", "RESTART", null,
+ Arrays.asList(
+ new RequestResourceFilter("GANGLIA", "GANGLIA_SERVER",
+ Collections.singletonList("c6401")),
+ new RequestResourceFilter("GANGLIA", "GANGLIA_MONITOR",
+ Collections.singletonList("c6401")),
+ new RequestResourceFilter("GANGLIA", "GANGLIA_MONITOR",
+ Collections.singletonList("c6402"))),
+ new RequestOperationLevel(Resource.Type.Host, "c1", "GANGLIA", null, null),
+ new HashMap<String, String>() {
+ {
+ }
+ }, false);
+
+ controller.createAction(actionRequest, requestProperties);
+
+ Mockito.verify(am, Mockito.times(1)).sendActions(requestCapture.capture(),
+ any(ExecuteActionRequest.class));
+
+ Request request = requestCapture.getValue();
+ Assert.assertNotNull(request);
+ Assert.assertNotNull(request.getStages());
+ Assert.assertEquals(1, request.getStages().size());
+ Stage stage = request.getStages().iterator().next();
+
+ // Check if was generated command for one health host
+ Assert.assertEquals(1, stage.getHostRoleCommands().size());
+ }
+
+ /**
+ * Tests that trying to run a service check when there are no available hosts
+ * will throw an exception.
+ */
+ @Test(expected = AmbariException.class)
+ public void testNoCandidateHostThrowsException() throws Exception {
+ createClusterFixture("HDP-2.0.6");
+ long clusterId = clusters.getCluster("c1").getClusterId();
+
+ // put host into MM
+ clusters.getHost("c6402").setMaintenanceState(clusterId, MaintenanceState.ON);
+
+ // ensure that service check is added for ZOOKEEPER
+ injector.getInstance(ActionMetadata.class).addServiceCheckAction("ZOOKEEPER");
+
+ Map<String, String> requestProperties = new HashMap<String, String>() {
+ {
+ put("context", "Service Check ZooKeeper");
+ put("operation_level/level", "SERVICE");
+ put("operation_level/service_name", "ZOOKEEPER");
+ put("operation_level/cluster_name", "c1");
+ }
+ };
+
+ // create the service check on the host in MM
+ ExecuteActionRequest actionRequest = new ExecuteActionRequest("c1",
+ "ZOOKEEPER_QUORUM_SERVICE_CHECK",
+ null, Arrays.asList(new RequestResourceFilter("ZOOKEEPER", "ZOOKEEPER_CLIENT",
+ Collections.singletonList("c6402"))),
+
+ new RequestOperationLevel(Resource.Type.Service, "c1", "ZOOKEEPER", null, null),
+ new HashMap<String, String>() {
+ {
+ }
+ }, false);
+
+ controller.createAction(actionRequest, requestProperties);
+ Assert.fail(
+ "Expected an exception since there are no hosts which can run the ZK service check");
}
@Test
@@ -294,23 +339,26 @@ public class AmbariCustomCommandExecutionHelperTest {
createCluster("c1", stackVersion);
addHost("c6401","c1");
addHost("c6402","c1");
-
+
clusters.getCluster("c1");
createService("c1", "YARN", null);
createService("c1", "GANGLIA", null);
+ createService("c1", "ZOOKEEPER", null);
createServiceComponent("c1", "YARN","RESOURCEMANAGER", State.INIT);
createServiceComponent("c1", "YARN", "NODEMANAGER", State.INIT);
createServiceComponent("c1", "GANGLIA", "GANGLIA_SERVER", State.INIT);
createServiceComponent("c1", "GANGLIA", "GANGLIA_MONITOR", State.INIT);
-
+ createServiceComponent("c1", "ZOOKEEPER", "ZOOKEEPER_CLIENT", State.INIT);
+
createServiceComponentHost("c1","YARN","RESOURCEMANAGER","c6401", null);
createServiceComponentHost("c1","YARN","NODEMANAGER","c6401", null);
createServiceComponentHost("c1","GANGLIA","GANGLIA_SERVER","c6401", State.INIT);
createServiceComponentHost("c1","GANGLIA","GANGLIA_MONITOR","c6401", State.INIT);
-
+
createServiceComponentHost("c1","YARN","NODEMANAGER","c6402", null);
createServiceComponentHost("c1","GANGLIA","GANGLIA_MONITOR","c6402", State.INIT);
+ createServiceComponentHost("c1", "ZOOKEEPER", "ZOOKEEPER_CLIENT", "c6402", State.INIT);
}
private void addHost(String hostname, String clusterName) throws AmbariException {
@@ -326,7 +374,7 @@ public class AmbariCustomCommandExecutionHelperTest {
Map<String, String> hostAttributes = new HashMap<String, String>();
hostAttributes.put("os_family", osFamily);
hostAttributes.put("os_release_version", osVersion);
-
+
host.setHostAttributes(hostAttributes);
}
@@ -335,7 +383,7 @@ public class AmbariCustomCommandExecutionHelperTest {
SecurityType.NONE, stackVersion, null);
controller.createCluster(r);
}
-
+
private void createService(String clusterName,
String serviceName, State desiredState) throws AmbariException {
String dStateStr = null;