ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nc...@apache.org
Subject [44/50] [abbrv] ambari git commit: AMBARI-18680. Add orchestration for HOST_ORDERED upgrades (ncole)
Date Fri, 04 Nov 2016 16:55:25 GMT
AMBARI-18680. Add orchestration for HOST_ORDERED upgrades (ncole)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/343b4d8f
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/343b4d8f
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/343b4d8f

Branch: refs/heads/branch-dev-patch-upgrade
Commit: 343b4d8fec60d678349d9f1f68403d5063724ae6
Parents: 1f4221c
Author: Nate Cole <ncole@hortonworks.com>
Authored: Thu Nov 3 11:22:42 2016 -0400
Committer: Nate Cole <ncole@hortonworks.com>
Committed: Fri Nov 4 09:32:47 2016 -0400

----------------------------------------------------------------------
 .../server/state/cluster/ClustersImpl.java      |   1 -
 .../state/stack/upgrade/HostOrderGrouping.java  | 174 ++++++++++++++++++-
 .../stack/upgrade/StageWrapperBuilder.java      |   2 +-
 .../HDP/2.5/upgrades/host-ordered-upgrade.xml   |  10 +-
 .../src/main/resources/upgrade-pack.xsd         |   4 +-
 .../ambari/server/state/UpgradeHelperTest.java  | 151 ++++++++++++++--
 .../upgrades/upgrade_test_host_ordered.xml      |   2 +-
 .../upgrades/upgrade_test_host_ordered.xml      |   2 +-
 8 files changed, 307 insertions(+), 39 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/343b4d8f/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java
b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java
index 706a476..8e5f37e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java
@@ -938,6 +938,5 @@ public class ClustersImpl implements Clusters {
     Cluster currentCluster = clusterFactory.create(clusterEntity);
     clusters.put(clusterEntity.getClusterName(), currentCluster);
     clustersById.put(currentCluster.getClusterId(), currentCluster);
-    clusterHostMap.put(currentCluster.getClusterName(), Collections.newSetFromMap(new ConcurrentHashMap<Host,
Boolean>()));
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/343b4d8f/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/HostOrderGrouping.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/HostOrderGrouping.java
b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/HostOrderGrouping.java
index f3dca62..b999f2f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/HostOrderGrouping.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/HostOrderGrouping.java
@@ -17,14 +17,24 @@
  */
 package org.apache.ambari.server.state.stack.upgrade;
 
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
 import javax.xml.bind.annotation.XmlType;
 
+import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.stack.HostsType;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.ComponentInfo;
+import org.apache.ambari.server.state.ServiceComponentHost;
+import org.apache.ambari.server.state.StackId;
 import org.apache.ambari.server.state.UpgradeContext;
 import org.apache.ambari.server.state.stack.UpgradePack.ProcessingComponent;
+import org.apache.commons.collections.CollectionUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Marker group for Host-Ordered upgrades.
@@ -32,6 +42,8 @@ import org.apache.ambari.server.state.stack.UpgradePack.ProcessingComponent;
 @XmlType(name="host-order")
 public class HostOrderGrouping extends Grouping {
 
+  private static Logger LOG = LoggerFactory.getLogger(HostOrderGrouping.class);
+
   /**
    * Contains the ordered actions to schedule for this grouping.
    */
@@ -61,29 +73,175 @@ public class HostOrderGrouping extends Grouping {
    * Builder for host upgrades.
    */
   private static class HostBuilder extends StageWrapperBuilder {
+    private final List<HostOrderItem> hostOrderItems;
+
     /**
      * @param grouping the grouping
      */
     protected HostBuilder(HostOrderGrouping grouping) {
       super(grouping);
+      hostOrderItems = grouping.m_hostOrderItems;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public void add(UpgradeContext upgradeContext, HostsType hostsType, String service,
         boolean clientOnly, ProcessingComponent pc, Map<String, String> params) {
-
+      // !!! NOOP, this called when there are services in the group, and there
+      // are none for host-ordered.
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public List<StageWrapper> build(UpgradeContext upgradeContext,
         List<StageWrapper> stageWrappers) {
-      return null;
+
+      List<StageWrapper> wrappers = new ArrayList<>(stageWrappers);
+
+      for (HostOrderItem orderItem : hostOrderItems) {
+        switch (orderItem.getType()) {
+          case HOST_UPGRADE:
+            wrappers.addAll(buildHosts(upgradeContext, orderItem.getActionItems()));
+            break;
+          case SERVICE_CHECK:
+            wrappers.addAll(buildServiceChecks(upgradeContext, orderItem.getActionItems()));
+            break;
+        }
+      }
+
+      return wrappers;
+    }
+
+    /**
+     * @param upgradeContext  the context
+     * @param hosts           the list of hostnames
+     * @return  the wrappers for a host
+     */
+    private List<StageWrapper> buildHosts(UpgradeContext upgradeContext, List<String>
hosts) {
+      if (CollectionUtils.isEmpty(hosts)) {
+        return Collections.emptyList();
+      }
+
+      Cluster cluster = upgradeContext.getCluster();
+      List<StageWrapper> wrappers = new ArrayList<>();
+
+      for (String hostName : hosts) {
+
+        List<TaskWrapper> stopTasks = new ArrayList<>();
+        List<TaskWrapper> upgradeTasks = new ArrayList<>();
+
+        for (ServiceComponentHost sch : cluster.getServiceComponentHosts(hostName)) {
+          if (!isVersionAdvertised(upgradeContext, sch)) {
+            continue;
+          }
+
+          HostsType hostsType = upgradeContext.getResolver().getMasterAndHosts(
+              sch.getServiceName(), sch.getServiceComponentName());
+
+          // !!! if the hosts do not contain the current one, that means the component
+          // either doesn't exist or the downgrade is to the current target version.
+          // hostsType better not be null either, but check anyway
+          if (null != hostsType && !hostsType.hosts.contains(hostName)) {
+            LOG.warn("Host {} could not be orchestrated. Either there are no components for
{}/{} " +
+                "or the target version {} is already current.",
+                hostName, sch.getServiceName(), sch.getServiceComponentName(), upgradeContext.getVersion());
+            continue;
+          }
+
+          if (!sch.isClientComponent()) {
+            stopTasks.add(new TaskWrapper(sch.getServiceName(), sch.getServiceComponentName(),
+                Collections.singleton(hostName), new StopTask()));
+          }
+
+          // !!! simple restart will do
+          upgradeTasks.add(new TaskWrapper(sch.getServiceName(), sch.getServiceComponentName(),
+              Collections.singleton(hostName), new RestartTask()));
+        }
+
+        if (stopTasks.isEmpty() && upgradeTasks.isEmpty()) {
+          LOG.info("No tasks for {}", hostName);
+          continue;
+        }
+
+        StageWrapper stopWrapper = new StageWrapper(StageWrapper.Type.STOP, String.format("Stop
on %s", hostName),
+            stopTasks.toArray(new TaskWrapper[stopTasks.size()]));
+
+        StageWrapper startWrapper = new StageWrapper(StageWrapper.Type.RESTART, String.format("Start
on %s", hostName),
+            upgradeTasks.toArray(new TaskWrapper[upgradeTasks.size()]));
+
+
+        String message = String.format("Please acknowledge that host %s has been prepared.",
hostName);
+
+        ManualTask mt = new ManualTask();
+        mt.messages.add(message);
+
+        StageWrapper manualWrapper = new StageWrapper(StageWrapper.Type.SERVER_SIDE_ACTION,
"Manual Confirmation",
+            new TaskWrapper(null, null, Collections.<String>emptySet(), mt));
+
+        wrappers.add(stopWrapper);
+        wrappers.add(manualWrapper);
+        // !!! TODO install_packages for hdp and conf-select changes.  Hopefully these will
no-op.
+        wrappers.add(startWrapper);
+      }
+
+      return wrappers;
+    }
+
+    /**
+     * @param upgradeContext  the context
+     * @param hosts           the list of hostnames
+     * @return  the wrappers for a host
+     */
+    private List<StageWrapper> buildServiceChecks(UpgradeContext upgradeContext, List<String>
serviceChecks) {
+      if (CollectionUtils.isEmpty(serviceChecks)) {
+        return Collections.emptyList();
+      }
+
+      List<StageWrapper> wrappers = new ArrayList<>();
+
+      Cluster cluster = upgradeContext.getCluster();
+
+      for (String serviceName : serviceChecks) {
+        boolean hasService = false;
+        try {
+          cluster.getService(serviceName);
+          hasService = true;
+        } catch (Exception e) {
+          LOG.warn("Service {} not found to orchestrate", serviceName);
+        }
+
+        if (!hasService) {
+          continue;
+        }
+
+        StageWrapper wrapper = new StageWrapper(StageWrapper.Type.SERVICE_CHECK,
+            String.format("Service Check %s", upgradeContext.getServiceDisplay(serviceName)),
+            new TaskWrapper(serviceName, "", Collections.<String>emptySet(), new ServiceCheckTask()));
+
+        wrappers.add(wrapper);
+      }
+
+      return wrappers;
+    }
+
+
+    /**
+     * @param upgradeContext  the context
+     * @param sch             the host component
+     * @return                {@code true} if the host component advertises its version
+     */
+    private boolean isVersionAdvertised(UpgradeContext upgradeContext, ServiceComponentHost
sch) {
+      StackId targetStack = upgradeContext.getTargetStackId();
+
+      try {
+        ComponentInfo component = upgradeContext.getAmbariMetaInfo().getComponent(
+            targetStack.getStackName(), targetStack.getStackVersion(),
+            sch.getServiceName(), sch.getServiceComponentName());
+
+        return component.isVersionAdvertised();
+      } catch (AmbariException e) {
+       LOG.warn("Could not determine if {}/{}/{} could be upgraded; returning false",
+           targetStack, sch.getServiceName(), sch.getServiceComponentName(), e);
+       return false;
+      }
     }
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/343b4d8f/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 267133b..0b9cb3d 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
@@ -197,7 +197,7 @@ public abstract class StageWrapperBuilder {
    *   <li>When performing a downgrade, but no downgrade tasks exist, reuse the upgrade
tasks</li>
    * </ul>
    * @param context     the upgrade context
-   * @param preTasks    {@code true} if loading pre-upgrade or pre-downgrade
+   * @param preTasks    {@code true} if loading pre-(upgrade|downgrade) or {@code false for
post-(upgrade|downgrade)
    * @param pc          the processing component holding task definitions
    * @return A collection, potentially empty, of the tasks to run, which may contain either
    * pre or post tasks if they exist, and the order depends on whether it's an upgrade or
downgrade.

http://git-wip-us.apache.org/repos/asf/ambari/blob/343b4d8f/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/host-ordered-upgrade.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/host-ordered-upgrade.xml
b/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/host-ordered-upgrade.xml
index d59be50..37b75b8 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/host-ordered-upgrade.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/host-ordered-upgrade.xml
@@ -74,14 +74,14 @@
       </execute-stage>
 
     </group>
-    
+     
     <!--
     In a HOST_ORDERED upgrade, this placeholder group is expanded by the number of hosts
passed
     when creating the upgrade.  For starters, this will include "stop" commands, a manual
     verification task, and the "start" commands as indicated by the processing element.
     If we get to the point where we need additional flexibility, it will get added at that
time.
     -->
-    <group xsi:type="host-order" name="HOST_ORDER" />
+    <group xsi:type="host-order" name="HOST_ORDER" title="Upgrade All Hosts"/>
          
     <!--
     After processing this group, the user-specified Kerberos descriptor will be updated to
work with
@@ -441,12 +441,6 @@
     <service name="OOZIE">
       <component name="OOZIE_SERVER">
         <pre-upgrade>
-          <task xsi:type="execute" hosts="all" sequential="true">
-            <summary>Shut down all Oozie servers</summary>
-            <script>scripts/oozie_server.py</script>
-            <function>stop</function>
-          </task>
-
           <task xsi:type="server_action" class="org.apache.ambari.server.serveraction.upgrades.OozieConfigCalculation">
             <summary>Adjusting Oozie properties</summary>
           </task>

http://git-wip-us.apache.org/repos/asf/ambari/blob/343b4d8f/ambari-server/src/main/resources/upgrade-pack.xsd
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/upgrade-pack.xsd b/ambari-server/src/main/resources/upgrade-pack.xsd
index cfccb29..2871f05 100644
--- a/ambari-server/src/main/resources/upgrade-pack.xsd
+++ b/ambari-server/src/main/resources/upgrade-pack.xsd
@@ -143,8 +143,8 @@
         </xs:complexType>
       </xs:element>
     </xs:sequence>
-    <xs:attribute name="name" type="xs:string" />
-    <xs:attribute name="title" type="xs:string" />
+    <xs:attribute name="name" type="xs:string" use="required" />
+    <xs:attribute name="title" type="xs:string" use="required" />
   </xs:complexType>
   
   <xs:complexType name="cluster">

http://git-wip-us.apache.org/repos/asf/ambari/blob/343b4d8f/ambari-server/src/test/java/org/apache/ambari/server/state/UpgradeHelperTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/UpgradeHelperTest.java
b/ambari-server/src/test/java/org/apache/ambari/server/state/UpgradeHelperTest.java
index 52e6513..78969e4 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/UpgradeHelperTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/UpgradeHelperTest.java
@@ -58,6 +58,9 @@ import org.apache.ambari.server.state.stack.upgrade.ConfigureTask;
 import org.apache.ambari.server.state.stack.upgrade.Direction;
 import org.apache.ambari.server.state.stack.upgrade.ExecuteTask;
 import org.apache.ambari.server.state.stack.upgrade.Grouping;
+import org.apache.ambari.server.state.stack.upgrade.HostOrderGrouping;
+import org.apache.ambari.server.state.stack.upgrade.HostOrderItem;
+import org.apache.ambari.server.state.stack.upgrade.HostOrderItem.HostOrderActionType;
 import org.apache.ambari.server.state.stack.upgrade.ManualTask;
 import org.apache.ambari.server.state.stack.upgrade.SecurityCondition;
 import org.apache.ambari.server.state.stack.upgrade.StageWrapper;
@@ -527,7 +530,7 @@ public class UpgradeHelperTest {
     List<ServiceComponentHost> schs = cluster.getServiceComponentHosts("h4");
     assertEquals(1, schs.size());
     assertEquals(HostState.HEARTBEAT_LOST, schs.get(0).getHostState());
-    
+
     UpgradeContext context = new UpgradeContext(cluster, UpgradeType.ROLLING, Direction.UPGRADE,
null);
     context.setSourceAndTargetStacks(HDP_21, HDP_21);
     context.setVersion(UPGRADE_VERSION);
@@ -571,7 +574,7 @@ public class UpgradeHelperTest {
     context.setSourceAndTargetStacks(HDP_21, HDP_21);
     context.setVersion(DOWNGRADE_VERSION);
     context.setResolver(m_masterHostResolver);
-    
+
     List<UpgradeGroupHolder> groups = m_upgradeHelper.createSequence(upgrade, context);
 
     assertEquals(7, groups.size());
@@ -613,7 +616,7 @@ public class UpgradeHelperTest {
     context.setSourceAndTargetStacks(HDP_21, HDP_21);
     context.setVersion(UPGRADE_VERSION);
     context.setResolver(m_masterHostResolver);
-    
+
     List<UpgradeGroupHolder> groups = m_upgradeHelper.createSequence(upgrade, context);
 
     assertEquals(1, groups.size());
@@ -1069,8 +1072,8 @@ public class UpgradeHelperTest {
     UpgradeContext context = new UpgradeContext(c, UpgradeType.ROLLING, Direction.UPGRADE,
null);
     context.setSourceAndTargetStacks(HDP_21, HDP_22);
     context.setVersion(UPGRADE_VERSION);
-    context.setResolver(m_masterHostResolver);    
-    
+    context.setResolver(m_masterHostResolver);
+
     List<UpgradeGroupHolder> groups = m_upgradeHelper.createSequence(upgrade, context);
 
     assertEquals(7, groups.size());
@@ -1116,8 +1119,8 @@ public class UpgradeHelperTest {
     UpgradeContext context = new UpgradeContext(cluster, UpgradeType.ROLLING, Direction.DOWNGRADE,
null);
     context.setSourceAndTargetStacks(HDP_21, HDP_21);
     context.setVersion(DOWNGRADE_VERSION);
-    context.setResolver(m_masterHostResolver);    
-    
+    context.setResolver(m_masterHostResolver);
+
     List<UpgradeGroupHolder> groups = m_upgradeHelper.createSequence(upgrade, context);
 
     assertEquals(5, groups.size());
@@ -1401,8 +1404,8 @@ public class UpgradeHelperTest {
     UpgradeContext context = new UpgradeContext(cluster, UpgradeType.ROLLING, Direction.UPGRADE,
null);
     context.setSourceAndTargetStacks(HDP_21, HDP_21);
     context.setVersion(UPGRADE_VERSION);
-    context.setResolver(m_masterHostResolver);    
-    
+    context.setResolver(m_masterHostResolver);
+
     List<UpgradeGroupHolder> groups = m_upgradeHelper.createSequence(upgrade, context);
 
     // The upgrade pack has 2 tasks for Oozie in the pre-upgrade group.
@@ -1502,8 +1505,8 @@ public class UpgradeHelperTest {
     UpgradeContext context = new UpgradeContext(c, UpgradeType.ROLLING, Direction.DOWNGRADE,
null);
     context.setSourceAndTargetStacks(HDP_21, HDP_21);
     context.setVersion(DOWNGRADE_VERSION);
-    context.setResolver(m_masterHostResolver);    
-    
+    context.setResolver(m_masterHostResolver);
+
     Map<String, UpgradePack> upgrades = ambariMetaInfo.getUpgradePacks("HDP", "2.1.1");
     assertTrue(upgrades.containsKey("upgrade_direction"));
     UpgradePack upgrade = upgrades.get("upgrade_direction");
@@ -1855,8 +1858,8 @@ public class UpgradeHelperTest {
     UpgradeContext context = new UpgradeContext(c, UpgradeType.NON_ROLLING, Direction.UPGRADE,
null);
     context.setSourceAndTargetStacks(stackId, stackId2);
     context.setVersion("2.2.0");
-    context.setResolver(resolver);    
-    
+    context.setResolver(resolver);
+
     List<UpgradeGroupHolder> groups = m_upgradeHelper.createSequence(upgradePack, context);
 
     assertEquals(1, groups.size());
@@ -1864,17 +1867,131 @@ public class UpgradeHelperTest {
     sch1.setVersion("2.1.1");
     sch2.setVersion("2.1.1");
     resolver = new MasterHostResolver(m_configHelper, c, "2.1.1");
-    
+
     context = new UpgradeContext(c, UpgradeType.NON_ROLLING, Direction.DOWNGRADE, null);
     context.setSourceAndTargetStacks(stackId2, stackId);
     context.setVersion("2.1.1");
-    context.setResolver(resolver);    
-    
+    context.setResolver(resolver);
+
     groups = m_upgradeHelper.createSequence(upgradePack, context);
 
     assertTrue(groups.isEmpty());
   }
 
+  @Test
+  public void testHostGroupingOrchestration() throws Exception {
+
+    Clusters clusters = injector.getInstance(Clusters.class);
+    ServiceFactory serviceFactory = injector.getInstance(ServiceFactory.class);
+
+    String clusterName = "c1";
+
+    StackId stackId = new StackId("HDP-2.1.1");
+    StackId stackId2 = new StackId("HDP-2.2.0");
+    clusters.addCluster(clusterName, stackId);
+    Cluster c = clusters.getCluster(clusterName);
+
+    helper.getOrCreateRepositoryVersion(stackId,
+        c.getDesiredStackVersion().getStackVersion());
+    helper.getOrCreateRepositoryVersion(stackId2,"2.2.0");
+
+    c.createClusterVersion(stackId,
+        c.getDesiredStackVersion().getStackVersion(), "admin",
+        RepositoryVersionState.INSTALLING);
+
+    for (int i = 0; i < 2; i++) {
+      String hostName = "h" + (i+1);
+      clusters.addHost(hostName);
+      Host host = clusters.getHost(hostName);
+
+      Map<String, String> hostAttributes = new HashMap<String, String>();
+      hostAttributes.put("os_family", "redhat");
+      hostAttributes.put("os_release_version", "6");
+
+      host.setHostAttributes(hostAttributes);
+
+      clusters.mapHostToCluster(hostName, clusterName);
+    }
+
+    // !!! add storm
+    c.addService(serviceFactory.createNew(c, "ZOOKEEPER"));
+
+    Service s = c.getService("ZOOKEEPER");
+    ServiceComponent sc = s.addServiceComponent("ZOOKEEPER_SERVER");
+    ServiceComponentHost sch1 = sc.addServiceComponentHost("h1");
+    ServiceComponentHost sch2 = sc.addServiceComponentHost("h2");
+
+    UpgradePack upgradePack = new UpgradePack() {
+      @Override
+      public List<Grouping> getGroups(Direction direction) {
+        HostOrderItem hostItem = new HostOrderItem(HostOrderActionType.HOST_UPGRADE,
+            Lists.newArrayList("h1", "h2"));
+        HostOrderItem checkItem = new HostOrderItem(HostOrderActionType.SERVICE_CHECK,
+            Lists.newArrayList("ZOOKEEPER", "STORM"));
+
+        Grouping g = new HostOrderGrouping();
+        ((HostOrderGrouping) g).setHostOrderItems(Lists.newArrayList(hostItem, checkItem));
+        g.title = "Some Title";
+        return Lists.newArrayList(g);
+      }
+
+      @Override
+      public Map<String, Map<String, ProcessingComponent>> getTasks() {
+        return new HashMap<>();
+      }
+    };
+
+    MasterHostResolver resolver = new MasterHostResolver(m_configHelper, c);
+    UpgradeContext context = new UpgradeContext(c, UpgradeType.HOST_ORDERED, Direction.UPGRADE,
new HashMap<String, Object>());
+    context.setResolver(resolver);
+    context.setSourceAndTargetStacks(stackId, stackId2);
+    context.setVersion("2.2.0");
+    List<UpgradeGroupHolder> groups = m_upgradeHelper.createSequence(upgradePack, context);
+
+    assertEquals(1, groups.size());
+
+    UpgradeGroupHolder holder = groups.get(0);
+    assertEquals(7, holder.items.size());
+
+    for (int i = 0; i < 6; i++) {
+      StageWrapper w = holder.items.get(i);
+      if (i == 0 || i == 3) {
+        assertEquals(StageWrapper.Type.STOP, w.getType());
+      } else if (i == 1 || i == 4) {
+        assertEquals(StageWrapper.Type.SERVER_SIDE_ACTION, w.getType());
+      } else {
+        assertEquals(StageWrapper.Type.RESTART, w.getType());
+      }
+    }
+    assertEquals(StageWrapper.Type.SERVICE_CHECK, holder.items.get(6).getType());
+
+    // !!! test downgrade when all host components have failed
+    sch1.setVersion("2.1.1");
+    sch2.setVersion("2.1.1");
+    resolver = new MasterHostResolver(m_configHelper, c, "2.1.1");
+    context = new UpgradeContext(c, UpgradeType.HOST_ORDERED, Direction.DOWNGRADE, new HashMap<String,
Object>());
+    context.setResolver(resolver);
+    context.setSourceAndTargetStacks(stackId2, stackId);
+    context.setVersion("2.1.1");
+    groups = m_upgradeHelper.createSequence(upgradePack, context);
+
+    assertEquals(1, groups.size());
+    assertEquals(1, groups.get(0).items.size());
+
+    // !!! test downgrade when one of the hosts had failed
+    sch1.setVersion("2.1.1");
+    sch2.setVersion("2.2.0");
+    resolver = new MasterHostResolver(m_configHelper, c, "2.1.1");
+    context = new UpgradeContext(c, UpgradeType.HOST_ORDERED, Direction.DOWNGRADE, new HashMap<String,
Object>());
+    context.setResolver(resolver);
+    context.setSourceAndTargetStacks(stackId2, stackId);
+    context.setVersion("2.1.1");
+    groups = m_upgradeHelper.createSequence(upgradePack, context);
+
+    assertEquals(1, groups.size());
+    assertEquals(4, groups.get(0).items.size());
+  }
+
   /**
    * Tests that the {@link SecurityCondition} element correctly restricts the groups in
    * an upgrade.
@@ -1893,7 +2010,7 @@ public class UpgradeHelperTest {
     UpgradeContext context = new UpgradeContext(cluster, UpgradeType.ROLLING, Direction.UPGRADE,
null);
     context.setSourceAndTargetStacks(HDP_22, HDP_22);
     context.setVersion(UPGRADE_VERSION);
-    context.setResolver(m_masterHostResolver);    
+    context.setResolver(m_masterHostResolver);
 
     // initially, no conditions should be met
     List<UpgradeGroupHolder> groups = m_upgradeHelper.createSequence(upgrade, context);

http://git-wip-us.apache.org/repos/asf/ambari/blob/343b4d8f/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_test_host_ordered.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_test_host_ordered.xml
b/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_test_host_ordered.xml
index b7ffb89..6238c82 100644
--- a/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_test_host_ordered.xml
+++ b/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_test_host_ordered.xml
@@ -21,7 +21,7 @@
   <type>HOST_ORDERED</type>
   
   <order>
-    <group xsi:type="host-order" name="HOST_GROUP" />
+    <group xsi:type="host-order" name="HOST_GROUP" title="Host Group" />
     
     <group xsi:type="cluster" name="MANUAL_TASK" title="A manual task just for fun">
       <execute-stage title="You need to accept this task">

http://git-wip-us.apache.org/repos/asf/ambari/blob/343b4d8f/ambari-server/src/test/resources/stacks/HDP/2.2.0/upgrades/upgrade_test_host_ordered.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/stacks/HDP/2.2.0/upgrades/upgrade_test_host_ordered.xml
b/ambari-server/src/test/resources/stacks/HDP/2.2.0/upgrades/upgrade_test_host_ordered.xml
index 6a49472..020a49f 100644
--- a/ambari-server/src/test/resources/stacks/HDP/2.2.0/upgrades/upgrade_test_host_ordered.xml
+++ b/ambari-server/src/test/resources/stacks/HDP/2.2.0/upgrades/upgrade_test_host_ordered.xml
@@ -35,7 +35,7 @@
   </prerequisite-checks>
   <order>
 
-    <group xsi:type="host-order" name="HOST_GROUP" />
+    <group xsi:type="host-order" name="HOST_GROUP" title="Host Group" />
 
     <group name="ZOOKEEPER" title="Zookeeper">
       <skippable>true</skippable>


Mime
View raw message