Repository: ambari
Updated Branches:
  refs/heads/branch-2.4 7c809e278 -> 31bef88b6


AMBARI-17667 - Storm 1.0 Does Not Support Rolling Upgrades (jonathanhurley)


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

Branch: refs/heads/branch-2.4
Commit: 31bef88b6d0edc333001a3d316e3095d1f1761fa
Parents: 7c809e2
Author: Jonathan Hurley <[email protected]>
Authored: Tue Jul 12 10:52:47 2016 -0400
Committer: Jonathan Hurley <[email protected]>
Committed: Tue Jul 12 16:38:19 2016 -0400

----------------------------------------------------------------------
 .../ambari/server/checks/CheckDescription.java  |  8 +-
 .../server/checks/StormShutdownWarning.java     | 72 +++++++++++++++
 .../ambari/server/state/UpgradeHelper.java      | 67 +++++++-------
 .../stacks/HDP/2.3/upgrades/upgrade-2.5.xml     | 49 ++++++++--
 .../stacks/HDP/2.4/upgrades/upgrade-2.5.xml     | 49 ++++++++--
 .../server/checks/StormShutdownWarningTest.java | 96 ++++++++++++++++++++
 .../AmbariManagementControllerTest.java         | 34 +++----
 .../ambari/server/state/UpgradeHelperTest.java  | 54 ++++++++++-
 .../2.1.1/upgrades/upgrade_grouping_rolling.xml | 49 ++++++++++
 9 files changed, 405 insertions(+), 73 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/31bef88b/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java
index 29feb28..da07b26 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java
@@ -263,7 +263,13 @@ public enum CheckDescription {
       "Hive Server Port Change",
       new ImmutableMap.Builder<String, String>()
       .put(AbstractCheckDescriptor.DEFAULT,
-        "In order to support rolling upgrades, the Hive server is required to 
change its port. Applications and users which use a URL that includes the port 
will no longer be able to connect after Hive has upgraded. If this behavior is 
not desired, then the port can be restored to its original value after the 
upgrade has been finalized.").build());
+        "In order to support rolling upgrades, the Hive server is required to 
change its port. Applications and users which use a URL that includes the port 
will no longer be able to connect after Hive has upgraded. If this behavior is 
not desired, then the port can be restored to its original value after the 
upgrade has been finalized.").build()),
+  
+  SERVICES_STORM_ROLLING_WARNING(PrereqCheckType.SERVICE,
+      "Storm Downtime During Upgrade",
+      new ImmutableMap.Builder<String, String>()
+      .put(AbstractCheckDescriptor.DEFAULT,
+        "Storm does not support rolling upgrades on this version of the stack. 
If you proceed, you will be required to stop all running topologies before 
Storm is restarted.").build());  
 
 
   private PrereqCheckType m_type;

http://git-wip-us.apache.org/repos/asf/ambari/blob/31bef88b/ambari-server/src/main/java/org/apache/ambari/server/checks/StormShutdownWarning.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/checks/StormShutdownWarning.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/checks/StormShutdownWarning.java
new file mode 100644
index 0000000..3ed7a27
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/checks/StormShutdownWarning.java
@@ -0,0 +1,72 @@
+/*
+ * 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.checks;
+
+import java.util.Arrays;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.controller.PrereqCheckRequest;
+import org.apache.ambari.server.state.stack.PrereqCheckStatus;
+import org.apache.ambari.server.state.stack.PrerequisiteCheck;
+import org.apache.ambari.server.state.stack.upgrade.UpgradeType;
+
+import com.google.inject.Singleton;
+
+/**
+ * The {@link StormShutdownWarning} to see if Storm is installed and if the
+ * upgrade type is {@link UpgradeType#ROLLING}. If so, then a
+ * {@link PrereqCheckStatus#WARNING} is produced which will let the operator
+ * know that Storm cannot be rolling on ceratin versions of the HDP stack.
+ * <p/>
+ * The upgrade packs must include this check where it is applicable. It 
contains
+ * no logic for determine stack versions and only checks for the presence of
+ * Storm and the type of upgrade.
+ */
+@Singleton
+@UpgradeCheck(group = UpgradeCheckGroup.INFORMATIONAL_WARNING, required = 
false)
+public class StormShutdownWarning extends AbstractCheckDescriptor {
+
+  /**
+   * Constructor.
+   */
+  public StormShutdownWarning() {
+    super(CheckDescription.SERVICES_STORM_ROLLING_WARNING);
+  }
+
+  /**
+   * {@inheritDoc}
+   * <p/>
+   * This check is only applicable if Storm is installed and the upgrade type 
is
+   * {@link UpgradeType#ROLLING}.
+   */
+  @Override
+  public boolean isApplicable(PrereqCheckRequest request) throws 
AmbariException {
+    boolean isApplicable = super.isApplicable(request, Arrays.asList("STORM"), 
true);
+    return isApplicable && request.getUpgradeType() == UpgradeType.ROLLING;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void perform(PrerequisiteCheck prerequisiteCheck, PrereqCheckRequest 
request) throws AmbariException {
+    prerequisiteCheck.getFailedOn().add("STORM");
+    prerequisiteCheck.setStatus(PrereqCheckStatus.WARNING);
+    prerequisiteCheck.setFailReason(getFailReason(prerequisiteCheck, request));
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/31bef88b/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 66272e3..8dcd163 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
@@ -54,17 +54,15 @@ import 
org.apache.ambari.server.state.stack.UpgradePack.ProcessingComponent;
 import org.apache.ambari.server.state.stack.upgrade.Direction;
 import org.apache.ambari.server.state.stack.upgrade.Grouping;
 import org.apache.ambari.server.state.stack.upgrade.ManualTask;
-import org.apache.ambari.server.state.stack.upgrade.RestartGrouping;
 import org.apache.ambari.server.state.stack.upgrade.RestartTask;
 import org.apache.ambari.server.state.stack.upgrade.StageWrapper;
 import org.apache.ambari.server.state.stack.upgrade.StageWrapperBuilder;
-import org.apache.ambari.server.state.stack.upgrade.StartGrouping;
 import org.apache.ambari.server.state.stack.upgrade.StartTask;
-import org.apache.ambari.server.state.stack.upgrade.StopGrouping;
 import org.apache.ambari.server.state.stack.upgrade.StopTask;
 import org.apache.ambari.server.state.stack.upgrade.Task;
 import org.apache.ambari.server.state.stack.upgrade.Task.Type;
 import org.apache.ambari.server.state.stack.upgrade.TaskWrapper;
+import org.apache.ambari.server.state.stack.upgrade.UpgradeFunction;
 import org.apache.ambari.server.state.stack.upgrade.UpgradeType;
 import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
@@ -291,20 +289,14 @@ public class UpgradeHelper {
 
       // Attempt to get the function of the group, during a NonRolling Upgrade
       Task.Type functionName = null;
+      if (group instanceof UpgradeFunction) {
+        functionName = ((UpgradeFunction) group).getFunction();
+      }
+
       // NonRolling defaults to not performing service checks on a group.
       // Of course, a Service Check Group does indeed run them.
       if (upgradePack.getType() == UpgradeType.NON_ROLLING) {
         group.performServiceCheck = false;
-
-        if (RestartGrouping.class.isInstance(group)) {
-          functionName = ((RestartGrouping) group).getFunction();
-        }
-        if (StartGrouping.class.isInstance(group)) {
-          functionName = ((StartGrouping) group).getFunction();
-        }
-        if (StopGrouping.class.isInstance(group)) {
-          functionName = ((StopGrouping) group).getFunction();
-        }
       }
 
       StageWrapperBuilder builder = group.getBuilder();
@@ -352,34 +344,37 @@ public class UpgradeHelper {
 
           Service svc = cluster.getService(service.serviceName);
 
+          // if a function name is present, build the tasks dynamically;
+          // otherwise use the tasks defined in the upgrade pack processing
           ProcessingComponent pc = null;
-          if (upgradePack.getType() == UpgradeType.ROLLING) {
+          if (null == functionName) {
             pc = allTasks.get(service.serviceName).get(component);
-          } else if (upgradePack.getType() == UpgradeType.NON_ROLLING) {
-            if (null != functionName) {
-              // Construct a processing task on-the-fly if it is a "stop" 
group.
-              if (functionName == Type.STOP) {
+          } else {
+            // Construct a processing task on-the-fly if it is a "stop" group.
+            if (functionName == Type.STOP) {
+              pc = new ProcessingComponent();
+              pc.name = component;
+              pc.tasks = new ArrayList<>();
+              pc.tasks.add(new StopTask());
+            } else {
+              // For Start and Restart, make a best attempt at finding
+              // Processing Components.
+              // If they don't exist, make one on the fly.
+              if (allTasks.containsKey(service.serviceName)
+                  && allTasks.get(service.serviceName).containsKey(component)) 
{
+                pc = allTasks.get(service.serviceName).get(component);
+              } else {
+                // Construct a processing task on-the-fly so that the Upgrade
+                // Pack is less verbose.
                 pc = new ProcessingComponent();
                 pc.name = component;
                 pc.tasks = new ArrayList<>();
-                pc.tasks.add(new StopTask());
-              } else {
-                // For Start and Restart, make a best attempt at finding 
Processing Components.
-                // If they don't exist, make one on the fly.
-                if (allTasks.containsKey(service.serviceName) && 
allTasks.get(service.serviceName).containsKey(component)) {
-                  pc = allTasks.get(service.serviceName).get(component);
-                } else {
-                  // Construct a processing task on-the-fly so that the 
Upgrade Pack is less verbose.
-                  pc = new ProcessingComponent();
-                  pc.name = component;
-                  pc.tasks = new ArrayList<>();
-
-                  if (functionName == Type.START) {
-                    pc.tasks.add(new StartTask());
-                  }
-                  if (functionName == Type.RESTART) {
-                    pc.tasks.add(new RestartTask());
-                  }
+
+                if (functionName == Type.START) {
+                  pc.tasks.add(new StartTask());
+                }
+                if (functionName == Type.RESTART) {
+                  pc.tasks.add(new RestartTask());
                 }
               }
             }

http://git-wip-us.apache.org/repos/asf/ambari/blob/31bef88b/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/upgrade-2.5.xml
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/upgrade-2.5.xml 
b/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/upgrade-2.5.xml
index 85ffb8c..4c122e9 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/upgrade-2.5.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/upgrade-2.5.xml
@@ -38,6 +38,9 @@
     <check>org.apache.ambari.server.checks.AtlasPresenceCheck</check>
     <check>org.apache.ambari.server.checks.RangerAuditDbCheck</check>
 
+    <!-- Specific to HDP 2.5, Storm is not rolling -->
+    <check>org.apache.ambari.server.checks.StormShutdownWarning</check>
+
     <configuration>
       <!-- Configuration properties for all pre-reqs including required 
pre-reqs -->
       <!--TODO: is it required? -->
@@ -386,8 +389,44 @@
       </service>
     </group>
 
-    <group name="STORM" title="Storm">
+    <!-- Storm package names changed causing an incompatibility between 
versions; we must
+    shut all daemons down before deleting ZooKeeper/local data. -->
+    <group xsi:type="cluster" name="STOP_STORM_WARNING" title="Deactivate 
Storm Topologies">
+      <direction>UPGRADE</direction>
+      <supports-auto-skip-failure>false</supports-auto-skip-failure>
+      <execute-stage service="STORM" component="NIMBUS" title="Deactivate 
Storm Topologies">
+        <task xsi:type="manual">
+          <message>Before continuing, please deactivate and kill any currently 
running topologies.</message>
+        </task>
+      </execute-stage>
+    </group>
+
+    <group xsi:type="stop" name="STOP_STORM" title="Stop Storm Services">
+      <direction>UPGRADE</direction>
       <skippable>true</skippable>
+      <service-check>false</service-check>
+      <service name="STORM">
+        <component>NIMBUS</component>
+        <component>SUPERVISOR</component>
+        <component>STORM_UI_SERVER</component>
+        <component>DRPC_SERVER</component>
+      </service>
+    </group>
+
+    <group xsi:type="restart" name="RESTART_STORM" title="Restart Storm 
Services">
+      <skippable>true</skippable>
+      <service name="STORM">
+        <component>NIMBUS</component>
+        <component>SUPERVISOR</component>
+        <component>STORM_UI_SERVER</component>
+        <component>DRPC_SERVER</component>
+      </service>
+    </group>
+
+    <group xsi:type="stop" name="STOP_STORM" title="Stop Storm Services">
+      <direction>DOWNGRADE</direction>
+      <skippable>true</skippable>
+      <service-check>false</service-check>
       <service name="STORM">
         <component>NIMBUS</component>
         <component>SUPERVISOR</component>
@@ -904,10 +943,6 @@
     <service name="STORM">
       <component name="NIMBUS">
         <pre-upgrade>
-          <task xsi:type="manual">
-            <message>Before continuing, please deactivate and kill any 
currently running topologies.</message>
-          </task>
-
           <task xsi:type="configure" 
id="hdp_2_5_0_0_remove_ranger_storm_audit_db" />
           <task xsi:type="configure" id="hdp_2_5_0_0_upgrade_storm_1.0"/>
 
@@ -948,10 +983,6 @@
         </pre-upgrade>
 
         <pre-downgrade>
-          <task xsi:type="manual">
-            <message>Before continuing, please deactivate and kill any 
currently running topologies.</message>
-          </task>
-
           <task xsi:type="execute" summary="Removing local Storm data">
             <script>scripts/storm_upgrade.py</script>
             <function>delete_storm_local_data</function>

http://git-wip-us.apache.org/repos/asf/ambari/blob/31bef88b/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/upgrade-2.5.xml
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/upgrade-2.5.xml 
b/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/upgrade-2.5.xml
index 68e8fc2..bbd0fe4 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/upgrade-2.5.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/upgrade-2.5.xml
@@ -38,6 +38,9 @@
     <check>org.apache.ambari.server.checks.AtlasPresenceCheck</check>
     <check>org.apache.ambari.server.checks.RangerAuditDbCheck</check>
 
+    <!-- Specific to HDP 2.5, Storm is not rolling -->
+    <check>org.apache.ambari.server.checks.StormShutdownWarning</check>
+
     <configuration>
       <!-- Configuration properties for all pre-reqs including required 
pre-reqs -->
       <!--TODO: is it required? -->
@@ -381,8 +384,44 @@
       </service>
     </group>
 
-    <group name="STORM" title="Storm">
+    <!-- Storm package names changed causing an incompatibility between 
versions; we must
+    shut all daemons down before deleting ZooKeeper/local data. -->
+    <group xsi:type="cluster" name="STOP_STORM_WARNING" title="Deactivate 
Storm Topologies">
+      <direction>UPGRADE</direction>
+      <supports-auto-skip-failure>false</supports-auto-skip-failure>
+      <execute-stage service="STORM" component="NIMBUS" title="Deactivate 
Storm Topologies">
+        <task xsi:type="manual">
+          <message>Before continuing, please deactivate and kill any currently 
running topologies.</message>
+        </task>
+      </execute-stage>
+    </group>
+
+    <group xsi:type="stop" name="STOP_STORM" title="Stop Storm Services">
+      <direction>UPGRADE</direction>
       <skippable>true</skippable>
+      <service-check>false</service-check>
+      <service name="STORM">
+        <component>NIMBUS</component>
+        <component>SUPERVISOR</component>
+        <component>STORM_UI_SERVER</component>
+        <component>DRPC_SERVER</component>
+      </service>
+    </group>
+
+    <group xsi:type="restart" name="RESTART_STORM" title="Restart Storm 
Services">
+      <skippable>true</skippable>
+      <service name="STORM">
+        <component>NIMBUS</component>
+        <component>SUPERVISOR</component>
+        <component>STORM_UI_SERVER</component>
+        <component>DRPC_SERVER</component>
+      </service>
+    </group>
+
+    <group xsi:type="stop" name="STOP_STORM" title="Stop Storm Services">
+      <direction>DOWNGRADE</direction>
+      <skippable>true</skippable>
+      <service-check>false</service-check>
       <service name="STORM">
         <component>NIMBUS</component>
         <component>SUPERVISOR</component>
@@ -866,10 +905,6 @@
     <service name="STORM">
       <component name="NIMBUS">
         <pre-upgrade>
-          <task xsi:type="manual">
-            <message>Before continuing, please deactivate and kill any 
currently running topologies.</message>
-          </task>
-
           <task xsi:type="configure" 
id="hdp_2_5_0_0_remove_ranger_storm_audit_db" />
           <task xsi:type="configure" id="hdp_2_5_0_0_upgrade_storm_1.0"/>
 
@@ -910,10 +945,6 @@
         </pre-upgrade>
 
         <pre-downgrade>
-          <task xsi:type="manual">
-            <message>Before continuing, please deactivate and kill any 
currently running topologies.</message>
-          </task>
-
           <task xsi:type="execute" summary="Removing local Storm data">
             <script>scripts/storm_upgrade.py</script>
             <function>delete_storm_local_data</function>

http://git-wip-us.apache.org/repos/asf/ambari/blob/31bef88b/ambari-server/src/test/java/org/apache/ambari/server/checks/StormShutdownWarningTest.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/test/java/org/apache/ambari/server/checks/StormShutdownWarningTest.java
 
b/ambari-server/src/test/java/org/apache/ambari/server/checks/StormShutdownWarningTest.java
new file mode 100644
index 0000000..39089f3
--- /dev/null
+++ 
b/ambari-server/src/test/java/org/apache/ambari/server/checks/StormShutdownWarningTest.java
@@ -0,0 +1,96 @@
+/*
+ * 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.checks;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.ambari.server.controller.PrereqCheckRequest;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.Service;
+import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.stack.PrereqCheckStatus;
+import org.apache.ambari.server.state.stack.PrerequisiteCheck;
+import org.apache.ambari.server.state.stack.upgrade.UpgradeType;
+import org.easymock.EasyMock;
+import org.easymock.EasyMockSupport;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.google.inject.Provider;
+
+/**
+ * Tests {@link StormShutdownWarning}.
+ */
+public class StormShutdownWarningTest extends EasyMockSupport {
+
+  private final String m_clusterName = "c1";
+  private final Clusters m_clusters = niceMock(Clusters.class);
+
+  /**
+   * @throws Exception
+   */
+  @Test
+  public void testIsApplicable() throws Exception {
+    final StormShutdownWarning shutdownWarning = new StormShutdownWarning();
+    shutdownWarning.clustersProvider = new Provider<Clusters>() {
+
+      @Override
+      public Clusters get() {
+        return m_clusters;
+      }
+    };
+
+    final Cluster cluster = niceMock(Cluster.class);
+    final Service hive = niceMock(Service.class);
+
+    final Map<String, Service> services = new HashMap<>();
+    services.put("STORM", hive);
+
+    EasyMock.expect(cluster.getClusterId()).andReturn(1L).anyTimes();
+
+    EasyMock.expect(cluster.getCurrentStackVersion()).andReturn(new 
StackId("HDP", "2.3")).anyTimes();
+    EasyMock.expect(cluster.getServices()).andReturn(services).atLeastOnce();
+    
EasyMock.expect(m_clusters.getCluster(m_clusterName)).andReturn(cluster).atLeastOnce();
+
+    PrereqCheckRequest request = niceMock(PrereqCheckRequest.class);
+    EasyMock.expect(request.getClusterName()).andReturn(m_clusterName);
+    EasyMock.expect(request.getUpgradeType()).andReturn(UpgradeType.ROLLING);
+
+    replayAll();
+
+    Assert.assertTrue(shutdownWarning.isApplicable(request));
+
+    verifyAll();
+  }
+
+  /**
+   * @throws Exception
+   */
+  @Test
+  public void testPerform() throws Exception {
+    final StormShutdownWarning shutdownWarning = new StormShutdownWarning();
+
+    PrereqCheckRequest request = new PrereqCheckRequest(m_clusterName);
+    PrerequisiteCheck check = new PrerequisiteCheck(null, null);
+
+    shutdownWarning.perform(check, request);
+    Assert.assertEquals(PrereqCheckStatus.WARNING, check.getStatus());
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/31bef88b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
 
b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
index 89e3284..58f07e8 100644
--- 
a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
+++ 
b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
@@ -18,6 +18,22 @@
 
 package org.apache.ambari.server.controller;
 
+import static org.easymock.EasyMock.capture;
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.createStrictMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
 import java.io.StringReader;
 import java.lang.reflect.Type;
 import java.net.UnknownHostException;
@@ -160,22 +176,6 @@ import com.google.inject.persist.PersistService;
 
 import junit.framework.Assert;
 
-import static org.easymock.EasyMock.capture;
-import static org.easymock.EasyMock.createNiceMock;
-import static org.easymock.EasyMock.createStrictMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
 public class AmbariManagementControllerTest {
 
   private static final Logger LOG =
@@ -7417,7 +7417,7 @@ public class AmbariManagementControllerTest {
     Assert.assertEquals(1, responsesWithParams.size());
     StackVersionResponse resp = responsesWithParams.iterator().next();
     assertNotNull(resp.getUpgradePacks());
-    assertEquals(9, resp.getUpgradePacks().size());
+    assertEquals(10, resp.getUpgradePacks().size());
     assertTrue(resp.getUpgradePacks().contains("upgrade_test"));
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/31bef88b/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 414259a..55b44bf 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,7 @@ 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.ManualTask;
 import org.apache.ambari.server.state.stack.upgrade.StageWrapper;
+import org.apache.ambari.server.state.stack.upgrade.StopGrouping;
 import org.apache.ambari.server.state.stack.upgrade.Task;
 import org.apache.ambari.server.state.stack.upgrade.TaskWrapper;
 import org.apache.ambari.server.state.stack.upgrade.UpgradeScope;
@@ -1597,7 +1598,58 @@ public class UpgradeHelperTest {
   }
 
   /**
-   * Extend {@link org.apache.ambari.server.stack.MasterHostResolver} in order 
to overwrite the JMX methods.
+   * Tests that advanced {@link Grouping} instances like {@link StopGrouping}
+   * work with rolling upgrade packs.
+   *
+   * @throws Exception
+   */
+  @Test
+  public void testRollingUpgradesCanUseAdvancedGroupings() throws Exception {
+    final String clusterName = "c1";
+    final String upgradeFromVersion = "2.1.1";
+    final String upgradeToVersion = "2.2.0";
+    final Direction upgradeDirection = Direction.UPGRADE;
+    final UpgradeType upgradeType = UpgradeType.ROLLING;
+
+    makeCluster();
+
+    // grab the right pack
+    String preferredUpgradePackName = "upgrade_grouping_rolling";
+    UpgradePack upgradePack = m_upgradeHelper.suggestUpgradePack(clusterName, 
upgradeFromVersion,
+        upgradeToVersion, upgradeDirection, upgradeType, 
preferredUpgradePackName);
+
+    assertEquals(upgradeType, upgradePack.getType());
+
+    // get an upgrade
+    UpgradeContext context = new UpgradeContext(m_masterHostResolver, HDP_21, 
HDP_21,
+        UPGRADE_VERSION, Direction.UPGRADE, UpgradeType.ROLLING);
+
+    context.setSupportedServices(Collections.singleton("ZOOKEEPER"));
+    context.setScope(UpgradeScope.COMPLETE);
+
+    List<Grouping> groupings = upgradePack.getGroups(Direction.UPGRADE);
+    assertEquals(2, groupings.size());
+    assertEquals("STOP_ZOOKEEPER", groupings.get(0).name);
+    assertEquals("RESTART_ZOOKEEPER", groupings.get(1).name);
+
+    List<UpgradeGroupHolder> groups = 
m_upgradeHelper.createSequence(upgradePack, context);
+
+    assertEquals(2, groups.size());
+
+    assertEquals("STOP_ZOOKEEPER", groups.get(0).name);
+    assertEquals("RESTART_ZOOKEEPER", groups.get(1).name);
+
+    // STOP_ZOOKEEPER GROUP
+    UpgradeGroupHolder group = groups.get(0);
+
+    // Check that the upgrade framework properly expanded the STOP grouping 
into
+    // STOP tasks
+    assertEquals("Stopping ZooKeeper Server on h1 (Batch 1 of 3)", 
group.items.get(0).getText());
+  }
+
+  /**
+   * Extend {@link org.apache.ambari.server.stack.MasterHostResolver} in order
+   * to overwrite the JMX methods.
    */
   private class MockMasterHostResolver extends MasterHostResolver {
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/31bef88b/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_grouping_rolling.xml
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_grouping_rolling.xml
 
b/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_grouping_rolling.xml
new file mode 100644
index 0000000..b8b5511
--- /dev/null
+++ 
b/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_grouping_rolling.xml
@@ -0,0 +1,49 @@
+<?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>
+  <target-stack>HDP-2.2.0</target-stack>
+  <type>ROLLING</type>
+
+  <order>
+    <group xsi:type="stop" name="STOP_ZOOKEEPER" title="Stop ZooKeeper">
+      <skippable>true</skippable>
+      <service-check>false</service-check>
+      <service name="ZOOKEEPER">
+        <component>ZOOKEEPER_SERVER</component>
+      </service>
+    </group>
+
+    <group xsi:type="restart" name="RESTART_ZOOKEEPER" title="Restart 
ZooKeeper Services">
+      <skippable>true</skippable>
+      <service name="ZOOKEEPER">
+        <component>ZOOKEEPER_SERVER</component>
+      </service>
+    </group>
+  </order>
+  
+  <processing>
+    <service name="ZOOKEEPER">
+      <component name="ZOOKEEPER_SERVER">
+        <upgrade>
+          <task xsi:type="restart-task" />
+        </upgrade>
+      </component>
+    </service>
+  </processing>
+</upgrade>  
\ No newline at end of file

Reply via email to