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/09/12 15:22:42 UTC
[1/2] ambari git commit: AMBARI-13078 - Upgrade Packs Should Define
Skippable Failed Slave/Clients (jonathanhurley)
Repository: ambari
Updated Branches:
refs/heads/trunk 70ca85005 -> e5f6fb164
AMBARI-13078 - Upgrade Packs Should Define Skippable Failed Slave/Clients (jonathanhurley)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/e5f6fb16
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/e5f6fb16
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/e5f6fb16
Branch: refs/heads/trunk
Commit: e5f6fb164b44244527009ea3f74fe086aed7c7e0
Parents: c7a714c
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Fri Sep 11 14:39:52 2015 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Fri Sep 11 22:51:25 2015 -0400
----------------------------------------------------------------------
.../internal/UpgradeResourceProvider.java | 10 +-
.../server/orm/entities/UpgradeGroupEntity.java | 13 ++
.../ambari/server/state/stack/UpgradePack.java | 45 ++++-
.../stacks/HDP/2.2/upgrades/upgrade-2.2.xml | 3 +-
.../stacks/HDP/2.2/upgrades/upgrade-2.3.xml | 3 +
.../stacks/HDP/2.3/upgrades/upgrade-2.3.xml | 2 +
.../internal/UpgradeResourceProviderTest.java | 171 ++++++++++++-------
.../server/state/stack/UpgradePackTest.java | 27 ++-
.../upgrades/upgrade_test_skip_failures.xml | 52 ++++++
9 files changed, 246 insertions(+), 80 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/e5f6fb16/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 19a3397..e9ac429 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
@@ -654,13 +654,17 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
}
// optionally skip failures - this can be supplied on either the request or
- // in the upgrade pack explicitely
- boolean skipComponentFailures = false;
- boolean skipServiceCheckFailures = false;
+ // in the upgrade pack explicitely, however the request will always override
+ // the upgrade pack if explicitely specified
+ boolean skipComponentFailures = pack.isComponentFailureAutoSkipped();
+ boolean skipServiceCheckFailures = pack.isServiceCheckFailureAutoSkipped();
+
+ // only override the upgrade pack if set on the request
if (requestMap.containsKey(UPGRADE_SKIP_FAILURES)) {
skipComponentFailures = Boolean.parseBoolean((String) requestMap.get(UPGRADE_SKIP_FAILURES));
}
+ // only override the upgrade pack if set on the request
if (requestMap.containsKey(UPGRADE_SKIP_SC_FAILURES)) {
skipServiceCheckFailures = Boolean.parseBoolean(
(String) requestMap.get(UPGRADE_SKIP_SC_FAILURES));
http://git-wip-us.apache.org/repos/asf/ambari/blob/e5f6fb16/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradeGroupEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradeGroupEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradeGroupEntity.java
index 7b57184..96f96d5 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradeGroupEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradeGroupEntity.java
@@ -129,5 +129,18 @@ public class UpgradeGroupEntity {
upgradeItems = items;
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ StringBuilder buffer = new StringBuilder("UpgradeGroupEntity{");
+ buffer.append("upgradeGroupId=").append(upgradeGroupId);
+ buffer.append(", upgradeId=").append(upgradeId);
+ buffer.append(", groupName=").append(groupName);
+ buffer.append(", groupTitle=").append(groupTitle);
+ buffer.append("}");
+ return buffer.toString();
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/e5f6fb16/ambari-server/src/main/java/org/apache/ambari/server/state/stack/UpgradePack.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/UpgradePack.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/UpgradePack.java
index 3e9aa5f..5b65732 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/UpgradePack.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/UpgradePack.java
@@ -50,7 +50,6 @@ public class UpgradePack {
@XmlElement(name="target-stack")
private String targetStack;
-
@XmlElementWrapper(name="order")
@XmlElement(name="group")
private List<Grouping> groups;
@@ -59,13 +58,30 @@ public class UpgradePack {
@XmlElement(name="service")
private List<ProcessingService> processing;
+ /**
+ * {@code true} to automatically skip slave/client component failures. The
+ * default is {@code false}.
+ */
+ @XmlElement(name = "skip-failures")
+ private boolean skipFailures = false;
+
+ /**
+ * {@code true} to automatically skip service check failures. The default is
+ * {@code false}.
+ */
+ @XmlElement(name = "skip-service-check-failures")
+ private boolean skipServiceCheckFailures = false;
+
@XmlTransient
private Map<String, List<String>> m_orders = null;
+
@XmlTransient
private Map<String, Map<String, ProcessingComponent>> m_process = null;
+
@XmlTransient
private boolean m_resolvedGroups = false;
+
/**
* @return the target version for the upgrade pack
*/
@@ -81,9 +97,30 @@ public class UpgradePack {
}
/**
- * Gets the groups defined for the upgrade pack. If a direction is defined
- * for a group, it must match the supplied direction to be returned
- * @param direction the direction to return the ordered groups
+ * Gets whether skippable components that failed are automatically skipped.
+ *
+ * @return the skipComponentFailures
+ */
+ public boolean isComponentFailureAutoSkipped() {
+ return skipFailures;
+ }
+
+ /**
+ * Gets whether skippable service checks that failed are automatically
+ * skipped.
+ *
+ * @return the skipServiceCheckFailures
+ */
+ public boolean isServiceCheckFailureAutoSkipped() {
+ return skipServiceCheckFailures;
+ }
+
+ /**
+ * Gets the groups defined for the upgrade pack. If a direction is defined for
+ * a group, it must match the supplied direction to be returned
+ *
+ * @param direction
+ * the direction to return the ordered groups
* @return the list of groups
*/
public List<Grouping> getGroups(Direction direction) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/e5f6fb16/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/upgrade-2.2.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/upgrade-2.2.xml b/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/upgrade-2.2.xml
index d67671c..5920b72 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/upgrade-2.2.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/upgrade-2.2.xml
@@ -19,9 +19,10 @@
<upgrade xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<target>2.2.*.*</target>
+ <skip-failures>false</skip-failures>
+ <skip-service-check-failures>false</skip-service-check-failures>
<order>
-
<group xsi:type="cluster" name="PRE_CLUSTER" title="Prepare Upgrade">
<direction>UPGRADE</direction>
<execute-stage service="HDFS" component="NAMENODE" title="Pre Upgrade HDFS">
http://git-wip-us.apache.org/repos/asf/ambari/blob/e5f6fb16/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/upgrade-2.3.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/upgrade-2.3.xml b/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/upgrade-2.3.xml
index 04befaf..6e1b38f 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/upgrade-2.3.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/upgrade-2.3.xml
@@ -20,6 +20,9 @@
<upgrade xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<target>2.3.*.*</target>
<target-stack>HDP-2.3</target-stack>
+ <skip-failures>false</skip-failures>
+ <skip-service-check-failures>false</skip-service-check-failures>
+
<order>
<group xsi:type="cluster" name="PRE_CLUSTER" title="Prepare Upgrade">
<direction>UPGRADE</direction>
http://git-wip-us.apache.org/repos/asf/ambari/blob/e5f6fb16/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/upgrade-2.3.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/upgrade-2.3.xml b/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/upgrade-2.3.xml
index 4719558..65ae2ed 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/upgrade-2.3.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/upgrade-2.3.xml
@@ -19,6 +19,8 @@
<upgrade xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<target>2.3.*.*</target>
+ <skip-failures>false</skip-failures>
+ <skip-service-check-failures>false</skip-service-check-failures>
<order>
<group xsi:type="cluster" name="PRE_CLUSTER" title="Prepare Upgrade">
http://git-wip-us.apache.org/repos/asf/ambari/blob/e5f6fb16/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java
index 7d2c117..61f65fa 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java
@@ -38,7 +38,6 @@ import org.apache.ambari.server.Role;
import org.apache.ambari.server.actionmanager.ActionManager;
import org.apache.ambari.server.actionmanager.HostRoleCommand;
import org.apache.ambari.server.actionmanager.HostRoleStatus;
-import org.apache.ambari.server.actionmanager.RequestStatus;
import org.apache.ambari.server.actionmanager.Stage;
import org.apache.ambari.server.api.resources.UpgradeResourceDefinition;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
@@ -46,6 +45,7 @@ import org.apache.ambari.server.controller.AmbariManagementController;
import org.apache.ambari.server.controller.AmbariServer;
import org.apache.ambari.server.controller.spi.Predicate;
import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.RequestStatus;
import org.apache.ambari.server.controller.spi.Resource;
import org.apache.ambari.server.controller.spi.ResourceProvider;
import org.apache.ambari.server.controller.utilities.PredicateBuilder;
@@ -66,6 +66,7 @@ import org.apache.ambari.server.orm.entities.StageEntity;
import org.apache.ambari.server.orm.entities.UpgradeEntity;
import org.apache.ambari.server.orm.entities.UpgradeGroupEntity;
import org.apache.ambari.server.orm.entities.UpgradeItemEntity;
+import org.apache.ambari.server.serveraction.upgrades.AutoSkipFailedSummaryAction;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.state.Config;
@@ -227,90 +228,43 @@ public class UpgradeResourceProviderTest {
injector = null;
}
- private org.apache.ambari.server.controller.spi.RequestStatus testCreateResources() throws Exception {
-
+ @Test
+ public void testCreateResourcesWithAutoSkipFailures() throws Exception {
Cluster cluster = clusters.getCluster("c1");
- List<UpgradeEntity> upgrades = upgradeDao.findUpgrades(cluster.getClusterId());
- assertEquals(0, upgrades.size());
-
Map<String, Object> requestProps = new HashMap<String, Object>();
requestProps.put(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME, "c1");
requestProps.put(UpgradeResourceProvider.UPGRADE_VERSION, "2.1.1.1");
+ requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_FAILURES, Boolean.TRUE.toString());
+ requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_SC_FAILURES, Boolean.TRUE.toString());
ResourceProvider upgradeResourceProvider = createProvider(amc);
-
Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null);
- org.apache.ambari.server.controller.spi.RequestStatus status = upgradeResourceProvider.createResources(request);
+ upgradeResourceProvider.createResources(request);
- upgrades = upgradeDao.findUpgrades(cluster.getClusterId());
+ List<UpgradeEntity> upgrades = upgradeDao.findUpgrades(cluster.getClusterId());
assertEquals(1, upgrades.size());
UpgradeEntity entity = upgrades.get(0);
assertEquals(cluster.getClusterId(), entity.getClusterId().longValue());
- StageDAO stageDAO = injector.getInstance(StageDAO.class);
- List<StageEntity> stageEntities = stageDAO.findByRequestId(entity.getRequestId());
- Gson gson = new Gson();
- for (StageEntity se : stageEntities) {
- Map<String, String> map = gson.<Map<String, String>>fromJson(se.getCommandParamsStage(), Map.class);
- assertTrue(map.containsKey("upgrade_direction"));
- assertEquals("upgrade", map.get("upgrade_direction"));
- }
-
List<UpgradeGroupEntity> upgradeGroups = entity.getUpgradeGroups();
assertEquals(3, upgradeGroups.size());
- UpgradeGroupEntity group = upgradeGroups.get(1);
- assertEquals(4, group.getItems().size());
-
- assertTrue(group.getItems().get(0).getText().contains(
- "placeholder of placeholder-rendered-properly"));
-
- assertTrue(group.getItems().get(1).getText().contains("Restarting"));
- assertTrue(group.getItems().get(2).getText().contains("Skipping"));
- assertTrue(group.getItems().get(3).getText().contains("Service Check"));
-
- ActionManager am = injector.getInstance(ActionManager.class);
- List<Long> requests = am.getRequestsByStatus(RequestStatus.IN_PROGRESS, 100, true);
-
- assertEquals(1, requests.size());
- assertEquals(requests.get(0), entity.getRequestId());
+ UpgradeGroupEntity zookeeperGroup = upgradeGroups.get(1);
+ assertEquals("ZOOKEEPER", zookeeperGroup.getName());
- List<Stage> stages = am.getRequestStatus(requests.get(0).longValue());
-
- assertEquals(8, stages.size());
+ List<UpgradeItemEntity> upgradeItems = zookeeperGroup.getItems();
+ assertEquals(5, upgradeItems.size());
- List<HostRoleCommand> tasks = am.getRequestTasks(requests.get(0).longValue());
- // same number of tasks as stages here
- assertEquals(8, tasks.size());
-
- Set<Long> slaveStageIds = new HashSet<Long>();
-
- UpgradeGroupEntity coreSlavesGroup = upgradeGroups.get(1);
-
- for (UpgradeItemEntity itemEntity : coreSlavesGroup.getItems()) {
- slaveStageIds.add(itemEntity.getStageId());
- }
-
- for (Stage stage : stages) {
-
- // For this test the core slaves group stages should be skippable and NOT allow retry.
- assertEquals(slaveStageIds.contains(stage.getStageId()), stage.isSkippable());
-
- for (Map<String, HostRoleCommand> taskMap : stage.getHostRoleCommands().values()) {
-
- for (HostRoleCommand task : taskMap.values()) {
- assertEquals(!slaveStageIds.contains(stage.getStageId()), task.isRetryAllowed());
- }
- }
- }
- return status;
+ // the last upgrade item is the skipped failure check
+ UpgradeItemEntity skippedFailureCheck = upgradeItems.get(upgradeItems.size() - 1);
+ skippedFailureCheck.getTasks().contains(AutoSkipFailedSummaryAction.class.getName());
}
@Test
public void testGetResources() throws Exception {
- org.apache.ambari.server.controller.spi.RequestStatus status = testCreateResources();
+ RequestStatus status = testCreateResources();
Set<Resource> createdResources = status.getAssociatedResources();
assertEquals(1, createdResources.size());
@@ -476,7 +430,8 @@ public class UpgradeResourceProviderTest {
ResourceProvider upgradeResourceProvider = createProvider(amc);
Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null);
- org.apache.ambari.server.controller.spi.RequestStatus status = upgradeResourceProvider.createResources(request);
+ RequestStatus status = upgradeResourceProvider.createResources(
+ request);
List<UpgradeEntity> upgrades = upgradeDao.findUpgrades(cluster.getClusterId());
assertEquals(1, upgrades.size());
@@ -525,7 +480,7 @@ public class UpgradeResourceProviderTest {
@Test
public void testAbort() throws Exception {
- org.apache.ambari.server.controller.spi.RequestStatus status = testCreateResources();
+ RequestStatus status = testCreateResources();
Set<Resource> createdResources = status.getAssociatedResources();
assertEquals(1, createdResources.size());
@@ -547,7 +502,7 @@ public class UpgradeResourceProviderTest {
@Test
public void testRetry() throws Exception {
- org.apache.ambari.server.controller.spi.RequestStatus status = testCreateResources();
+ RequestStatus status = testCreateResources();
Set<Resource> createdResources = status.getAssociatedResources();
assertEquals(1, createdResources.size());
@@ -657,7 +612,7 @@ public class UpgradeResourceProviderTest {
@Test
public void testPercents() throws Exception {
- org.apache.ambari.server.controller.spi.RequestStatus status = testCreateResources();
+ RequestStatus status = testCreateResources();
Set<Resource> createdResources = status.getAssociatedResources();
assertEquals(1, createdResources.size());
@@ -892,6 +847,90 @@ public class UpgradeResourceProviderTest {
return new UpgradeResourceProvider(amc);
}
+ private RequestStatus testCreateResources() throws Exception {
+
+ Cluster cluster = clusters.getCluster("c1");
+
+ List<UpgradeEntity> upgrades = upgradeDao.findUpgrades(cluster.getClusterId());
+ assertEquals(0, upgrades.size());
+
+ Map<String, Object> requestProps = new HashMap<String, Object>();
+ requestProps.put(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME, "c1");
+ requestProps.put(UpgradeResourceProvider.UPGRADE_VERSION, "2.1.1.1");
+
+ ResourceProvider upgradeResourceProvider = createProvider(amc);
+
+ Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null);
+ RequestStatus status = upgradeResourceProvider.createResources(request);
+
+ upgrades = upgradeDao.findUpgrades(cluster.getClusterId());
+ assertEquals(1, upgrades.size());
+
+ UpgradeEntity entity = upgrades.get(0);
+ assertEquals(cluster.getClusterId(), entity.getClusterId().longValue());
+
+ StageDAO stageDAO = injector.getInstance(StageDAO.class);
+ List<StageEntity> stageEntities = stageDAO.findByRequestId(entity.getRequestId());
+ Gson gson = new Gson();
+ for (StageEntity se : stageEntities) {
+ Map<String, String> map = gson.<Map<String, String>> fromJson(se.getCommandParamsStage(),
+ Map.class);
+ assertTrue(map.containsKey("upgrade_direction"));
+ assertEquals("upgrade", map.get("upgrade_direction"));
+ }
+
+ List<UpgradeGroupEntity> upgradeGroups = entity.getUpgradeGroups();
+ assertEquals(3, upgradeGroups.size());
+
+ UpgradeGroupEntity group = upgradeGroups.get(1);
+ assertEquals(4, group.getItems().size());
+
+ assertTrue(
+ group.getItems().get(0).getText().contains("placeholder of placeholder-rendered-properly"));
+
+ assertTrue(group.getItems().get(1).getText().contains("Restarting"));
+ assertTrue(group.getItems().get(2).getText().contains("Skipping"));
+ assertTrue(group.getItems().get(3).getText().contains("Service Check"));
+
+ ActionManager am = injector.getInstance(ActionManager.class);
+ List<Long> requests = am.getRequestsByStatus(
+ org.apache.ambari.server.actionmanager.RequestStatus.IN_PROGRESS, 100, true);
+
+ assertEquals(1, requests.size());
+ assertEquals(requests.get(0), entity.getRequestId());
+
+ List<Stage> stages = am.getRequestStatus(requests.get(0).longValue());
+
+ assertEquals(8, stages.size());
+
+ List<HostRoleCommand> tasks = am.getRequestTasks(requests.get(0).longValue());
+ // same number of tasks as stages here
+ assertEquals(8, tasks.size());
+
+ Set<Long> slaveStageIds = new HashSet<Long>();
+
+ UpgradeGroupEntity coreSlavesGroup = upgradeGroups.get(1);
+
+ for (UpgradeItemEntity itemEntity : coreSlavesGroup.getItems()) {
+ slaveStageIds.add(itemEntity.getStageId());
+ }
+
+ for (Stage stage : stages) {
+
+ // For this test the core slaves group stages should be skippable and NOT
+ // allow retry.
+ assertEquals(slaveStageIds.contains(stage.getStageId()), stage.isSkippable());
+
+ for (Map<String, HostRoleCommand> taskMap : stage.getHostRoleCommands().values()) {
+
+ for (HostRoleCommand task : taskMap.values()) {
+ assertEquals(!slaveStageIds.contains(stage.getStageId()), task.isRetryAllowed());
+ }
+ }
+ }
+ return status;
+ }
+
/**
*
*/
http://git-wip-us.apache.org/repos/asf/ambari/blob/e5f6fb16/ambari-server/src/test/java/org/apache/ambari/server/state/stack/UpgradePackTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/stack/UpgradePackTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/stack/UpgradePackTest.java
index e073b43..9ae78c4 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/stack/UpgradePackTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/stack/UpgradePackTest.java
@@ -44,6 +44,7 @@ import org.apache.ambari.server.state.stack.upgrade.ServiceCheckGrouping;
import org.apache.ambari.server.state.stack.upgrade.Task;
import org.apache.ambari.server.state.stack.upgrade.TransferOperation;
import org.junit.After;
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -156,12 +157,12 @@ public class UpgradePackTest {
assertEquals(4, ct.getTransfers().size());
/*
- <transfer operation="COPY" from-key="copy-key" to-key="copy-key-to" />
- <transfer operation="COPY" from-type="my-site" from-key="my-copy-key" to-key="my-copy-key-to" />
- <transfer operation="MOVE" from-key="move-key" to-key="move-key-to" />
- <transfer operation="DELETE" delete-key="delete-key">
- <keep-key>important-key</keep-key>
- </transfer>
+ <transfer operation="COPY" from-key="copy-key" to-key="copy-key-to" />
+ <transfer operation="COPY" from-type="my-site" from-key="my-copy-key" to-key="my-copy-key-to" />
+ <transfer operation="MOVE" from-key="move-key" to-key="move-key-to" />
+ <transfer operation="DELETE" delete-key="delete-key">
+ <keep-key>important-key</keep-key>
+ </transfer>
*/
Transfer t1 = ct.getTransfers().get(0);
assertEquals(TransferOperation.COPY, t1.operation);
@@ -283,7 +284,21 @@ public class UpgradePackTest {
group = groups.get(2);
assertEquals(ClusterGrouping.class, group.getClass());
assertEquals("Finalize Upgrade", group.title);
+ }
+
+ @Test
+ public void testSkippableFailures() throws Exception {
+ Map<String, UpgradePack> upgrades = ambariMetaInfo.getUpgradePacks("HDP", "2.1.1");
+ Set<String> keys = upgrades.keySet();
+ for (String key : keys) {
+ Assert.assertFalse(upgrades.get(key).isComponentFailureAutoSkipped());
+ Assert.assertFalse(upgrades.get(key).isServiceCheckFailureAutoSkipped());
+ }
+ upgrades = ambariMetaInfo.getUpgradePacks("HDP", "2.2.0");
+ UpgradePack upgradePack = upgrades.get("upgrade_test_skip_failures");
+ Assert.assertTrue(upgradePack.isComponentFailureAutoSkipped());
+ Assert.assertTrue(upgradePack.isServiceCheckFailureAutoSkipped());
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/e5f6fb16/ambari-server/src/test/resources/stacks/HDP/2.2.0/upgrades/upgrade_test_skip_failures.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/stacks/HDP/2.2.0/upgrades/upgrade_test_skip_failures.xml b/ambari-server/src/test/resources/stacks/HDP/2.2.0/upgrades/upgrade_test_skip_failures.xml
new file mode 100644
index 0000000..467e63a
--- /dev/null
+++ b/ambari-server/src/test/resources/stacks/HDP/2.2.0/upgrades/upgrade_test_skip_failures.xml
@@ -0,0 +1,52 @@
+<?xml version="1.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.
+-->
+<upgrade xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <target>2.2.*</target>
+ <skip-failures>true</skip-failures>
+ <skip-service-check-failures>true</skip-service-check-failures>
+
+ <order>
+ <group name="ZOOKEEPER" title="Zookeeper">
+ <skippable>true</skippable>
+ <allow-retry>false</allow-retry>
+ <service name="ZOOKEEPER">
+ <component>ZOOKEEPER_SERVER</component>
+ <component>ZOOKEEPER_CLIENT</component>
+ </service>
+ </group>
+ </order>
+
+ <processing>
+ <service name="ZOOKEEPER">
+ <component name="ZOOKEEPER_SERVER">
+ <pre-upgrade>
+ <task xsi:type="manual">
+ <summary>SUMMARY OF PREPARE</summary>
+ <message>This is a manual task with a placeholder of {{foo/bar}}</message>
+ </task>
+ </pre-upgrade>
+ <upgrade>
+ <task xsi:type="restart" />
+ </upgrade>
+ <post-upgrade>
+ <task xsi:type="configure" />
+ </post-upgrade>
+ </component>
+ </service>
+ </processing>
+</upgrade>
[2/2] ambari git commit: AMBARI-13064 - Provide Summary Of Skipped
Failures During Upgrade (jonathanhurley)
Posted by jo...@apache.org.
AMBARI-13064 - Provide Summary Of Skipped Failures During Upgrade (jonathanhurley)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/c7a714cf
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/c7a714cf
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/c7a714cf
Branch: refs/heads/trunk
Commit: c7a714cf0f4d0a86f6840a5e5d7997a185ae4166
Parents: 70ca850
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Thu Sep 10 15:06:21 2015 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Fri Sep 11 22:51:25 2015 -0400
----------------------------------------------------------------------
.../internal/UpgradeResourceProvider.java | 6 +-
.../server/orm/dao/HostRoleCommandDAO.java | 29 +++
.../orm/entities/HostRoleCommandEntity.java | 19 +-
.../upgrades/AutoSkipFailedSummaryAction.java | 189 +++++++++++++++++++
.../ambari/server/state/UpgradeHelper.java | 16 +-
.../ambari/server/state/stack/UpgradePack.java | 1 +
.../state/stack/upgrade/ClusterGrouping.java | 35 ++--
.../state/stack/upgrade/ColocatedGrouping.java | 26 ++-
.../server/state/stack/upgrade/Grouping.java | 33 ++--
.../state/stack/upgrade/ServerActionTask.java | 2 -
.../stack/upgrade/ServiceCheckGrouping.java | 49 +++--
.../stack/upgrade/StageWrapperBuilder.java | 127 ++++++++++++-
.../server/orm/dao/HostRoleCommandDAOTest.java | 155 +++++++++++++++
.../stack/upgrade/StageWrapperBuilderTest.java | 162 ++++++++++++++++
14 files changed, 784 insertions(+), 65 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/c7a714cf/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 b45f1ac..19a3397 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
@@ -35,7 +35,6 @@ import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import com.google.gson.Gson;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.Role;
import org.apache.ambari.server.RoleCommand;
@@ -66,7 +65,6 @@ import org.apache.ambari.server.controller.spi.SystemException;
import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
import org.apache.ambari.server.controller.utilities.PredicateBuilder;
import org.apache.ambari.server.controller.utilities.PropertyHelper;
-import org.apache.ambari.server.orm.dao.HostDAO;
import org.apache.ambari.server.orm.dao.HostRoleCommandDAO;
import org.apache.ambari.server.orm.dao.HostRoleCommandStatusSummaryDTO;
import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
@@ -104,6 +102,7 @@ import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.gson.Gson;
import com.google.inject.Inject;
import com.google.inject.Provider;
@@ -204,9 +203,6 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
@Inject
private static HostRoleCommandDAO s_hostRoleCommandDAO = null;
- @Inject
- private static HostDAO s_hostDAO = null;
-
/**
* Used to generated the correct tasks and stages during an upgrade.
*/
http://git-wip-us.apache.org/repos/asf/ambari/blob/c7a714cf/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAO.java
index 06799a0..70e2940 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAO.java
@@ -313,6 +313,35 @@ public class HostRoleCommandDAO {
}
/**
+ * Finds all the {@link HostRoleCommandEntity}s for the given request that are
+ * between the specified stage IDs and have the specified status.
+ *
+ * @param requestId
+ * the request ID
+ * @param status
+ * the command status to query for (not {@code null}).
+ * @param minStageId
+ * the lowest stage ID to requests tasks for.
+ * @param maxStageId
+ * the highest stage ID to request tasks for.
+ * @return the tasks that satisfy the specified parameters.
+ */
+ @RequiresSession
+ public List<HostRoleCommandEntity> findByStatusBetweenStages(long requestId,
+ HostRoleStatus status, long minStageId, long maxStageId) {
+
+ TypedQuery<HostRoleCommandEntity> query = entityManagerProvider.get().createNamedQuery(
+ "HostRoleCommandEntity.findByStatusBetweenStages", HostRoleCommandEntity.class);
+
+ query.setParameter("requestId", requestId);
+ query.setParameter("status", status);
+ query.setParameter("minStageId", minStageId);
+ query.setParameter("maxStageId", maxStageId);
+
+ return daoUtils.selectList(query);
+ }
+
+ /**
* Gets requests that have tasks in any of the specified statuses.
*
* @param statuses
http://git-wip-us.apache.org/repos/asf/ambari/blob/c7a714cf/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostRoleCommandEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostRoleCommandEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostRoleCommandEntity.java
index ae78890..e0662fb 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostRoleCommandEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostRoleCommandEntity.java
@@ -59,7 +59,8 @@ import org.apache.commons.lang.ArrayUtils;
@NamedQuery(name = "HostRoleCommandEntity.findByCommandStatuses", query = "SELECT command FROM HostRoleCommandEntity command WHERE command.status IN :statuses ORDER BY command.requestId, command.stageId"),
@NamedQuery(name = "HostRoleCommandEntity.findByHostId", query = "SELECT command FROM HostRoleCommandEntity command WHERE command.hostId=:hostId"),
@NamedQuery(name = "HostRoleCommandEntity.findByHostRole", query = "SELECT command FROM HostRoleCommandEntity command WHERE command.hostEntity.hostName=:hostName AND command.requestId=:requestId AND command.stageId=:stageId AND command.role=:role ORDER BY command.taskId"),
- @NamedQuery(name = "HostRoleCommandEntity.findByHostRoleNullHost", query = "SELECT command FROM HostRoleCommandEntity command WHERE command.hostEntity IS NULL AND command.requestId=:requestId AND command.stageId=:stageId AND command.role=:role")
+ @NamedQuery(name = "HostRoleCommandEntity.findByHostRoleNullHost", query = "SELECT command FROM HostRoleCommandEntity command WHERE command.hostEntity IS NULL AND command.requestId=:requestId AND command.stageId=:stageId AND command.role=:role"),
+ @NamedQuery(name = "HostRoleCommandEntity.findByStatusBetweenStages", query = "SELECT command FROM HostRoleCommandEntity command WHERE command.requestId = :requestId AND command.stageId >= :minStageId AND command.stageId <= :maxStageId AND command.status = :status")
})
public class HostRoleCommandEntity {
@@ -492,4 +493,20 @@ public class HostRoleCommandEntity {
public void setTopologyLogicalTaskEntity(TopologyLogicalTaskEntity topologyLogicalTaskEntity) {
this.topologyLogicalTaskEntity = topologyLogicalTaskEntity;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ StringBuilder buffer = new StringBuilder("HostRoleCommandEntity{ ");
+ buffer.append("taskId").append(taskId);
+ buffer.append(", stageId=").append(stageId);
+ buffer.append(", requestId=").append(requestId);
+ buffer.append(", role=").append(role);
+ buffer.append(", roleCommand=").append(roleCommand);
+ buffer.append(", exitcode=").append(exitcode);
+ buffer.append("}");
+ return buffer.toString();
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c7a714cf/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/AutoSkipFailedSummaryAction.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/AutoSkipFailedSummaryAction.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/AutoSkipFailedSummaryAction.java
new file mode 100644
index 0000000..9a84e38
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/AutoSkipFailedSummaryAction.java
@@ -0,0 +1,189 @@
+/**
+ * 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.ambari.server.serveraction.upgrades;
+
+import java.text.MessageFormat;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeSet;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.actionmanager.HostRoleCommand;
+import org.apache.ambari.server.actionmanager.HostRoleStatus;
+import org.apache.ambari.server.actionmanager.ServiceComponentHostEventWrapper;
+import org.apache.ambari.server.agent.CommandReport;
+import org.apache.ambari.server.orm.dao.HostRoleCommandDAO;
+import org.apache.ambari.server.orm.dao.UpgradeDAO;
+import org.apache.ambari.server.orm.entities.HostRoleCommandEntity;
+import org.apache.ambari.server.orm.entities.UpgradeGroupEntity;
+import org.apache.ambari.server.orm.entities.UpgradeItemEntity;
+import org.apache.ambari.server.serveraction.AbstractServerAction;
+import org.apache.ambari.server.state.ServiceComponentHostEvent;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.gson.Gson;
+import com.google.inject.Inject;
+
+/**
+ * The {@link AutoSkipFailedSummaryAction} is used to check if any
+ * {@link HostRoleCommand}s were skipped automatically after they failed during
+ * an upgrade. This will be automatically marked as
+ * {@link HostRoleStatus#COMPLETED} if there are no skipped failures. Otherwise
+ * it will be placed into {@link HostRoleStatus#HOLDING}.
+ */
+public class AutoSkipFailedSummaryAction extends AbstractServerAction {
+
+ /**
+ * Logger.
+ */
+ private static final Logger LOG = LoggerFactory.getLogger(AutoSkipFailedSummaryAction.class);
+
+ /**
+ * The standard output template message.
+ */
+ private static final String FAILURE_STD_OUT_TEMPLATE = "There were {0} skipped failure(s) that must be addressed before you can proceed. Please resolve each failure before continuing with the upgrade.";
+
+ /**
+ * ...
+ */
+ private static final String MIDDLE_ELLIPSIZE_MARKER = "\n\u2026\n";
+
+ /**
+ * Used to lookup the {@link UpgradeGroupEntity}.
+ */
+ @Inject
+ private UpgradeDAO m_upgradeDAO;
+
+ /**
+ * Used to lookup the tasks that need to be checked for
+ * {@link HostRoleStatus#SKIPPED_FAILED}.
+ */
+ @Inject
+ private HostRoleCommandDAO m_hostRoleCommandDAO;
+
+ /**
+ * Used for writing structured out.
+ */
+ @Inject
+ private Gson m_gson;
+
+ /**
+ * A mapping of host -> Map<key,info> for each failure.
+ */
+ private Map<String, Map<String, Object>> m_structuredFailures = new HashMap<>();
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public CommandReport execute(ConcurrentMap<String, Object> requestSharedDataContext)
+ throws AmbariException, InterruptedException {
+
+ HostRoleCommand hostRoleCommand = getHostRoleCommand();
+ long requestId = hostRoleCommand.getRequestId();
+ long stageId = hostRoleCommand.getStageId();
+
+ // use the host role command to get to the parent upgrade group
+ UpgradeItemEntity upgradeItem = m_upgradeDAO.findUpgradeItemByRequestAndStage(requestId,stageId);
+ UpgradeGroupEntity upgradeGroup = upgradeItem.getGroupEntity();
+
+ // find all of the stages in this group
+ long upgradeGroupId = upgradeGroup.getId();
+ UpgradeGroupEntity upgradeGroupEntity = m_upgradeDAO.findUpgradeGroup(upgradeGroupId);
+ List<UpgradeItemEntity> groupUpgradeItems = upgradeGroupEntity.getItems();
+ TreeSet<Long> stageIds = new TreeSet<>();
+ for (UpgradeItemEntity groupUpgradeItem : groupUpgradeItems) {
+ stageIds.add(groupUpgradeItem.getStageId());
+ }
+
+ // for every stage, find all tasks that have been SKIPPED_FAILED - we use a
+ // bit of trickery here since within any given request, the stage ID are
+ // always sequential. This allows us to make a simple query instead of some
+ // overly complex IN or NESTED SELECT query
+ long minStageId = stageIds.first();
+ long maxStageId = stageIds.last();
+
+ List<HostRoleCommandEntity> skippedTasks = m_hostRoleCommandDAO.findByStatusBetweenStages(
+ hostRoleCommand.getRequestId(),
+ HostRoleStatus.SKIPPED_FAILED, minStageId, maxStageId);
+
+ if (skippedTasks.isEmpty()) {
+ return createCommandReport(0, HostRoleStatus.COMPLETED, "{}",
+ "There were no skipped failures", null);
+ }
+
+ StringBuilder buffer = new StringBuilder("The following steps failed and were automatically skipped:\n");
+
+ for (HostRoleCommandEntity skippedTask : skippedTasks) {
+ try{
+ ServiceComponentHostEventWrapper eventWrapper = new ServiceComponentHostEventWrapper(
+ skippedTask.getEvent());
+
+ ServiceComponentHostEvent event = eventWrapper.getEvent();
+
+ String hostName = skippedTask.getHostName();
+ if(null != hostName){
+ Map<String, Object> failures = m_structuredFailures.get(hostName);
+ if( null == failures ){
+ failures = new HashMap<>();
+ m_structuredFailures.put(hostName, failures);
+ }
+
+ failures.put("id", skippedTask.getTaskId());
+ failures.put("exit_code", skippedTask.getExitcode());
+ failures.put("output_log", skippedTask.getOutputLog());
+ failures.put("error_log", skippedTask.getErrorLog());
+
+ String stdOut = StringUtils.abbreviateMiddle(new String(skippedTask.getStdOut()),
+ MIDDLE_ELLIPSIZE_MARKER, 1000);
+
+ String stderr = StringUtils.abbreviateMiddle(new String(skippedTask.getStdError()),
+ MIDDLE_ELLIPSIZE_MARKER, 1000);
+
+ failures.put("stdout", stdOut);
+ failures.put("stderr", stderr);
+ }
+
+ buffer.append(event.getServiceComponentName());
+ if (null != event.getHostName()) {
+ buffer.append(" on ");
+ buffer.append(event.getHostName());
+ }
+
+ buffer.append(": ");
+ buffer.append(skippedTask.getCommandDetail());
+ buffer.append("\n");
+ } catch (Exception exception) {
+ LOG.warn("Unable to extract failure information for {}", skippedTask);
+ buffer.append(": ");
+ buffer.append(skippedTask);
+ }
+ }
+
+ String structuredOutput = m_gson.toJson(m_structuredFailures);
+ String standardOutput = MessageFormat.format(FAILURE_STD_OUT_TEMPLATE, skippedTasks.size());
+ String standardError = buffer.toString();
+
+ return createCommandReport(0, HostRoleStatus.HOLDING, structuredOutput, standardOutput,
+ standardError);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c7a714cf/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeHelper.java
index 5e63744..75c04da 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeHelper.java
@@ -439,9 +439,21 @@ public class UpgradeHelper {
* List of stages for the group
*/
public List<StageWrapper> items = new ArrayList<StageWrapper>();
- }
-
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ StringBuilder buffer = new StringBuilder("UpgradeGroupHolder{ ");
+ buffer.append("name").append(name);
+ buffer.append(", title=").append(title);
+ buffer.append(", allowRetry=").append(allowRetry);
+ buffer.append(", skippable=").append(skippable);
+ buffer.append("}");
+ return buffer.toString();
+ }
+ }
/**
* Gets a set of Stages resources to aggregate an UpgradeItem with Stage.
http://git-wip-us.apache.org/repos/asf/ambari/blob/c7a714cf/ambari-server/src/main/java/org/apache/ambari/server/state/stack/UpgradePack.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/UpgradePack.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/UpgradePack.java
index 9691292..3e9aa5f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/UpgradePack.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/UpgradePack.java
@@ -94,6 +94,7 @@ public class UpgradePack {
if (null == group.intendedDirection || direction == group.intendedDirection) {
checked.add(group);
}
+
}
return checked;
http://git-wip-us.apache.org/repos/asf/ambari/blob/c7a714cf/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ClusterGrouping.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ClusterGrouping.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ClusterGrouping.java
index cf58511..eff1b13 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ClusterGrouping.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ClusterGrouping.java
@@ -31,7 +31,6 @@ import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
import org.apache.ambari.server.stack.HostsType;
@@ -59,12 +58,9 @@ public class ClusterGrouping extends Grouping {
@XmlElement(name="execute-stage")
public List<ExecuteStage> executionStages;
- @XmlTransient
- private ClusterBuilder m_builder = new ClusterBuilder();
-
@Override
public ClusterBuilder getBuilder() {
- return m_builder;
+ return new ClusterBuilder(this);
}
@@ -100,24 +96,39 @@ public class ClusterGrouping extends Grouping {
public class ClusterBuilder extends StageWrapperBuilder {
+ /**
+ * Constructor.
+ *
+ * @param grouping
+ * the upgrade/downgrade grouping (not {@code null}).
+ */
+ private ClusterBuilder(Grouping grouping) {
+ super(grouping);
+ }
+
@Override
public void add(UpgradeContext ctx, HostsType hostsType, String service,
boolean clientOnly, ProcessingComponent pc) {
// !!! no-op in this case
}
+ /**
+ * {@inheritDoc}
+ */
@Override
- public List<StageWrapper> build(UpgradeContext ctx) {
+ public List<StageWrapper> build(UpgradeContext upgradeContext,
+ List<StageWrapper> stageWrappers) {
+
if (null == executionStages) {
- return Collections.emptyList();
+ return stageWrappers;
}
- List<StageWrapper> results = new ArrayList<StageWrapper>();
+ List<StageWrapper> results = new ArrayList<StageWrapper>(stageWrappers);
if (executionStages != null) {
for (ExecuteStage execution : executionStages) {
- if (null != execution.intendedDirection &&
- execution.intendedDirection != ctx.getDirection()) {
+ if (null != execution.intendedDirection
+ && execution.intendedDirection != upgradeContext.getDirection()) {
continue;
}
@@ -127,7 +138,7 @@ public class ClusterGrouping extends Grouping {
switch (task.getType()) {
case MANUAL:
- wrapper = getManualStageWrapper(ctx, execution);
+ wrapper = getManualStageWrapper(upgradeContext, execution);
break;
case SERVER_ACTION:
@@ -138,7 +149,7 @@ public class ClusterGrouping extends Grouping {
break;
case EXECUTE:
- wrapper = getExecuteStageWrapper(ctx, execution);
+ wrapper = getExecuteStageWrapper(upgradeContext, execution);
break;
default:
http://git-wip-us.apache.org/repos/asf/ambari/blob/c7a714cf/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ColocatedGrouping.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ColocatedGrouping.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ColocatedGrouping.java
index a8e9c43..2aef43c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ColocatedGrouping.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ColocatedGrouping.java
@@ -54,9 +54,12 @@ public class ColocatedGrouping extends Grouping {
public Batch batch;
+ /**
+ * {@inheritDoc}
+ */
@Override
public StageWrapperBuilder getBuilder() {
- return new MultiHomedBuilder(batch, performServiceCheck);
+ return new MultiHomedBuilder(this, batch, performServiceCheck);
}
private static class MultiHomedBuilder extends StageWrapperBuilder {
@@ -69,7 +72,9 @@ public class ColocatedGrouping extends Grouping {
private Map<String, List<TaskProxy>> finalBatches = new LinkedHashMap<String, List<TaskProxy>>();
- private MultiHomedBuilder(Batch batch, boolean serviceCheck) {
+ private MultiHomedBuilder(Grouping grouping, Batch batch, boolean serviceCheck) {
+ super(grouping);
+
m_batch = batch;
m_serviceCheck = serviceCheck;
}
@@ -143,16 +148,20 @@ public class ColocatedGrouping extends Grouping {
}
+ /**
+ * {@inheritDoc}
+ */
@Override
- public List<StageWrapper> build(UpgradeContext ctx) {
- List<StageWrapper> results = new ArrayList<StageWrapper>();
+ public List<StageWrapper> build(UpgradeContext upgradeContext,
+ List<StageWrapper> stageWrappers) {
+ List<StageWrapper> results = new ArrayList<StageWrapper>(stageWrappers);
if (LOG.isDebugEnabled()) {
LOG.debug("RU initial: {}", initialBatch);
LOG.debug("RU final: {}", finalBatches);
}
- List<StageWrapper> befores = fromProxies(ctx.getDirection(), initialBatch);
+ List<StageWrapper> befores = fromProxies(upgradeContext.getDirection(), initialBatch);
results.addAll(befores);
if (!befores.isEmpty()) {
@@ -160,16 +169,17 @@ public class ColocatedGrouping extends Grouping {
ManualTask task = new ManualTask();
task.summary = m_batch.summary;
task.message = m_batch.message;
- formatFirstBatch(ctx, task, befores);
+ formatFirstBatch(upgradeContext, task, befores);
StageWrapper wrapper = new StageWrapper(
StageWrapper.Type.SERVER_SIDE_ACTION,
- "Validate Partial " + ctx.getDirection().getText(true),
+ "Validate Partial " + upgradeContext.getDirection().getText(true),
new TaskWrapper(null, null, Collections.<String>emptySet(), task));
+
results.add(wrapper);
}
- results.addAll(fromProxies(ctx.getDirection(), finalBatches));
+ results.addAll(fromProxies(upgradeContext.getDirection(), finalBatches));
return results;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c7a714cf/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/Grouping.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/Grouping.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/Grouping.java
index a1e1fcd..cd27722 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/Grouping.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/Grouping.java
@@ -65,7 +65,7 @@ public class Grouping {
* Gets the default builder.
*/
public StageWrapperBuilder getBuilder() {
- return new DefaultBuilder(performServiceCheck);
+ return new DefaultBuilder(this, performServiceCheck);
}
@@ -75,7 +75,8 @@ public class Grouping {
private Set<String> m_servicesToCheck = new HashSet<String>();
private boolean m_serviceCheck = true;
- private DefaultBuilder(boolean serviceCheck) {
+ private DefaultBuilder(Grouping grouping, boolean serviceCheck) {
+ super(grouping);
m_serviceCheck = serviceCheck;
}
@@ -139,23 +140,32 @@ public class Grouping {
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
- public List<StageWrapper> build(UpgradeContext ctx) {
+ public List<StageWrapper> build(UpgradeContext upgradeContext,
+ List<StageWrapper> stageWrappers) {
+
+ // insert all pre-processed stage wrappers first
+ if (!stageWrappers.isEmpty()) {
+ m_stages.addAll(0, stageWrappers);
+ }
List<TaskWrapper> tasks = new ArrayList<TaskWrapper>();
List<String> displays = new ArrayList<String>();
for (String service : m_servicesToCheck) {
tasks.add(new TaskWrapper(
service, "", Collections.<String>emptySet(), new ServiceCheckTask()));
- displays.add(ctx.getServiceDisplay(service));
+
+ displays.add(upgradeContext.getServiceDisplay(service));
}
- if (ctx.getDirection().isUpgrade() && m_serviceCheck && m_servicesToCheck.size() > 0) {
- StageWrapper wrapper = new StageWrapper(
- StageWrapper.Type.SERVICE_CHECK,
- "Service Check " + StringUtils.join(displays, ", "),
- tasks.toArray(new TaskWrapper[0])
- );
+ if (upgradeContext.getDirection().isUpgrade() && m_serviceCheck
+ && m_servicesToCheck.size() > 0) {
+
+ StageWrapper wrapper = new StageWrapper(StageWrapper.Type.SERVICE_CHECK,
+ "Service Check " + StringUtils.join(displays, ", "), tasks.toArray(new TaskWrapper[0]));
m_stages.add(wrapper);
}
@@ -168,8 +178,9 @@ public class Grouping {
* Group all like-typed tasks together. When they change, create a new type.
*/
private static List<TaskBucket> buckets(List<Task> tasks) {
- if (null == tasks || tasks.isEmpty())
+ if (null == tasks || tasks.isEmpty()) {
return Collections.emptyList();
+ }
List<TaskBucket> holders = new ArrayList<TaskBucket>();
http://git-wip-us.apache.org/repos/asf/ambari/blob/c7a714cf/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ServerActionTask.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ServerActionTask.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ServerActionTask.java
index 7a42c3b..74144b7 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ServerActionTask.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ServerActionTask.java
@@ -17,8 +17,6 @@
*/
package org.apache.ambari.server.state.stack.upgrade;
-import org.apache.ambari.server.serveraction.upgrades.FinalizeUpgradeAction;
-
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
http://git-wip-us.apache.org/repos/asf/ambari/blob/c7a714cf/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ServiceCheckGrouping.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ServiceCheckGrouping.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ServiceCheckGrouping.java
index fdf89cc..6061895 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ServiceCheckGrouping.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ServiceCheckGrouping.java
@@ -58,11 +58,12 @@ public class ServiceCheckGrouping extends Grouping {
@XmlElement(name="service")
private Set<String> excludeServices = new HashSet<String>();
- private ServiceCheckBuilder m_builder = new ServiceCheckBuilder();
-
+ /**
+ * {@inheritDoc}
+ */
@Override
public ServiceCheckBuilder getBuilder() {
- return m_builder;
+ return new ServiceCheckBuilder(this);
}
/**
@@ -76,23 +77,40 @@ public class ServiceCheckGrouping extends Grouping {
* Used to build stages for service check groupings.
*/
public class ServiceCheckBuilder extends StageWrapperBuilder {
+
private Cluster m_cluster;
private AmbariMetaInfo m_metaInfo;
+ /**
+ * Constructor.
+ *
+ * @param grouping
+ * the upgrade/downgrade grouping (not {@code null}).
+ */
+ protected ServiceCheckBuilder(Grouping grouping) {
+ super(grouping);
+ }
+ /**
+ * {@inheritDoc}
+ */
@Override
public void add(UpgradeContext ctx, HostsType hostsType, String service,
boolean clientOnly, ProcessingComponent pc) {
// !!! nothing to do here
}
+ /**
+ * {@inheritDoc}
+ */
@Override
- public List<StageWrapper> build(UpgradeContext ctx) {
- m_cluster = ctx.getCluster();
- m_metaInfo = ctx.getAmbariMetaInfo();
+ public List<StageWrapper> build(UpgradeContext upgradeContext,
+ List<StageWrapper> stageWrappers) {
+ m_cluster = upgradeContext.getCluster();
+ m_metaInfo = upgradeContext.getAmbariMetaInfo();
- List<StageWrapper> result = new ArrayList<StageWrapper>();
- if (ctx.getDirection().isDowngrade()) {
+ List<StageWrapper> result = new ArrayList<StageWrapper>(stageWrappers);
+ if (upgradeContext.getDirection().isDowngrade()) {
return result;
}
@@ -101,28 +119,29 @@ public class ServiceCheckGrouping extends Grouping {
Set<String> clusterServices = new LinkedHashSet<String>(serviceMap.keySet());
// create stages for the priorities
- for (String service : ServiceCheckGrouping.this.priorityServices) {
- if (checkServiceValidity(ctx, service, serviceMap)) {
+ for (String service : priorityServices) {
+ if (checkServiceValidity(upgradeContext, service, serviceMap)) {
StageWrapper wrapper = new StageWrapper(
StageWrapper.Type.SERVICE_CHECK,
- "Service Check " + ctx.getServiceDisplay(service),
+ "Service Check " + upgradeContext.getServiceDisplay(service),
new TaskWrapper(service, "", Collections.<String>emptySet(),
new ServiceCheckTask()));
- result.add(wrapper);
+ result.add(wrapper);
clusterServices.remove(service);
}
}
// create stages for everything else, as long it is valid
for (String service : clusterServices) {
- if (ServiceCheckGrouping.this.excludeServices.contains(service)) {
+ if (excludeServices.contains(service)) {
continue;
}
- if (checkServiceValidity(ctx, service, serviceMap)) {
+
+ if (checkServiceValidity(upgradeContext, service, serviceMap)) {
StageWrapper wrapper = new StageWrapper(
StageWrapper.Type.SERVICE_CHECK,
- "Service Check " + ctx.getServiceDisplay(service),
+ "Service Check " + upgradeContext.getServiceDisplay(service),
new TaskWrapper(service, "", Collections.<String>emptySet(),
new ServiceCheckTask()));
result.add(wrapper);
http://git-wip-us.apache.org/repos/asf/ambari/blob/c7a714cf/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/StageWrapperBuilder.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/StageWrapperBuilder.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/StageWrapperBuilder.java
index f7b37ab..57cd41f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/StageWrapperBuilder.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/StageWrapperBuilder.java
@@ -17,9 +17,12 @@
*/
package org.apache.ambari.server.state.stack.upgrade;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Set;
+import org.apache.ambari.server.serveraction.upgrades.AutoSkipFailedSummaryAction;
import org.apache.ambari.server.stack.HostsType;
import org.apache.ambari.server.state.UpgradeContext;
import org.apache.ambari.server.state.stack.UpgradePack.ProcessingComponent;
@@ -30,23 +33,129 @@ import org.apache.ambari.server.state.stack.UpgradePack.ProcessingComponent;
public abstract class StageWrapperBuilder {
/**
+ * The message for the task which checks for skipped failures.
+ */
+ private static final String AUTO_SKIPPED_TASK_SUMMARY = "Pauses the upgrade if there were failed steps that were automatically skipped.";
+
+ /**
+ * The upgrade/downgrade grouping that the builder is for.
+ */
+ protected final Grouping m_grouping;
+
+ /**
+ * Constructor.
+ *
+ * @param grouping
+ * the upgrade/downgrade grouping (not {@code null}).
+ */
+ protected StageWrapperBuilder(Grouping grouping) {
+ m_grouping = grouping;
+ }
+
+ /**
* Adds a processing component that will be built into stage wrappers.
*
- * @param ctx the upgrade context
- * @param hostsType the hosts, along with their type
- * @param service the service name
- * @param clientOnly whether the service is client only, no service checks
- * @param pc the ProcessingComponent derived from the upgrade pack
+ * @param upgradeContext
+ * the upgrade context
+ * @param hostsType
+ * the hosts, along with their type
+ * @param service
+ * the service name
+ * @param clientOnly
+ * whether the service is client only, no service checks
+ * @param pc
+ * the ProcessingComponent derived from the upgrade pack
*/
- public abstract void add(UpgradeContext ctx, HostsType hostsType, String service,
+ public abstract void add(UpgradeContext upgradeContext, HostsType hostsType, String service,
boolean clientOnly, ProcessingComponent pc);
/**
- * Builds the stage wrappers.
- * @param ctx the upgrade context
+ * Builds the stage wrappers, including any pre- and post-procesing that needs
+ * to be performed.
+ *
+ * @param upgradeContext
+ * the upgrade context (not {@code null}).
* @return a list of stages, never {@code null}
*/
- public abstract List<StageWrapper> build(UpgradeContext ctx);
+ public final List<StageWrapper> build(UpgradeContext upgradeContext) {
+ List<StageWrapper> stageWrappers = beforeBuild(upgradeContext);
+ stageWrappers = build(upgradeContext, stageWrappers);
+ stageWrappers = afterBuild(upgradeContext, stageWrappers);
+ return stageWrappers;
+ }
+
+ /**
+ * Performs any pre-processing that needs to be performed on the list of stage
+ * wrappers.
+ *
+ * @param upgradeContext
+ * the upgrade context (not {@code null}).
+ * @return the initial list of stage wrappers, or an empty list (never
+ * {@code null}).
+ */
+ protected List<StageWrapper> beforeBuild(UpgradeContext upgradeContext) {
+ List<StageWrapper> stageWrappers = new ArrayList<>(100);
+ return stageWrappers;
+ }
+
+ /**
+ * Builds the stage wrappers.
+ *
+ * @param upgradeContext
+ * the upgrade context (not {@code null}).
+ * @param stageWrappers
+ * the list of stage wrappers created by
+ * {@link #beforeBuild(UpgradeContext)}.
+ * @return the stage wrapper list, (never {@code null})
+ */
+ public abstract List<StageWrapper> build(UpgradeContext upgradeContext,
+ List<StageWrapper> stageWrappers);
+
+ /**
+ * Performs any post-processing that needs to be performed on the list of
+ * stage wrappers.
+ *
+ * @param upgradeContext
+ * the upgrade context (not {@code null}).
+ * @param stageWrappers
+ * the list of stage wrappers created by
+ * {@link #build(UpgradeContext, List)}.
+ * @return the post-processed list of stage wrappers (never {@code null})
+ */
+ protected List<StageWrapper> afterBuild(UpgradeContext upgradeContext,
+ List<StageWrapper> stageWrappers) {
+
+ if (stageWrappers.isEmpty()) {
+ return stageWrappers;
+ }
+
+ // we only want to insert the auto skip summary if the group is skippable
+ // and the upgrade context says to auto skip failures
+ final boolean autoSkipFailures;
+ if (m_grouping instanceof ServiceCheckGrouping) {
+ autoSkipFailures = upgradeContext.isServiceCheckFailureAutoSkipped();
+ } else {
+ autoSkipFailures = upgradeContext.isComponentFailureAutoSkipped();
+ }
+
+ if (m_grouping.skippable && autoSkipFailures) {
+ ServerActionTask skippedFailedCheck = new ServerActionTask();
+ skippedFailedCheck.implClass = AutoSkipFailedSummaryAction.class.getName();
+ skippedFailedCheck.summary = AUTO_SKIPPED_TASK_SUMMARY;
+
+ TaskWrapper skippedFailedTaskWrapper = new TaskWrapper(null, null,
+ Collections.<String> emptySet(), skippedFailedCheck);
+
+ StageWrapper skippedFailedStageWrapper = new StageWrapper(
+ StageWrapper.Type.SERVER_SIDE_ACTION, "Verifying Skipped Failures",
+ skippedFailedTaskWrapper);
+
+ stageWrappers.add(skippedFailedStageWrapper);
+ }
+
+ return stageWrappers;
+ }
+
/**
* Consistently formats a string.
http://git-wip-us.apache.org/repos/asf/ambari/blob/c7a714cf/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAOTest.java
new file mode 100644
index 0000000..1fded28
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAOTest.java
@@ -0,0 +1,155 @@
+/**
+ * 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.ambari.server.orm.dao;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.Role;
+import org.apache.ambari.server.RoleCommand;
+import org.apache.ambari.server.actionmanager.HostRoleStatus;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.orm.GuiceJpaInitializer;
+import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
+import org.apache.ambari.server.orm.OrmTestHelper;
+import org.apache.ambari.server.orm.entities.ClusterEntity;
+import org.apache.ambari.server.orm.entities.HostEntity;
+import org.apache.ambari.server.orm.entities.HostRoleCommandEntity;
+import org.apache.ambari.server.orm.entities.RequestEntity;
+import org.apache.ambari.server.orm.entities.StageEntity;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.persist.PersistService;
+
+import junit.framework.Assert;
+
+/**
+ * Tests {@link HostRoleCommandDAO}.
+ */
+public class HostRoleCommandDAOTest {
+
+ private Injector m_injector;
+ private ClusterDAO m_clusterDAO;
+ private StageDAO m_stageDAO;
+ private HostRoleCommandDAO m_hostRoleCommandDAO;
+ private HostDAO m_hostDAO;
+ private RequestDAO m_requestDAO;
+
+ @Before
+ public void setup() throws Exception {
+ m_injector = Guice.createInjector(new InMemoryDefaultTestModule());
+ m_injector.getInstance(GuiceJpaInitializer.class);
+ m_injector.getInstance(AmbariMetaInfo.class);
+
+ m_clusterDAO = m_injector.getInstance(ClusterDAO.class);
+ m_stageDAO = m_injector.getInstance(StageDAO.class);
+ m_hostRoleCommandDAO = m_injector.getInstance(HostRoleCommandDAO.class);
+ m_hostDAO = m_injector.getInstance(HostDAO.class);
+ m_requestDAO = m_injector.getInstance(RequestDAO.class);
+ }
+
+ @After
+ public void teardown() throws AmbariException {
+ m_injector.getInstance(PersistService.class).stop();
+ }
+
+ /**
+ * Tests finding all tasks between a range of stages.
+ */
+ @Test
+ public void testFindTasksBetweenStages() {
+ OrmTestHelper helper = m_injector.getInstance(OrmTestHelper.class);
+ helper.createDefaultData();
+
+ Long requestId = Long.valueOf(100L);
+ ClusterEntity clusterEntity = m_clusterDAO.findByName("test_cluster1");
+
+ RequestEntity requestEntity = new RequestEntity();
+ requestEntity.setRequestId(requestId);
+ requestEntity.setClusterId(clusterEntity.getClusterId());
+ requestEntity.setStages(new ArrayList<StageEntity>());
+ m_requestDAO.create(requestEntity);
+
+ AtomicLong stageId = new AtomicLong(1);
+ HostEntity host = m_hostDAO.findByName("test_host1");
+ host.setHostRoleCommandEntities(new ArrayList<HostRoleCommandEntity>());
+
+ createStage(stageId.getAndIncrement(), 3, host, requestEntity, HostRoleStatus.COMPLETED, false);
+ createStage(stageId.getAndIncrement(), 2, host, requestEntity, HostRoleStatus.SKIPPED_FAILED, false);
+ createStage(stageId.getAndIncrement(), 1, host, requestEntity, HostRoleStatus.ABORTED, false);
+
+ List<HostRoleCommandEntity> tasks = m_hostRoleCommandDAO.findByStatusBetweenStages(requestId,
+ HostRoleStatus.SKIPPED_FAILED, 1, 3);
+
+ Assert.assertEquals(2, tasks.size());
+
+ tasks = m_hostRoleCommandDAO.findByStatusBetweenStages(requestId, HostRoleStatus.SKIPPED_FAILED, 1, 1);
+ Assert.assertEquals(0, tasks.size());
+ }
+
+ /**
+ * Creates a single stage with the specified number of commands.
+ *
+ * @param startStageId
+ * @param count
+ * @param hostEntity
+ * @param requestEntity
+ * @param status
+ * @param skipStage
+ * @return
+ */
+ private void createStage(long startStageId, int count, HostEntity hostEntity,
+ RequestEntity requestEntity, HostRoleStatus status, boolean skipStage) {
+ long stageId = startStageId;
+
+ ClusterEntity clusterEntity = m_clusterDAO.findByName("test_cluster1");
+
+ StageEntity stageEntity = new StageEntity();
+ stageEntity.setClusterId(clusterEntity.getClusterId());
+ stageEntity.setRequest(requestEntity);
+ stageEntity.setStageId(stageId);
+ stageEntity.setHostRoleCommands(new ArrayList<HostRoleCommandEntity>());
+ stageEntity.setSkippable(skipStage);
+ m_stageDAO.create(stageEntity);
+ requestEntity.getStages().add(stageEntity);
+
+ for (int i = 0; i < count; i++) {
+ HostRoleCommandEntity commandEntity = new HostRoleCommandEntity();
+ commandEntity.setRequestId(requestEntity.getRequestId());
+ commandEntity.setStageId(stageId);
+ commandEntity.setRoleCommand(RoleCommand.INSTALL);
+ commandEntity.setStatus(status);
+ commandEntity.setRole(Role.DATANODE);
+ commandEntity.setHostEntity(hostEntity);
+ commandEntity.setStage(stageEntity);
+ m_hostRoleCommandDAO.create(commandEntity);
+
+ hostEntity.getHostRoleCommandEntities().add(commandEntity);
+ hostEntity = m_hostDAO.merge(hostEntity);
+
+ stageEntity.getHostRoleCommands().add(commandEntity);
+ m_stageDAO.merge(stageEntity);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c7a714cf/ambari-server/src/test/java/org/apache/ambari/server/state/stack/upgrade/StageWrapperBuilderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/stack/upgrade/StageWrapperBuilderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/stack/upgrade/StageWrapperBuilderTest.java
new file mode 100644
index 0000000..e2a3995
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/stack/upgrade/StageWrapperBuilderTest.java
@@ -0,0 +1,162 @@
+/**
+ * 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.ambari.server.state.stack.upgrade;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.ambari.server.serveraction.upgrades.AutoSkipFailedSummaryAction;
+import org.apache.ambari.server.stack.HostsType;
+import org.apache.ambari.server.state.UpgradeContext;
+import org.apache.ambari.server.state.stack.UpgradePack.ProcessingComponent;
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Tests the {@link StageWrapperBuilder}.
+ */
+public class StageWrapperBuilderTest {
+
+
+ /**
+ * Tests that the various build methods of a builder are invoked in the
+ * correct order.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testBuildOrder() throws Exception {
+ UpgradeContext upgradeContext = new UpgradeContext(null, null, null, null, Direction.UPGRADE);
+ MockStageWrapperBuilder builder = new MockStageWrapperBuilder(null);
+ List<StageWrapper> stageWrappers = builder.build(upgradeContext);
+ List<Integer> invocationOrder = builder.getInvocationOrder();
+
+ Assert.assertEquals(Integer.valueOf(0), invocationOrder.get(0));
+ Assert.assertEquals(Integer.valueOf(1), invocationOrder.get(1));
+ Assert.assertEquals(Integer.valueOf(2), invocationOrder.get(2));
+
+ // nothing happened, so this should be empty
+ Assert.assertTrue(stageWrappers.isEmpty());
+ }
+
+ /**
+ * Tests that a new task was inserted into the upgrade which will check for
+ * skipped failures and display a summary.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testAutoSkipCheckInserted() throws Exception {
+ UpgradeContext upgradeContext = new UpgradeContext(null, null, null, null, Direction.UPGRADE);
+ upgradeContext.setAutoSkipComponentFailures(true);
+ upgradeContext.setAutoSkipServiceCheckFailures(true);
+
+ Grouping grouping = new Grouping();
+ grouping.skippable = true;
+
+ MockStageWrapperBuilder builder = new MockStageWrapperBuilder(grouping);
+
+ List<StageWrapper> mockStageWrappers = new ArrayList<>();
+ StageWrapper mockStageWrapper = EasyMock.createNiceMock(StageWrapper.class);
+ mockStageWrappers.add(mockStageWrapper);
+
+ builder.setMockStageWrappers(mockStageWrappers);
+
+ List<StageWrapper> stageWrappers = builder.build(upgradeContext);
+ Assert.assertEquals(2, stageWrappers.size());
+
+ StageWrapper skipSummaryWrapper = stageWrappers.get(1);
+ Assert.assertEquals(StageWrapper.Type.SERVER_SIDE_ACTION, skipSummaryWrapper.getType());
+
+ ServerActionTask task = (ServerActionTask)(skipSummaryWrapper.getTasks().get(0).getTasks().get(0));
+ Assert.assertEquals(AutoSkipFailedSummaryAction.class.getName(), task.implClass);
+
+ }
+
+ /**
+ * A mock {@link StageWrapperBuilder}.
+ */
+ private final class MockStageWrapperBuilder extends StageWrapperBuilder {
+
+ private List<Integer> m_invocationOrder = new ArrayList<>();
+ private List<StageWrapper> m_stageWrappers = Collections.emptyList();
+
+ /**
+ * Constructor.
+ *
+ * @param grouping
+ */
+ protected MockStageWrapperBuilder(Grouping grouping) {
+ super(grouping);
+ }
+
+ private void setMockStageWrappers(List<StageWrapper> stageWrappers) {
+ m_stageWrappers = stageWrappers;
+ }
+
+ /**
+ * Gets the invocation order.
+ *
+ * @return
+ */
+ private List<Integer> getInvocationOrder() {
+ return m_invocationOrder;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void add(UpgradeContext upgradeContext, HostsType hostsType, String service,
+ boolean clientOnly, ProcessingComponent pc) {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<StageWrapper> build(UpgradeContext upgradeContext,
+ List<StageWrapper> stageWrappers) {
+ m_invocationOrder.add(1);
+ return m_stageWrappers;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected List<StageWrapper> beforeBuild(UpgradeContext upgradeContext) {
+ List<StageWrapper> stageWrappers = super.beforeBuild(upgradeContext);
+ m_invocationOrder.add(0);
+ return stageWrappers;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected List<StageWrapper> afterBuild(UpgradeContext upgradeContext,
+ List<StageWrapper> stageWrappers) {
+ stageWrappers = super.afterBuild(upgradeContext, stageWrappers);
+ m_invocationOrder.add(2);
+ return stageWrappers;
+ }
+ }
+}