You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by al...@apache.org on 2015/10/12 23:07:34 UTC

[1/9] ambari git commit: AMBARI-13392. Stop-and-Start Upgrade: Merge branch branch-dev-stop-all-upgrade to branch-2.1 for feature Stop-the-World Upgrade, aka Express Upgrade (alejandro, dlysnichenko, Dmytro Grinenko)

Repository: ambari
Updated Branches:
  refs/heads/branch-2.1 1abf2ae9c -> ff8a56af6


http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_test.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_test.xml b/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_test.xml
index b7a62f5..827348a 100644
--- a/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_test.xml
+++ b/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_test.xml
@@ -16,7 +16,9 @@
    limitations under the License.
 -->
 <upgrade xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-  <target>2.2.*</target>
+  <target>2.2.*.*</target>
+  <target-stack>HDP-2.1.1</target-stack>
+  <type>ROLLING</type>
   
   <order>
     <group xsi:type="cluster" name="PRE_CLUSTER" title="Pre {{direction.text.proper}}">
@@ -125,10 +127,10 @@
           </task>
         </pre-upgrade>
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
         <post-upgrade>
-          <task xsi:type="configure" />
+          <task xsi:type="configure" id="2.2.0" />
         </post-upgrade>
       </component>
     </service>
@@ -139,16 +141,13 @@
           <task xsi:type="execute" hosts="master">
             <command>su - {hdfs-user} -c 'dosomething'</command>
           </task>
-          <task xsi:type="configure">
-            <type>hdfs-site</type>
-            <set key="myproperty" value="mynewvalue"/>
-          </task>
+          <task xsi:type="configure" id="hdp_2_1_1_nn_pre_upgrade" />
           <task xsi:type="manual">
             <message>{{direction.verb.proper}} your database</message>
           </task>
         </pre-upgrade>
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
         <post-upgrade>
           <task xsi:type="execute">
@@ -159,7 +158,7 @@
       <component name="DATANODE">
         <pre-downgrade />
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
         <post-downgrade>
           <task xsi:type="manual">
@@ -182,15 +181,7 @@
           <task xsi:type="execute">
             <command>ls</command>
           </task>
-          <task xsi:type="configure">
-            <type>core-site</type>
-            <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" preserve-edits="true">
-            <keep-key>important-key</keep-key>
-            </transfer>
-          </task>
+          <task xsi:type="configure" id="hdp_2_1_1_nm_pre_upgrade"/>
         </pre-upgrade>
       </component>
     </service>
@@ -203,36 +194,10 @@
             <message>The HiveServer port will now change to 10010 if hive is using a binary transfer mode or 10011 if hive is using an http transport mode. You can use "netstat -anp | grep 1001[01]" to determine if the port is available on each of following HiveServer host(s): {{hosts.all}}. If the port is not available, the process using it must be terminated.</message>
           </task>
 
-          <task xsi:type="configure">
-            <condition type="hive-site" key="hive.server2.transport.mode" value="binary">
-              <type>hive-site</type>
-              <key>hive.server2.thrift.port</key>
-              <value>10010</value>
-            </condition>
-            <condition type="hive-site" key="hive.server2.transport.mode" value="http">
-              <type>hive-site</type>
-              <key>hive.server2.http.port</key>
-              <value>10011</value>
-            </condition>
-          </task>
-          
-          <task xsi:type="configure">
-            <type>hive-site</type>
-            <set key="fooKey" value="fooValue"/>
-            <set key="fooKey2" value="fooValue2"/>
-            <set key="fooKey3" value="fooValue3"/>
-            <transfer operation="copy" from-key="copy-key" to-key="copy-key-to" />
-            <transfer operation="move" from-key="move-key" to-key="move-key-to" />
-            <transfer operation="delete" delete-key="delete-key" />
-            <transfer operation="delete" delete-key="delete-http" if-key="hive.server2.transport.mode" if-type="hive-site" if-value="http" />
-            <transfer operation="delete" delete-key="delete-https-fail" if-key="hive.server2.transport.mode" if-type="hive-site" if-value="https" />
-            <transfer operation="delete" delete-key="delete-prop-fail" if-key="non.existent" if-type="hive-site" if-value="https" />
-            <transfer operation="delete" delete-key="delete-type-fail" if-key="non.existent" if-type="non.existent" if-value="" />
-            <transfer operation="delete" delete-key="delete-null-if-value" if-key="non.existent" if-type="non.existent" />
-            <transfer operation="delete" delete-key="delete-blank-if-key" if-key="" if-type="non.existent" />
-            <transfer operation="delete" delete-key="delete-blank-if-type" if-key="non.existent" if-type="" />
-            <transfer operation="delete" delete-key="delete-thrift" if-key="hive.server2.thrift.port" if-type="hive-site" if-value="10001" />
-          </task>
+          <task xsi:type="configure" id="hdp_2_1_1_set_transport_mode"/>
+
+          <task xsi:type="configure" id="hdp_2_1_1_hive_server_foo"/>
+
         </pre-upgrade>
        </component>
      </service>    

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_test_checks.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_test_checks.xml b/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_test_checks.xml
index 7590c5b..05d3db9 100644
--- a/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_test_checks.xml
+++ b/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_test_checks.xml
@@ -16,8 +16,21 @@
    limitations under the License.
 -->
 <upgrade xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-  <target>2.2.*</target>
-  
+  <target>2.2.*.*</target>
+  <target-stack>HDP-2.2.0</target-stack>
+  <type>ROLLING</type>
+  <prerequisite-checks>
+    <check>org.apache.ambari.server.checks.HiveMultipleMetastoreCheck</check>
+    <check>org.apache.ambari.server.checks.MapReduce2JobHistoryStatePreservingCheck</check>
+    <check>org.apache.ambari.server.checks.SecondaryNamenodeDeletedCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesMapReduceDistributedCacheCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesNamenodeHighAvailabilityCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesNamenodeTruncateCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesTezDistributedCacheCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesYarnWorkPreservingCheck</check>
+    <check>org.apache.ambari.server.checks.YarnRMHighAvailabilityCheck</check>
+    <check>org.apache.ambari.server.checks.YarnTimelineServerStatePreservingCheck</check>
+  </prerequisite-checks>
   <order>
     <group xsi:type="cluster" name="PRE_CLUSTER" title="Pre Upgrade" stage="pre">
       <execute-stage title="Confirm 1">
@@ -120,10 +133,10 @@
           </task>
         </pre-upgrade>
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
         <post-upgrade>
-          <task xsi:type="configure" />
+          <task xsi:type="configure" id="hdp_2_1_1_zk_post_upgrade"/>
         </post-upgrade>
       </component>
     </service>
@@ -133,16 +146,13 @@
           <task xsi:type="execute" hosts="master">
             <command>su - {hdfs-user} -c 'dosomething'</command>
           </task>
-          <task xsi:type="configure">
-            <type>hdfs-site</type>
-            <set key="myproperty" value="mynewvalue"/>
-          </task>
+          <task xsi:type="configure" id="hdp_2_1_1_nn_pre_upgrade"/>
           <task xsi:type="manual">
             <message>Update your database</message>
           </task>
         </pre-upgrade>
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
         <post-upgrade>
           <task xsi:type="execute">
@@ -153,7 +163,7 @@
       <component name="DATANODE">
         <pre-downgrade />
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
         <post-downgrade>
           <task xsi:type="manual">

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_test_nonrolling.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_test_nonrolling.xml b/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_test_nonrolling.xml
new file mode 100644
index 0000000..c1e03e0
--- /dev/null
+++ b/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_test_nonrolling.xml
@@ -0,0 +1,182 @@
+<?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.3</target-stack>
+  <type>NON_ROLLING</type>
+  <prerequisite-checks>
+    <check>org.apache.ambari.server.checks.HiveMultipleMetastoreCheck</check>
+    <check>org.apache.ambari.server.checks.MapReduce2JobHistoryStatePreservingCheck</check>
+    <check>org.apache.ambari.server.checks.SecondaryNamenodeDeletedCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesMapReduceDistributedCacheCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesNamenodeHighAvailabilityCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesNamenodeTruncateCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesTezDistributedCacheCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesYarnWorkPreservingCheck</check>
+    <check>org.apache.ambari.server.checks.YarnRMHighAvailabilityCheck</check>
+    <check>org.apache.ambari.server.checks.YarnTimelineServerStatePreservingCheck</check>
+  </prerequisite-checks>
+  <order>
+    <group xsi:type="cluster" name="PRE_CLUSTER" title="Prepare Upgrade">
+      <skippable>true</skippable>
+      <direction>UPGRADE</direction>
+      <execute-stage service="YARN" component="RESOURCEMANAGER" title="Stop YARN Queues">
+        <task xsi:type="manual">
+          <message>Before continuing, please stop all YARN queues.</message>
+        </task>
+      </execute-stage>
+    </group>
+
+    <group xsi:type="stop" name="Stop High-Level Daemons" title="Stop Daemons for High-Level Services">
+      <skippable>true</skippable>
+      <service-check>false</service-check>
+
+      <service name="YARN">
+        <component>NODEMANAGER</component>
+        <component>RESOURCEMANAGER</component>
+        <component>APP_TIMELINE_SERVER</component>
+      </service>
+
+      <service name="MAPREDUCE2">
+        <component>HISTORYSERVER</component>
+      </service>
+    </group>
+
+    <group xsi:type="cluster" name="Backups" title="Take Backups">
+      <direction>UPGRADE</direction>
+      <skippable>true</skippable>
+
+      <execute-stage service="HDFS" component="NAMENODE" title="Snapshot HDFS">
+        <task xsi:type="execute" hosts="master">
+          <script>scripts/namenode.py</script>
+          <function>prepare_non_rolling_upgrade</function>
+        </task>
+      </execute-stage>
+    </group>
+
+    <group xsi:type="stop" name="Stop Low-Level Daemons" title="Stop Daemons for Low-Level Services">
+      <skippable>true</skippable>
+      <service-check>false</service-check>
+
+      <service name="HDFS">
+        <component>DATANODE</component>
+        <component>NAMENODE</component>
+        <component>SECONDARY_NAMENODE</component>
+        <component>ZKFC</component>
+        <component>JOURNALNODE</component>
+      </service>
+
+      <service name="ZOOKEEPER">
+        <component>ZOOKEEPER_SERVER</component>
+      </service>
+    </group>
+
+    <group xsi:type="cluster" name="Restore Backups" title="Restore Backups">
+      <direction>DOWNGRADE</direction>
+      <skippable>true</skippable>
+
+      <execute-stage service="HDFS" component="NAMENODE" title="Snapshot HDFS">
+        <task xsi:type="execute" hosts="master">
+          <script>scripts/namenode.py</script>
+          <function>restore_snapshot</function>
+        </task>
+      </execute-stage>
+    </group>
+
+    <!-- After processing this group, will change the effective Stack of the UpgradeContext object. -->
+    <group xsi:type="update-stack" name="UPDATE_DESIRED_STACK_ID" title="Update Desired Stack Id">
+      <execute-stage title="Update Desired Stack Id" service="" component="">
+        <task xsi:type="server_action" class="org.apache.ambari.server.serveraction.upgrades.UpdateDesiredStackAction">
+        </task>
+      </execute-stage>
+    </group>
+
+    <group xsi:type="cluster" name="ALL_HOST_OPS" title="Set Version On All Hosts">
+      <skippable>true</skippable>
+      <execute-stage title="Update stack to {{version}}">
+        <task xsi:type="execute">
+          <script>scripts/ru_set_all.py</script>
+          <function>actionexecute</function>
+        </task>
+      </execute-stage>
+    </group>
+
+    <!-- Now, restart all of the services. -->
+
+    <group xsi:type="restart" name="ZOOKEEPER" title="Zookeeper">
+      <service name="ZOOKEEPER">
+        <service-check>false</service-check>
+        <component>ZOOKEEPER_SERVER</component>
+        <component>ZOOKEEPER_CLIENT</component>
+      </service>
+    </group>
+
+    <group xsi:type="restart" name="HDFS" title="HDFS">
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <service name="HDFS">
+        <component>JOURNALNODE</component>
+        <component>ZKFC</component>
+        <component>NAMENODE</component>
+        <component>SECONDARY_NAMENODE</component>
+        <component>DATANODE</component>
+        <component>HDFS_CLIENT</component>
+      </service>
+    </group>
+
+    <group xsi:type="restart" name="MR and YARN" title="MR and YARN">
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <service name="MAPREDUCE2">
+        <component>HISTORYSERVER</component>
+        <component>MAPREDUCE2_CLIENT</component>
+      </service>
+      <service name="YARN">
+        <component>APP_TIMELINE_SERVER</component>
+        <component>RESOURCEMANAGER</component>
+        <component>NODEMANAGER</component>
+        <component>YARN_CLIENT</component>
+      </service>
+    </group>
+
+    <group xsi:type="cluster" name="POST_CLUSTER" title="Finalize {{direction.text.proper}}">
+      <skippable>true</skippable>
+
+      <execute-stage title="Confirm Finalize">
+        <direction>UPGRADE</direction>
+        <task xsi:type="manual">
+          <message>Please confirm you are ready to finalize.</message>
+        </task>
+      </execute-stage>
+
+      <execute-stage service="HDFS" component="NAMENODE" title="Execute HDFS Finalize">
+        <task xsi:type="execute" hosts="master">
+          <script>scripts/namenode.py</script>
+          <function>finalize_non_rolling_upgrade</function>
+        </task>
+      </execute-stage>
+
+      <execute-stage title="Save Cluster State" service="" component="">
+        <task xsi:type="server_action" class="org.apache.ambari.server.serveraction.upgrades.FinalizeUpgradeAction">
+        </task>
+      </execute-stage>
+    </group>
+  </order>
+</upgrade>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_to_new_stack.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_to_new_stack.xml b/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_to_new_stack.xml
index 02b0ebf..a9ce2b0 100644
--- a/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_to_new_stack.xml
+++ b/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_to_new_stack.xml
@@ -16,9 +16,21 @@
    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>
-  
+  <target>2.2.*.*</target>
+  <target-stack>HDP-2.2.4</target-stack>
+  <type>ROLLING</type>
+  <prerequisite-checks>
+    <check>org.apache.ambari.server.checks.HiveMultipleMetastoreCheck</check>
+    <check>org.apache.ambari.server.checks.MapReduce2JobHistoryStatePreservingCheck</check>
+    <check>org.apache.ambari.server.checks.SecondaryNamenodeDeletedCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesMapReduceDistributedCacheCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesNamenodeHighAvailabilityCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesNamenodeTruncateCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesTezDistributedCacheCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesYarnWorkPreservingCheck</check>
+    <check>org.apache.ambari.server.checks.YarnRMHighAvailabilityCheck</check>
+    <check>org.apache.ambari.server.checks.YarnTimelineServerStatePreservingCheck</check>
+  </prerequisite-checks>
   <order>
     <group xsi:type="cluster" name="PRE_CLUSTER" title="Pre {{direction.text.proper}}">
       <execute-stage title="Confirm 1">
@@ -135,7 +147,7 @@
           </task>
         </pre-upgrade>
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
         <post-upgrade>
           <task xsi:type="configure" />
@@ -159,7 +171,7 @@
           </task>
         </pre-upgrade>
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
         <post-upgrade>
           <task xsi:type="execute">
@@ -170,7 +182,7 @@
       <component name="DATANODE">
         <pre-downgrade />
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
         <post-downgrade>
           <task xsi:type="manual">

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/test/resources/stacks/HDP/2.2.0/upgrades/config-upgrade.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/stacks/HDP/2.2.0/upgrades/config-upgrade.xml b/ambari-server/src/test/resources/stacks/HDP/2.2.0/upgrades/config-upgrade.xml
new file mode 100644
index 0000000..90d64b4
--- /dev/null
+++ b/ambari-server/src/test/resources/stacks/HDP/2.2.0/upgrades/config-upgrade.xml
@@ -0,0 +1,101 @@
+<?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-config-changes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+  <services>
+    <service name="ZOOKEEPER">
+      <component name="ZOOKEEPER_SERVER">
+        <changes>
+          <definition xsi:type="configure" id="hdp_2_2_0_zk_post_upgrade">
+          </definition>
+        </changes>
+      </component>
+    </service>
+
+    <service name="HDFS">
+      <component name="NAMENODE">
+        <changes>
+          <definition xsi:type="configure" id="hdp_2_2_0_nn_pre_upgrade">
+            <type>hdfs-site</type>
+            <set key="myproperty" value="mynewvalue"/>
+          </definition>
+        </changes>
+      </component>
+    </service>
+
+    <service name="YARN">
+      <component name="NODEMANAGER">
+        <changes>
+          <definition xsi:type="configure" id="hdp_2_2_0_nm_pre_upgrade">
+            <type>core-site</type>
+            <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"
+                      preserve-edits="true">
+              <keep-key>important-key</keep-key>
+            </transfer>
+          </definition>
+        </changes>
+      </component>
+    </service>
+
+    <service name="HIVE">
+      <component name="HIVE_SERVER">
+        <changes>
+          <definition xsi:type="configure" id="hdp_2_2_0_set_transport_mode">
+            <condition type="hive-site" key="hive.server2.transport.mode" value="binary">
+              <type>hive-site</type>
+              <key>hive.server2.thrift.port</key>
+              <value>10010</value>
+            </condition>
+            <condition type="hive-site" key="hive.server2.transport.mode" value="http">
+              <type>hive-site</type>
+              <key>hive.server2.http.port</key>
+              <value>10011</value>
+            </condition>
+          </definition>
+
+          <definition xsi:type="configure" id="hdp_2_2_0_hive_server_foo">
+            <type>hive-site</type>
+            <set key="fooKey" value="fooValue"/>
+            <set key="fooKey2" value="fooValue2"/>
+            <set key="fooKey3" value="fooValue3"/>
+            <transfer operation="copy" from-key="copy-key" to-key="copy-key-to" />
+            <transfer operation="move" from-key="move-key" to-key="move-key-to" />
+            <transfer operation="delete" delete-key="delete-key" />
+            <transfer operation="delete" delete-key="delete-http" if-key="hive.server2.transport.mode" if-type="hive-site" if-value="http" />
+            <transfer operation="delete" delete-key="delete-https-fail" if-key="hive.server2.transport.mode" if-type="hive-site" if-value="https" />
+            <transfer operation="delete" delete-key="delete-prop-fail" if-key="non.existent" if-type="hive-site" if-value="https" />
+            <transfer operation="delete" delete-key="delete-type-fail" if-key="non.existent" if-type="non.existent" if-value="" />
+            <transfer operation="delete" delete-key="delete-null-if-value" if-key="non.existent" if-type="non.existent" />
+            <transfer operation="delete" delete-key="delete-blank-if-key" if-key="" if-type="non.existent" />
+            <transfer operation="delete" delete-key="delete-blank-if-type" if-key="non.existent" if-type="" />
+            <transfer operation="delete" delete-key="delete-thrift" if-key="hive.server2.thrift.port" if-type="hive-site" if-value="10001" />
+          </definition>
+        </changes>
+      </component>
+    </service>
+  </services>
+
+</upgrade-config-changes>

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/test/resources/stacks/HDP/2.2.0/upgrades/upgrade_test.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/stacks/HDP/2.2.0/upgrades/upgrade_test.xml b/ambari-server/src/test/resources/stacks/HDP/2.2.0/upgrades/upgrade_test.xml
index 5271ae6..34ebe32 100644
--- a/ambari-server/src/test/resources/stacks/HDP/2.2.0/upgrades/upgrade_test.xml
+++ b/ambari-server/src/test/resources/stacks/HDP/2.2.0/upgrades/upgrade_test.xml
@@ -17,7 +17,20 @@
 -->
 <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>
+  <prerequisite-checks>
+    <check>org.apache.ambari.server.checks.HiveMultipleMetastoreCheck</check>
+    <check>org.apache.ambari.server.checks.MapReduce2JobHistoryStatePreservingCheck</check>
+    <check>org.apache.ambari.server.checks.SecondaryNamenodeDeletedCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesMapReduceDistributedCacheCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesNamenodeHighAvailabilityCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesNamenodeTruncateCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesTezDistributedCacheCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesYarnWorkPreservingCheck</check>
+    <check>org.apache.ambari.server.checks.YarnRMHighAvailabilityCheck</check>
+    <check>org.apache.ambari.server.checks.YarnTimelineServerStatePreservingCheck</check>
+  </prerequisite-checks>
   <order>
     <group xsi:type="cluster" name="PRE_CLUSTER" title="Pre {{direction.text.proper}}">
       <execute-stage title="Confirm 1">
@@ -126,7 +139,7 @@
           </task>
         </pre-upgrade>
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
         <post-upgrade>
           <task xsi:type="configure" />
@@ -149,7 +162,7 @@
           </task>
         </pre-upgrade>
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
         <post-upgrade>
           <task xsi:type="execute">
@@ -160,7 +173,7 @@
       <component name="DATANODE">
         <pre-downgrade />
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
         <post-downgrade>
           <task xsi:type="manual">

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/test/resources/stacks/HDP/2.2.0/upgrades/upgrade_test_checks.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/stacks/HDP/2.2.0/upgrades/upgrade_test_checks.xml b/ambari-server/src/test/resources/stacks/HDP/2.2.0/upgrades/upgrade_test_checks.xml
index 892b9b4..14c68be 100644
--- a/ambari-server/src/test/resources/stacks/HDP/2.2.0/upgrades/upgrade_test_checks.xml
+++ b/ambari-server/src/test/resources/stacks/HDP/2.2.0/upgrades/upgrade_test_checks.xml
@@ -16,8 +16,21 @@
    limitations under the License.
 -->
 <upgrade xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-  <target>2.2.*</target>
-  
+  <target>2.2.*.*</target>
+  <target-stack>HDP-2.2.1</target-stack>
+  <type>ROLLING</type>
+  <prerequisite-checks>
+    <check>org.apache.ambari.server.checks.HiveMultipleMetastoreCheck</check>
+    <check>org.apache.ambari.server.checks.MapReduce2JobHistoryStatePreservingCheck</check>
+    <check>org.apache.ambari.server.checks.SecondaryNamenodeDeletedCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesMapReduceDistributedCacheCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesNamenodeHighAvailabilityCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesNamenodeTruncateCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesTezDistributedCacheCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesYarnWorkPreservingCheck</check>
+    <check>org.apache.ambari.server.checks.YarnRMHighAvailabilityCheck</check>
+    <check>org.apache.ambari.server.checks.YarnTimelineServerStatePreservingCheck</check>
+  </prerequisite-checks>
   <order>
     <group xsi:type="cluster" name="PRE_CLUSTER" title="Pre Upgrade" stage="pre">
       <execute-stage title="Confirm 1">
@@ -125,10 +138,10 @@
           </task>
         </pre-upgrade>
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
         <post-upgrade>
-          <task xsi:type="configure" />
+          <task xsi:type="configure" id="hdp_2_2_0_zk_post_upgrade"/>
         </post-upgrade>
       </component>
     </service>
@@ -138,16 +151,13 @@
           <task xsi:type="execute" hosts="master">
             <command>su - {hdfs-user} -c 'dosomething'</command>
           </task>
-          <task xsi:type="configure">
-            <type>hdfs-site</type>
-            <set key="myproperty" value="mynewvalue"/>
-          </task>
+          <task xsi:type="configure" id="hdp_2_2_0_nn_pre_upgrade"/>
           <task xsi:type="manual">
             <message>Update your database</message>
           </task>
         </pre-upgrade>
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
         <post-upgrade>
           <task xsi:type="execute">
@@ -158,7 +168,7 @@
       <component name="DATANODE">
         <pre-downgrade />
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
         <post-downgrade>
           <task xsi:type="manual">

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/browser/HiveBrowserService.java.orig
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/browser/HiveBrowserService.java.orig b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/browser/HiveBrowserService.java.orig
deleted file mode 100644
index 55919a7..0000000
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/browser/HiveBrowserService.java.orig
+++ /dev/null
@@ -1,282 +0,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.
- */
-
-package org.apache.ambari.view.hive.resources.browser;
-
-import org.apache.ambari.view.ViewContext;
-import org.apache.ambari.view.ViewResourceHandler;
-import org.apache.ambari.view.hive.client.ColumnDescription;
-import org.apache.ambari.view.hive.client.Cursor;
-import org.apache.ambari.view.hive.client.IConnectionFactory;
-import org.apache.ambari.view.hive.resources.jobs.ResultsPaginationController;
-import org.apache.ambari.view.hive.utils.BadRequestFormattedException;
-import org.apache.ambari.view.hive.utils.ServiceFormattedException;
-import org.apache.ambari.view.hive.utils.SharedObjectsFactory;
-import org.apache.commons.collections4.map.PassiveExpiringMap;
-import org.apache.hive.service.cli.thrift.TSessionHandle;
-import org.json.simple.JSONObject;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.inject.Inject;
-import javax.ws.rs.*;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Callable;
-
-/**
- * Database access resource
- */
-public class HiveBrowserService {
-  @Inject
-  ViewResourceHandler handler;
-  @Inject
-  protected ViewContext context;
-
-  protected final static Logger LOG =
-      LoggerFactory.getLogger(HiveBrowserService.class);
-
-  private static final long EXPIRING_TIME = 10*60*1000;  // 10 minutes
-  private static Map<String, Cursor> resultsCache;
-  private IConnectionFactory connectionFactory;
-
-  public static Map<String, Cursor> getResultsCache() {
-    if (resultsCache == null) {
-      PassiveExpiringMap<String, Cursor> resultsCacheExpiringMap =
-          new PassiveExpiringMap<String, Cursor>(EXPIRING_TIME);
-      resultsCache = Collections.synchronizedMap(resultsCacheExpiringMap);
-    }
-    return resultsCache;
-  }
-
-  private IConnectionFactory getConnectionFactory() {
-    if (connectionFactory == null)
-      connectionFactory = new SharedObjectsFactory(context);
-    return new SharedObjectsFactory(context);
-  }
-
-  /**
-   * Returns list of databases
-   */
-  @GET
-  @Path("database")
-  @Produces(MediaType.APPLICATION_JSON)
-  public Response databases(@QueryParam("like")String like,
-                            @QueryParam("first") String fromBeginning,
-                            @QueryParam("count") Integer count,
-                            @QueryParam("columns") final String requestedColumns) {
-    if (like == null)
-      like = "*";
-    else
-      like = "*" + like + "*";
-    String curl = null;
-    try {
-      JSONObject response = new JSONObject();
-      TSessionHandle session = getConnectionFactory().getHiveConnection().getOrCreateSessionByTag("DDL");
-      List<String> tables = getConnectionFactory().getHiveConnection().ddl().getDBList(session, like);
-      response.put("databases", tables);
-      return Response.ok(response).build();
-    } catch (WebApplicationException ex) {
-      throw ex;
-    } catch (IllegalArgumentException ex) {
-      throw new BadRequestFormattedException(ex.getMessage(), ex);
-    } catch (Exception ex) {
-      throw new ServiceFormattedException(ex.getMessage(), ex, curl);
-    }
-  }
-
-  /**
-   * Returns list of databases
-   */
-  @GET
-  @Path("database.page")
-  @Produces(MediaType.APPLICATION_JSON)
-  public Response databasesPaginated(@QueryParam("like")String like,
-                            @QueryParam("first") String fromBeginning,
-                            @QueryParam("count") Integer count,
-                            @QueryParam("searchId") String searchId,
-                            @QueryParam("format") String format,
-                            @QueryParam("columns") final String requestedColumns) {
-    if (like == null)
-      like = "*";
-    else
-      like = "*" + like + "*";
-    String curl = null;
-    try {
-      final String finalLike = like;
-      return ResultsPaginationController.getInstance(context)
-          .request("databases", searchId, false, fromBeginning, count, format,
-                  new Callable<Cursor>() {
-                    @Override
-                    public Cursor call() throws Exception {
-                      TSessionHandle session = getConnectionFactory().getHiveConnection().getOrCreateSessionByTag("DDL");
-                      return getConnectionFactory().getHiveConnection().ddl().getDBListCursor(session, finalLike);
-                    }
-                  }).build();
-    } catch (WebApplicationException ex) {
-      throw ex;
-    } catch (IllegalArgumentException ex) {
-      throw new BadRequestFormattedException(ex.getMessage(), ex);
-    } catch (Exception ex) {
-      throw new ServiceFormattedException(ex.getMessage(), ex, curl);
-    }
-  }
-
-  /**
-   * Returns list of databases
-   */
-  @GET
-  @Path("database/{db}/table")
-  @Produces(MediaType.APPLICATION_JSON)
-  public Response tablesInDatabase(@PathParam("db") String db,
-                                   @QueryParam("like")String like,
-                                   @QueryParam("first") String fromBeginning,
-                                   @QueryParam("count") Integer count,
-                                   @QueryParam("columns") final String requestedColumns) {
-    if (like == null)
-      like = "*";
-    else
-      like = "*" + like + "*";
-    String curl = null;
-    try {
-      JSONObject response = new JSONObject();
-      TSessionHandle session = getConnectionFactory().getHiveConnection().getOrCreateSessionByTag("DDL");
-      List<String> tables = getConnectionFactory().getHiveConnection().ddl().getTableList(session, db, like);
-      response.put("tables", tables);
-      response.put("database", db);
-      return Response.ok(response).build();
-    } catch (WebApplicationException ex) {
-      throw ex;
-    } catch (IllegalArgumentException ex) {
-      throw new BadRequestFormattedException(ex.getMessage(), ex);
-    } catch (Exception ex) {
-      throw new ServiceFormattedException(ex.getMessage(), ex, curl);
-    }
-  }
-
-  /**
-   * Returns list of databases
-   */
-  @GET
-  @Path("database/{db}/table.page")
-  @Produces(MediaType.APPLICATION_JSON)
-  public Response tablesInDatabasePaginated(@PathParam("db") final String db,
-                                   @QueryParam("like")String like,
-                                   @QueryParam("first") String fromBeginning,
-                                   @QueryParam("count") Integer count,
-                                   @QueryParam("searchId") String searchId,
-                                   @QueryParam("format") String format,
-                                   @QueryParam("columns") final String requestedColumns) {
-    if (like == null)
-      like = "*";
-    else
-      like = "*" + like + "*";
-    String curl = null;
-    try {
-      final String finalLike = like;
-      return ResultsPaginationController.getInstance(context)
-          .request(db + ":tables", searchId, false, fromBeginning, count, format,
-                  new Callable<Cursor>() {
-                    @Override
-                    public Cursor call() throws Exception {
-                      TSessionHandle session = getConnectionFactory().getHiveConnection().getOrCreateSessionByTag("DDL");
-                      Cursor cursor = getConnectionFactory().getHiveConnection().ddl().getTableListCursor(session, db, finalLike);
-                      cursor.selectColumns(requestedColumns);
-                      return cursor;
-                    }
-                  }).build();
-    } catch (WebApplicationException ex) {
-      throw ex;
-    } catch (IllegalArgumentException ex) {
-      throw new BadRequestFormattedException(ex.getMessage(), ex);
-    } catch (Exception ex) {
-      throw new ServiceFormattedException(ex.getMessage(), ex, curl);
-    }
-  }
-
-  /**
-   * Returns list of databases
-   */
-  @GET
-  @Path("database/{db}/table/{table}")
-  @Produces(MediaType.APPLICATION_JSON)
-  public Response describeTable(@PathParam("db") String db,
-                                @PathParam("table") String table,
-                                @QueryParam("like") String like,
-                                @QueryParam("columns") String requestedColumns,
-                                @QueryParam("extended") String extended) {
-    boolean extendedTableDescription = (extended != null && extended.equals("true"));
-    String curl = null;
-    try {
-      JSONObject response = new JSONObject();
-      TSessionHandle session = getConnectionFactory().getHiveConnection().getOrCreateSessionByTag("DDL");
-      List<ColumnDescription> columnDescriptions = getConnectionFactory().getHiveConnection().ddl()
-          .getTableDescription(session, db, table, like, extendedTableDescription);
-      response.put("columns", columnDescriptions);
-      response.put("database", db);
-      response.put("table", table);
-      return Response.ok(response).build();
-    } catch (WebApplicationException ex) {
-      throw ex;
-    } catch (IllegalArgumentException ex) {
-      throw new BadRequestFormattedException(ex.getMessage(), ex);
-    } catch (Exception ex) {
-      throw new ServiceFormattedException(ex.getMessage(), ex, curl);
-    }
-  }
-
-  /**
-   * Returns list of databases
-   */
-  @GET
-  @Path("database/{db}/table/{table}.page")
-  @Produces(MediaType.APPLICATION_JSON)
-  public Response describeTablePaginated(@PathParam("db") final String db,
-                                         @PathParam("table") final String table,
-                                         @QueryParam("like") final String like,
-                                         @QueryParam("first") String fromBeginning,
-                                         @QueryParam("searchId") String searchId,
-                                         @QueryParam("count") Integer count,
-                                         @QueryParam("format") String format,
-                                         @QueryParam("columns") final String requestedColumns) {
-    String curl = null;
-    try {
-      return ResultsPaginationController.getInstance(context)
-          .request(db + ":tables:" + table + ":columns", searchId, false, fromBeginning, count, format,
-              new Callable<Cursor>() {
-                @Override
-                public Cursor call() throws Exception {
-                  TSessionHandle session = getConnectionFactory().getHiveConnection().getOrCreateSessionByTag("DDL");
-                  Cursor cursor = getConnectionFactory().getHiveConnection().ddl().
-                      getTableDescriptionCursor(session, db, table, like);
-                  cursor.selectColumns(requestedColumns);
-                  return cursor;
-                }
-              }).build();
-    } catch (WebApplicationException ex) {
-      throw ex;
-    } catch (IllegalArgumentException ex) {
-      throw new BadRequestFormattedException(ex.getMessage(), ex);
-    } catch (Exception ex) {
-      throw new ServiceFormattedException(ex.getMessage(), ex, curl);
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/JobService.java.orig
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/JobService.java.orig b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/JobService.java.orig
deleted file mode 100644
index ad46e33..0000000
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/JobService.java.orig
+++ /dev/null
@@ -1,476 +0,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.
- */
-
-package org.apache.ambari.view.hive.resources.jobs;
-
-import org.apache.ambari.view.ViewResourceHandler;
-import org.apache.ambari.view.hive.BaseService;
-import org.apache.ambari.view.hive.backgroundjobs.BackgroundJobController;
-import org.apache.ambari.view.hive.client.Connection;
-import org.apache.ambari.view.hive.client.Cursor;
-import org.apache.ambari.view.hive.client.HiveClientException;
-import org.apache.ambari.view.hive.persistence.utils.ItemNotFound;
-import org.apache.ambari.view.hive.resources.jobs.atsJobs.IATSParser;
-import org.apache.ambari.view.hive.resources.jobs.viewJobs.*;
-import org.apache.ambari.view.hive.utils.*;
-import org.apache.commons.beanutils.PropertyUtils;
-import org.apache.commons.csv.CSVFormat;
-import org.apache.commons.csv.CSVPrinter;
-import org.apache.hadoop.fs.FSDataOutputStream;
-import org.json.simple.JSONObject;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.inject.Inject;
-import javax.servlet.http.HttpServletResponse;
-import javax.ws.rs.*;
-import javax.ws.rs.core.*;
-import java.io.*;
-import java.lang.reflect.InvocationTargetException;
-import java.util.*;
-import java.util.concurrent.Callable;
-
-/**
- * Servlet for queries
- * API:
- * GET /:id
- *      read job
- * POST /
- *      create new job
- *      Required: title, queryFile
- * GET /
- *      get all Jobs of current user
- */
-public class JobService extends BaseService {
-  @Inject
-  ViewResourceHandler handler;
-
-  protected JobResourceManager resourceManager;
-  private IOperationHandleResourceManager opHandleResourceManager;
-  protected final static Logger LOG =
-      LoggerFactory.getLogger(JobService.class);
-  private Aggregator aggregator;
-
-  protected synchronized JobResourceManager getResourceManager() {
-    if (resourceManager == null) {
-      SharedObjectsFactory connectionsFactory = getSharedObjectsFactory();
-      resourceManager = new JobResourceManager(connectionsFactory, context);
-    }
-    return resourceManager;
-  }
-
-  protected IOperationHandleResourceManager getOperationHandleResourceManager() {
-    if (opHandleResourceManager == null) {
-      opHandleResourceManager = new OperationHandleResourceManager(getSharedObjectsFactory());
-    }
-    return opHandleResourceManager;
-  }
-
-  protected Aggregator getAggregator() {
-    if (aggregator == null) {
-      IATSParser atsParser = getSharedObjectsFactory().getATSParser();
-      aggregator = new Aggregator(getResourceManager(), getOperationHandleResourceManager(), atsParser);
-    }
-    return aggregator;
-  }
-
-  protected void setAggregator(Aggregator aggregator) {
-    this.aggregator = aggregator;
-  }
-
-  /**
-   * Get single item
-   */
-  @GET
-  @Path("{jobId}")
-  @Produces(MediaType.APPLICATION_JSON)
-  public Response getOne(@PathParam("jobId") String jobId) {
-    try {
-      JobController jobController = getResourceManager().readController(jobId);
-
-      JSONObject jsonJob = jsonObjectFromJob(jobController);
-
-      return Response.ok(jsonJob).build();
-    } catch (WebApplicationException ex) {
-      throw ex;
-    } catch (ItemNotFound itemNotFound) {
-      throw new NotFoundFormattedException(itemNotFound.getMessage(), itemNotFound);
-    } catch (Exception ex) {
-      throw new ServiceFormattedException(ex.getMessage(), ex);
-    }
-  }
-
-  private JSONObject jsonObjectFromJob(JobController jobController) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
-    Job hiveJob = jobController.getJobPOJO();
-
-    Job mergedJob;
-    try {
-      mergedJob = getAggregator().readATSJob(hiveJob);
-    } catch (ItemNotFound itemNotFound) {
-      throw new ServiceFormattedException("E010 Job not found", itemNotFound);
-    }
-    Map createdJobMap = PropertyUtils.describe(mergedJob);
-    createdJobMap.remove("class"); // no need to show Bean class on client
-
-    JSONObject jobJson = new JSONObject();
-    jobJson.put("job", createdJobMap);
-    return jobJson;
-  }
-
-  /**
-   * Get job results in csv format
-   */
-  @GET
-  @Path("{jobId}/results/csv")
-  @Produces("text/csv")
-  public Response getResultsCSV(@PathParam("jobId") String jobId,
-                                @Context HttpServletResponse response,
-                                @QueryParam("fileName") String fileName,
-                                @QueryParam("columns") final String requestedColumns) {
-    try {
-      JobController jobController = getResourceManager().readController(jobId);
-      final Cursor resultSet = jobController.getResults();
-      resultSet.selectColumns(requestedColumns);
-
-      StreamingOutput stream = new StreamingOutput() {
-        @Override
-        public void write(OutputStream os) throws IOException, WebApplicationException {
-          Writer writer = new BufferedWriter(new OutputStreamWriter(os));
-          CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT);
-          try {
-
-            try {
-              csvPrinter.printRecord(resultSet.getHeadersRow().getRow());
-            } catch (HiveClientException e) {
-              LOG.error("Error on reading results header", e);
-            }
-
-            while (resultSet.hasNext()) {
-              csvPrinter.printRecord(resultSet.next().getRow());
-              writer.flush();
-            }
-          } finally {
-            writer.close();
-          }
-        }
-      };
-
-      if (fileName == null || fileName.isEmpty()) {
-        fileName = "results.csv";
-      }
-
-      return Response.ok(stream).
-          header("Content-Disposition", String.format("attachment; filename=\"%s\"", fileName)).
-          build();
-    } catch (WebApplicationException ex) {
-      throw ex;
-    } catch (ItemNotFound itemNotFound) {
-      throw new NotFoundFormattedException(itemNotFound.getMessage(), itemNotFound);
-    } catch (Exception ex) {
-      throw new ServiceFormattedException(ex.getMessage(), ex);
-    }
-  }
-
-  /**
-   * Get job results in csv format
-   */
-  @GET
-  @Path("{jobId}/results/csv/saveToHDFS")
-  @Produces(MediaType.APPLICATION_JSON)
-  public Response getResultsToHDFS(@PathParam("jobId") String jobId,
-                                   @QueryParam("commence") String commence,
-                                   @QueryParam("file") final String targetFile,
-                                   @QueryParam("stop") final String stop,
-                                   @QueryParam("columns") final String requestedColumns,
-                                   @Context HttpServletResponse response) {
-    try {
-      final JobController jobController = getResourceManager().readController(jobId);
-
-      String backgroundJobId = "csv" + String.valueOf(jobController.getJob().getId());
-      if (commence != null && commence.equals("true")) {
-        if (targetFile == null)
-          throw new MisconfigurationFormattedException("targetFile should not be empty");
-        BackgroundJobController.getInstance(context).startJob(String.valueOf(backgroundJobId), new Runnable() {
-          @Override
-          public void run() {
-
-            try {
-              Cursor resultSet = jobController.getResults();
-              resultSet.selectColumns(requestedColumns);
-
-              FSDataOutputStream stream = getSharedObjectsFactory().getHdfsApi().create(targetFile, true);
-              Writer writer = new BufferedWriter(new OutputStreamWriter(stream));
-              CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT);
-              try {
-                while (resultSet.hasNext() && !Thread.currentThread().isInterrupted()) {
-                  csvPrinter.printRecord(resultSet.next().getRow());
-                  writer.flush();
-                }
-              } finally {
-                writer.close();
-              }
-              stream.close();
-
-            } catch (IOException e) {
-              throw new ServiceFormattedException("F010 Could not write CSV to HDFS for job#" + jobController.getJob().getId(), e);
-            } catch (InterruptedException e) {
-              throw new ServiceFormattedException("F010 Could not write CSV to HDFS for job#" + jobController.getJob().getId(), e);
-            } catch (ItemNotFound itemNotFound) {
-              throw new NotFoundFormattedException("E020 Job results are expired", itemNotFound);
-            }
-
-          }
-        });
-      }
-
-      if (stop != null && stop.equals("true")) {
-        BackgroundJobController.getInstance(context).interrupt(backgroundJobId);
-      }
-
-      JSONObject object = new JSONObject();
-      object.put("stopped", BackgroundJobController.getInstance(context).isInterrupted(backgroundJobId));
-      object.put("jobId", jobController.getJob().getId());
-      object.put("backgroundJobId", backgroundJobId);
-      object.put("operationType", "CSV2HDFS");
-      object.put("status", BackgroundJobController.getInstance(context).state(backgroundJobId).toString());
-
-      return Response.ok(object).build();
-    } catch (WebApplicationException ex) {
-      throw ex;
-    } catch (ItemNotFound itemNotFound) {
-      throw new NotFoundFormattedException(itemNotFound.getMessage(), itemNotFound);
-    } catch (Exception ex) {
-      throw new ServiceFormattedException(ex.getMessage(), ex);
-    }
-  }
-
-  /**
-   * Get next results page
-   */
-  @GET
-  @Path("{jobId}/results")
-  @Produces(MediaType.APPLICATION_JSON)
-  public Response getResults(@PathParam("jobId") String jobId,
-                             @QueryParam("first") String fromBeginning,
-                             @QueryParam("count") Integer count,
-                             @QueryParam("searchId") String searchId,
-                             @QueryParam("format") String format,
-                             @QueryParam("columns") final String requestedColumns) {
-    try {
-      final JobController jobController = getResourceManager().readController(jobId);
-      if (!jobController.hasResults()) {
-        return ResultsPaginationController.emptyResponse().build();
-      }
-
-      return ResultsPaginationController.getInstance(context)
-           .request(jobId, searchId, true, fromBeginning, count, format,
-               new Callable<Cursor>() {
-                 @Override
-                 public Cursor call() throws Exception {
-                   Cursor cursor = jobController.getResults();
-                   cursor.selectColumns(requestedColumns);
-                   return cursor;
-                 }
-               }).build();
-    } catch (WebApplicationException ex) {
-      throw ex;
-    } catch (ItemNotFound itemNotFound) {
-      throw new NotFoundFormattedException(itemNotFound.getMessage(), itemNotFound);
-    } catch (Exception ex) {
-      throw new ServiceFormattedException(ex.getMessage(), ex);
-    }
-  }
-
-  /**
-   * Renew expiration time for results
-   */
-  @GET
-  @Path("{jobId}/results/keepAlive")
-  public Response keepAliveResults(@PathParam("jobId") String jobId,
-                             @QueryParam("first") String fromBeginning,
-                             @QueryParam("count") Integer count) {
-    try {
-      if (!ResultsPaginationController.getInstance(context).keepAlive(jobId, ResultsPaginationController.DEFAULT_SEARCH_ID)) {
-        throw new NotFoundFormattedException("Results already expired", null);
-      }
-      return Response.ok().build();
-    } catch (WebApplicationException ex) {
-      throw ex;
-    } catch (Exception ex) {
-      throw new ServiceFormattedException(ex.getMessage(), ex);
-    }
-  }
-
-  /**
-   * Get progress info
-   */
-  @GET
-  @Path("{jobId}/progress")
-  @Produces(MediaType.APPLICATION_JSON)
-  public Response getProgress(@PathParam("jobId") String jobId) {
-    try {
-      final JobController jobController = getResourceManager().readController(jobId);
-
-      ProgressRetriever.Progress progress = new ProgressRetriever(jobController.getJob(), getSharedObjectsFactory()).
-          getProgress();
-
-      return Response.ok(progress).build();
-    } catch (WebApplicationException ex) {
-      throw ex;
-    } catch (ItemNotFound itemNotFound) {
-      throw new NotFoundFormattedException(itemNotFound.getMessage(), itemNotFound);
-    } catch (Exception ex) {
-      throw new ServiceFormattedException(ex.getMessage(), ex);
-    }
-  }
-
-  /**
-   * Delete single item
-   */
-  @DELETE
-  @Path("{id}")
-  public Response delete(@PathParam("id") String id,
-                         @QueryParam("remove") final String remove) {
-    try {
-      JobController jobController;
-      try {
-        jobController = getResourceManager().readController(id);
-      } catch (ItemNotFound itemNotFound) {
-        throw new NotFoundFormattedException(itemNotFound.getMessage(), itemNotFound);
-      }
-      jobController.cancel();
-      if (remove != null && remove.compareTo("true") == 0) {
-        getResourceManager().delete(id);
-      }
-      return Response.status(204).build();
-    } catch (WebApplicationException ex) {
-      throw ex;
-    } catch (ItemNotFound itemNotFound) {
-      throw new NotFoundFormattedException(itemNotFound.getMessage(), itemNotFound);
-    } catch (Exception ex) {
-      throw new ServiceFormattedException(ex.getMessage(), ex);
-    }
-  }
-
-  /**
-   * Get all Jobs
-   */
-  @GET
-  @Produces(MediaType.APPLICATION_JSON)
-  public Response getList() {
-    try {
-      LOG.debug("Getting all job");
-      List<Job> allJobs = getAggregator().readAll(context.getUsername());
-      for(Job job : allJobs) {
-        job.setSessionTag(null);
-      }
-
-      JSONObject object = new JSONObject();
-      object.put("jobs", allJobs);
-      return Response.ok(object).build();
-    } catch (WebApplicationException ex) {
-      throw ex;
-    } catch (Exception ex) {
-      throw new ServiceFormattedException(ex.getMessage(), ex);
-    }
-  }
-
-  /**
-   * Create job
-   */
-  @POST
-  @Consumes(MediaType.APPLICATION_JSON)
-  public Response create(JobRequest request, @Context HttpServletResponse response,
-                         @Context UriInfo ui) {
-    try {
-      Map jobInfo = PropertyUtils.describe(request.job);
-      Job job = new JobImpl(jobInfo);
-      getResourceManager().create(job);
-
-      JobController createdJobController = getResourceManager().readController(job.getId());
-      createdJobController.submit();
-      getResourceManager().saveIfModified(createdJobController);
-
-      response.setHeader("Location",
-          String.format("%s/%s", ui.getAbsolutePath().toString(), job.getId()));
-
-      JSONObject jobObject = jsonObjectFromJob(createdJobController);
-
-      return Response.ok(jobObject).status(201).build();
-    } catch (WebApplicationException ex) {
-      throw ex;
-    } catch (ItemNotFound itemNotFound) {
-      throw new NotFoundFormattedException(itemNotFound.getMessage(), itemNotFound);
-    } catch (Exception ex) {
-      throw new ServiceFormattedException(ex.getMessage(), ex);
-    }
-  }
-
-  /**
-   * Invalidate session
-   */
-  @DELETE
-  @Path("sessions/{sessionTag}")
-  public Response invalidateSession(@PathParam("sessionTag") String sessionTag) {
-    try {
-      Connection connection = getSharedObjectsFactory().getHiveConnection();
-      connection.invalidateSessionByTag(sessionTag);
-      return Response.ok().build();
-    } catch (WebApplicationException ex) {
-      throw ex;
-    } catch (Exception ex) {
-      throw new ServiceFormattedException(ex.getMessage(), ex);
-    }
-  }
-
-  /**
-   * Session status
-   */
-  @GET
-  @Path("sessions/{sessionTag}")
-  @Produces(MediaType.APPLICATION_JSON)
-  public Response sessionStatus(@PathParam("sessionTag") String sessionTag) {
-    try {
-      Connection connection = getSharedObjectsFactory().getHiveConnection();
-
-      JSONObject session = new JSONObject();
-      session.put("sessionTag", sessionTag);
-      try {
-        connection.getSessionByTag(sessionTag);
-        session.put("actual", true);
-      } catch (HiveClientException ex) {
-        session.put("actual", false);
-      }
-
-      JSONObject status = new JSONObject();
-      status.put("session", session);
-      return Response.ok(status).build();
-    } catch (WebApplicationException ex) {
-      throw ex;
-    } catch (Exception ex) {
-      throw new ServiceFormattedException(ex.getMessage(), ex);
-    }
-  }
-
-  /**
-   * Wrapper object for json mapping
-   */
-  public static class JobRequest {
-    public JobImpl job;
-  }
-}


[6/9] ambari git commit: AMBARI-13392. Stop-and-Start Upgrade: Merge branch branch-dev-stop-all-upgrade to branch-2.1 for feature Stop-the-World Upgrade, aka Express Upgrade (alejandro, dlysnichenko, Dmytro Grinenko)

Posted by al...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog213.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog213.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog213.java
index 2c152e4..3eac5ce 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog213.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog213.java
@@ -22,21 +22,48 @@ import com.google.gson.JsonObject;
 import com.google.gson.JsonParser;
 import com.google.inject.Inject;
 import com.google.inject.Injector;
+import com.google.inject.persist.Transactional;
 import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.orm.DBAccessor.DBColumnInfo;
 import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
+import org.apache.ambari.server.orm.dao.ClusterDAO;
+import org.apache.ambari.server.orm.dao.ClusterVersionDAO;
 import org.apache.ambari.server.orm.dao.DaoUtils;
+import org.apache.ambari.server.orm.dao.HostVersionDAO;
+import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
+import org.apache.ambari.server.orm.dao.StackDAO;
 import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
+import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
+import org.apache.ambari.server.orm.entities.HostEntity;
+import org.apache.ambari.server.orm.entities.HostVersionEntity;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.Config;
 import org.apache.ambari.server.state.alert.SourceType;
+import org.apache.ambari.server.orm.entities.ClusterEntity;
+import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
+import org.apache.ambari.server.orm.entities.StackEntity;
+import org.apache.ambari.server.state.RepositoryVersionState;
+import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.StackInfo;
+import org.apache.ambari.server.state.stack.upgrade.Direction;
+import org.apache.ambari.server.state.stack.upgrade.RepositoryVersionHelper;
+import org.apache.ambari.server.state.stack.upgrade.UpgradeType;
+import org.apache.commons.lang.StringUtils;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.persistence.EntityManager;
 import javax.persistence.Query;
+import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.sql.Statement;
+import java.text.MessageFormat;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.UUID;
@@ -50,6 +77,11 @@ public class UpgradeCatalog213 extends AbstractUpgradeCatalog {
   private static final String AMS_ENV = "ams-env";
   private static final String AMS_HBASE_ENV = "ams-hbase-env";
 
+  public static final String UPGRADE_PACKAGE_COL = "upgrade_package";
+  public static final String UPGRADE_TYPE_COL = "upgrade_type";
+  public static final String UPGRADE_TABLE = "upgrade";
+  public static final String REPO_VERSION_TABLE = "repo_version";
+
 
   /**
    * Logger.
@@ -59,6 +91,11 @@ public class UpgradeCatalog213 extends AbstractUpgradeCatalog {
   @Inject
   DaoUtils daoUtils;
 
+  @Inject
+  private RepositoryVersionDAO repositoryVersionDAO;
+
+  @Inject
+  private ClusterDAO clusterDAO;
 
   // ----- Constructors ------------------------------------------------------
 
@@ -70,8 +107,7 @@ public class UpgradeCatalog213 extends AbstractUpgradeCatalog {
   @Inject
   public UpgradeCatalog213(Injector injector) {
     super(injector);
-
-    daoUtils = injector.getInstance(DaoUtils.class);
+    this.injector = injector;
   }
 
   // ----- UpgradeCatalog ----------------------------------------------------
@@ -110,12 +146,341 @@ public class UpgradeCatalog213 extends AbstractUpgradeCatalog {
 
   @Override
   protected void executeDMLUpdates() throws AmbariException, SQLException {
+    // This one actually performs both DDL and DML, so it needs to be first.
+    executeStackUpgradeDDLUpdates();
+    bootstrapRepoVersionForHDP21();
+
     addMissingConfigs();
     updateAMSConfigs();
     updateAlertDefinitions();
   }
 
   /**
+   * Move the upgrade_package column from the repo_version table to the upgrade table as follows,
+   * add column upgrade_package to upgrade table as String 255 and nullable
+   * populate column in the upgrade table
+   * drop the column in the repo_version table
+   * make the column in the upgrade table non-nullable.
+   * This has to be called as part of DML and not DDL since the persistence service has to be started.
+   * @throws AmbariException
+   * @throws SQLException
+   */
+  @Transactional
+  private void executeStackUpgradeDDLUpdates() throws SQLException, AmbariException {
+    final Configuration.DatabaseType databaseType = configuration.getDatabaseType();
+
+    // Add columns
+    if (!dbAccessor.tableHasColumn(UPGRADE_TABLE, UPGRADE_PACKAGE_COL)) {
+      LOG.info("Adding upgrade_package column to upgrade table.");
+      dbAccessor.addColumn(UPGRADE_TABLE, new DBColumnInfo(UPGRADE_PACKAGE_COL, String.class, 255, null, true));
+    }
+    if (!dbAccessor.tableHasColumn(UPGRADE_TABLE, UPGRADE_TYPE_COL)) {
+      LOG.info("Adding upgrade_type column to upgrade table.");
+      dbAccessor.addColumn(UPGRADE_TABLE, new DBColumnInfo(UPGRADE_TYPE_COL, String.class, 32, null, true));
+    }
+
+    // Populate values in upgrade table.
+    boolean success = this.populateUpgradeTable();
+
+    if (!success) {
+      throw new AmbariException("Errors found while populating the upgrade table with values for columns upgrade_type and upgrade_package.");
+    }
+
+    if (dbAccessor.tableHasColumn(REPO_VERSION_TABLE, UPGRADE_PACKAGE_COL)) {
+      LOG.info("Dropping upgrade_package column from repo_version table.");
+      dbAccessor.dropColumn(REPO_VERSION_TABLE, UPGRADE_PACKAGE_COL);
+
+      // Now, make the added column non-nullable
+      // Make the hosts id non-null after all the values are populated
+      LOG.info("Making upgrade_package column in the upgrade table non-nullable.");
+      if (databaseType == Configuration.DatabaseType.DERBY) {
+        // This is a workaround for UpgradeTest.java unit test
+        dbAccessor.executeQuery("ALTER TABLE " + UPGRADE_TABLE + " ALTER column " + UPGRADE_PACKAGE_COL + " NOT NULL");
+      } else {
+        dbAccessor.alterColumn(UPGRADE_TABLE, new DBColumnInfo(UPGRADE_PACKAGE_COL, String.class, 255, null, false));
+      }
+    }
+
+    if (dbAccessor.tableHasColumn(REPO_VERSION_TABLE, UPGRADE_TYPE_COL)) {
+      // Now, make the added column non-nullable
+      // Make the hosts id non-null after all the values are populated
+      LOG.info("Making upgrade_type column in the upgrade table non-nullable.");
+      if (databaseType == Configuration.DatabaseType.DERBY) {
+        // This is a workaround for UpgradeTest.java unit test
+        dbAccessor.executeQuery("ALTER TABLE " + UPGRADE_TABLE + " ALTER column " + UPGRADE_TYPE_COL + " NOT NULL");
+      } else {
+        dbAccessor.alterColumn(UPGRADE_TABLE, new DBColumnInfo(UPGRADE_TYPE_COL, String.class, 32, null, false));
+      }
+    }
+  }
+
+  /**
+   * Populate the upgrade table with values for the columns upgrade_type and upgrade_package.
+   * The upgrade_type will default to {@code org.apache.ambari.server.state.stack.upgrade.UpgradeType.ROLLING}
+   * whereas the upgrade_package will be calculated.
+   * @return {@code} true on success, and {@code} false otherwise.
+   */
+  private boolean populateUpgradeTable() {
+    boolean success = true;
+    Statement statement = null;
+    ResultSet rs = null;
+    try {
+      statement = dbAccessor.getConnection().createStatement();
+      if (statement != null) {
+        // Need to use SQL since the schema is changing and some of the columns have not yet been added..
+        rs = statement.executeQuery("SELECT upgrade_id, cluster_id, from_version, to_version, direction, upgrade_package, upgrade_type FROM upgrade");
+        if (rs != null) {
+          try {
+            while (rs.next()) {
+              final long upgradeId = rs.getLong("upgrade_id");
+              final long clusterId = rs.getLong("cluster_id");
+              final String fromVersion = rs.getString("from_version");
+              final String toVersion = rs.getString("to_version");
+              final Direction direction = Direction.valueOf(rs.getString("direction"));
+              // These two values are likely null.
+              String upgradePackage = rs.getString("upgrade_package");
+              String upgradeType = rs.getString("upgrade_type");
+
+              LOG.info(MessageFormat.format("Populating rows for the upgrade table record with " +
+                      "upgrade_id: {0,number,#}, cluster_id: {1,number,#}, from_version: {2}, to_version: {3}, direction: {4}",
+                  upgradeId, clusterId, fromVersion, toVersion, direction));
+
+              // Set all upgrades that have been done so far to type "rolling"
+              if (StringUtils.isEmpty(upgradeType)) {
+                LOG.info("Updating the record's upgrade_type to " + UpgradeType.ROLLING);
+                dbAccessor.executeQuery("UPDATE upgrade SET upgrade_type = '" + UpgradeType.ROLLING + "' WHERE upgrade_id = " + upgradeId);
+              }
+
+              if (StringUtils.isEmpty(upgradePackage)) {
+                String version = null;
+                StackEntity stack = null;
+
+                if (direction == Direction.UPGRADE) {
+                  version = toVersion;
+                } else if (direction == Direction.DOWNGRADE) {
+                  // TODO AMBARI-12698, this is going to be a problem.
+                  // During a downgrade, the "to_version" is overwritten to the source version, but the "from_version"
+                  // doesn't swap. E.g.,
+                  //  upgrade_id | from_version |  to_version  | direction
+                  // ------------+--------------+--------------+----------
+                  //           1 | 2.2.6.0-2800 | 2.3.0.0-2557 | UPGRADE
+                  //           2 | 2.2.6.0-2800 | 2.2.6.0-2800 | DOWNGRADE
+                  version = fromVersion;
+                }
+
+                ClusterEntity cluster = clusterDAO.findById(clusterId);
+
+                if (null != cluster) {
+                  stack = cluster.getDesiredStack();
+                  upgradePackage = this.calculateUpgradePackage(stack, version);
+                } else {
+                  LOG.error("Could not find a cluster with cluster_id " + clusterId);
+                }
+
+                if (!StringUtils.isEmpty(upgradePackage)) {
+                  LOG.info("Updating the record's upgrade_package to " + upgradePackage);
+                  dbAccessor.executeQuery("UPDATE upgrade SET upgrade_package = '" + upgradePackage + "' WHERE upgrade_id = " + upgradeId);
+                } else {
+                  success = false;
+                  LOG.error("Unable to populate column upgrade_package for record in table upgrade with id " + upgradeId);
+                }
+              }
+            }
+          } catch (Exception e) {
+            success = false;
+            e.printStackTrace();
+            LOG.error("Unable to populate the upgrade_type and upgrade_package columns of the upgrade table. " + e);
+          }
+        }
+      }
+    } catch (Exception e) {
+      success = false;
+      e.printStackTrace();
+      LOG.error("Failed to retrieve records from the upgrade table to populate the upgrade_type and upgrade_package columns. Exception: " + e);
+    } finally {
+      try {
+        if (rs != null) {
+          rs.close();
+        }
+        if (statement != null) {
+          statement.close();
+        }
+      } catch (SQLException e) {
+        ;
+      }
+    }
+    return success;
+  }
+
+  /**
+   * Find the single Repo Version for the given stack and version, and return its upgrade_package column.
+   * Because the upgrade_package column is going to be removed from this entity, must use raw SQL
+   * instead of the entity class.
+   * @param stack Stack
+   * @param version Stack version
+   * @return The value of the upgrade_package column, or null if not found.
+   */
+
+  private String calculateUpgradePackage(StackEntity stack, String version) {
+    String upgradePackage = null;
+    // Find the corresponding repo_version, and extract its upgrade_package
+    if (null != version && null != stack) {
+      RepositoryVersionEntity repoVersion = repositoryVersionDAO.findByStackNameAndVersion(stack.getStackName(), version);
+
+      Statement statement = null;
+      ResultSet rs = null;
+      try {
+        statement = dbAccessor.getConnection().createStatement();
+        if (statement != null) {
+          // Need to use SQL since the schema is changing and the entity will no longer have the upgrade_package column.
+          rs = statement.executeQuery("SELECT upgrade_package FROM repo_version WHERE repo_version_id = " + repoVersion.getId());
+          if (rs != null && rs.next()) {
+            upgradePackage = rs.getString("upgrade_package");
+          }
+        }
+      } catch (Exception e) {
+        LOG.error("Failed to retrieve upgrade_package for repo_version record with id " + repoVersion.getId() + ". Exception: " + e.getMessage());
+      } finally {
+        try {
+          if (rs != null) {
+            rs.close();
+          }
+          if (statement != null) {
+            statement.close();
+          }
+        } catch (SQLException e) {
+          ;
+        }
+      }
+    }
+    return upgradePackage;
+  }
+
+  /**
+   * If still on HDP 2.1, then no repo versions exist, so need to bootstrap the HDP 2.1 repo version,
+   * and mark it as CURRENT in the cluster_version table for the cluster, as well as the host_version table
+   * for all hosts.
+   */
+  @Transactional
+  public void bootstrapRepoVersionForHDP21() throws AmbariException, SQLException {
+    final String hardcodedInitialVersion = "2.1.0.0-0001";
+    AmbariManagementController amc = injector.getInstance(AmbariManagementController.class);
+    AmbariMetaInfo ambariMetaInfo = amc.getAmbariMetaInfo();
+    StackDAO stackDAO = injector.getInstance(StackDAO.class);
+    RepositoryVersionHelper repositoryVersionHelper = injector.getInstance(RepositoryVersionHelper.class);
+    RepositoryVersionDAO repositoryVersionDAO = injector.getInstance(RepositoryVersionDAO.class);
+    ClusterVersionDAO clusterVersionDAO = injector.getInstance(ClusterVersionDAO.class);
+    HostVersionDAO hostVersionDAO = injector.getInstance(HostVersionDAO.class);
+
+    Clusters clusters = amc.getClusters();
+    if (clusters == null) {
+      LOG.error("Unable to get Clusters entity.");
+      return;
+    }
+
+    for (Cluster cluster : clusters.getClusters().values()) {
+      ClusterEntity clusterEntity = clusterDAO.findByName(cluster.getClusterName());
+      final StackId stackId = cluster.getCurrentStackVersion();
+      LOG.info(MessageFormat.format("Analyzing cluster {0}, currently at stack {1} and version {2}",
+          cluster.getClusterName(), stackId.getStackName(), stackId.getStackVersion()));
+
+      if (stackId.getStackName().equalsIgnoreCase("HDP") && stackId.getStackVersion().equalsIgnoreCase("2.1")) {
+        final StackInfo stackInfo = ambariMetaInfo.getStack(stackId.getStackName(), stackId.getStackVersion());
+        StackEntity stackEntity = stackDAO.find(stackId.getStackName(), stackId.getStackVersion());
+
+        LOG.info("Bootstrapping the versions since using HDP-2.1");
+
+        // The actual value is not known, so use this.
+        String displayName = stackId.getStackName() + "-" + hardcodedInitialVersion;
+
+        // However, the Repo URLs should be correct.
+        String operatingSystems = repositoryVersionHelper.serializeOperatingSystems(stackInfo.getRepositories());
+
+        // Create the Repo Version if it doesn't already exist.
+        RepositoryVersionEntity repoVersionEntity = repositoryVersionDAO.findByDisplayName(displayName);
+        if (null != repoVersionEntity) {
+          LOG.info(MessageFormat.format("A Repo Version already exists with Display Name: {0}", displayName));
+        } else {
+          final long repoVersionIdSeq = repositoryVersionDAO.findMaxId("id");
+          // Safe to attempt to add the sequence if it doesn't exist already.
+          addSequence("repo_version_id_seq", repoVersionIdSeq, false);
+
+          repoVersionEntity = repositoryVersionDAO.create(
+              stackEntity, hardcodedInitialVersion, displayName, operatingSystems);
+          LOG.info(MessageFormat.format("Created Repo Version with ID: {0,number,#}\n, Display Name: {1}, Repo URLs: {2}\n",
+              repoVersionEntity.getId(), displayName, operatingSystems));
+        }
+
+        // Create the Cluster Version if it doesn't already exist.
+        ClusterVersionEntity clusterVersionEntity = clusterVersionDAO.findByClusterAndStackAndVersion(cluster.getClusterName(),
+            stackId, hardcodedInitialVersion);
+
+        if (null != clusterVersionEntity) {
+          LOG.info(MessageFormat.format("A Cluster Version version for cluster: {0}, version: {1}, already exists; its state is {2}.",
+              cluster.getClusterName(), clusterVersionEntity.getRepositoryVersion().getVersion(), clusterVersionEntity.getState()));
+
+          // If there are not CURRENT cluster versions, make this one the CURRENT one.
+          if (clusterVersionEntity.getState() != RepositoryVersionState.CURRENT &&
+              clusterVersionDAO.findByClusterAndState(cluster.getClusterName(), RepositoryVersionState.CURRENT).isEmpty()) {
+            clusterVersionEntity.setState(RepositoryVersionState.CURRENT);
+            clusterVersionDAO.merge(clusterVersionEntity);
+          }
+        } else {
+          final long clusterVersionIdSeq = clusterVersionDAO.findMaxId("id");
+          // Safe to attempt to add the sequence if it doesn't exist already.
+          addSequence("cluster_version_id_seq", clusterVersionIdSeq, false);
+
+          clusterVersionEntity = clusterVersionDAO.create(clusterEntity, repoVersionEntity, RepositoryVersionState.CURRENT,
+              System.currentTimeMillis(), System.currentTimeMillis(), "admin");
+          LOG.info(MessageFormat.format("Created Cluster Version with ID: {0,number,#}, cluster: {1}, version: {2}, state: {3}.",
+              clusterVersionEntity.getId(), cluster.getClusterName(), clusterVersionEntity.getRepositoryVersion().getVersion(),
+              clusterVersionEntity.getState()));
+        }
+
+        // Create the Host Versions if they don't already exist.
+        Collection<HostEntity> hosts = clusterEntity.getHostEntities();
+        boolean addedAtLeastOneHost = false;
+        if (null != hosts && !hosts.isEmpty()) {
+          for (HostEntity hostEntity : hosts) {
+            HostVersionEntity hostVersionEntity = hostVersionDAO.findByClusterStackVersionAndHost(cluster.getClusterName(),
+                stackId, hardcodedInitialVersion, hostEntity.getHostName());
+
+            if (null != hostVersionEntity) {
+              LOG.info(MessageFormat.format("A Host Version version for cluster: {0}, version: {1}, host: {2}, already exists; its state is {3}.",
+                  cluster.getClusterName(), hostVersionEntity.getRepositoryVersion().getVersion(),
+                  hostEntity.getHostName(), hostVersionEntity.getState()));
+
+              if (hostVersionEntity.getState() != RepositoryVersionState.CURRENT &&
+                  hostVersionDAO.findByClusterHostAndState(cluster.getClusterName(), hostEntity.getHostName(),
+                      RepositoryVersionState.CURRENT).isEmpty()) {
+                hostVersionEntity.setState(RepositoryVersionState.CURRENT);
+                hostVersionDAO.merge(hostVersionEntity);
+              }
+            } else {
+              // This should only be done the first time.
+              if (!addedAtLeastOneHost) {
+                final long hostVersionIdSeq = hostVersionDAO.findMaxId("id");
+                // Safe to attempt to add the sequence if it doesn't exist already.
+                addSequence("host_version_id_seq", hostVersionIdSeq, false);
+                addedAtLeastOneHost = true;
+              }
+
+              hostVersionEntity = new HostVersionEntity(hostEntity, repoVersionEntity, RepositoryVersionState.CURRENT);
+              hostVersionDAO.create(hostVersionEntity);
+              LOG.info(MessageFormat.format("Created Host Version with ID: {0,number,#}, cluster: {1}, version: {2}, host: {3}, state: {4}.",
+                  hostVersionEntity.getId(), cluster.getClusterName(), hostVersionEntity.getRepositoryVersion().getVersion(),
+                  hostEntity.getHostName(), hostVersionEntity.getState()));
+            }
+          }
+        } else {
+          LOG.info(MessageFormat.format("Not inserting any Host Version records since cluster {0} does not have any hosts.",
+              cluster.getClusterName()));
+        }
+      }
+    }
+  }
+  
+  /**
    * Modifies the JSON of some of the alert definitions which have changed
    * between Ambari versions.
    */

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
index b803c37..a4d0c42 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
@@ -541,7 +541,6 @@ CREATE TABLE repo_version (
   stack_id BIGINT NOT NULL,
   version VARCHAR(255) NOT NULL,
   display_name VARCHAR(128) NOT NULL,
-  upgrade_package VARCHAR(255) NOT NULL,
   repositories LONGTEXT NOT NULL,
   PRIMARY KEY(repo_version_id)
 );
@@ -883,6 +882,8 @@ CREATE TABLE upgrade (
   from_version VARCHAR(255) DEFAULT '' NOT NULL,
   to_version VARCHAR(255) DEFAULT '' NOT NULL,
   direction VARCHAR(255) DEFAULT 'UPGRADE' NOT NULL,
+  upgrade_package VARCHAR(255) NOT NULL,
+  upgrade_type VARCHAR(32) NOT NULL,
   PRIMARY KEY (upgrade_id),
   FOREIGN KEY (cluster_id) REFERENCES clusters(cluster_id),
   FOREIGN KEY (request_id) REFERENCES request(request_id)

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
index c3195e5..016d0c4 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
@@ -530,7 +530,6 @@ CREATE TABLE repo_version (
   stack_id NUMBER(19) NOT NULL,
   version VARCHAR2(255) NOT NULL,
   display_name VARCHAR2(128) NOT NULL,
-  upgrade_package VARCHAR2(255) NOT NULL,
   repositories CLOB NOT NULL,
   PRIMARY KEY(repo_version_id)
 );
@@ -872,6 +871,8 @@ CREATE TABLE upgrade (
   from_version VARCHAR2(255) DEFAULT '' NOT NULL,
   to_version VARCHAR2(255) DEFAULT '' NOT NULL,
   direction VARCHAR2(255) DEFAULT 'UPGRADE' NOT NULL,
+  upgrade_package VARCHAR2(255) NOT NULL,
+  upgrade_type VARCHAR2(32) NOT NULL,
   PRIMARY KEY (upgrade_id),
   FOREIGN KEY (cluster_id) REFERENCES clusters(cluster_id),
   FOREIGN KEY (request_id) REFERENCES request(request_id)

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
index b7bc440..a3caf50 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
@@ -535,7 +535,6 @@ CREATE TABLE repo_version (
   stack_id BIGINT NOT NULL,
   version VARCHAR(255) NOT NULL,
   display_name VARCHAR(128) NOT NULL,
-  upgrade_package VARCHAR(255) NOT NULL,
   repositories TEXT NOT NULL,
   PRIMARY KEY(repo_version_id)
 );
@@ -874,6 +873,8 @@ CREATE TABLE upgrade (
   from_version VARCHAR(255) DEFAULT '' NOT NULL,
   to_version VARCHAR(255) DEFAULT '' NOT NULL,
   direction VARCHAR(255) DEFAULT 'UPGRADE' NOT NULL,
+  upgrade_package VARCHAR(255) NOT NULL,
+  upgrade_type VARCHAR(32) NOT NULL,
   PRIMARY KEY (upgrade_id),
   FOREIGN KEY (cluster_id) REFERENCES clusters(cluster_id),
   FOREIGN KEY (request_id) REFERENCES request(request_id)

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
index cd16120..e4a5799 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
@@ -602,7 +602,6 @@ CREATE TABLE ambari.repo_version (
   stack_id BIGINT NOT NULL,
   version VARCHAR(255) NOT NULL,
   display_name VARCHAR(128) NOT NULL,
-  upgrade_package VARCHAR(255) NOT NULL,
   repositories TEXT NOT NULL,
   PRIMARY KEY(repo_version_id)
 );
@@ -965,6 +964,8 @@ CREATE TABLE ambari.upgrade (
   from_version VARCHAR(255) DEFAULT '' NOT NULL,
   to_version VARCHAR(255) DEFAULT '' NOT NULL,
   direction VARCHAR(255) DEFAULT 'UPGRADE' NOT NULL,
+  upgrade_package VARCHAR(255) NOT NULL,
+  upgrade_type VARCHAR(32) NOT NULL,
   PRIMARY KEY (upgrade_id),
   FOREIGN KEY (cluster_id) REFERENCES ambari.clusters(cluster_id),
   FOREIGN KEY (request_id) REFERENCES ambari.request(request_id)

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
index 5f98d47..4aaab7e 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
@@ -641,7 +641,6 @@ CREATE TABLE repo_version (
   stack_id BIGINT NOT NULL,
   version VARCHAR(255) NOT NULL,
   display_name VARCHAR(128) NOT NULL,
-  upgrade_package VARCHAR(255) NOT NULL,
   repositories VARCHAR(MAX) NOT NULL,
   PRIMARY KEY CLUSTERED (repo_version_id)
   );
@@ -989,6 +988,8 @@ CREATE TABLE upgrade (
   from_version VARCHAR(255) DEFAULT '' NOT NULL,
   to_version VARCHAR(255) DEFAULT '' NOT NULL,
   direction VARCHAR(255) DEFAULT 'UPGRADE' NOT NULL,
+  upgrade_package VARCHAR(255) NOT NULL,
+  upgrade_type VARCHAR(32) NOT NULL,
   PRIMARY KEY CLUSTERED (upgrade_id),
   FOREIGN KEY (cluster_id) REFERENCES clusters(cluster_id),
   FOREIGN KEY (request_id) REFERENCES request(request_id)

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/resources/common-services/HBASE/0.96.0.2.0/package/scripts/hbase_upgrade.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HBASE/0.96.0.2.0/package/scripts/hbase_upgrade.py b/ambari-server/src/main/resources/common-services/HBASE/0.96.0.2.0/package/scripts/hbase_upgrade.py
index 610f527..2dc9883 100644
--- a/ambari-server/src/main/resources/common-services/HBASE/0.96.0.2.0/package/scripts/hbase_upgrade.py
+++ b/ambari-server/src/main/resources/common-services/HBASE/0.96.0.2.0/package/scripts/hbase_upgrade.py
@@ -24,7 +24,7 @@ from resource_management.core.resources.system import Execute
 
 class HbaseMasterUpgrade(Script):
 
-  def snapshot(self, env):
+  def take_snapshot(self, env):
     import params
 
     snap_cmd = "echo 'snapshot_all' | {0} shell".format(params.hbase_cmd)
@@ -33,5 +33,9 @@ class HbaseMasterUpgrade(Script):
 
     Execute(exec_cmd, user=params.hbase_user)
 
+  def restore_snapshot(self, env):
+    import params
+    print "TODO AMBARI-12698"
+
 if __name__ == "__main__":
   HbaseMasterUpgrade().execute()

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/namenode.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/namenode.py b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/namenode.py
index a3c02a6..23e775a 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/namenode.py
+++ b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/namenode.py
@@ -107,9 +107,24 @@ class NameNodeDefault(NameNode):
   def get_stack_to_component(self):
     return {"HDP": "hadoop-hdfs-namenode"}
 
+  def restore_snapshot(self, env):
+    """
+    Restore the snapshot during a Downgrade.
+    """
+    print "TODO AMBARI-12698"
+    pass
+
+  def prepare_non_rolling_upgrade(self, env):
+    print "TODO AMBARI-12698"
+    pass
+
   def prepare_rolling_upgrade(self, env):
     namenode_upgrade.prepare_rolling_upgrade()
 
+  def finalize_non_rolling_upgrade(self, env):
+    print "TODO AMBARI-12698"
+    pass
+
   def finalize_rolling_upgrade(self, env):
     namenode_upgrade.finalize_rolling_upgrade()
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/resources/stacks/HDP/2.1/upgrades/nonrolling-upgrade-2.3.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.1/upgrades/nonrolling-upgrade-2.3.xml b/ambari-server/src/main/resources/stacks/HDP/2.1/upgrades/nonrolling-upgrade-2.3.xml
new file mode 100644
index 0000000..1da05c2
--- /dev/null
+++ b/ambari-server/src/main/resources/stacks/HDP/2.1/upgrades/nonrolling-upgrade-2.3.xml
@@ -0,0 +1,382 @@
+<?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.3.*.*</target>
+  <target-stack>HDP-2.3</target-stack>
+  <type>NON_ROLLING</type>
+
+  <upgrade-path>
+    <intermediate-stack version="2.2"/>
+    <intermediate-stack version="2.3"/>
+  </upgrade-path>
+
+  <order>
+    <group xsi:type="cluster" name="PRE_CLUSTER" title="Prepare Upgrade">
+      <skippable>true</skippable>
+      <direction>UPGRADE</direction>
+      <execute-stage service="YARN" component="RESOURCEMANAGER" title="Stop YARN Queues">
+        <task xsi:type="manual">
+          <message>Before continuing, please stop all YARN queues. If yarn-site's yarn.resourcemanager.work-preserving-recovery.enabled is set to true, then you can skip this step since the clients will retry on their own.</message>
+        </task>
+      </execute-stage>
+
+      <execute-stage service="STORM" component="NIMBUS" title="Stop 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 High-Level Daemons" title="Stop Daemons for High-Level Services">
+      <skippable>true</skippable>
+      <service-check>false</service-check>
+
+      <service name="FLUME">
+        <component>FLUME_HANDLER</component>
+      </service>
+
+      <service name="STORM">
+        <component>DRPC_SERVER</component>
+        <component>STORM_UI_SERVER</component>
+        <component>SUPERVISOR</component>
+        <component>STORM_REST_API</component>
+        <component>NIMBUS</component>
+      </service>
+
+      <service name="FALCON">
+        <component>FALCON_SERVER</component>
+      </service>
+
+      <service name="OOZIE">
+        <component>OOZIE_SERVER</component>
+      </service>
+
+      <service name="HIVE">
+        <component>WEBHCAT_SERVER</component>
+        <component>HIVE_SERVER</component>
+        <component>HIVE_METASTORE</component>
+      </service>
+
+      <service name="YARN">
+        <component>NODEMANAGER</component>
+        <component>RESOURCEMANAGER</component>
+        <component>APP_TIMELINE_SERVER</component>
+      </service>
+
+      <service name="MAPREDUCE2">
+        <component>HISTORYSERVER</component>
+      </service>
+    </group>
+
+    <group xsi:type="cluster" name="Backups" title="Take Backups">
+      <direction>UPGRADE</direction>
+      <skippable>true</skippable>
+      <execute-stage service="OOZIE" component="OOZIE_SERVER" title="Backup Oozie Database">
+        <task xsi:type="manual">
+          <message>Before continuing, please backup the Oozie Server database on {{oozie-env/oozie_hostname}}.</message>
+        </task>
+      </execute-stage>
+
+      <execute-stage service="HIVE" component="HIVE_METASTORE" title="Backup Hive Metastore">
+        <task xsi:type="manual">
+          <message>Before continuing, please backup the Hive Metastore database located on the following host(s): {{hosts.all}}.</message>
+        </task>
+      </execute-stage>
+
+      <execute-stage service="HBASE" component="HBASE_MASTER" title="Snapshot HBASE">
+        <task xsi:type="execute" hosts="master">
+          <script>scripts/hbase_upgrade.py</script>
+          <function>take_snapshot</function>
+        </task>
+      </execute-stage>
+
+      <execute-stage service="HDFS" component="NAMENODE" title="Snapshot HDFS">
+        <task xsi:type="execute" hosts="master">
+          <script>scripts/namenode.py</script>
+          <function>prepare_non_rolling_upgrade</function>
+        </task>
+      </execute-stage>
+    </group>
+
+    <group xsi:type="stop" name="Stop Low-Level Daemons" title="Stop Daemons for Low-Level Services">
+      <skippable>true</skippable>
+      <service-check>false</service-check>
+
+      <service name="HBASE">
+        <component>HBASE_REGIONSERVER</component>
+        <component>HBASE_MASTER</component>
+      </service>
+
+      <service name="HDFS">
+        <component>DATANODE</component>
+        <component>NAMENODE</component>
+        <component>SECONDARY_NAMENODE</component>
+        <component>ZKFC</component>
+        <component>JOURNALNODE</component>
+      </service>
+
+      <service name="ZOOKEEPER">
+        <component>ZOOKEEPER_SERVER</component>
+      </service>
+    </group>
+
+    <group name="Marker for Downgrade" title="Marker for Downgrade">
+      <direction>UPGRADE</direction>
+      <!-- TODO, if the user attempts a downgrade before this step, they can simply abort. -->
+    </group>
+
+    <group xsi:type="cluster" name="Restore Backups" title="Restore Backups">
+      <direction>DOWNGRADE</direction>
+      <skippable>true</skippable>
+
+      <!-- If the user attempts a downgrade after this point, they will need to restore backups
+      before starting any of the services. -->
+
+      <execute-stage service="OOZIE" component="OOZIE_SERVER" title="Backup Oozie Database">
+        <task xsi:type="manual">
+          <message>Before continuing, please restore the Oozie Server database on {{hosts.all}}.</message>
+        </task>
+      </execute-stage>
+
+      <execute-stage service="HIVE" component="HIVE_METASTORE" title="Backup Hive Metastore">
+        <task xsi:type="manual">
+          <message>Before continuing, please restore the Hive Metastore database located on the following host(s): {{hosts.all}}.</message>
+        </task>
+      </execute-stage>
+
+      <execute-stage service="HBASE" component="HBASE_MASTER" title="Snapshot HBASE">
+        <task xsi:type="execute" hosts="master">
+          <script>scripts/hbase_upgrade.py</script>
+          <function>restore_snapshot</function>
+        </task>
+      </execute-stage>
+
+      <execute-stage service="HDFS" component="NAMENODE" title="Snapshot HDFS">
+        <task xsi:type="execute" hosts="master">
+          <script>scripts/namenode.py</script>
+          <function>restore_snapshot</function>
+        </task>
+      </execute-stage>
+    </group>
+
+    <!-- After processing this group, will change the effective Stack of the UpgradeContext object. -->
+    <group xsi:type="update-stack" name="UPDATE_DESIRED_STACK_ID" title="Update Desired Stack Id">
+      <execute-stage title="Update Desired Stack Id" service="" component="">
+        <task xsi:type="server_action" class="org.apache.ambari.server.serveraction.upgrades.UpdateDesiredStackAction">
+        </task>
+      </execute-stage>
+    </group>
+
+    <group xsi:type="cluster" name="ALL_HOST_OPS" title="Set Version On All Hosts">
+      <skippable>true</skippable>
+      <execute-stage title="Update stack to {{version}}">
+        <task xsi:type="execute">
+          <script>scripts/ru_set_all.py</script>
+          <function>actionexecute</function>
+        </task>
+      </execute-stage>
+    </group>
+
+    <!-- Now, restart all of the services. -->
+
+    <group xsi:type="restart" name="ZOOKEEPER" title="Zookeeper">
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <service name="ZOOKEEPER">
+        <service-check>false</service-check>
+        <component>ZOOKEEPER_SERVER</component>
+        <component>ZOOKEEPER_CLIENT</component>
+      </service>
+    </group>
+
+    <group xsi:type="restart" name="HDFS" title="HDFS">
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <service name="HDFS">
+        <component>JOURNALNODE</component>
+        <component>ZKFC</component>
+        <component>NAMENODE</component>
+        <component>SECONDARY_NAMENODE</component>
+        <component>DATANODE</component>
+        <component>HDFS_CLIENT</component>
+      </service>
+    </group>
+
+    <group xsi:type="restart" name="MR and YARN" title="MR and YARN">
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <service name="MAPREDUCE2">
+        <component>HISTORYSERVER</component>
+        <component>MAPREDUCE2_CLIENT</component>
+      </service>
+      <service name="YARN">
+        <component>APP_TIMELINE_SERVER</component>
+        <component>RESOURCEMANAGER</component>
+        <component>NODEMANAGER</component>
+        <component>YARN_CLIENT</component>
+      </service>
+    </group>
+
+    <group xsi:type="restart" name="HBASE" title="HBASE">
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <service name="HBASE">
+        <component>HBASE_MASTER</component>
+        <component>HBASE_REGIONSERVER</component>
+        <component>HBASE_CLIENT</component>
+      </service>
+    </group>
+
+    <group xsi:type="restart" name="CLIENTS" title="Tez, Pig, Sqoop Clients">
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <service name="TEZ">
+        <component>TEZ_CLIENT</component>
+      </service>
+
+      <service name="PIG">
+        <component>PIG</component>
+      </service>
+
+      <service name="SQOOP">
+        <component>SQOOP</component>
+      </service>
+    </group>
+
+    <group name="SERVICE_CHECK" title="All Service Checks" xsi:type="service-check">
+      <skippable>true</skippable>
+      <direction>UPGRADE</direction>
+      <priority>
+        <service>HBASE</service>
+        <service>MAPREDUCE2</service>
+        <service>YARN</service>
+        <service>HDFS</service>
+      </priority>
+    </group>
+
+    <group xsi:type="restart" name="HIVE" title="Hive">
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <service name="HIVE">
+        <component>HIVE_METASTORE</component>
+        <component>HIVE_SERVER</component>
+        <component>WEBHCAT_SERVER</component>
+        <component>HIVE_CLIENT</component>
+        <component>HCAT</component>
+      </service>
+    </group>
+
+    <!-- Upgrade Oozie DB only on Upgrade direction, and always create a new ShareLib. -->
+    <group name="Upgrade Oozie" title="Upgrade Oozie Database">
+      <direction>UPGRADE</direction>
+      <skippable>true</skippable>
+      <execute-stage service="OOZIE" component="OOZIE_SERVER" title="Upgrade Oozie Database">
+        <task xsi:type="execute" hosts="any" summary="Upgrading the database and creating a new sharelib">
+          <script>scripts/oozie_server_upgrade.py</script>
+          <function>upgrade_oozie_database_and_sharelib</function>
+        </task>
+      </execute-stage>
+    </group>
+
+    <!-- Only create the ShareLib folder during a Downgrade. -->
+    <group name="Downgrade Oozie" title="Downgrade Oozie ShareLib">
+      <direction>DOWNGRADE</direction>
+      <skippable>true</skippable>
+      <execute-stage service="OOZIE" component="OOZIE_SERVER" title="Downgrade Oozie ShareLib">
+        <task xsi:type="execute" hosts="any" summary="Upgrading the database and creating a new sharelib">
+          <script>scripts/oozie_server_upgrade.py</script>
+          <function>create_sharelib</function>
+        </task>
+      </execute-stage>
+    </group>
+
+    <group xsi:type="restart" name="OOZIE" title="Oozie">
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <service name="OOZIE">
+        <component>OOZIE_SERVER</component>
+        <component>OOZIE_CLIENT</component>
+      </service>
+    </group>
+
+    <group xsi:type="restart" name="FALCON" title="Falcon">
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <service name="FALCON">
+        <component>FALCON_SERVER</component>
+        <component>FALCON_CLIENT</component>
+      </service>
+    </group>
+
+    <group xsi:type="restart" name="STORM" title="Storm">
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <service name="STORM">
+        <component>NIMBUS</component>
+        <component>STORM_REST_API</component>
+        <component>SUPERVISOR</component>
+        <component>STORM_UI_SERVER</component>
+        <component>DRPC_SERVER</component>
+      </service>
+
+      <execute-stage service="STORM" component="DRPC_SERVER" title="Rebuild Storm Topology">
+        <task xsi:type="manual">
+          <message>Please rebuild your topology using the new Storm version dependencies and resubmit it using the newly created jar.</message>
+        </task>
+      </execute-stage>
+    </group>
+
+    <group xsi:type="restart" name="FLUME" title="Flume">
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <service name="FLUME">
+        <component>FLUME_HANDLER</component>
+      </service>
+    </group>
+
+    <group xsi:type="cluster" name="POST_CLUSTER" title="Finalize {{direction.text.proper}}">
+      <skippable>true</skippable>
+      <execute-stage title="Check Unhealthy Hosts" id="unhealthy-hosts">
+        <task xsi:type="manual">
+          <message>The following hosts were unhealthy and should be resolved before finalizing can be completed: {{hosts.unhealthy}}</message>
+        </task>
+      </execute-stage>
+      
+      <execute-stage title="Confirm Finalize">
+        <direction>UPGRADE</direction>
+        <task xsi:type="manual">
+          <message>Please confirm you are ready to finalize.</message>
+        </task>
+      </execute-stage>
+
+      <execute-stage service="HDFS" component="NAMENODE" title="Execute HDFS Finalize">
+        <task xsi:type="execute" hosts="master">
+          <script>scripts/namenode.py</script>
+          <function>finalize_non_rolling_upgrade</function>
+        </task>
+      </execute-stage>
+
+      <execute-stage title="Save Cluster State" service="" component="">
+        <task xsi:type="server_action" class="org.apache.ambari.server.serveraction.upgrades.FinalizeUpgradeAction">
+        </task>
+      </execute-stage>
+    </group>
+  </order>
+</upgrade>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/config-upgrade.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/config-upgrade.xml b/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/config-upgrade.xml
new file mode 100644
index 0000000..fbd21a4
--- /dev/null
+++ b/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/config-upgrade.xml
@@ -0,0 +1,55 @@
+<?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-config-changes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+  <services>
+    <service name="HIVE">
+      <component name="HIVE_SERVER">
+        <changes>
+          <definition xsi:type="configure" id="hdp_2_2_0_0_hive_server_set_transport_modes">
+            <condition type="hive-site" key="hive.server2.transport.mode" value="binary">
+              <type>hive-site</type>
+              <key>hive.server2.thrift.port</key>
+              <value>10010</value>
+            </condition>
+            <condition type="hive-site" key="hive.server2.transport.mode" value="http">
+              <type>hive-site</type>
+              <key>hive.server2.http.port</key>
+              <value>10011</value>
+            </condition>
+          </definition>
+
+          <definition xsi:type="configure" id="hdp_2_2_0_0_hive_server_restore_transport_mode_on_downgrade">
+            <condition type="hive-site" key="hive.server2.transport.mode" value="binary">
+              <type>hive-site</type>
+              <key>hive.server2.thrift.port</key>
+              <value>10000</value>
+            </condition>
+            <condition type="hive-site" key="hive.server2.transport.mode" value="http">
+              <type>hive-site</type>
+              <key>hive.server2.http.port</key>
+              <value>10001</value>
+            </condition>
+          </definition>
+        </changes>
+      </component>
+    </service>
+  </services>
+
+</upgrade-config-changes>

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/nonrolling-upgrade-2.2.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/nonrolling-upgrade-2.2.xml b/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/nonrolling-upgrade-2.2.xml
new file mode 100644
index 0000000..2f6840f
--- /dev/null
+++ b/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/nonrolling-upgrade-2.2.xml
@@ -0,0 +1,469 @@
+<?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</target-stack>
+  <type>NON_ROLLING</type>
+  <prechecks>
+  </prechecks>
+  <order>
+    <group xsi:type="cluster" name="PRE_CLUSTER" title="Prepare Upgrade">
+      <skippable>true</skippable>
+      <direction>UPGRADE</direction>
+      <execute-stage service="YARN" component="RESOURCEMANAGER" title="Stop YARN Queues">
+        <task xsi:type="manual">
+          <message>Before continuing, please stop all YARN queues. If yarn-site's yarn.resourcemanager.work-preserving-recovery.enabled is set to true, then you can skip this step since the clients will retry on their own.</message>
+        </task>
+      </execute-stage>
+
+      <execute-stage service="SLIDER" component="SLIDER" title="Stop Long Running Applications on Slider">
+        <task xsi:type="manual">
+          <message>Before continuing, please stop all long-running applications deployed using Slider. E.g., su - yarn "/usr/hdp/current/slider-client/bin/slider stop &lt;app_name&gt;"</message>
+        </task>
+      </execute-stage>
+
+      <execute-stage service="STORM" component="NIMBUS" title="Stop 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 High-Level Daemons" title="Stop Daemons for High-Level Services">
+      <skippable>true</skippable>
+      <service-check>false</service-check>
+
+      <service name="FLUME">
+        <component>FLUME_HANDLER</component>
+      </service>
+
+      <service name="STORM">
+        <component>DRPC_SERVER</component>
+        <component>STORM_UI_SERVER</component>
+        <component>SUPERVISOR</component>
+        <component>STORM_REST_API</component>
+        <component>NIMBUS</component>
+      </service>
+
+      <service name="KNOX">
+        <component>KNOX_GATEWAY</component>
+      </service>
+
+      <service name="KAFKA">
+        <component>KAFKA_BROKER</component>
+      </service>
+
+      <service name="FALCON">
+        <component>FALCON_SERVER</component>
+      </service>
+
+      <service name="OOZIE">
+        <component>OOZIE_SERVER</component>
+      </service>
+
+      <service name="SPARK">
+        <component>SPARK_JOBHISTORYSERVER</component>
+      </service>
+
+      <service name="HIVE">
+        <component>WEBHCAT_SERVER</component>
+        <component>HIVE_SERVER</component>
+        <component>HIVE_METASTORE</component>
+      </service>
+
+      <service name="YARN">
+        <component>NODEMANAGER</component>        <!-- TODO, parallelize -->
+        <component>RESOURCEMANAGER</component>
+        <component>APP_TIMELINE_SERVER</component>
+      </service>
+
+      <service name="MAPREDUCE2">
+        <component>HISTORYSERVER</component>
+      </service>
+    </group>
+
+    <group xsi:type="cluster" name="Backups" title="Take Backups">
+      <direction>UPGRADE</direction>
+      <skippable>true</skippable>
+      <execute-stage service="OOZIE" component="OOZIE_SERVER" title="Backup Oozie Database">
+        <task xsi:type="manual">
+          <message>Before continuing, please backup the Oozie Server database on {{oozie-env/oozie_hostname}}.</message>
+        </task>
+      </execute-stage>
+
+      <execute-stage service="HIVE" component="HIVE_METASTORE" title="Backup Hive Metastore">
+        <task xsi:type="manual">
+          <message>Before continuing, please backup the Hive Metastore database located on the following host(s): {{hosts.all}}.</message>
+        </task>
+      </execute-stage>
+
+      <execute-stage service="KNOX" component="KNOX_GATEWAY" title="Backup Knox Data">
+        <task xsi:type="manual">
+          <message>Before continuing, please backup the Knox data. E.g., "cp -RL /etc/knox/data/security ~/knox_backup" on the following host(s): {{hosts.all}}.</message>
+        </task>
+      </execute-stage>
+
+      <execute-stage service="HBASE" component="HBASE_MASTER" title="Snapshot HBASE">
+        <task xsi:type="execute" hosts="master">
+          <script>scripts/hbase_upgrade.py</script>
+          <function>take_snapshot</function>        <!-- TODO, this function used to be called just "snapshot" -->
+        </task>
+      </execute-stage>
+
+      <execute-stage service="HDFS" component="NAMENODE" title="Snapshot HDFS">
+        <task xsi:type="execute" hosts="master">  <!-- TODO, this can be any NameNode, not just the active. -->
+          <script>scripts/namenode.py</script>
+          <function>prepare_non_rolling_upgrade</function>
+        </task>
+      </execute-stage>
+
+      <execute-stage service="RANGER" component="RANGER_ADMIN" title="Backup Ranger">
+        <task xsi:type="manual">
+          <message>Before continuing, please backup the Ranger Admin database and Ranger Audit database on the following host(s): {{hosts.all}}.</message>
+        </task>
+      </execute-stage>
+    </group>
+
+    <group xsi:type="stop" name="Stop Low-Level Daemons" title="Stop Daemons for Low-Level Services">
+      <skippable>true</skippable>
+      <service-check>false</service-check>
+
+      <service name="HBASE">
+        <component>HBASE_REGIONSERVER</component>
+        <component>HBASE_MASTER</component>
+      </service>
+
+      <service name="HDFS">
+        <component>DATANODE</component>
+        <component>NAMENODE</component>
+        <component>SECONDARY_NAMENODE</component>   <!-- TODO, may not be present. -->
+        <component>ZKFC</component>                 <!-- TODO, may not be present. -->
+        <component>JOURNALNODE</component>          <!-- TODO, may not be present. -->
+      </service>
+
+      <service name="RANGER">
+        <component>RANGER_USERSYNC</component>
+        <component>RANGER_ADMIN</component>
+      </service>
+
+      <service name="ZOOKEEPER">
+        <component>ZOOKEEPER_SERVER</component>
+      </service>
+    </group>
+
+    <group name="Marker for Downgrade" title="Marker for Downgrade">
+      <direction>UPGRADE</direction>
+      <!-- TODO, if the user attempts a downgrade before this step, they can simply abort. -->
+    </group>
+
+    <group xsi:type="cluster" name="Restore Backups" title="Restore Backups">
+      <direction>DOWNGRADE</direction>
+      <skippable>true</skippable>
+
+      <!-- If the user attempts a downgrade after this point, they will need to restore backups
+      before starting any of the services. -->
+
+      <execute-stage service="OOZIE" component="OOZIE_SERVER" title="Backup Oozie Database">
+        <task xsi:type="manual">
+          <message>Before continuing, please restore the Oozie Server database on {{hosts.all}}.</message>
+        </task>
+      </execute-stage>
+
+      <execute-stage service="HIVE" component="HIVE_METASTORE" title="Backup Hive Metastore">
+        <task xsi:type="manual">
+          <message>Before continuing, please restore the Hive Metastore database located on the following host(s): {{hosts.all}}.</message>
+        </task>
+      </execute-stage>
+
+      <execute-stage service="KNOX" component="KNOX_GATEWAY" title="Backup Knox Data">
+        <task xsi:type="manual">
+          <message>Before continuing, please restore the Knox data. E.g., "cp -RL ~/knox_backup/* /etc/knox/data/security/" on the following host(s): {{hosts.all}}.</message>
+        </task>
+      </execute-stage>
+
+      <execute-stage service="HBASE" component="HBASE_MASTER" title="Snapshot HBASE">
+        <task xsi:type="execute" hosts="master">
+          <script>scripts/hbase_upgrade.py</script>
+          <function>restore_snapshot</function>   <!-- TODO, this function name is new. -->
+        </task>
+      </execute-stage>
+
+      <execute-stage service="HDFS" component="NAMENODE" title="Snapshot HDFS">
+        <task xsi:type="execute" hosts="master">  <!-- TODO, this can be any NameNode, not just the active. -->
+          <script>scripts/namenode.py</script>
+          <function>restore_snapshot</function>    <!-- TODO, this function doesn't exist yet. -->
+        </task>
+      </execute-stage>
+
+      <execute-stage service="RANGER" component="RANGER_ADMIN" title="Backup Ranger">
+        <task xsi:type="manual">
+          <message>Before continuing, please restore the Ranger Admin database and Ranger Audit database on the following host(s): {{hosts.all}}.</message>
+        </task>
+      </execute-stage>
+    </group>
+
+    <!-- After processing this group, will change the effective Stack of the UpgradeContext object. -->
+    <group xsi:type="update-stack" name="UPDATE_DESIRED_STACK_ID" title="Update Desired Stack Id">
+      <execute-stage title="Update Desired Stack Id" service="" component="">
+        <task xsi:type="server_action" class="org.apache.ambari.server.serveraction.upgrades.UpdateDesiredStackAction">
+        </task>
+      </execute-stage>
+    </group>
+
+    <group xsi:type="cluster" name="ALL_HOST_OPS" title="Set Version On All Hosts">
+      <skippable>true</skippable>
+      <execute-stage title="Update stack to {{version}}">
+        <task xsi:type="execute">
+          <script>scripts/ru_set_all.py</script>
+          <function>actionexecute</function>      <!-- TODO, parallelize -->
+        </task>
+      </execute-stage>
+    </group>
+
+    <!-- Now, restart all of the services. -->
+
+    <group xsi:type="restart" name="ZOOKEEPER" title="Zookeeper">
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <service name="ZOOKEEPER">
+        <service-check>false</service-check>        <!-- TODO, enable service-check once done testing -->
+        <component>ZOOKEEPER_SERVER</component>
+        <component>ZOOKEEPER_CLIENT</component>     <!-- TODO, parallelize -->
+      </service>
+    </group>
+
+    <group xsi:type="restart" name="RANGER" title="Ranger">
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <service name="RANGER">
+        <component>RANGER_ADMIN</component>
+        <component>RANGER_USERSYNC</component>
+      </service>
+    </group>
+
+    <group xsi:type="restart" name="HDFS" title="HDFS">
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <service name="HDFS">
+        <component>JOURNALNODE</component>
+        <component>ZKFC</component>
+        <component>NAMENODE</component>
+        <component>SECONDARY_NAMENODE</component>   <!-- TODO, may not be present -->
+        <component>DATANODE</component>             <!-- TODO, parallelize -->
+        <component>HDFS_CLIENT</component>          <!-- TODO, parallelize -->
+      </service>
+    </group>
+
+    <group xsi:type="restart" name="MR and YARN" title="MR and YARN">
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <service name="MAPREDUCE2">
+        <component>HISTORYSERVER</component>
+        <component>MAPREDUCE2_CLIENT</component>    <!-- TODO, parallelize -->
+      </service>
+      <service name="YARN">
+        <component>APP_TIMELINE_SERVER</component>
+        <component>RESOURCEMANAGER</component>
+        <component>NODEMANAGER</component>          <!-- TODO, parallelize -->
+        <component>YARN_CLIENT</component>          <!-- TODO, parallelize -->
+      </service>
+    </group>
+
+    <group xsi:type="restart" name="HBASE" title="HBASE">
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <service name="HBASE">
+        <component>HBASE_MASTER</component>
+        <component>HBASE_REGIONSERVER</component>   <!-- TODO, parallelize -->
+        <component>HBASE_CLIENT</component>         <!-- TODO, parallelize -->
+      </service>
+    </group>
+
+    <group xsi:type="restart" name="CLIENTS" title="Tez, Pig, Sqoop Clients">  <!-- TODO, parallelize -->
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <service name="TEZ">
+        <component>TEZ_CLIENT</component>
+      </service>
+
+      <service name="PIG">
+        <component>PIG</component>
+      </service>
+
+      <service name="SQOOP">
+        <component>SQOOP</component>
+      </service>
+    </group>
+
+    <group name="SERVICE_CHECK" title="All Service Checks" xsi:type="service-check">
+      <skippable>true</skippable>
+      <direction>UPGRADE</direction>
+      <priority>
+        <!-- TODO, for some reason, it flips the order. -->
+        <service>HBASE</service>
+        <service>MAPREDUCE2</service>
+        <service>YARN</service>
+        <service>HDFS</service>
+      </priority>
+    </group>
+
+    <group xsi:type="restart" name="HIVE" title="Hive">
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <service name="HIVE">
+        <component>HIVE_METASTORE</component>
+        <component>HIVE_SERVER</component>
+        <component>WEBHCAT_SERVER</component>
+        <component>HIVE_CLIENT</component>          <!-- TODO, parallelize -->
+        <component>HCAT</component>                 <!-- TODO, parallelize -->
+      </service>
+    </group>
+
+    <group xsi:type="restart" name="SPARK" title="Spark">
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <service name="SPARK">
+        <component>SPARK_JOBHISTORYSERVER</component>
+        <component>SPARK_CLIENT</component>         <!-- TODO, parallelize -->
+      </service>
+    </group>
+
+    <!-- Upgrade Oozie DB only on Upgrade direction, and always create a new ShareLib. -->
+    <group name="Upgrade Oozie" title="Upgrade Oozie Database">
+      <direction>UPGRADE</direction>
+      <skippable>true</skippable>
+      <execute-stage service="OOZIE" component="OOZIE_SERVER" title="Upgrade Oozie Database">
+        <task xsi:type="execute" hosts="any" summary="Upgrading the database and creating a new sharelib">
+          <script>scripts/oozie_server_upgrade.py</script>
+          <function>upgrade_oozie_database_and_sharelib</function>
+        </task>
+      </execute-stage>
+    </group>
+
+    <!-- Only create the ShareLib folder during a Downgrade. -->
+    <group name="Downgrade Oozie" title="Downgrade Oozie ShareLib">
+      <direction>DOWNGRADE</direction>
+      <skippable>true</skippable>
+      <execute-stage service="OOZIE" component="OOZIE_SERVER" title="Downgrade Oozie ShareLib">
+        <task xsi:type="execute" hosts="any" summary="Upgrading the database and creating a new sharelib">
+          <script>scripts/oozie_server_upgrade.py</script>
+          <function>create_sharelib</function>
+        </task>
+      </execute-stage>
+    </group>
+
+    <group xsi:type="restart" name="OOZIE" title="Oozie">
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <service name="OOZIE">
+        <component>OOZIE_SERVER</component>
+        <component>OOZIE_CLIENT</component>         <!-- TODO, parallelize -->
+      </service>
+    </group>
+
+    <group xsi:type="restart" name="FALCON" title="Falcon">
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <service name="FALCON">
+        <component>FALCON_SERVER</component>
+        <component>FALCON_CLIENT</component>        <!-- TODO, parallelize -->
+      </service>
+    </group>
+
+    <group xsi:type="restart" name="KAFKA" title="Kafka">
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <service name="KAFKA">
+        <component>KAFKA_BROKER</component>
+      </service>
+    </group>
+
+    <group xsi:type="restart" name="KNOX" title="Knox">
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <service name="KNOX">
+        <component>KNOX_GATEWAY</component>
+      </service>
+    </group>
+
+    <group xsi:type="restart" name="STORM" title="Storm">
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <service name="STORM">
+        <component>NIMBUS</component>
+        <component>STORM_REST_API</component>
+        <component>SUPERVISOR</component>
+        <component>STORM_UI_SERVER</component>
+        <component>DRPC_SERVER</component>
+      </service>
+
+      <!-- TODO, does this work? -->
+      <execute-stage service="STORM" component="DRPC_SERVER" title="Rebuild Storm Topology">
+        <task xsi:type="manual">
+          <message>Please rebuild your topology using the new Storm version dependencies and resubmit it using the newly created jar.</message>
+        </task>
+      </execute-stage>
+    </group>
+
+    <group xsi:type="restart" name="SLIDER" title="Slider">
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <service name="SLIDER">
+        <component>SLIDER</component>
+      </service>
+    </group>
+
+    <group xsi:type="restart" name="FLUME" title="Flume">
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <service name="FLUME">
+        <component>FLUME_HANDLER</component>
+      </service>
+    </group>
+
+    <group xsi:type="cluster" name="POST_CLUSTER" title="Finalize {{direction.text.proper}}">
+      <skippable>true</skippable>
+      <execute-stage title="Check Unhealthy Hosts" id="unhealthy-hosts">
+        <task xsi:type="manual">
+          <message>The following hosts were unhealthy and should be resolved before finalizing can be completed: {{hosts.unhealthy}}</message>
+        </task>
+      </execute-stage>
+      
+      <execute-stage title="Confirm Finalize">
+        <direction>UPGRADE</direction>
+        <task xsi:type="manual">
+          <message>Please confirm you are ready to finalize.</message>
+        </task>
+      </execute-stage>
+
+      <execute-stage service="HDFS" component="NAMENODE" title="Execute HDFS Finalize">
+        <task xsi:type="execute" hosts="master">      <!-- TODO, what happens if there's no HA. -->
+          <script>scripts/namenode.py</script>
+          <function>finalize_non_rolling_upgrade</function>
+        </task>
+      </execute-stage>
+
+      <execute-stage title="Save Cluster State" service="" component="">
+        <task xsi:type="server_action" class="org.apache.ambari.server.serveraction.upgrades.FinalizeUpgradeAction">
+        </task>
+      </execute-stage>
+    </group>
+  </order>
+</upgrade>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/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 3837e63..b351aae 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,8 +19,21 @@
 
 <upgrade xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <target>2.2.*.*</target>
+  <type>ROLLING</type>
   <skip-failures>false</skip-failures>
   <skip-service-check-failures>false</skip-service-check-failures>
+  <prerequisite-checks>
+    <check>org.apache.ambari.server.checks.HiveMultipleMetastoreCheck</check>
+    <check>org.apache.ambari.server.checks.MapReduce2JobHistoryStatePreservingCheck</check>
+    <check>org.apache.ambari.server.checks.SecondaryNamenodeDeletedCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesMapReduceDistributedCacheCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesNamenodeHighAvailabilityCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesNamenodeTruncateCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesTezDistributedCacheCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesYarnWorkPreservingCheck</check>
+    <check>org.apache.ambari.server.checks.YarnRMHighAvailabilityCheck</check>
+    <check>org.apache.ambari.server.checks.YarnTimelineServerStatePreservingCheck</check>
+  </prerequisite-checks>
 
   <order>
     <group xsi:type="cluster" name="PRE_CLUSTER" title="Prepare Upgrade">
@@ -35,7 +48,7 @@
       <execute-stage service="HBASE" component="HBASE_MASTER" title="Pre Upgrade HBase">
         <task xsi:type="execute" hosts="master">
           <script>scripts/hbase_upgrade.py</script>
-          <function>snapshot</function>
+          <function>take_snapshot</function>
         </task>
       </execute-stage>
 
@@ -314,13 +327,13 @@
     <service name="ZOOKEEPER">
       <component name="ZOOKEEPER_SERVER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="ZOOKEEPER_CLIENT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -328,13 +341,13 @@
     <service name="RANGER">
       <component name="RANGER_ADMIN">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="RANGER_USERSYNC">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -342,31 +355,31 @@
     <service name="HDFS">
       <component name="NAMENODE">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="DATANODE">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="HDFS_CLIENT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="JOURNALNODE">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="ZKFC">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -374,13 +387,13 @@
     <service name="MAPREDUCE2">
       <component name="HISTORYSERVER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="MAPREDUCE2_CLIENT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -388,44 +401,44 @@
     <service name="YARN">
       <component name="APP_TIMELINE_SERVER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="RESOURCEMANAGER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="NODEMANAGER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="YARN_CLIENT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
     <service name="HBASE">
       <component name="HBASE_MASTER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="HBASE_REGIONSERVER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="HBASE_CLIENT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -433,7 +446,7 @@
     <service name="TEZ">
       <component name="TEZ_CLIENT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -441,7 +454,7 @@
     <service name="PIG">
       <component name="PIG">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -449,7 +462,7 @@
     <service name="SQOOP">
       <component name="SQOOP">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -457,7 +470,7 @@
     <service name="HIVE">
       <component name="HIVE_METASTORE">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
@@ -468,18 +481,7 @@
             <message>Please note that the HiveServer port will now change to 10010 if hive is using a binary transfer mode or 10011 if hive is using an http transport mode. You can use "netstat -anp | grep 1001[01]" to determine if the port is available on each of following HiveServer host(s): {{hosts.all}}. If the port is not available, the process using it must be terminated.</message>
           </task>
 
-          <task xsi:type="configure">
-            <condition type="hive-site" key="hive.server2.transport.mode" value="binary">
-              <type>hive-site</type>
-              <key>hive.server2.thrift.port</key>
-              <value>10010</value>
-            </condition>
-            <condition type="hive-site" key="hive.server2.transport.mode" value="http">
-              <type>hive-site</type>
-              <key>hive.server2.http.port</key>
-              <value>10011</value>
-            </condition>
-          </task>
+          <task xsi:type="configure" id="hdp_2_2_0_0_hive_server_set_transport_modes" />
         </pre-upgrade>
 
         <pre-downgrade>
@@ -488,40 +490,29 @@
             <message>Please note that the HiveServer port will now change to 10000 if hive is using a binary transfer mode or 10001 if hive is using an http transport mode. You can use "netstat -anp | grep 1000[01]" to determine if the port is available on each of following HiveServer host(s): {{hosts.all}}. If the port is not available, the process using it must be terminated.</message>
           </task>
 
-          <task xsi:type="configure">
-            <condition type="hive-site" key="hive.server2.transport.mode" value="binary">
-              <type>hive-site</type>
-              <key>hive.server2.thrift.port</key>
-              <value>10000</value>
-            </condition>
-            <condition type="hive-site" key="hive.server2.transport.mode" value="http">
-              <type>hive-site</type>
-              <key>hive.server2.http.port</key>
-              <value>10001</value>
-            </condition>
-          </task>
+          <task xsi:type="configure" id="hdp_2_2_0_0_hive_server_restore_transport_mode_on_downgrade" />
         </pre-downgrade>
 
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="WEBHCAT_SERVER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="HIVE_CLIENT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="HCAT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -529,7 +520,7 @@
     <service name="SLIDER">
       <component name="SLIDER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -537,12 +528,12 @@
     <service name="SPARK">
       <component name="SPARK_JOBHISTORYSERVER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
       <component name="SPARK_CLIENT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -574,13 +565,13 @@
         </pre-downgrade>
 
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="OOZIE_CLIENT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -588,12 +579,12 @@
     <service name="FALCON">
       <component name="FALCON_SERVER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
       <component name="FALCON_CLIENT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -601,7 +592,7 @@
     <service name="KAFKA">
       <component name="KAFKA_BROKER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -609,7 +600,7 @@
     <service name="KNOX">
       <component name="KNOX_GATEWAY">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -622,27 +613,27 @@
           </task>
         </pre-upgrade>
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
       <component name="STORM_REST_API">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
       <component name="SUPERVISOR">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
       <component name="STORM_UI_SERVER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
       <component name="DRPC_SERVER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
         <post-upgrade>
           <task xsi:type="manual">
@@ -655,7 +646,7 @@
     <service name="FLUME">
       <component name="FLUME_HANDLER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>


[3/9] ambari git commit: AMBARI-13392. Stop-and-Start Upgrade: Merge branch branch-dev-stop-all-upgrade to branch-2.1 for feature Stop-the-World Upgrade, aka Express Upgrade (alejandro, dlysnichenko, Dmytro Grinenko)

Posted by al...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/test/java/org/apache/ambari/server/checks/ServicesNamenodeHighAvailabilityCheckTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/checks/ServicesNamenodeHighAvailabilityCheckTest.java b/ambari-server/src/test/java/org/apache/ambari/server/checks/ServicesNamenodeHighAvailabilityCheckTest.java
index 947121a..5713f59 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/checks/ServicesNamenodeHighAvailabilityCheckTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/checks/ServicesNamenodeHighAvailabilityCheckTest.java
@@ -65,14 +65,18 @@ public class ServicesNamenodeHighAvailabilityCheckTest {
   @Test
   public void testIsApplicable() throws Exception {
     final Cluster cluster = Mockito.mock(Cluster.class);
+    final Map<String, Service> services = new HashMap<>();
+    final Service service = Mockito.mock(Service.class);
+
+    services.put("HDFS", service);
+
+    Mockito.when(cluster.getServices()).thenReturn(services);
     Mockito.when(cluster.getClusterId()).thenReturn(1L);
     Mockito.when(clusters.getCluster("cluster")).thenReturn(cluster);
 
-    final Service service = Mockito.mock(Service.class);
-    Mockito.when(cluster.getService("HDFS")).thenReturn(service);
     Assert.assertTrue(servicesNamenodeHighAvailabilityCheck.isApplicable(new PrereqCheckRequest("cluster")));
 
-    Mockito.when(cluster.getService("HDFS")).thenThrow(new ServiceNotFoundException("no", "service"));
+    services.remove("HDFS");
     Assert.assertFalse(servicesNamenodeHighAvailabilityCheck.isApplicable(new PrereqCheckRequest("cluster")));
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/test/java/org/apache/ambari/server/checks/ServicesNamenodeTruncateCheckTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/checks/ServicesNamenodeTruncateCheckTest.java b/ambari-server/src/test/java/org/apache/ambari/server/checks/ServicesNamenodeTruncateCheckTest.java
index 07d17d8..ef39e9e 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/checks/ServicesNamenodeTruncateCheckTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/checks/ServicesNamenodeTruncateCheckTest.java
@@ -40,6 +40,7 @@ import org.junit.Before;
 import org.junit.Test;
 
 import com.google.inject.Provider;
+import org.mockito.Mockito;
 
 /**
  * Unit tests for ServicesUpCheck
@@ -56,9 +57,14 @@ public class ServicesNamenodeTruncateCheckTest {
     Cluster cluster = EasyMock.createMock(Cluster.class);
 
     Config config = EasyMock.createMock(Config.class);
+    final Map<String, Service> services = new HashMap<>();
+    final Service service = Mockito.mock(Service.class);
 
+    services.put("HDFS", service);
+
+    expect(cluster.getServices()).andReturn(services).anyTimes();
     expect(config.getProperties()).andReturn(m_configMap).anyTimes();
-    expect(cluster.getService("HDFS")).andReturn(EasyMock.createMock(Service.class));
+    expect(cluster.getService("HDFS")).andReturn(service);
     expect(cluster.getDesiredConfigByType("hdfs-site")).andReturn(config).anyTimes();
     expect(m_clusters.getCluster((String) anyObject())).andReturn(cluster).anyTimes();
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/test/java/org/apache/ambari/server/checks/ServicesTezDistributedCacheCheckTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/checks/ServicesTezDistributedCacheCheckTest.java b/ambari-server/src/test/java/org/apache/ambari/server/checks/ServicesTezDistributedCacheCheckTest.java
index d732302..d70d575 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/checks/ServicesTezDistributedCacheCheckTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/checks/ServicesTezDistributedCacheCheckTest.java
@@ -65,27 +65,28 @@ public class ServicesTezDistributedCacheCheckTest {
   @Test
   public void testIsApplicable() throws Exception {
     final Cluster cluster = Mockito.mock(Cluster.class);
+    final Map<String, Service> services = new HashMap<>();
+    final Service service = Mockito.mock(Service.class);
+
+    services.put("TEZ", service);
+
+    Mockito.when(cluster.getServices()).thenReturn(services);
     Mockito.when(cluster.getClusterId()).thenReturn(1L);
     Mockito.when(clusters.getCluster("cluster")).thenReturn(cluster);
 
-    final Service service = Mockito.mock(Service.class);
-    Mockito.when(cluster.getService("TEZ")).thenReturn(service);
+
     Assert.assertTrue(servicesTezDistributedCacheCheck.isApplicable(new PrereqCheckRequest("cluster")));
 
     PrereqCheckRequest req = new PrereqCheckRequest("cluster");
     req.addResult(CheckDescription.SERVICES_NAMENODE_HA, PrereqCheckStatus.FAIL);
-    Mockito.when(cluster.getService("TEZ")).thenReturn(service);
     Assert.assertFalse(servicesTezDistributedCacheCheck.isApplicable(req));
 
     req.addResult(CheckDescription.SERVICES_NAMENODE_HA, PrereqCheckStatus.PASS);
-    Mockito.when(cluster.getService("TEZ")).thenReturn(service);
     Assert.assertTrue(servicesTezDistributedCacheCheck.isApplicable(req));
 
 
-    Mockito.when(cluster.getService("TEZ")).thenThrow(new ServiceNotFoundException("no", "service"));
+    services.remove("TEZ");
     Assert.assertFalse(servicesTezDistributedCacheCheck.isApplicable(new PrereqCheckRequest("cluster")));
-
-
   }
 
   @Test

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/test/java/org/apache/ambari/server/checks/ServicesYarnWorkPreservingCheckTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/checks/ServicesYarnWorkPreservingCheckTest.java b/ambari-server/src/test/java/org/apache/ambari/server/checks/ServicesYarnWorkPreservingCheckTest.java
index 135c9c9..5658f17 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/checks/ServicesYarnWorkPreservingCheckTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/checks/ServicesYarnWorkPreservingCheckTest.java
@@ -65,14 +65,18 @@ public class ServicesYarnWorkPreservingCheckTest {
   @Test
   public void testIsApplicable() throws Exception {
     final Cluster cluster = Mockito.mock(Cluster.class);
+    final Map<String, Service> services = new HashMap<>();
+    final Service service = Mockito.mock(Service.class);
+
+    services.put("YARN", service);
+
+    Mockito.when(cluster.getServices()).thenReturn(services);
     Mockito.when(cluster.getClusterId()).thenReturn(1L);
     Mockito.when(clusters.getCluster("cluster")).thenReturn(cluster);
 
-    final Service service = Mockito.mock(Service.class);
-    Mockito.when(cluster.getService("YARN")).thenReturn(service);
     Assert.assertTrue(servicesYarnWorkPreservingCheck.isApplicable(new PrereqCheckRequest("cluster")));
 
-    Mockito.when(cluster.getService("YARN")).thenThrow(new ServiceNotFoundException("no", "service"));
+   services.remove("YARN");
     Assert.assertFalse(servicesYarnWorkPreservingCheck.isApplicable(new PrereqCheckRequest("cluster")));
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/test/java/org/apache/ambari/server/checks/UpgradeCheckStackVersionTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/checks/UpgradeCheckStackVersionTest.java b/ambari-server/src/test/java/org/apache/ambari/server/checks/UpgradeCheckStackVersionTest.java
deleted file mode 100644
index 8d8b08f..0000000
--- a/ambari-server/src/test/java/org/apache/ambari/server/checks/UpgradeCheckStackVersionTest.java
+++ /dev/null
@@ -1,170 +0,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.
- */
-package org.apache.ambari.server.checks;
-
-import junit.framework.Assert;
-
-import org.apache.ambari.server.controller.PrereqCheckRequest;
-import org.apache.ambari.server.state.StackId;
-import org.easymock.EasyMock;
-import org.junit.Test;
-
-
-/**
- * Tests that the {@link AbstractCheckDescriptor} instances will return the
- * correct values for
- * {@link AbstractCheckDescriptor#isApplicable(org.apache.ambari.server.controller.PrereqCheckRequest)}
- * when different stack versions are present.
- */
-public class UpgradeCheckStackVersionTest {
-
-  @Test
-  public void testUpgradeCheckForMoreRecentStack() throws Exception {
-    AbstractCheckDescriptor invalidCheck = EasyMock.createMockBuilder(AbstractCheckDescriptor.class).addMockedMethods(
-        "getSourceStack", "getTargetStack").createMock();
-
-    EasyMock.expect(invalidCheck.getSourceStack()).andReturn(new StackId("HDP-2.3"));
-    EasyMock.expect(invalidCheck.getTargetStack()).andReturn(new StackId("HDP-2.3"));
-
-    EasyMock.replay(invalidCheck);
-
-    PrereqCheckRequest checkRequest = new PrereqCheckRequest("c1");
-    checkRequest.setRepositoryVersion("HDP-2.2.0.0");
-    checkRequest.setSourceStackId(new StackId("HDP", "2.2"));
-    checkRequest.setTargetStackId(new StackId("HDP", "2.2"));
-
-    // false because the upgrade is for 2.2->2.2 and the check starts at 2.3
-    Assert.assertFalse(invalidCheck.isApplicable(checkRequest));
-
-    EasyMock.verify(invalidCheck);
-  }
-
-  @Test
-  public void testUpgradeCheckForOlderStack() throws Exception {
-    AbstractCheckDescriptor invalidCheck = EasyMock.createMockBuilder(AbstractCheckDescriptor.class).addMockedMethods(
-        "getSourceStack", "getTargetStack").createMock();
-
-    EasyMock.expect(invalidCheck.getSourceStack()).andReturn(new StackId("HDP-2.2"));
-    EasyMock.expect(invalidCheck.getTargetStack()).andReturn(new StackId("HDP-2.2"));
-
-    EasyMock.replay(invalidCheck);
-
-    PrereqCheckRequest checkRequest = new PrereqCheckRequest("c1");
-    checkRequest.setRepositoryVersion("HDP-2.3.0.0");
-    checkRequest.setSourceStackId(new StackId("HDP", "2.3"));
-    checkRequest.setTargetStackId(new StackId("HDP", "2.3"));
-
-    // false because the upgrade is for 2.3->2.3 and the check is only for 2.2
-    Assert.assertFalse(invalidCheck.isApplicable(checkRequest));
-
-    EasyMock.verify(invalidCheck);
-  }
-
-  @Test
-  public void testUpgradeCheckForWithinStackOnly() throws Exception {
-    AbstractCheckDescriptor invalidCheck = EasyMock.createMockBuilder(AbstractCheckDescriptor.class).addMockedMethods(
-        "getSourceStack", "getTargetStack").createMock();
-
-    EasyMock.expect(invalidCheck.getSourceStack()).andReturn(new StackId("HDP-2.2"));
-    EasyMock.expect(invalidCheck.getTargetStack()).andReturn(new StackId("HDP-2.2"));
-
-    EasyMock.replay(invalidCheck);
-
-    PrereqCheckRequest checkRequest = new PrereqCheckRequest("c1");
-    checkRequest.setRepositoryVersion("HDP-2.3.0.0");
-    checkRequest.setSourceStackId(new StackId("HDP", "2.2"));
-    checkRequest.setTargetStackId(new StackId("HDP", "2.3"));
-
-    // false because the upgrade is for 2.2->2.3 and the check is only for 2.2
-    // to 2.2
-    Assert.assertFalse(invalidCheck.isApplicable(checkRequest));
-
-    EasyMock.verify(invalidCheck);
-  }
-
-  @Test
-  public void testUpgradeCheckMatchesExactly() throws Exception {
-    AbstractCheckDescriptor invalidCheck = EasyMock.createMockBuilder(AbstractCheckDescriptor.class).addMockedMethods(
-        "getSourceStack", "getTargetStack").createMock();
-
-    EasyMock.expect(invalidCheck.getSourceStack()).andReturn(new StackId("HDP-2.2"));
-    EasyMock.expect(invalidCheck.getTargetStack()).andReturn(new StackId("HDP-2.2"));
-
-    EasyMock.replay(invalidCheck);
-
-    PrereqCheckRequest checkRequest = new PrereqCheckRequest("c1");
-    checkRequest.setRepositoryVersion("HDP-2.2.0.0");
-    checkRequest.setSourceStackId(new StackId("HDP", "2.2"));
-    checkRequest.setTargetStackId(new StackId("HDP", "2.2"));
-
-    // pass because the upgrade is for 2.2->2.2 and the check is only for 2.2
-    // to 2.2
-    Assert.assertTrue(invalidCheck.isApplicable(checkRequest));
-
-    EasyMock.verify(invalidCheck);
-  }
-
-  @Test
-  public void testNoUpgradeStacksDefined() throws Exception {
-    AbstractCheckDescriptor invalidCheck = EasyMock.createMockBuilder(AbstractCheckDescriptor.class).addMockedMethods(
-        "getSourceStack", "getTargetStack").createMock();
-
-    EasyMock.expect(invalidCheck.getSourceStack()).andReturn(null);
-    EasyMock.expect(invalidCheck.getTargetStack()).andReturn(null);
-
-    EasyMock.replay(invalidCheck);
-
-    PrereqCheckRequest checkRequest = new PrereqCheckRequest("c1");
-    checkRequest.setRepositoryVersion("HDP-2.3.0.0");
-    checkRequest.setSourceStackId(new StackId("HDP", "2.2"));
-    checkRequest.setTargetStackId(new StackId("HDP", "2.3"));
-
-    // pass because there are no restrictions
-    Assert.assertTrue(invalidCheck.isApplicable(checkRequest));
-
-    EasyMock.verify(invalidCheck);
-  }
-
-  @Test
-  public void testUpgradeStartsAtSpecifiedStackVersion() throws Exception {
-    AbstractCheckDescriptor invalidCheck = EasyMock.createMockBuilder(AbstractCheckDescriptor.class).addMockedMethods(
-        "getSourceStack", "getTargetStack").createMock();
-
-    EasyMock.expect(invalidCheck.getSourceStack()).andReturn(new StackId("HDP-2.3")).atLeastOnce();
-    EasyMock.expect(invalidCheck.getTargetStack()).andReturn(null).atLeastOnce();
-
-    EasyMock.replay(invalidCheck);
-
-    PrereqCheckRequest checkRequest = new PrereqCheckRequest("c1");
-    checkRequest.setRepositoryVersion("HDP-2.2.0.0");
-    checkRequest.setSourceStackId(new StackId("HDP", "2.2"));
-    checkRequest.setTargetStackId(new StackId("HDP", "2.2"));
-
-    // false because this check starts at 2.3 and the upgrade is 2.2 -> 2.2
-    Assert.assertFalse(invalidCheck.isApplicable(checkRequest));
-
-    checkRequest.setRepositoryVersion("HDP-2.3.0.0");
-    checkRequest.setSourceStackId(new StackId("HDP", "2.2"));
-    checkRequest.setTargetStackId(new StackId("HDP", "2.3"));
-
-    // false because this check starts at 2.3 and the upgrade is 2.2 -> 2.3
-    Assert.assertFalse(invalidCheck.isApplicable(checkRequest));
-
-    EasyMock.verify(invalidCheck);
-  }
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/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 d1e58a1..eed4379 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
@@ -7189,7 +7189,7 @@ public class AmbariManagementControllerTest {
     Assert.assertEquals(1, responsesWithParams.size());
     StackVersionResponse resp = responsesWithParams.iterator().next();
     assertNotNull(resp.getUpgradePacks());
-    assertEquals(5, resp.getUpgradePacks().size());
+    assertEquals(6, resp.getUpgradePacks().size());
     assertTrue(resp.getUpgradePacks().contains("upgrade_test"));
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/CompatibleRepositoryVersionResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/CompatibleRepositoryVersionResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/CompatibleRepositoryVersionResourceProviderTest.java
index ea6e56e..ab06a5c 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/CompatibleRepositoryVersionResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/CompatibleRepositoryVersionResourceProviderTest.java
@@ -102,6 +102,12 @@ public class CompatibleRepositoryVersionResourceProviderTest {
         Map<String, UpgradePack> map = new HashMap<String, UpgradePack>();
 
         UpgradePack pack1 = new UpgradePack() {
+
+          @Override
+          public String getName() {
+            return "pack1";
+          }
+
           @Override
           public String getTarget() {
             return "1.1.*.*";
@@ -110,6 +116,11 @@ public class CompatibleRepositoryVersionResourceProviderTest {
 
         final UpgradePack pack2 = new UpgradePack() {
           @Override
+          public String getName() {
+            return "pack2";
+          }
+
+          @Override
           public String getTarget() {
             return "2.2.*.*";
           }
@@ -133,6 +144,11 @@ public class CompatibleRepositoryVersionResourceProviderTest {
 
         UpgradePack pack = new UpgradePack() {
           @Override
+          public String getName() {
+            return "pack2";
+          }
+
+          @Override
           public String getTarget() {
             return "2.2.*.*";
           }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProviderTest.java
index 442bcb2..493cfbb 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProviderTest.java
@@ -42,11 +42,14 @@ import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
 import org.apache.ambari.server.orm.dao.ClusterVersionDAO;
 import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
 import org.apache.ambari.server.orm.dao.StackDAO;
+import org.apache.ambari.server.orm.entities.ClusterEntity;
 import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
 import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 import org.apache.ambari.server.orm.entities.StackEntity;
+import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.OperatingSystemInfo;
 import org.apache.ambari.server.state.RepositoryVersionState;
+import org.apache.ambari.server.state.StackId;
 import org.apache.ambari.server.state.StackInfo;
 import org.apache.ambari.server.state.stack.UpgradePack;
 import org.junit.After;
@@ -67,16 +70,43 @@ import com.google.inject.persist.PersistService;
  */
 public class RepositoryVersionResourceProviderTest {
 
+  private ClusterVersionDAO clusterVersionDAO;
+
   private static Injector injector;
 
   private static String jsonStringRedhat6 = "[{\"OperatingSystems\":{\"os_type\":\"redhat6\"},\"repositories\":[]}]";
   private static String jsonStringRedhat7 = "[{\"OperatingSystems\":{\"os_type\":\"redhat7\"},\"repositories\":[]}]";
 
+  private List<ClusterVersionEntity> getNoClusterVersions() {
+    final List<ClusterVersionEntity> emptyList = new ArrayList<ClusterVersionEntity>();
+    return emptyList;
+  }
+
+  private List<ClusterVersionEntity> getInstallFailedClusterVersions() {
+    ClusterEntity cluster = new ClusterEntity();
+    cluster.setClusterName("c1");
+    cluster.setClusterId(1L);
+
+    final List<ClusterVersionEntity> clusterVersions = new ArrayList<ClusterVersionEntity>();
+    final RepositoryVersionEntity repositoryVersion = new RepositoryVersionEntity();
+    repositoryVersion.setId(1L);
+    final ClusterVersionEntity installFailedVersion = new ClusterVersionEntity();
+    installFailedVersion.setState(RepositoryVersionState.INSTALL_FAILED);
+    installFailedVersion.setRepositoryVersion(repositoryVersion);
+    installFailedVersion.setClusterEntity(cluster);
+    clusterVersions.add(installFailedVersion);
+    cluster.setClusterVersionEntities(clusterVersions);
+    return clusterVersions;
+  }
+
   @Before
   public void before() throws Exception {
     final Set<String> validVersions = Sets.newHashSet("1.1", "1.1-17", "1.1.1.1", "1.1.343432.2", "1.1.343432.2-234234324");
+    final Set<StackInfo> stacks = new HashSet<StackInfo>();
+
     final AmbariMetaInfo ambariMetaInfo = Mockito.mock(AmbariMetaInfo.class);
-    final ClusterVersionDAO clusterVersionDAO = Mockito.mock(ClusterVersionDAO.class);
+    clusterVersionDAO = Mockito.mock(ClusterVersionDAO.class);
+
     final InMemoryDefaultTestModule injectorModule = new InMemoryDefaultTestModule() {
       @Override
       protected void configure() {
@@ -93,12 +123,22 @@ public class RepositoryVersionResourceProviderTest {
         final Map<String, UpgradePack> map = new HashMap<String, UpgradePack>();
         final UpgradePack pack1 = new UpgradePack() {
           @Override
+          public String getName() {
+            return "pack1";
+          }
+
+          @Override
           public String getTarget() {
             return "1.1.*.*";
           }
         };
         final UpgradePack pack2 = new UpgradePack() {
           @Override
+          public String getName() {
+            return "pack2";
+          }
+
+          @Override
           public String getTarget() {
             return "1.1.*.*";
           }
@@ -108,6 +148,9 @@ public class RepositoryVersionResourceProviderTest {
         return map;
       }
     };
+    stackInfo.setName("HDP");
+    stackInfo.setVersion("1.1");
+    stacks.add(stackInfo);
     Mockito.when(ambariMetaInfo.getStack(Mockito.anyString(), Mockito.anyString())).thenAnswer(new Answer<StackInfo>() {
 
       @Override
@@ -122,7 +165,7 @@ public class RepositoryVersionResourceProviderTest {
       }
 
     });
-
+    Mockito.when(ambariMetaInfo.getStacks()).thenReturn(stacks);
     Mockito.when(ambariMetaInfo.getUpgradePacks(Mockito.anyString(), Mockito.anyString())).thenAnswer(new Answer<Map<String, UpgradePack>>() {
 
       @Override
@@ -151,29 +194,17 @@ public class RepositoryVersionResourceProviderTest {
       }
     });
 
-    Mockito.when(
-        clusterVersionDAO.findByStackAndVersion(Mockito.anyString(),
-            Mockito.anyString(), Mockito.anyString())).thenAnswer(
+    Mockito.when(clusterVersionDAO.findByStackAndVersion(Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenAnswer(
         new Answer<List<ClusterVersionEntity>>() {
-
       @Override
-      public List<ClusterVersionEntity> answer(InvocationOnMock invocation)
-          throws Throwable {
+      public List<ClusterVersionEntity> answer(InvocationOnMock invocation) throws Throwable {
         final String stack = invocation.getArguments()[0].toString();
         final String version = invocation.getArguments()[1].toString();
+
         if (stack.equals("HDP-1.1") && version.equals("1.1.1.1")) {
-          final List<ClusterVersionEntity> notEmptyList = new ArrayList<ClusterVersionEntity>();
-          notEmptyList.add(null);
-          return notEmptyList;
+          return getNoClusterVersions();
         } else {
-          final List<ClusterVersionEntity> clusterVersions = new ArrayList<ClusterVersionEntity>();
-          final RepositoryVersionEntity repositoryVersion = new RepositoryVersionEntity();
-          repositoryVersion.setId(1L);
-          final ClusterVersionEntity installFailedVersion = new ClusterVersionEntity();
-          installFailedVersion.setState(RepositoryVersionState.INSTALL_FAILED);
-          installFailedVersion.setRepositoryVersion(repositoryVersion);
-          clusterVersions.add(installFailedVersion);
-          return clusterVersions;
+          return getInstallFailedClusterVersions();
         }
       }
     });
@@ -187,6 +218,9 @@ public class RepositoryVersionResourceProviderTest {
     stackEntity.setStackName("HDP");
     stackEntity.setStackVersion("1.1");
     stackDAO.create(stackEntity);
+
+    Clusters clusters = injector.getInstance(Clusters.class);
+    clusters.addCluster("c1", new StackId("HDP", "1.1"));
   }
 
   @Test
@@ -198,7 +232,6 @@ public class RepositoryVersionResourceProviderTest {
     properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID, "name");
     properties.put(RepositoryVersionResourceProvider.SUBRESOURCE_OPERATING_SYSTEMS_PROPERTY_ID, new Gson().fromJson("[{\"OperatingSystems/os_type\":\"redhat6\",\"repositories\":[{\"Repositories/repo_id\":\"1\",\"Repositories/repo_name\":\"1\",\"Repositories/base_url\":\"1\"}]}]", Object.class));
     properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_STACK_NAME_PROPERTY_ID, "HDP");
-    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID, "pack1");
     properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_STACK_VERSION_PROPERTY_ID, "1.1");
     properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_REPOSITORY_VERSION_PROPERTY_ID, "1.1.1.1");
     propertySet.add(properties);
@@ -251,7 +284,6 @@ public class RepositoryVersionResourceProviderTest {
     final RepositoryVersionEntity entity = new RepositoryVersionEntity();
     entity.setDisplayName("name");
     entity.setStack(stackEntity);
-    entity.setUpgradePackage("pack1");
     entity.setVersion("1.1");
     entity.setOperatingSystems("[{\"OperatingSystems/os_type\":\"redhat6\",\"repositories\":[{\"Repositories/repo_id\":\"1\",\"Repositories/repo_name\":\"1\",\"Repositories/base_url\":\"http://example.com/repo1\"}]}]");
 
@@ -281,13 +313,6 @@ public class RepositoryVersionResourceProviderTest {
     } catch (Exception ex) {
     }
 
-    entity.setUpgradePackage("pack2");
-    try {
-      provider.validateRepositoryVersion(entity);
-      Assert.fail("Should throw exception");
-    } catch (Exception ex) {
-    }
-
     StackEntity bigtop = new StackEntity();
     stackEntity.setStackName("BIGTOP");
     entity.setStack(bigtop);
@@ -300,7 +325,6 @@ public class RepositoryVersionResourceProviderTest {
     final RepositoryVersionDAO repositoryVersionDAO = injector.getInstance(RepositoryVersionDAO.class);
     entity.setDisplayName("name");
     entity.setStack(stackEntity);
-    entity.setUpgradePackage("pack1");
     entity.setVersion("1.1");
     entity.setOperatingSystems("[{\"OperatingSystems/os_type\":\"redhat6\",\"repositories\":[{\"Repositories/repo_id\":\"1\",\"Repositories/repo_name\":\"1\",\"Repositories/base_url\":\"http://example.com/repo1\"}]}]");
     repositoryVersionDAO.create(entity);
@@ -309,7 +333,6 @@ public class RepositoryVersionResourceProviderTest {
     entity2.setId(2l);
     entity2.setDisplayName("name2");
     entity2.setStack(stackEntity);
-    entity2.setUpgradePackage("pack1");
     entity2.setVersion("1.2");
     entity2.setOperatingSystems("[{\"OperatingSystems/os_type\":\"redhat6\",\"repositories\":[{\"Repositories/repo_id\":\"1\",\"Repositories/repo_name\":\"1\",\"Repositories/base_url\":\"http://example.com/repo1\"}]}]");
 
@@ -330,7 +353,6 @@ public class RepositoryVersionResourceProviderTest {
     properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID, "name");
     properties.put(RepositoryVersionResourceProvider.SUBRESOURCE_OPERATING_SYSTEMS_PROPERTY_ID, new Gson().fromJson("[{\"OperatingSystems/os_type\":\"redhat6\",\"repositories\":[{\"Repositories/repo_id\":\"1\",\"Repositories/repo_name\":\"1\",\"Repositories/base_url\":\"1\"}]}]", Object.class));
     properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_STACK_NAME_PROPERTY_ID, "HDP");
-    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID, "pack1");
     properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_STACK_VERSION_PROPERTY_ID, "1.1");
     properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_REPOSITORY_VERSION_PROPERTY_ID, "1.1.1.2");
     propertySet.add(properties);
@@ -355,12 +377,19 @@ public class RepositoryVersionResourceProviderTest {
   public void testUpdateResources() throws Exception {
     final ResourceProvider provider = injector.getInstance(ResourceProviderFactory.class).getRepositoryVersionResourceProvider();
 
+    Mockito.when(clusterVersionDAO.findByStackAndVersion(Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenAnswer(
+        new Answer<List<ClusterVersionEntity>>() {
+          @Override
+          public List<ClusterVersionEntity> answer(InvocationOnMock invocation) throws Throwable {
+            return getNoClusterVersions();
+          }
+        });
+
     final Set<Map<String, Object>> propertySet = new LinkedHashSet<Map<String, Object>>();
     final Map<String, Object> properties = new LinkedHashMap<String, Object>();
     properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID, "name");
     properties.put(RepositoryVersionResourceProvider.SUBRESOURCE_OPERATING_SYSTEMS_PROPERTY_ID, new Gson().fromJson("[{\"OperatingSystems/os_type\":\"redhat6\",\"repositories\":[{\"Repositories/repo_id\":\"1\",\"Repositories/repo_name\":\"1\",\"Repositories/base_url\":\"http://example.com/repo1\"}]}]", Object.class));
     properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_STACK_NAME_PROPERTY_ID, "HDP");
-    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID, "pack1");
     properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_STACK_VERSION_PROPERTY_ID, "1.1");
     properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_REPOSITORY_VERSION_PROPERTY_ID, "1.1.1.1");
     propertySet.add(properties);
@@ -368,9 +397,8 @@ public class RepositoryVersionResourceProviderTest {
     final Predicate predicateStackName = new PredicateBuilder().property(RepositoryVersionResourceProvider.REPOSITORY_VERSION_STACK_NAME_PROPERTY_ID).equals("HDP").toPredicate();
     final Predicate predicateStackVersion = new PredicateBuilder().property(RepositoryVersionResourceProvider.REPOSITORY_VERSION_STACK_VERSION_PROPERTY_ID).equals("1.1").toPredicate();
     final Request getRequest = PropertyHelper.getReadRequest(
-        RepositoryVersionResourceProvider.REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID,
-        RepositoryVersionResourceProvider.SUBRESOURCE_OPERATING_SYSTEMS_PROPERTY_ID,
-        RepositoryVersionResourceProvider.REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID);
+      RepositoryVersionResourceProvider.REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID,
+      RepositoryVersionResourceProvider.SUBRESOURCE_OPERATING_SYSTEMS_PROPERTY_ID);
     Assert.assertEquals(0, provider.getResources(getRequest, new AndPredicate(predicateStackName, predicateStackVersion)).size());
 
     final Request createRequest = PropertyHelper.getCreateRequest(propertySet, null);
@@ -379,8 +407,6 @@ public class RepositoryVersionResourceProviderTest {
     Assert.assertEquals(1, provider.getResources(getRequest, new AndPredicate(predicateStackName, predicateStackVersion)).size());
     Assert.assertEquals("name", provider.getResources(getRequest, new AndPredicate(predicateStackName, predicateStackVersion)).iterator().next().getPropertyValue(RepositoryVersionResourceProvider.REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID));
 
-    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID, null);
-
     properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_ID_PROPERTY_ID, "1");
     properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID, "name2");
     final Request updateRequest = PropertyHelper.getUpdateRequest(properties, null);
@@ -391,7 +417,15 @@ public class RepositoryVersionResourceProviderTest {
     properties.put(RepositoryVersionResourceProvider.SUBRESOURCE_OPERATING_SYSTEMS_PROPERTY_ID, new Gson().fromJson("[{\"OperatingSystems/os_type\":\"redhat6\",\"repositories\":[{\"Repositories/repo_id\":\"2\",\"Repositories/repo_name\":\"2\",\"Repositories/base_url\":\"2\"}]}]", Object.class));
     provider.updateResources(updateRequest, new AndPredicate(predicateStackName, predicateStackVersion));
 
-    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID, "pack2");
+    // Now, insert a cluster version whose state is INSTALL_FAILED, so the operation will not be permitted.
+    Mockito.when(clusterVersionDAO.findByStackAndVersion(Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenAnswer(
+      new Answer<List<ClusterVersionEntity>>() {
+        @Override
+        public List<ClusterVersionEntity> answer(InvocationOnMock invocation) throws Throwable {
+          return getInstallFailedClusterVersions();
+        }
+      });
+
     try {
       provider.updateResources(updateRequest, new AndPredicate(predicateStackName, predicateStackVersion));
       Assert.fail("Update of upgrade pack should not be allowed when repo version is installed on any cluster");

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderHDP22Test.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderHDP22Test.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderHDP22Test.java
index f786445..8997f58 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderHDP22Test.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderHDP22Test.java
@@ -178,7 +178,6 @@ public class UpgradeResourceProviderHDP22Test {
     repoVersionEntity.setDisplayName("For Stack Version 2.2.0");
     repoVersionEntity.setOperatingSystems("");
     repoVersionEntity.setStack(stackEntity);
-    repoVersionEntity.setUpgradePackage("upgrade_test");
     repoVersionEntity.setVersion("2.2.0.0");
     repoVersionDao.create(repoVersionEntity);
 
@@ -186,7 +185,6 @@ public class UpgradeResourceProviderHDP22Test {
     repoVersionEntity.setDisplayName("For Stack Version 2.2.4.2");
     repoVersionEntity.setOperatingSystems("");
     repoVersionEntity.setStack(stackEntity);
-    repoVersionEntity.setUpgradePackage("upgrade_test");
     repoVersionEntity.setVersion("2.2.4.2");
     repoVersionDao.create(repoVersionEntity);
 
@@ -270,6 +268,7 @@ public class UpgradeResourceProviderHDP22Test {
     Map<String, Object> requestProps = new HashMap<String, Object>();
     requestProps.put(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME, "c1");
     requestProps.put(UpgradeResourceProvider.UPGRADE_VERSION, "2.2.4.2");
+    requestProps.put(UpgradeResourceProvider.UPGRADE_PACK, "upgrade_test");
     requestProps.put(UpgradeResourceProvider.UPGRADE_SKIP_PREREQUISITE_CHECKS, "true");
 
     ResourceProvider upgradeResourceProvider = createProvider(amc);
@@ -281,6 +280,7 @@ public class UpgradeResourceProviderHDP22Test {
     assertEquals(1, upgrades.size());
 
     UpgradeEntity upgrade = upgrades.get(0);
+    assertEquals("upgrade_test", upgrade.getUpgradePackage());
     assertEquals(3, upgrade.getUpgradeGroups().size());
 
     UpgradeGroupEntity group = upgrade.getUpgradeGroups().get(2);

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/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 9873104..066c0e6 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
@@ -23,6 +23,7 @@ import static org.easymock.EasyMock.replay;
 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.assertTrue;
 
 import java.lang.reflect.Field;
@@ -33,6 +34,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+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;
@@ -80,6 +82,7 @@ import org.apache.ambari.server.state.ServiceComponentHost;
 import org.apache.ambari.server.state.StackId;
 import org.apache.ambari.server.state.stack.UpgradePack;
 import org.apache.ambari.server.state.stack.upgrade.Direction;
+import org.apache.ambari.server.state.stack.upgrade.UpgradeType;
 import org.apache.ambari.server.topology.TopologyManager;
 import org.apache.ambari.server.utils.StageUtils;
 import org.apache.ambari.server.view.ViewRegistry;
@@ -88,6 +91,7 @@ import org.easymock.EasyMock;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 
 import com.google.gson.Gson;
@@ -163,41 +167,42 @@ public class UpgradeResourceProviderTest {
     replay(publisher);
     ViewRegistry.initInstance(new ViewRegistry(publisher));
 
-    StackEntity stackEntity = stackDAO.find("HDP", "2.1.1");
+    StackEntity stackEntity211 = stackDAO.find("HDP", "2.1.1");
+    StackEntity stackEntity220 = stackDAO.find("HDP", "2.2.0");
+    StackId stack211 = new StackId("HDP-2.1.1");
+    StackId stack220 = new StackId("HDP-2.2.0");
 
     RepositoryVersionEntity repoVersionEntity = new RepositoryVersionEntity();
     repoVersionEntity.setDisplayName("My New Version 1");
     repoVersionEntity.setOperatingSystems("");
-    repoVersionEntity.setStack(stackEntity);
-    repoVersionEntity.setUpgradePackage("upgrade_test");
+    repoVersionEntity.setStack(stackEntity211);
     repoVersionEntity.setVersion("2.1.1.0");
     repoVersionDao.create(repoVersionEntity);
 
     repoVersionEntity = new RepositoryVersionEntity();
-    repoVersionEntity.setDisplayName("My New Version 2");
+    repoVersionEntity.setDisplayName("My New Version 2 for patch upgrade");
     repoVersionEntity.setOperatingSystems("");
-    repoVersionEntity.setStack(stackEntity);
-    repoVersionEntity.setUpgradePackage("upgrade_test");
+    repoVersionEntity.setStack(stackEntity211);
     repoVersionEntity.setVersion("2.1.1.1");
     repoVersionDao.create(repoVersionEntity);
 
     repoVersionEntity = new RepositoryVersionEntity();
-    repoVersionEntity.setDisplayName("For Stack Version 2.2.0");
+    repoVersionEntity.setDisplayName("My New Version 3 for major upgrade");
     repoVersionEntity.setOperatingSystems("");
-    repoVersionEntity.setStack(stackDAO.find("HDP", "2.2.0"));
-    repoVersionEntity.setUpgradePackage("upgrade_test");
+    repoVersionEntity.setStack(stackEntity220);
     repoVersionEntity.setVersion("2.2.0.0");
     repoVersionDao.create(repoVersionEntity);
 
     clusters = injector.getInstance(Clusters.class);
 
-    StackId stackId = new StackId("HDP-2.1.1");
-    clusters.addCluster("c1", stackId);
+    clusters.addCluster("c1", stack211);
     Cluster cluster = clusters.getCluster("c1");
 
-    helper.getOrCreateRepositoryVersion(stackId, stackId.getStackVersion());
-    cluster.createClusterVersion(stackId, stackId.getStackVersion(), "admin", RepositoryVersionState.UPGRADING);
-    cluster.transitionClusterVersion(stackId, stackId.getStackVersion(), RepositoryVersionState.CURRENT);
+    helper.getOrCreateRepositoryVersion(stack211, stack211.getStackVersion());
+    helper.getOrCreateRepositoryVersion(stack220, stack220.getStackVersion());
+
+    cluster.createClusterVersion(stack211, stack211.getStackVersion(), "admin", RepositoryVersionState.UPGRADING);
+    cluster.transitionClusterVersion(stack211, stack211.getStackVersion(), RepositoryVersionState.CURRENT);
 
     clusters.addHost(s_serverHostName);
     Host host = clusters.getHost(s_serverHostName);
@@ -388,6 +393,8 @@ public class UpgradeResourceProviderTest {
     upgradeEntity.setDirection(Direction.UPGRADE);
     upgradeEntity.setFromVersion("2.1.1.1");
     upgradeEntity.setToVersion("2.2.2.2");
+    upgradeEntity.setUpgradePackage("upgrade_test");
+    upgradeEntity.setUpgradeType(UpgradeType.ROLLING);
     upgradeEntity.setRequestId(1L);
 
     upgradeDao.create(upgradeEntity);
@@ -432,6 +439,7 @@ public class UpgradeResourceProviderTest {
     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_PACK, "upgrade_test");
 
     ResourceProvider upgradeResourceProvider = createProvider(amc);
 
@@ -445,6 +453,7 @@ public class UpgradeResourceProviderTest {
     requestProps = new HashMap<String, Object>();
     requestProps.put(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME, "c1");
     requestProps.put(UpgradeResourceProvider.UPGRADE_VERSION, "2.2");
+    requestProps.put(UpgradeResourceProvider.UPGRADE_PACK, "upgrade_test");
     request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null);
     try {
       status = upgradeResourceProvider.createResources(request);
@@ -454,7 +463,8 @@ public class UpgradeResourceProviderTest {
     }
 
     requestProps.put(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME, "c1");
-    requestProps.put(UpgradeResourceProvider.UPGRADE_VERSION, "2.2");
+    requestProps.put(UpgradeResourceProvider.UPGRADE_VERSION, "2.2.0.0");
+    requestProps.put(UpgradeResourceProvider.UPGRADE_PACK, "upgrade_test");
     requestProps.put(UpgradeResourceProvider.UPGRADE_FROM_VERSION, "2.1.1.0");
 
     Map<String, String> requestInfoProperties = new HashMap<String, String>();
@@ -469,7 +479,7 @@ public class UpgradeResourceProviderTest {
     UpgradeEntity entity = upgradeDao.findUpgrade(Long.parseLong(id));
     assertNotNull(entity);
     assertEquals("2.1.1", entity.getFromVersion());
-    assertEquals("2.2", entity.getToVersion());
+    assertEquals("2.2.0.0", entity.getToVersion());
     assertEquals(Direction.DOWNGRADE, entity.getDirection());
 
     StageDAO dao = injector.getInstance(StageDAO.class);
@@ -531,6 +541,16 @@ public class UpgradeResourceProviderTest {
 
     List<HostRoleCommand> commands = am.getRequestTasks(id);
 
+    boolean foundOne = false;
+    for (HostRoleCommand hrc : commands) {
+      if (hrc.getRole().equals(Role.AMBARI_SERVER_ACTION)) {
+        assertEquals(-1L, hrc.getHostId());
+        assertNull(hrc.getHostName());
+        foundOne = true;
+      }
+    }
+    assertTrue("Expected at least one server-side action", foundOne);
+
     HostRoleCommand cmd = commands.get(commands.size()-1);
 
     HostRoleCommandDAO dao = injector.getInstance(HostRoleCommandDAO.class);
@@ -549,6 +569,7 @@ public class UpgradeResourceProviderTest {
 
 
   @Test
+  @Ignore
   public void testDirectionUpgrade() throws Exception {
     Cluster cluster = clusters.getCluster("c1");
 
@@ -557,7 +578,6 @@ public class UpgradeResourceProviderTest {
     repoVersionEntity.setDisplayName("My New Version 3");
     repoVersionEntity.setOperatingSystems("");
     repoVersionEntity.setStack(stackEntity);
-    repoVersionEntity.setUpgradePackage("upgrade_direction");
     repoVersionEntity.setVersion("2.2.2.3");
     repoVersionDao.create(repoVersionEntity);
 
@@ -576,12 +596,20 @@ public class UpgradeResourceProviderTest {
     UpgradeEntity upgrade = upgrades.get(0);
     Long id = upgrade.getRequestId();
     assertEquals(3, upgrade.getUpgradeGroups().size());
+    // Ensure that there are no items related to downgrade in the upgrade direction
     UpgradeGroupEntity group = upgrade.getUpgradeGroups().get(2);
-    assertEquals(1, group.getItems().size());
+    Assert.assertEquals("POST_CLUSTER", group.getName());
+    Assert.assertTrue(!group.getItems().isEmpty());
+    for (UpgradeItemEntity item : group.getItems()) {
+      Assert.assertFalse(item.getText().toLowerCase().contains("downgrade"));
+    }
+
 
     requestProps.clear();
+    // Now perform a downgrade
     requestProps.put(UpgradeResourceProvider.UPGRADE_CLUSTER_NAME, "c1");
     requestProps.put(UpgradeResourceProvider.UPGRADE_VERSION, "2.2");
+    requestProps.put(UpgradeResourceProvider.UPGRADE_PACK, "upgrade_direction");
     requestProps.put(UpgradeResourceProvider.UPGRADE_FROM_VERSION, "2.2.2.3");
 
     Map<String, String> requestInfoProps = new HashMap<String, String>();
@@ -695,10 +723,10 @@ public class UpgradeResourceProviderTest {
     assertEquals(1, upgrades.size());
 
     UpgradeEntity upgrade = upgrades.get(0);
-    assertEquals(3, upgrade.getUpgradeGroups().size());
+    assertEquals(5, upgrade.getUpgradeGroups().size());
 
     UpgradeGroupEntity group = upgrade.getUpgradeGroups().get(2);
-    assertEquals(2, group.getItems().size());
+    assertEquals(1, group.getItems().size());
 
     group = upgrade.getUpgradeGroups().get(0);
     assertEquals(2, group.getItems().size());
@@ -815,7 +843,8 @@ public class UpgradeResourceProviderTest {
     UpgradeResourceProvider upgradeResourceProvider = createProvider(amc);
 
     Map<String, UpgradePack> upgradePacks = ambariMetaInfo.getUpgradePacks("HDP", "2.1.1");
-    upgradeResourceProvider.processConfigurations(stack211.getStackName(), cluster, "2.2.0.0", Direction.UPGRADE, upgradePacks.get("upgrade_to_new_stack"));
+    UpgradePack upgrade = upgradePacks.get("upgrade_to_new_stack");
+    upgradeResourceProvider.applyStackAndProcessConfigurations(stack211.getStackName(), cluster, "2.2.0.0", Direction.UPGRADE, upgrade);
 
     Map<String, Map<String, String>> expectedConfigurations = expectedConfigurationsCapture.getValue();
     Map<String, String> expectedFooType = expectedConfigurations.get("foo-site");

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java
index b36480f..c5bb6e6 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java
@@ -614,7 +614,7 @@ public class OrmTestHelper {
     if (repositoryVersion == null) {
       try {
         repositoryVersion = repositoryVersionDAO.create(stackEntity, version,
-            String.valueOf(System.currentTimeMillis()), "pack", "");
+            String.valueOf(System.currentTimeMillis()), "");
       } catch (Exception ex) {
         Assert.fail(MessageFormat.format("Unable to create Repo Version for Stack {0} and version {1}",
             stackEntity.getStackName() + "-" + stackEntity.getStackVersion(), version));

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/CrudDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/CrudDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/CrudDAOTest.java
index 8777d33..6b5b297 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/CrudDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/CrudDAOTest.java
@@ -69,7 +69,6 @@ public class CrudDAOTest {
     entity.setDisplayName("display name" + uniqueCounter);
     entity.setOperatingSystems("repositories");
     entity.setStack(stackEntity);
-    entity.setUpgradePackage("upgrade package");
     entity.setVersion("version");
     repositoryVersionDAO.create(entity);
     uniqueCounter++;

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAOTest.java
index adda018..9d390a9 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAOTest.java
@@ -81,7 +81,6 @@ public class RepositoryVersionDAOTest {
     entity.setDisplayName("display name");
     entity.setOperatingSystems("repositories");
     entity.setStack(stackEntity);
-    entity.setUpgradePackage("upgrade package");
     entity.setVersion("version");
     repositoryVersionDAO.create(entity);
 
@@ -103,12 +102,11 @@ public class RepositoryVersionDAOTest {
     dupVersion.setDisplayName("display name " + uuid.toString());
     dupVersion.setOperatingSystems("repositories");
     dupVersion.setStack(stackEntity);
-    dupVersion.setUpgradePackage("upgrade package");
     dupVersion.setVersion(first.getVersion());
 
     boolean exceptionThrown = false;
     try {
-      repositoryVersionDAO.create(stackEntity, dupVersion.getVersion(), dupVersion.getDisplayName(), dupVersion.getUpgradePackage(), dupVersion.getOperatingSystemsJson());
+      repositoryVersionDAO.create(stackEntity, dupVersion.getVersion(), dupVersion.getDisplayName(), dupVersion.getOperatingSystemsJson());
     } catch (AmbariException e) {
       exceptionThrown = true;
       Assert.assertTrue(e.getMessage().contains("already exists"));
@@ -121,7 +119,7 @@ public class RepositoryVersionDAOTest {
     // The version must belong to the stack
     dupVersion.setVersion("2.3-1234");
     try {
-      repositoryVersionDAO.create(stackEntity, dupVersion.getVersion(), dupVersion.getDisplayName(), dupVersion.getUpgradePackage(), dupVersion.getOperatingSystemsJson());
+      repositoryVersionDAO.create(stackEntity, dupVersion.getVersion(), dupVersion.getDisplayName(), dupVersion.getOperatingSystemsJson());
     } catch (AmbariException e) {
       exceptionThrown = true;
       Assert.assertTrue(e.getMessage().contains("needs to belong to stack"));
@@ -132,7 +130,7 @@ public class RepositoryVersionDAOTest {
     // Success
     dupVersion.setVersion(stackEntity.getStackVersion() + "-1234");
     try {
-      repositoryVersionDAO.create(stackEntity, dupVersion.getVersion(), dupVersion.getDisplayName(), dupVersion.getUpgradePackage(), dupVersion.getOperatingSystemsJson());
+      repositoryVersionDAO.create(stackEntity, dupVersion.getVersion(), dupVersion.getDisplayName(), dupVersion.getOperatingSystemsJson());
     } catch (AmbariException e) {
       Assert.fail("Did not expect a failure creating the Repository Version");
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/UpgradeDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/UpgradeDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/UpgradeDAOTest.java
index 0b12e97..f6d1acf 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/UpgradeDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/UpgradeDAOTest.java
@@ -35,6 +35,7 @@ import org.apache.ambari.server.orm.entities.UpgradeGroupEntity;
 import org.apache.ambari.server.orm.entities.UpgradeItemEntity;
 import org.apache.ambari.server.state.UpgradeState;
 import org.apache.ambari.server.state.stack.upgrade.Direction;
+import org.apache.ambari.server.state.stack.upgrade.UpgradeType;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -69,13 +70,14 @@ public class UpgradeDAOTest {
     helper = injector.getInstance(OrmTestHelper.class);
     clusterId = helper.createCluster();
 
-
     // create upgrade entities
     UpgradeEntity entity = new UpgradeEntity();
     entity.setClusterId(Long.valueOf(1));
     entity.setRequestId(Long.valueOf(1));
     entity.setFromVersion("");
     entity.setToVersion("");
+    entity.setUpgradeType(UpgradeType.ROLLING);
+    entity.setUpgradePackage("test-upgrade");
 
     UpgradeGroupEntity group = new UpgradeGroupEntity();
     group.setName("group_name");
@@ -144,6 +146,8 @@ public class UpgradeDAOTest {
     entity1.setRequestId(Long.valueOf(1));
     entity1.setFromVersion("2.2.0.0-1234");
     entity1.setToVersion("2.3.0.0-4567");
+    entity1.setUpgradeType(UpgradeType.ROLLING);
+    entity1.setUpgradePackage("test-upgrade");
     dao.create(entity1);
     UpgradeEntity entity2 = new UpgradeEntity();
     entity2.setId(22L);
@@ -152,6 +156,8 @@ public class UpgradeDAOTest {
     entity2.setRequestId(Long.valueOf(1));
     entity2.setFromVersion("2.3.0.0-4567");
     entity2.setToVersion("2.2.0.0-1234");
+    entity2.setUpgradeType(UpgradeType.ROLLING);
+    entity2.setUpgradePackage("test-upgrade");
     dao.create(entity2);
     UpgradeEntity entity3 = new UpgradeEntity();
     entity3.setId(33L);
@@ -160,6 +166,8 @@ public class UpgradeDAOTest {
     entity3.setRequestId(Long.valueOf(1));
     entity3.setFromVersion("2.2.0.0-1234");
     entity3.setToVersion("2.3.1.1-4567");
+    entity3.setUpgradeType(UpgradeType.ROLLING);
+    entity3.setUpgradePackage("test-upgrade");
     dao.create(entity3);
     UpgradeEntity lastUpgradeForCluster = dao.findLastUpgradeForCluster(1);
     assertNotNull(lastUpgradeForCluster);

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/ConfigureActionTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/ConfigureActionTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/ConfigureActionTest.java
index 93e29b5..d1d783c 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/ConfigureActionTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/ConfigureActionTest.java
@@ -56,7 +56,7 @@ import org.apache.ambari.server.state.Service;
 import org.apache.ambari.server.state.ServiceFactory;
 import org.apache.ambari.server.state.StackId;
 import org.apache.ambari.server.state.stack.upgrade.ConfigureTask;
-import org.apache.ambari.server.state.stack.upgrade.ConfigureTask.ConfigurationKeyValue;
+import org.apache.ambari.server.state.stack.upgrade.ConfigUpgradeChangeDefinition.*;
 import org.apache.ambari.server.state.stack.upgrade.TransferCoercionType;
 import org.apache.ambari.server.state.stack.upgrade.TransferOperation;
 import org.junit.After;
@@ -131,7 +131,7 @@ public class ConfigureActionTest {
     c.addDesiredConfig("user", Collections.singleton(config));
     assertEquals(2, c.getConfigsByType("zoo.cfg").size());
 
-    List<ConfigurationKeyValue> configurations = new ArrayList<ConfigureTask.ConfigurationKeyValue>();
+    List<ConfigurationKeyValue> configurations = new ArrayList<ConfigurationKeyValue>();
     ConfigurationKeyValue keyValue = new ConfigurationKeyValue();
     configurations.add(keyValue);
     keyValue.key = "initLimit";
@@ -206,8 +206,8 @@ public class ConfigureActionTest {
     commandParams.put(ConfigureTask.PARAMETER_CONFIG_TYPE, "zoo.cfg");
 
     // delete all keys, preserving edits or additions
-    List<ConfigureTask.Transfer> transfers = new ArrayList<ConfigureTask.Transfer>();
-    ConfigureTask.Transfer transfer = new ConfigureTask.Transfer();
+    List<Transfer> transfers = new ArrayList<>();
+    Transfer transfer = new Transfer();
     transfer.operation = TransferOperation.DELETE;
     transfer.deleteKey = "*";
     transfer.preserveEdits = true;
@@ -266,7 +266,7 @@ public class ConfigureActionTest {
     c.addDesiredConfig("user", Collections.singleton(config));
     assertEquals(2, c.getConfigsByType("zoo.cfg").size());
 
-    List<ConfigurationKeyValue> configurations = new ArrayList<ConfigureTask.ConfigurationKeyValue>();
+    List<ConfigurationKeyValue> configurations = new ArrayList<>();
     ConfigurationKeyValue keyValue = new ConfigurationKeyValue();
     configurations.add(keyValue);
     keyValue.key = "initLimit";
@@ -280,15 +280,15 @@ public class ConfigureActionTest {
     commandParams.put(ConfigureTask.PARAMETER_KEY_VALUE_PAIRS, new Gson().toJson(configurations));
 
     // normal copy
-    List<ConfigureTask.Transfer> transfers = new ArrayList<ConfigureTask.Transfer>();
-    ConfigureTask.Transfer transfer = new ConfigureTask.Transfer();
+    List<Transfer> transfers = new ArrayList<>();
+    Transfer transfer = new Transfer();
     transfer.operation = TransferOperation.COPY;
     transfer.fromKey = "copyIt";
     transfer.toKey = "copyKey";
     transfers.add(transfer);
 
     // copy with default
-    transfer = new ConfigureTask.Transfer();
+    transfer = new Transfer();
     transfer.operation = TransferOperation.COPY;
     transfer.fromKey = "copiedFromMissingKeyWithDefault";
     transfer.toKey = "copiedToMissingKeyWithDefault";
@@ -296,14 +296,14 @@ public class ConfigureActionTest {
     transfers.add(transfer);
 
     // normal move
-    transfer = new ConfigureTask.Transfer();
+    transfer = new Transfer();
     transfer.operation = TransferOperation.MOVE;
     transfer.fromKey = "moveIt";
     transfer.toKey = "movedKey";
     transfers.add(transfer);
 
     // move with default
-    transfer = new ConfigureTask.Transfer();
+    transfer = new Transfer();
     transfer.operation = TransferOperation.MOVE;
     transfer.fromKey = "movedFromKeyMissingWithDefault";
     transfer.toKey = "movedToMissingWithDefault";
@@ -311,7 +311,7 @@ public class ConfigureActionTest {
     transfer.mask = true;
     transfers.add(transfer);
 
-    transfer = new ConfigureTask.Transfer();
+    transfer = new Transfer();
     transfer.operation = TransferOperation.DELETE;
     transfer.deleteKey = "deleteIt";
     transfers.add(transfer);
@@ -357,7 +357,7 @@ public class ConfigureActionTest {
     assertEquals("defaultValue2", map.get("movedToMissingWithDefault"));
 
     transfers.clear();
-    transfer = new ConfigureTask.Transfer();
+    transfer = new Transfer();
     transfer.operation = TransferOperation.DELETE;
     transfer.deleteKey = "*";
     transfer.preserveEdits = true;
@@ -404,8 +404,8 @@ public class ConfigureActionTest {
     commandParams.put(ConfigureTask.PARAMETER_CONFIG_TYPE, "zoo.cfg");
 
     // copy with coerce
-    List<ConfigureTask.Transfer> transfers = new ArrayList<ConfigureTask.Transfer>();
-    ConfigureTask.Transfer transfer = new ConfigureTask.Transfer();
+    List<Transfer> transfers = new ArrayList<Transfer>();
+    Transfer transfer = new Transfer();
     transfer.operation = TransferOperation.COPY;
     transfer.coerceTo = TransferCoercionType.YAML_ARRAY;
     transfer.fromKey = "zoo.server.csv";
@@ -472,14 +472,14 @@ public class ConfigureActionTest {
     commandParams.put(ConfigureTask.PARAMETER_CONFIG_TYPE, "zoo.cfg");
 
     // Replacement task
-    List<ConfigureTask.Replace> replacements = new ArrayList<ConfigureTask.Replace>();
-    ConfigureTask.Replace replace = new ConfigureTask.Replace();
+    List<Replace> replacements = new ArrayList<Replace>();
+    Replace replace = new Replace();
     replace.key = "key_to_replace";
     replace.find = "New Cat";
     replace.replaceWith = "Wet Dog";
     replacements.add(replace);
 
-    replace = new ConfigureTask.Replace();
+    replace = new Replace();
     replace.key = "key_with_no_match";
     replace.find = "abc";
     replace.replaceWith = "def";
@@ -538,7 +538,7 @@ public class ConfigureActionTest {
     assertEquals(2, c.getConfigsByType("zoo.cfg").size());
 
     // create several configurations
-    List<ConfigurationKeyValue> configurations = new ArrayList<ConfigureTask.ConfigurationKeyValue>();
+    List<ConfigurationKeyValue> configurations = new ArrayList<ConfigurationKeyValue>();
     ConfigurationKeyValue fooKey2 = new ConfigurationKeyValue();
     configurations.add(fooKey2);
     fooKey2.key = "fooKey2";
@@ -633,8 +633,7 @@ public class ConfigureActionTest {
     String urlInfo = "[{'repositories':["
         + "{'Repositories/base_url':'http://foo1','Repositories/repo_name':'HDP','Repositories/repo_id':'HDP-2.2.0'}"
         + "], 'OperatingSystems/os_type':'redhat6'}]";
-    repoVersionDAO.create(stackEntity, HDP_2_2_0_1, String.valueOf(System.currentTimeMillis()),
-        "pack", urlInfo);
+    repoVersionDAO.create(stackEntity, HDP_2_2_0_1, String.valueOf(System.currentTimeMillis()), urlInfo);
 
 
     c.createClusterVersion(HDP_220_STACK, HDP_2_2_0_1, "admin", RepositoryVersionState.INSTALLING);

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/UpgradeActionTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/UpgradeActionTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/UpgradeActionTest.java
index 5f65e2d..a8c361a 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/UpgradeActionTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/UpgradeActionTest.java
@@ -214,8 +214,7 @@ public class UpgradeActionTest {
     String urlInfo = "[{'repositories':["
         + "{'Repositories/base_url':'http://foo1','Repositories/repo_name':'HDP','Repositories/repo_id':'" + targetStack.getStackId() + "'}"
         + "], 'OperatingSystems/os_type':'redhat6'}]";
-    repoVersionDAO.create(stackEntityTarget, targetRepo, String.valueOf(System.currentTimeMillis()),
-        "pack", urlInfo);
+    repoVersionDAO.create(stackEntityTarget, targetRepo, String.valueOf(System.currentTimeMillis()), urlInfo);
 
     // Start upgrading the newer repo
     c.createClusterVersion(targetStack, targetRepo, "admin", RepositoryVersionState.INSTALLING);
@@ -275,8 +274,7 @@ public class UpgradeActionTest {
     String urlInfo = "[{'repositories':["
         + "{'Repositories/base_url':'http://foo1','Repositories/repo_name':'HDP','Repositories/repo_id':'" + targetRepo + "'}"
         + "], 'OperatingSystems/os_type':'redhat6'}]";
-    repoVersionDAO.create(stackEntityTarget, targetRepo, String.valueOf(System.currentTimeMillis()),
-        "pack", urlInfo);
+    repoVersionDAO.create(stackEntityTarget, targetRepo, String.valueOf(System.currentTimeMillis()), urlInfo);
 
     // Start upgrading the newer repo
     c.createClusterVersion(targetStack, targetRepo, "admin", RepositoryVersionState.INSTALLING);

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/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 7077f4c..483a024 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
@@ -36,6 +36,7 @@ import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import com.google.gson.reflect.TypeToken;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.controller.AmbariManagementController;
@@ -44,19 +45,19 @@ import org.apache.ambari.server.controller.ConfigurationRequest;
 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.dao.RepositoryVersionDAO;
+import org.apache.ambari.server.orm.dao.StackDAO;
+import org.apache.ambari.server.orm.entities.StackEntity;
 import org.apache.ambari.server.stack.HostsType;
 import org.apache.ambari.server.stack.MasterHostResolver;
 import org.apache.ambari.server.state.UpgradeHelper.UpgradeGroupHolder;
+import org.apache.ambari.server.state.stack.ConfigUpgradePack;
 import org.apache.ambari.server.state.stack.UpgradePack;
-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.ManualTask;
-import org.apache.ambari.server.state.stack.upgrade.StageWrapper;
-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.*;
 import org.easymock.EasyMock;
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 
 import com.google.gson.Gson;
@@ -65,6 +66,7 @@ import com.google.inject.Binder;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Module;
+
 import com.google.inject.persist.PersistService;
 import com.google.inject.util.Modules;
 
@@ -93,24 +95,54 @@ public class UpgradeHelperTest {
     m_configHelper = EasyMock.createNiceMock(ConfigHelper.class);
 
     expect(
-        m_configHelper.getPlaceholderValueFromDesiredConfigurations(
-            EasyMock.anyObject(Cluster.class), EasyMock.eq("{{foo/bar}}"))).andReturn(
+      m_configHelper.getPlaceholderValueFromDesiredConfigurations(
+        EasyMock.anyObject(Cluster.class), EasyMock.eq("{{foo/bar}}"))).andReturn(
         "placeholder-rendered-properly").anyTimes();
 
+    expect(
+        m_configHelper.getEffectiveDesiredTags(
+            EasyMock.anyObject(Cluster.class), EasyMock.anyObject(String.class))).
+        andReturn(new HashMap<String, Map<String, String>>()).anyTimes();
+
     replay(m_configHelper);
 
-    // create an injector which will inject the mocks
-    injector = Guice.createInjector(Modules.override(
-        new InMemoryDefaultTestModule()).with(new MockModule()));
+    final InMemoryDefaultTestModule injectorModule = new InMemoryDefaultTestModule() {
+      @Override
+      protected void configure() {
+        super.configure();
+      }
+    };
 
+    MockModule mockModule = new MockModule();
+    // create an injector which will inject the mocks
+    injector = Guice.createInjector(Modules.override(injectorModule).with(mockModule));
     injector.getInstance(GuiceJpaInitializer.class);
 
     helper = injector.getInstance(OrmTestHelper.class);
     ambariMetaInfo = injector.getInstance(AmbariMetaInfo.class);
-
     m_upgradeHelper = injector.getInstance(UpgradeHelper.class);
     m_masterHostResolver = EasyMock.createMock(MasterHostResolver.class);
     m_managementController = injector.getInstance(AmbariManagementController.class);
+
+//    StackDAO stackDAO = injector.getInstance(StackDAO.class);
+//    StackEntity stackEntity = new StackEntity();
+//    stackEntity.setStackName("HDP");
+//    stackEntity.setStackVersion("2.1");
+//    stackDAO.create(stackEntity);
+//
+//    StackEntity stackEntityTo = new StackEntity();
+//    stackEntityTo.setStackName("HDP");
+//    stackEntityTo.setStackVersion("2.2");
+//    stackDAO.create(stackEntityTo);
+//
+//    Clusters clusters = injector.getInstance(Clusters.class);
+//    clusters.addCluster("c1", new StackId("HDP", "2.1"));
+//
+//    RepositoryVersionDAO repositoryVersionDAO = injector.getInstance(RepositoryVersionDAO.class);
+//    repositoryVersionDAO.create(stackEntity, "2.1.1", "2.1.1", "");
+//    repositoryVersionDAO.create(stackEntityTo, "2.2.0", "2.2.0", "");
+//
+//    replay(m_configHelper);
   }
 
   @After
@@ -119,6 +151,23 @@ public class UpgradeHelperTest {
   }
 
   @Test
+  public void testSuggestUpgradePack() 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();
+    try {
+      UpgradePack up = m_upgradeHelper.suggestUpgradePack(clusterName, upgradeFromVersion, upgradeToVersion, upgradeDirection, upgradeType);
+      assertEquals(upgradeType, up.getType());
+    } catch (AmbariException e){
+      assertTrue(false);
+    }
+  }
+
+  @Test
   public void testUpgradeOrchestration() throws Exception {
     Map<String, UpgradePack> upgrades = ambariMetaInfo.getUpgradePacks("foo", "bar");
     assertTrue(upgrades.isEmpty());
@@ -130,7 +179,6 @@ public class UpgradeHelperTest {
     ComponentInfo ci = si.getComponentByName("ZOOKEEPER_SERVER");
     ci.setDisplayName("ZooKeeper1 Server2");
 
-
     assertTrue(upgrades.containsKey("upgrade_test"));
     UpgradePack upgrade = upgrades.get("upgrade_test");
     assertNotNull(upgrade);
@@ -138,7 +186,7 @@ public class UpgradeHelperTest {
     makeCluster();
 
     UpgradeContext context = new UpgradeContext(m_masterHostResolver, HDP_21,
-        HDP_21, UPGRADE_VERSION, Direction.UPGRADE);
+        HDP_21, UPGRADE_VERSION, Direction.UPGRADE, UpgradeType.ROLLING);
 
     List<UpgradeGroupHolder> groups = m_upgradeHelper.createSequence(upgrade, context);
 
@@ -194,50 +242,6 @@ public class UpgradeHelperTest {
   }
 
   /**
-   * Tests that hosts in MM are not included in the upgrade.
-   *
-   * @throws Exception
-   */
-  @Test
-  public void testUpgradeOrchestrationWithHostsInMM() throws Exception {
-    Map<String, UpgradePack> upgrades = ambariMetaInfo.getUpgradePacks("foo", "bar");
-    assertTrue(upgrades.isEmpty());
-
-    upgrades = ambariMetaInfo.getUpgradePacks("HDP", "2.1.1");
-
-    ServiceInfo si = ambariMetaInfo.getService("HDP", "2.1.1", "ZOOKEEPER");
-    si.setDisplayName("Zk");
-
-    ComponentInfo ci = si.getComponentByName("ZOOKEEPER_SERVER");
-    ci.setDisplayName("ZooKeeper1 Server2");
-
-    assertTrue(upgrades.containsKey("upgrade_test"));
-    UpgradePack upgrade = upgrades.get("upgrade_test");
-    assertNotNull(upgrade);
-
-    // turn on MM for the first host
-    Cluster cluster = makeCluster();
-    Host hostInMaintenanceMode = cluster.getHosts().iterator().next();
-    hostInMaintenanceMode.setMaintenanceState(cluster.getClusterId(), MaintenanceState.ON);
-
-    // use a "real" master host resolver here so that we can actually test MM
-    MasterHostResolver masterHostResolver = new MasterHostResolver(null, cluster, "");
-
-    UpgradeContext context = new UpgradeContext(masterHostResolver, HDP_21, HDP_21,
-        UPGRADE_VERSION, Direction.UPGRADE);
-
-    List<UpgradeGroupHolder> groups = m_upgradeHelper.createSequence(upgrade, context);
-    assertEquals(6, groups.size());
-
-    for (UpgradeGroupHolder group : groups) {
-      for (StageWrapper stageWrapper : group.items) {
-        Set<String> hosts = stageWrapper.getHosts();
-        assertFalse(hosts.contains(hostInMaintenanceMode.getHostName()));
-      }
-    }
-  }
-
-  /**
    * Verify that a Rolling Upgrades restarts the NameNodes in the following order: standby, active.
    * @throws Exception
    */
@@ -251,7 +255,7 @@ public class UpgradeHelperTest {
     makeCluster();
 
     UpgradeContext context = new UpgradeContext(m_masterHostResolver, HDP_21,
-        HDP_21, UPGRADE_VERSION, Direction.UPGRADE);
+        HDP_21, UPGRADE_VERSION, Direction.UPGRADE, UpgradeType.ROLLING);
 
     List<UpgradeGroupHolder> groups = m_upgradeHelper.createSequence(upgrade, context);
 
@@ -262,7 +266,7 @@ public class UpgradeHelperTest {
 
     List<String> orderedNameNodes = new LinkedList<String>();
     for (StageWrapper sw : mastersGroup.items) {
-      if (sw.getType().equals(StageWrapper.Type.RESTART)) {
+      if (sw.getType().equals(StageWrapper.Type.RESTART) && sw.getText().toLowerCase().contains("NameNode".toLowerCase())) {
         for (TaskWrapper tw : sw.getTasks()) {
           for (String hostName : tw.getHosts()) {
             orderedNameNodes.add(hostName);
@@ -300,7 +304,7 @@ public class UpgradeHelperTest {
     assertEquals(HostState.HEARTBEAT_LOST, schs.get(0).getHostState());
 
     UpgradeContext context = new UpgradeContext(m_masterHostResolver, HDP_21,
-        HDP_21, UPGRADE_VERSION, Direction.UPGRADE);
+        HDP_21, UPGRADE_VERSION, Direction.UPGRADE, UpgradeType.ROLLING);
 
     List<UpgradeGroupHolder> groups = m_upgradeHelper.createSequence(upgrade, context);
 
@@ -336,7 +340,7 @@ public class UpgradeHelperTest {
     makeCluster();
 
     UpgradeContext context = new UpgradeContext(m_masterHostResolver, HDP_21,
-        HDP_21, DOWNGRADE_VERSION, Direction.DOWNGRADE);
+        HDP_21, DOWNGRADE_VERSION, Direction.DOWNGRADE, UpgradeType.ROLLING);
 
     List<UpgradeGroupHolder> groups = m_upgradeHelper.createSequence(upgrade, context);
 
@@ -376,7 +380,7 @@ public class UpgradeHelperTest {
     makeCluster();
 
     UpgradeContext context = new UpgradeContext(m_masterHostResolver, HDP_21,
-        HDP_21, UPGRADE_VERSION, Direction.UPGRADE);
+        HDP_21, UPGRADE_VERSION, Direction.UPGRADE, UpgradeType.ROLLING);
 
     List<UpgradeGroupHolder> groups = m_upgradeHelper.createSequence(upgrade, context);
 
@@ -396,7 +400,7 @@ public class UpgradeHelperTest {
     makeCluster();
 
     UpgradeContext context = new UpgradeContext(m_masterHostResolver, HDP_21,
-        HDP_21, UPGRADE_VERSION, Direction.UPGRADE);
+        HDP_21, UPGRADE_VERSION, Direction.UPGRADE, UpgradeType.ROLLING);
 
     List<UpgradeGroupHolder> groups = m_upgradeHelper.createSequence(upgrade, context);
 
@@ -415,20 +419,18 @@ public class UpgradeHelperTest {
 
   @Test
   public void testConditionalDeleteTask() throws Exception {
-    Map<String, UpgradePack> upgrades = ambariMetaInfo.getUpgradePacks("HDP",
-                                                                       "2.1.1");
-
+    Map<String, UpgradePack> upgrades = ambariMetaInfo.getUpgradePacks("HDP", "2.1.1");
     assertTrue(upgrades.containsKey("upgrade_test"));
     UpgradePack upgrade = upgrades.get("upgrade_test");
+    ConfigUpgradePack cup = ambariMetaInfo.getConfigUpgradePack("HDP", "2.1.1");
     assertNotNull(upgrade);
 
     Cluster cluster = makeCluster();
 
     UpgradeContext context = new UpgradeContext(m_masterHostResolver, HDP_21,
-                                                HDP_21, UPGRADE_VERSION, Direction.UPGRADE);
+                                                HDP_21, UPGRADE_VERSION, Direction.UPGRADE, UpgradeType.ROLLING);
 
-    List<UpgradeGroupHolder> groups = m_upgradeHelper.createSequence(upgrade,
-                                                                     context);
+    List<UpgradeGroupHolder> groups = m_upgradeHelper.createSequence(upgrade, context);
 
     assertEquals(6, groups.size());
 
@@ -459,16 +461,15 @@ public class UpgradeHelperTest {
       }
     }, null);
 
-    Map<String, String> configProperties = configureTask.getConfigurationChanges(cluster);
+    Map<String, String> configProperties = configureTask.getConfigurationChanges(cluster, cup);
     assertFalse(configProperties.isEmpty());
     assertEquals(configProperties.get(ConfigureTask.PARAMETER_CONFIG_TYPE), "hive-site");
 
     String configurationJson = configProperties.get(ConfigureTask.PARAMETER_TRANSFERS);
     assertNotNull(configurationJson);
 
-    List<ConfigureTask.Transfer> transfers = m_gson.fromJson(configurationJson,
-                                                                              new TypeToken<List<ConfigureTask.Transfer>>() {
-                                                                              }.getType());
+    List<ConfigUpgradeChangeDefinition.Transfer> transfers = m_gson.fromJson(configurationJson,
+            new TypeToken<List<ConfigUpgradeChangeDefinition.Transfer>>() { }.getType());
 
     assertEquals(8, transfers.size());
     assertEquals("copy-key", transfers.get(0).fromKey);
@@ -489,17 +490,16 @@ public class UpgradeHelperTest {
 
   @Test
   public void testConfigureTask() throws Exception {
-    Map<String, UpgradePack> upgrades = ambariMetaInfo.getUpgradePacks("HDP",
-        "2.1.1");
-
+    Map<String, UpgradePack> upgrades = ambariMetaInfo.getUpgradePacks("HDP", "2.1.1");
     assertTrue(upgrades.containsKey("upgrade_test"));
     UpgradePack upgrade = upgrades.get("upgrade_test");
+    ConfigUpgradePack cup = ambariMetaInfo.getConfigUpgradePack("HDP", "2.1.1");
     assertNotNull(upgrade);
 
     Cluster cluster = makeCluster();
 
     UpgradeContext context = new UpgradeContext(m_masterHostResolver, HDP_21,
-        HDP_21, UPGRADE_VERSION, Direction.UPGRADE);
+        HDP_21, UPGRADE_VERSION, Direction.UPGRADE, UpgradeType.ROLLING);
 
     List<UpgradeGroupHolder> groups = m_upgradeHelper.createSequence(upgrade,
         context);
@@ -512,15 +512,15 @@ public class UpgradeHelperTest {
     ConfigureTask configureTask = (ConfigureTask) hiveGroup.items.get(1).getTasks().get(
         0).getTasks().get(0);
 
-    Map<String, String> configProperties = configureTask.getConfigurationChanges(cluster);
+    Map<String, String> configProperties = configureTask.getConfigurationChanges(cluster, cup);
     assertFalse(configProperties.isEmpty());
     assertEquals(configProperties.get(ConfigureTask.PARAMETER_CONFIG_TYPE), "hive-site");
 
     String configurationJson = configProperties.get(ConfigureTask.PARAMETER_KEY_VALUE_PAIRS);
     assertNotNull(configurationJson);
 
-    List<ConfigureTask.ConfigurationKeyValue> keyValuePairs = m_gson.fromJson(configurationJson,
-        new TypeToken<List<ConfigureTask.ConfigurationKeyValue>>() {
+    List<ConfigUpgradeChangeDefinition.ConfigurationKeyValue> keyValuePairs = m_gson.fromJson(configurationJson,
+        new TypeToken<List<ConfigUpgradeChangeDefinition.ConfigurationKeyValue>>() {
         }.getType());
 
     assertEquals("hive.server2.thrift.port", keyValuePairs.get(0).key);
@@ -548,7 +548,7 @@ public class UpgradeHelperTest {
     }, null);
 
     // the configure task should now return different properties
-    configProperties = configureTask.getConfigurationChanges(cluster);
+    configProperties = configureTask.getConfigurationChanges(cluster, cup);
     assertFalse(configProperties.isEmpty());
     assertEquals( configProperties.get(ConfigureTask.PARAMETER_CONFIG_TYPE), "hive-site");
 
@@ -556,7 +556,7 @@ public class UpgradeHelperTest {
     assertNotNull(configurationJson);
 
     keyValuePairs = m_gson.fromJson(configurationJson,
-        new TypeToken<List<ConfigureTask.ConfigurationKeyValue>>() {
+        new TypeToken<List<ConfigUpgradeChangeDefinition.ConfigurationKeyValue>>() {
         }.getType());
 
     assertEquals("hive.server2.http.port", keyValuePairs.get(0).key);
@@ -566,15 +566,14 @@ public class UpgradeHelperTest {
   @Test
   public void testConfigureTaskWithMultipleConfigurations() throws Exception {
     Map<String, UpgradePack> upgrades = ambariMetaInfo.getUpgradePacks("HDP", "2.1.1");
-
     assertTrue(upgrades.containsKey("upgrade_test"));
     UpgradePack upgrade = upgrades.get("upgrade_test");
+    ConfigUpgradePack cup = ambariMetaInfo.getConfigUpgradePack("HDP", "2.1.1");
     assertNotNull(upgrade);
-
     Cluster cluster = makeCluster();
 
     UpgradeContext context = new UpgradeContext(m_masterHostResolver, HDP_21, HDP_21,
-        UPGRADE_VERSION, Direction.UPGRADE);
+        UPGRADE_VERSION, Direction.UPGRADE, UpgradeType.ROLLING);
 
     List<UpgradeGroupHolder> groups = m_upgradeHelper.createSequence(upgrade, context);
 
@@ -585,7 +584,7 @@ public class UpgradeHelperTest {
     assertEquals("HIVE", hiveGroup.name);
     ConfigureTask configureTask = (ConfigureTask) hiveGroup.items.get(1).getTasks().get(1).getTasks().get(0);
 
-    Map<String, String> configProperties = configureTask.getConfigurationChanges(cluster);
+    Map<String, String> configProperties = configureTask.getConfigurationChanges(cluster, cup);
     assertFalse(configProperties.isEmpty());
     assertEquals(configProperties.get(ConfigureTask.PARAMETER_CONFIG_TYPE), "hive-site");
 
@@ -594,12 +593,12 @@ public class UpgradeHelperTest {
     assertNotNull(configurationJson);
     assertNotNull(transferJson);
 
-    List<ConfigureTask.ConfigurationKeyValue> keyValuePairs = m_gson.fromJson(configurationJson,
-        new TypeToken<List<ConfigureTask.ConfigurationKeyValue>>() {
+    List<ConfigUpgradeChangeDefinition.ConfigurationKeyValue> keyValuePairs = m_gson.fromJson(configurationJson,
+        new TypeToken<List<ConfigUpgradeChangeDefinition.ConfigurationKeyValue>>() {
         }.getType());
 
-    List<ConfigureTask.Transfer> transfers = m_gson.fromJson(transferJson,
-        new TypeToken<List<ConfigureTask.Transfer>>() {
+    List<ConfigUpgradeChangeDefinition.Transfer> transfers = m_gson.fromJson(transferJson,
+        new TypeToken<List<ConfigUpgradeChangeDefinition.Transfer>>() {
         }.getType());
 
     assertEquals("fooKey", keyValuePairs.get(0).key);
@@ -616,7 +615,6 @@ public class UpgradeHelperTest {
     assertEquals("move-key-to", transfers.get(1).toKey);
   }
 
-
   @Test
   public void testServiceCheckUpgradeStages() throws Exception {
     Map<String, UpgradePack> upgrades = ambariMetaInfo.getUpgradePacks("HDP", "2.2.0");
@@ -651,7 +649,7 @@ public class UpgradeHelperTest {
     }
 
     UpgradeContext context = new UpgradeContext(m_masterHostResolver, HDP_21,
-        HDP_22, UPGRADE_VERSION, Direction.UPGRADE);
+        HDP_22, UPGRADE_VERSION, Direction.UPGRADE, UpgradeType.ROLLING);
 
     List<UpgradeGroupHolder> groups = m_upgradeHelper.createSequence(upgrade, context);
 
@@ -695,7 +693,7 @@ public class UpgradeHelperTest {
     makeCluster();
 
     UpgradeContext context = new UpgradeContext(m_masterHostResolver, HDP_21,
-        HDP_21, DOWNGRADE_VERSION, Direction.DOWNGRADE);
+        HDP_21, DOWNGRADE_VERSION, Direction.DOWNGRADE, UpgradeType.ROLLING);
 
     List<UpgradeGroupHolder> groups = m_upgradeHelper.createSequence(upgrade, context);
 
@@ -713,6 +711,7 @@ public class UpgradeHelperTest {
         manualTask.message);
   }
 
+  @Ignore
   @Test
   public void testUpgradeOrchestrationFullTask() throws Exception {
     Map<String, UpgradePack> upgrades = ambariMetaInfo.getUpgradePacks("HDP", "2.1.1");
@@ -729,7 +728,7 @@ public class UpgradeHelperTest {
     makeCluster();
 
     UpgradeContext context = new UpgradeContext(m_masterHostResolver, HDP_21,
-        HDP_21, UPGRADE_VERSION, Direction.UPGRADE);
+        HDP_21, UPGRADE_VERSION, Direction.UPGRADE, UpgradeType.ROLLING);
 
     List<UpgradeGroupHolder> groups = m_upgradeHelper.createSequence(upgrade, context);
 
@@ -807,11 +806,13 @@ public class UpgradeHelperTest {
     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",
@@ -977,9 +978,11 @@ public class UpgradeHelperTest {
     expect(m_masterHostResolver.getCluster()).andReturn(c).anyTimes();
     replay(m_masterHostResolver);
 
-    UpgradeContext context = new UpgradeContext(m_masterHostResolver, HDP_21, HDP_21, DOWNGRADE_VERSION, Direction.DOWNGRADE);
+    UpgradeContext context = new UpgradeContext(m_masterHostResolver, HDP_21, HDP_21, DOWNGRADE_VERSION,
+        Direction.DOWNGRADE, UpgradeType.ROLLING);
 
     Map<String, UpgradePack> upgrades = ambariMetaInfo.getUpgradePacks("HDP", "2.1.1");
+    assertTrue(upgrades.containsKey("upgrade_direction"));
     UpgradePack upgrade = upgrades.get("upgrade_direction");
     assertNotNull(upgrade);
 
@@ -1004,13 +1007,8 @@ public class UpgradeHelperTest {
 
 
 
-  /**
-   *
-   */
   private class MockModule implements Module {
-    /**
-    *
-    */
+
     @Override
     public void configure(Binder binder) {
       binder.bind(ConfigHelper.class).toInstance(m_configHelper);


[4/9] ambari git commit: AMBARI-13392. Stop-and-Start Upgrade: Merge branch branch-dev-stop-all-upgrade to branch-2.1 for feature Stop-the-World Upgrade, aka Express Upgrade (alejandro, dlysnichenko, Dmytro Grinenko)

Posted by al...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/config-upgrade.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/config-upgrade.xml b/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/config-upgrade.xml
new file mode 100644
index 0000000..072e15f
--- /dev/null
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/config-upgrade.xml
@@ -0,0 +1,800 @@
+<?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-config-changes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+  <services>
+
+    <service name="RANGER">
+      <component name="RANGER_ADMIN">
+        <changes>
+          <definition id="hdp_2_3_0_0_update_ranger_env">
+            <type>ranger-env</type>
+            <set key="xml_configurations_supported" value="true" />
+          </definition>
+          <definition id="hdp_2_3_0_0_update_ranger_admin" summary="Updating Ranger Admin">
+            <type>ranger-admin-site</type>
+            <transfer operation="copy" from-type="ranger-site" from-key="HTTPS_CLIENT_AUTH" to-key="ranger.service.https.attrib.clientAuth" default-value="" />
+            <transfer operation="copy" from-type="ranger-site" from-key="HTTPS_KEYSTORE_FILE" to-key="ranger.https.attrib.keystore.file" default-value="" />
+            <transfer operation="copy" from-type="ranger-site" from-key="HTTPS_KEYSTORE_PASS" to-key="ranger.service.https.attrib.keystore.pass" default-value="" mask="true" />
+            <transfer operation="copy" from-type="ranger-site" from-key="HTTPS_KEY_ALIAS" to-key="ranger.service.https.attrib.keystore.keyalias" default-value="" />
+            <transfer operation="copy" from-type="ranger-site" from-key="HTTPS_SERVICE_PORT" to-key="ranger.service.https.port" default-value="" />
+            <transfer operation="copy" from-type="ranger-site" from-key="HTTP_ENABLED" to-key="ranger.service.http.enabled" default-value="" />
+            <transfer operation="copy" from-type="ranger-site" from-key="HTTP_SERVICE_PORT" to-key="ranger.service.http.port" default-value="" />
+
+            <transfer operation="copy" from-type="admin-properties" from-key="authServiceHostName" to-key="ranger.unixauth.service.hostname" default-value="" />
+            <transfer operation="copy" from-type="admin-properties" from-key="authServicePort" to-key="ranger.unixauth.service.port" default-value="" />
+            <transfer operation="copy" from-type="admin-properties" from-key="authentication_method" to-key="ranger.authentication.method" default-value="" />
+            <transfer operation="copy" from-type="admin-properties" from-key="remoteLoginEnabled" to-key="ranger.unixauth.remote.login.enabled" default-value="" />
+            <transfer operation="copy" from-type="admin-properties" from-key="xa_ldap_url" to-key="ranger.ldap.url" default-value="" />
+            <transfer operation="copy" from-type="admin-properties" from-key="xa_ldap_userDNpattern" to-key="ranger.ldap.user.dnpattern" default-value="" />
+            <transfer operation="copy" from-type="admin-properties" from-key="xa_ldap_groupSearchBase" to-key="ranger.ldap.group.searchbase" default-value="" />
+            <transfer operation="copy" from-type="admin-properties" from-key="xa_ldap_groupSearchFilter" to-key="ranger.ldap.group.searchfilter" default-value="" />
+            <transfer operation="copy" from-type="admin-properties" from-key="xa_ldap_groupRoleAttribute" to-key="ranger.ldap.group.roleattribute" default-value="" />
+            <transfer operation="copy" from-type="admin-properties" from-key="xa_ldap_ad_domain" to-key="ranger.ldap.ad.domain" default-value="" />
+            <transfer operation="copy" from-type="admin-properties" from-key="xa_ldap_ad_url" to-key="ranger.ldap.ad.url" default-value="" />
+            <transfer operation="copy" from-type="admin-properties" from-key="db_user" to-key="ranger.jpa.jdbc.user" default-value="" />
+            <transfer operation="copy" from-type="admin-properties" from-key="db_password" to-key="ranger.jpa.jdbc.password" default-value="" mask="true" />
+            <transfer operation="copy" from-type="admin-properties" from-key="audit_db_user" to-key="ranger.jpa.audit.jdbc.user" default-value="" />
+            <transfer operation="copy" from-type="admin-properties" from-key="audit_db_password" to-key="ranger.jpa.audit.jdbc.password" default-value="" mask="true" />
+
+            <set key="ranger.externalurl" value="{{ranger_external_url}}" />
+          </definition>
+
+          <definition xsi:type="configure" id="hdp_2_3_0_0_update_ranger_usersync" summary="Updating Ranger Usersync">
+            <type>ranger-ugsync-site</type>
+            <transfer operation="copy" from-type="usersync-properties" from-key="CRED_KEYSTORE_FILENAME" to-key="ranger.usersync.credstore.filename" default-value="/etc/ranger/usersync/ugsync.jceks" />
+            <transfer operation="copy" from-type="usersync-properties" from-key="MIN_UNIX_USER_ID_TO_SYNC" to-key="ranger.usersync.unix.minUserId" default-value="" />
+            <transfer operation="copy" from-type="usersync-properties" from-key="SYNC_INTERVAL" to-key="ranger.usersync.sleeptimeinmillisbetweensynccycle" default-value="60000" />
+            <transfer operation="copy" from-type="usersync-properties" from-key="SYNC_LDAP_BIND_DN" to-key="ranger.usersync.ldap.binddn" default-value="" />
+            <transfer operation="copy" from-type="usersync-properties" from-key="SYNC_LDAP_BIND_PASSWORD" to-key="ranger.usersync.ldap.ldapbindpassword" default-value="" mask="true" />
+            <transfer operation="copy" from-type="usersync-properties" from-key="SYNC_LDAP_GROUPNAME_CASE_CONVERSION" to-key="ranger.usersync.ldap.groupname.caseconversion" default-value="" />
+            <transfer operation="copy" from-type="usersync-properties" from-key="SYNC_LDAP_URL" to-key="ranger.usersync.ldap.url" default-value="" />
+            <transfer operation="copy" from-type="usersync-properties" from-key="SYNC_LDAP_USERNAME_CASE_CONVERSION" to-key="ranger.usersync.ldap.username.caseconversion" default-value="" />
+            <transfer operation="copy" from-type="usersync-properties" from-key="SYNC_LDAP_USER_GROUP_NAME_ATTRIBUTE" to-key="ranger.usersync.ldap.user.groupnameattribute" default-value="" />
+            <transfer operation="copy" from-type="usersync-properties" from-key="SYNC_LDAP_USER_NAME_ATTRIBUTE" to-key="ranger.usersync.ldap.user.nameattribute" default-value="" />
+            <transfer operation="copy" from-type="usersync-properties" from-key="SYNC_LDAP_USER_OBJECT_CLASS" to-key="ranger.usersync.ldap.user.objectclass" default-value="" />
+            <transfer operation="copy" from-type="usersync-properties" from-key="SYNC_LDAP_USER_SEARCH_BASE" to-key="ranger.usersync.ldap.user.searchbase" default-value="" />
+            <transfer operation="copy" from-type="usersync-properties" from-key="SYNC_LDAP_USER_SEARCH_FILTER" to-key="ranger.usersync.ldap.user.searchfilter" default-value="" />
+            <transfer operation="copy" from-type="usersync-properties" from-key="SYNC_LDAP_USER_SEARCH_SCOPE" to-key="ranger.usersync.ldap.user.searchscope" default-value="" />
+            <transfer operation="copy" from-type="usersync-properties" from-key="logdir" to-key="ranger.usersync.logdir" default-value="" />
+            <transfer operation="copy" from-type="usersync-properties" from-key="SYNC_SOURCE" to-key="ranger.usersync.sync.source" default-value="unix" />
+            <transfer operation="copy" from-type="usersync-properties" from-key="POLICY_MGR_URL" to-key="ranger.usersync.policymanager.baseURL" default-value="{{ranger_external_url}}" />
+            <set key="ranger.usersync.source.impl.class" value="" />
+            <set key="ranger.usersync.ldap.searchBase" value="" />
+            <set key="ranger.usersync.group.memberattributename" value="" />
+            <set key="ranger.usersync.group.nameattribute" value="" />
+            <set key="ranger.usersync.group.objectclass" value="" />
+            <set key="ranger.usersync.group.searchbase" value="" />
+            <set key="ranger.usersync.group.searchenabled" value="" />
+            <set key="ranger.usersync.group.searchfilter" value="" />
+            <set key="ranger.usersync.group.searchscope" value="" />
+            <set key="ranger.usersync.group.usermapsyncenabled" value="" />
+          </definition>
+
+          <definition xsi:type="configure" id="hdp_2_3_0_0_update_ranger_site">
+            <type>ranger-site</type>
+            <transfer operation="delete" delete-key="HTTPS_CLIENT_AUTH" />
+            <transfer operation="delete" delete-key="HTTPS_KEYSTORE_FILE" />
+            <transfer operation="delete" delete-key="HTTPS_KEYSTORE_PASS" />
+            <transfer operation="delete" delete-key="HTTPS_KEY_ALIAS" />
+            <transfer operation="delete" delete-key="HTTPS_SERVICE_PORT" />
+            <transfer operation="delete" delete-key="HTTP_ENABLED" />
+            <transfer operation="delete" delete-key="HTTP_SERVICE_PORT" />
+          </definition>
+
+          <definition xsi:type="configure" id="hdp_2_3_0_0_update_ranger_usersync_properties">
+            <type>usersync-properties</type>
+            <transfer operation="delete" delete-key="CRED_KEYSTORE_FILENAME" />
+            <transfer operation="delete" delete-key="MIN_UNIX_USER_ID_TO_SYNC" />
+            <transfer operation="delete" delete-key="SYNC_INTERVAL" />
+            <transfer operation="delete" delete-key="SYNC_LDAP_BIND_DN" />
+            <transfer operation="delete" delete-key="SYNC_LDAP_BIND_PASSWORD" />
+            <transfer operation="delete" delete-key="SYNC_LDAP_GROUPNAME_CASE_CONVERSION" />
+            <transfer operation="delete" delete-key="SYNC_LDAP_URL" />
+            <transfer operation="delete" delete-key="SYNC_LDAP_USERNAME_CASE_CONVERSION" />
+            <transfer operation="delete" delete-key="SYNC_LDAP_USER_GROUP_NAME_ATTRIBUTE" />
+            <transfer operation="delete" delete-key="SYNC_LDAP_USER_NAME_ATTRIBUTE" />
+            <transfer operation="delete" delete-key="SYNC_LDAP_USER_OBJECT_CLASS" />
+            <transfer operation="delete" delete-key="SYNC_LDAP_USER_SEARCH_BASE" />
+            <transfer operation="delete" delete-key="SYNC_LDAP_USER_SEARCH_FILTER" />
+            <transfer operation="delete" delete-key="SYNC_LDAP_USER_SEARCH_SCOPE" />
+            <transfer operation="delete" delete-key="logdir" />
+            <transfer operation="delete" delete-key="SYNC_SOURCE" />
+            <transfer operation="delete" delete-key="POLICY_MGR_URL" />
+          </definition>
+
+          <definition xsi:type="configure" id="hdp_2_3_0_0_update_ranger_delete_oracle_home">
+            <type>ranger-env</type>
+            <transfer operation="delete" delete-key="oracle_home" />
+          </definition>
+          
+        </changes>
+      </component>
+    </service>
+
+    <service name="HDFS">
+      <component name="NAMENODE">
+        <changes>
+          <definition xsi:type="configure" id="hdp_2_3_0_0_modify_hadoop_env" summary="Modify hadoop-env.sh">
+            <type>hadoop-env</type>
+            <replace key="content" find="# Add libraries required by nodemanager" replace-with="" />
+            <replace key="content" find="MAPREDUCE_LIBS={{mapreduce_libs_path}}" replace-with="" />
+            <replace key="content" find=":${MAPREDUCE_LIBS}" replace-with="" />
+            <replace key="content" find=":/usr/hdp/current/tez-client/*:/usr/hdp/current/tez-client/lib/*:/etc/tez/conf/" replace-with="" />
+            <replace key="content" find=":/usr/hdp/current/tez-client/*:/usr/hdp/current/tez-client/lib/*:/usr/hdp/current/tez-client/conf/" replace-with="" />
+          </definition>
+
+          <definition xsi:type="configure" id="hdp_2_3_0_0_hdfs_adjust_ranger_plugin">
+            <condition type="ranger-hdfs-plugin-properties" key="ranger-hdfs-plugin-enabled" value="Yes">
+              <type>hdfs-site</type>
+              <key>dfs.namenode.inode.attributes.provider.class</key>
+              <value>org.apache.ranger.authorization.hadoop.RangerHdfsAuthorizer</value>
+            </condition>
+          </definition>
+
+          <definition xsi:type="configure" id="hdp_2_3_0_0_hdfs_transition_ranger_hdfs_policy" summary="Transitioning Ranger HDFS Policy">
+            <type>ranger-hdfs-policymgr-ssl</type>
+            <transfer operation="copy" from-type="ranger-hdfs-plugin-properties" from-key="SSL_KEYSTORE_FILE_PATH" to-key="xasecure.policymgr.clientssl.keystore" default-value="/usr/hdp/current/hadoop-client/conf/ranger-plugin-keystore.jks" />
+            <transfer operation="copy" from-type="ranger-hdfs-plugin-properties" from-key="SSL_KEYSTORE_PASSWORD" to-key="xasecure.policymgr.clientssl.keystore.password" mask="true" default-value="myKeyFilePassword" />
+            <transfer operation="copy" from-type="ranger-hdfs-plugin-properties" from-key="SSL_TRUSTSTORE_FILE_PATH" to-key="xasecure.policymgr.clientssl.truststore" default-value="/usr/hdp/current/hadoop-client/conf/ranger-plugin-truststore.jks" />
+            <transfer operation="copy" from-type="ranger-hdfs-plugin-properties" from-key="SSL_TRUSTSTORE_PASSWORD" to-key="xasecure.policymgr.clientssl.truststore.password" mask="true" default-value="changeit" />
+          </definition>
+
+          <definition xsi:type="configure" id="hdp_2_3_0_0_hdfs_transition_ranger_hdfs_audit" summary="Transitioning Ranger HDFS Audit">
+            <type>ranger-hdfs-audit</type>
+            <transfer operation="copy" from-type="ranger-hdfs-plugin-properties" from-key="XAAUDIT.DB.IS_ENABLED" to-key="xasecure.audit.destination.db" default-value="false"/>
+            <transfer operation="copy" from-type="ranger-hdfs-plugin-properties" from-key="XAAUDIT.HDFS.DESTINATION_DIRECTORY" to-key="xasecure.audit.destination.hdfs.dir" default-value="hdfs://NAMENODE_HOSTNAME:8020/ranger/audit" />
+            <transfer operation="copy" from-type="ranger-hdfs-plugin-properties" from-key="XAAUDIT.HDFS.IS_ENABLED" to-key="xasecure.audit.destination.hdfs" default-value="true" />
+            <transfer operation="copy" from-type="ranger-hdfs-plugin-properties" from-key="XAAUDIT.HDFS.LOCAL_ARCHIVE_DIRECTORY" to-key="xasecure.audit.destination.hdfs.batch.filespool.dir" default-value="/var/log/hadoop/hdfs/audit/hdfs/spool" />
+            <transfer operation="copy" from-type="ranger-hdfs-plugin-properties" from-key="XAAUDIT.DB.USER_NAME" to-key="xasecure.audit.destination.db.user" default-value="" />
+            <transfer operation="copy" from-type="ranger-hdfs-plugin-properties" from-key="XAAUDIT.DB.PASSWORD" to-key="xasecure.audit.destination.db.password" mask="true" default-value="" />
+            <set key="xasecure.audit.credential.provider.file" value="jceks://file{{credential_file}}"/>
+            <set key="xasecure.audit.destination.solr" value="false" />
+            <set key="xasecure.audit.destination.solr.urls" value="{{ranger_audit_solr_urls}}" />
+            <set key="xasecure.audit.destination.solr.zookeepers" value="none" />
+            <set key="xasecure.audit.destination.solr.batch.filespool.dir" value="/var/log/hadoop/hdfs/audit/solr/spool" />
+            <set key="xasecure.audit.destination.db.jdbc.driver" value="{{jdbc_driver}}" />
+            <set key="xasecure.audit.destination.db.jdbc.url" value="{{audit_jdbc_url}}" />
+            <set key="xasecure.audit.provider.summary.enabled" value="false" />
+          </definition>
+
+          <definition xsi:type="configure" id="hdp_2_3_0_0_hdfs_transition_ranger_hdfs_security" summary="Transitioning Ranger HDFS Security">
+            <type>ranger-hdfs-security</type>
+            <transfer operation="copy" from-type="ranger-hdfs-plugin-properties" from-key="REPOSITORY_NAME" to-key="ranger.plugin.hdfs.service.name" default-value="{{repo_name}}" />
+            <transfer operation="copy" from-type="ranger-hdfs-plugin-properties" from-key="POLICY_MGR_URL" to-key="ranger.plugin.hdfs.policy.rest.url" default-value="{{policymgr_mgr_url}}" />
+          </definition>
+
+          <definition xsi:type="configure" id="hdp_2_3_0_0_hdfs_ranger_hdfs_delete_old_properties">
+            <type>ranger-hdfs-plugin-properties</type>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_FILE" />
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_FLUSH_INTERVAL_SECONDS" />
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_OPEN_RETRY_INTERVAL_SECONDS" />
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_ROLLOVER_INTERVAL_SECONDS" />
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_ARCHIVE_MAX_FILE_COUNT" />
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_DIRECTORY" />
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_FILE" />
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_FLUSH_INTERVAL_SECONDS" />
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_ROLLOVER_INTERVAL_SECONDS" />
+            <transfer operation="delete" delete-key="SQL_CONNECTOR_JAR" />
+            <transfer operation="delete" delete-key="SSL_KEYSTORE_FILE_PATH" />
+            <transfer operation="delete" delete-key="SSL_KEYSTORE_PASSWORD" />
+            <transfer operation="delete" delete-key="SSL_TRUSTSTORE_FILE_PATH" />
+            <transfer operation="delete" delete-key="SSL_TRUSTSTORE_PASSWORD" />
+            <transfer operation="delete" delete-key="XAAUDIT.DB.IS_ENABLED" />
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINATION_DIRECTORY" />
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.IS_ENABLED" />
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_ARCHIVE_DIRECTORY" />
+            <transfer operation="delete" delete-key="XAAUDIT.DB.USER_NAME" />
+            <transfer operation="delete" delete-key="XAAUDIT.DB.PASSWORD" />
+            <transfer operation="delete" delete-key="REPOSITORY_NAME" />
+            <transfer operation="delete" delete-key="POLICY_MGR_URL" />
+            <transfer operation="delete" delete-key="XAAUDIT.DB.FLAVOUR" />
+            <transfer operation="delete" delete-key="XAAUDIT.DB.DATABASE_NAME" />
+            <transfer operation="delete" delete-key="XAAUDIT.DB.HOSTNAME" />
+          </definition>
+
+        </changes>
+      </component>
+    </service>
+
+    <service name="MAPREDUCE2">
+      <component name="HISTORYSERVER">
+        <changes>
+          <definition xsi:type="configure" id="hdp_2_3_0_0_mapreduce2_adjust_history_server">
+            <type>mapred-site</type>
+            <transfer operation="move" from-key="mapreduce.job.speculative.speculativecap" to-key="mapreduce.job.speculative.speculative-cap-running-tasks" default-value="0.1"/>
+            <transfer operation="delete" delete-key="mapreduce.task.tmp.dir" />
+            <set key="mapreduce.fileoutputcommitter.algorithm.version" value="1"/>
+          </definition>
+        </changes>
+      </component>
+    </service>
+
+    <service name="YARN">
+      <component name="APP_TIMELINE_SERVER">
+        <changes>
+          <definition xsi:type="configure" id="hdp_2_3_0_0_yarn_ats_enable_recovery">
+            <type>yarn-site</type>
+            <set key="yarn.timeline-service.recovery.enabled" value="true"/>
+            <set key="yarn.timeline-service.state-store-class" value="org.apache.hadoop.yarn.server.timeline.recovery.LeveldbTimelineStateStore"/>
+            <transfer operation="copy" from-key="yarn.timeline-service.leveldb-timeline-store.path" to-key="yarn.timeline-service.leveldb-state-store.path" default-value="/hadoop/yarn/timeline"/>
+          </definition>
+        </changes>
+      </component>
+
+      <component name="RESOURCEMANAGER">
+        <changes>
+          <definition xsi:type="configure" id="hdp_2_3_0_0_yarn_rm_disable_node_labels">
+            <type>yarn-site</type>
+            <set key="yarn.node-labels.enabled" value="false"/>
+          </definition>
+
+          <definition xsi:type="configure" id="hdp_2_3_0_0_yarn_rm_clear_default_node_label_expression">
+            <type>capacity-scheduler</type>
+            <set key="yarn.scheduler.capacity.root.default-node-label-expression" value=""/>
+          </definition>
+
+          <definition xsi:type="configure" id="hdp_2_3_0_0_yarn_rm_check_cs_root_def_capacity" summary="Deleting the Capacity Scheduler root default capacity">
+            <type>capacity-scheduler</type>
+            <transfer operation="delete" delete-key="yarn.scheduler.capacity.root.accessible-node-labels.default.capacity"/>
+          </definition>
+
+          <definition xsi:type="configure" id="hdp_2_3_0_0_yarn_rm_check_cs_root_max_capacity" summary="Deleting the Capacity Scheduler root maximum capacity">
+            <type>capacity-scheduler</type>
+            <transfer operation="delete" delete-key="yarn.scheduler.capacity.root.accessible-node-labels.default.maximum-capacity"/>
+          </definition>
+        </changes>
+      </component>
+    </service>
+
+    <service name="HBASE">
+      <component name="HBASE_MASTER">
+        <changes>
+          <definition xsi:type="configure"
+                id="hdp_2_3_0_0_hbase_master_adjust_phoenix_scheduler_factory">
+            <condition type="hbase-env" key="phoenix_sql_enabled" value="true">
+              <type>hbase-site</type>
+              <key>hbase.region.server.rpc.scheduler.factory.class</key>
+              <value>org.apache.hadoop.hbase.ipc.PhoenixRpcSchedulerFactory
+              </value>
+            </condition>
+          </definition>
+
+          <definition xsi:type="configure"
+                id="hdp_2_3_0_0_hbase_master_adjust_phoenix_rpc_controller_factory">
+            <condition type="hbase-env" key="phoenix_sql_enabled" value="true">
+              <type>hbase-site</type>
+              <key>hbase.rpc.controllerfactory.class</key>
+              <value>
+                org.apache.hadoop.hbase.ipc.controller.ServerRpcControllerFactory
+              </value>
+            </condition>
+          </definition>
+
+          <definition xsi:type="configure"
+                id="hdp_2_3_0_0_hbase_master_set_global_memstore_size">
+            <type>hbase-site</type>
+            <transfer operation="copy" from-type="hbase-site"
+                      from-key="hbase.regionserver.global.memstore.upperLimit"
+                      to-key="hbase.regionserver.global.memstore.size"
+                      default-value="0.4"/>
+          </definition>
+
+          <definition xsi:type="configure"
+                id="hdp_2_3_0_0_hbase_master_adjust_phoenix_indexed_wal_edit_codec">
+            <condition type="hbase-env" key="phoenix_sql_enabled" value="true">
+              <type>hbase-site</type>
+              <key>hbase.regionserver.wal.codec</key>
+              <value>
+                org.apache.hadoop.hbase.regionserver.wal.IndexedWALEditCodec
+              </value>
+            </condition>
+          </definition>
+
+          <definition xsi:type="configure"
+                id="hdp_2_3_0_0_hbase_master_adjust_authorization_coprocessors"
+                summary="Updating Authorization Coprocessors">
+            <type>hbase-site</type>
+            <replace key="hbase.coprocessor.master.classes"
+                     find="com.xasecure.authorization.hbase.XaSecureAuthorizationCoprocessor"
+                     replace-with="org.apache.ranger.authorization.hbase.RangerAuthorizationCoprocessor"/>
+            <replace key="hbase.coprocessor.region.classes"
+                     find="com.xasecure.authorization.hbase.XaSecureAuthorizationCoprocessor"
+                     replace-with="org.apache.ranger.authorization.hbase.RangerAuthorizationCoprocessor"/>
+          </definition>
+
+          <definition xsi:type="configure"
+                id="hdp_2_3_0_0_hbase_master_transition_ranger_hbase_policy"
+                summary="Transitioning Ranger HBase Policy">
+            <type>ranger-hbase-policymgr-ssl</type>
+            <transfer operation="copy"
+                      from-type="ranger-hbase-plugin-properties"
+                      from-key="SSL_KEYSTORE_FILE_PATH"
+                      to-key="xasecure.policymgr.clientssl.keystore"
+                      default-value="/usr/hdp/current/hbase-client/conf/ranger-plugin-keystore.jks"/>
+            <transfer operation="copy"
+                      from-type="ranger-hbase-plugin-properties"
+                      from-key="SSL_KEYSTORE_PASSWORD"
+                      to-key="xasecure.policymgr.clientssl.keystore.password"
+                      mask="true" default-value="myKeyFilePassword"/>
+            <transfer operation="copy"
+                      from-type="ranger-hbase-plugin-properties"
+                      from-key="SSL_TRUSTSTORE_FILE_PATH"
+                      to-key="xasecure.policymgr.clientssl.truststore"
+                      default-value="/usr/hdp/current/hbase-client/conf/ranger-plugin-truststore.jks"/>
+            <transfer operation="copy"
+                      from-type="ranger-hbase-plugin-properties"
+                      from-key="SSL_TRUSTSTORE_PASSWORD"
+                      to-key="xasecure.policymgr.clientssl.truststore.password"
+                      mask="true" default-value="changeit"/>
+          </definition>
+
+          <definition xsi:type="configure"
+                id="hdp_2_3_0_0_hbase_master_transition_ranger_hbase_audit"
+                summary="Transitioning Ranger HBase Audit">
+            <type>ranger-hbase-audit</type>
+            <transfer operation="copy"
+                      from-type="ranger-hbase-plugin-properties"
+                      from-key="XAAUDIT.DB.IS_ENABLED"
+                      to-key="xasecure.audit.destination.db"
+                      default-value="false"/>
+            <transfer operation="copy"
+                      from-type="ranger-hbase-plugin-properties"
+                      from-key="XAAUDIT.HDFS.DESTINATION_DIRECTORY"
+                      to-key="xasecure.audit.destination.hdfs.dir"
+                      default-value="hdfs://NAMENODE_HOSTNAME:8020/ranger/audit"/>
+            <transfer operation="copy"
+                      from-type="ranger-hbase-plugin-properties"
+                      from-key="XAAUDIT.HDFS.IS_ENABLED"
+                      to-key="xasecure.audit.destination.hdfs"
+                      default-value="true"/>
+            <transfer operation="copy"
+                      from-type="ranger-hbase-plugin-properties"
+                      from-key="XAAUDIT.HDFS.LOCAL_ARCHIVE_DIRECTORY"
+                      to-key="xasecure.audit.destination.hdfs.batch.filespool.dir"
+                      default-value="/var/log/hbase/audit/hdfs/spool"/>
+            <transfer operation="copy"
+                      from-type="ranger-hbase-plugin-properties"
+                      from-key="XAAUDIT.DB.USER_NAME"
+                      to-key="xasecure.audit.destination.db.user"
+                      default-value=""/>
+            <transfer operation="copy"
+                      from-type="ranger-hbase-plugin-properties"
+                      from-key="XAAUDIT.DB.PASSWORD"
+                      to-key="xasecure.audit.destination.db.password"
+                      mask="true" default-value=""/>
+            <set key="xasecure.audit.credential.provider.file"
+                 value="jceks://file{{credential_file}}"/>
+            <set key="xasecure.audit.destination.solr" value="false"/>
+            <set key="xasecure.audit.destination.solr.urls"
+                 value="{{ranger_audit_solr_urls}}"/>
+            <set key="xasecure.audit.destination.solr.zookeepers" value="none"/>
+            <set key="xasecure.audit.destination.solr.batch.filespool.dir"
+                 value="/var/log/hbase/audit/solr/spool"/>
+            <set key="xasecure.audit.destination.db.jdbc.driver"
+                 value="{{jdbc_driver}}"/>
+            <set key="xasecure.audit.destination.db.jdbc.url"
+                 value="{{audit_jdbc_url}}"/>
+            <set key="xasecure.audit.provider.summary.enabled" value="true"/>
+          </definition>
+
+          <definition xsi:type="configure"
+                id="hdp_2_3_0_0_hbase_master_copy_ranger_policies">
+            <type>ranger-hbase-security</type>
+            <transfer operation="copy"
+                      from-type="ranger-hbase-plugin-properties"
+                      from-key="UPDATE_XAPOLICIES_ON_GRANT_REVOKE"
+                      to-key="xasecure.hbase.update.xapolicies.on.grant.revoke"
+                      default-value="true"/>
+            <transfer operation="copy"
+                      from-type="ranger-hbase-plugin-properties"
+                      from-key="POLICY_MGR_URL"
+                      to-key="ranger.plugin.hbase.policy.rest.url"
+                      default-value="{{policymgr_mgr_url}}"/>
+            <transfer operation="copy"
+                      from-type="ranger-hbase-plugin-properties"
+                      from-key="REPOSITORY_NAME"
+                      to-key="ranger.plugin.hbase.service.name"
+                      default-value="{{repo_name}}"/>
+          </definition>
+
+          <definition xsi:type="configure"
+                id="hdp_2_3_0_0_hbase_master_delete_old_ranger_properties">
+            <type>ranger-hbase-plugin-properties</type>
+            <transfer operation="delete"
+                      delete-key="XAAUDIT.HDFS.DESTINTATION_FILE"/>
+            <transfer operation="delete"
+                      delete-key="XAAUDIT.HDFS.DESTINTATION_FLUSH_INTERVAL_SECONDS"/>
+            <transfer operation="delete"
+                      delete-key="XAAUDIT.HDFS.DESTINTATION_OPEN_RETRY_INTERVAL_SECONDS"/>
+            <transfer operation="delete"
+                      delete-key="XAAUDIT.HDFS.DESTINTATION_ROLLOVER_INTERVAL_SECONDS"/>
+            <transfer operation="delete"
+                      delete-key="XAAUDIT.HDFS.LOCAL_ARCHIVE_MAX_FILE_COUNT"/>
+            <transfer operation="delete"
+                      delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_DIRECTORY"/>
+            <transfer operation="delete"
+                      delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_FILE"/>
+            <transfer operation="delete"
+                      delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_FLUSH_INTERVAL_SECONDS"/>
+            <transfer operation="delete"
+                      delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_ROLLOVER_INTERVAL_SECONDS"/>
+            <transfer operation="delete" delete-key="SQL_CONNECTOR_JAR"/>
+            <transfer operation="delete" delete-key="REPOSITORY_NAME"/>
+            <transfer operation="delete" delete-key="POLICY_MGR_URL"/>
+            <transfer operation="delete"
+                      delete-key="UPDATE_XAPOLICIES_ON_GRANT_REVOKE"/>
+            <transfer operation="delete" delete-key="SSL_KEYSTORE_FILE_PATH"/>
+            <transfer operation="delete" delete-key="SSL_KEYSTORE_PASSWORD"/>
+            <transfer operation="delete" delete-key="SSL_TRUSTSTORE_FILE_PATH"/>
+            <transfer operation="delete" delete-key="SSL_TRUSTSTORE_PASSWORD"/>
+            <transfer operation="delete" delete-key="XAAUDIT.DB.IS_ENABLED"/>
+            <transfer operation="delete"
+                      delete-key="XAAUDIT.HDFS.DESTINATION_DIRECTORY"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.IS_ENABLED"/>
+            <transfer operation="delete"
+                      delete-key="XAAUDIT.HDFS.LOCAL_ARCHIVE_DIRECTORY"/>
+            <transfer operation="delete" delete-key="XAAUDIT.DB.USER_NAME"/>
+            <transfer operation="delete" delete-key="XAAUDIT.DB.PASSWORD"/>
+            <transfer operation="delete" delete-key="XAAUDIT.DB.FLAVOUR"/>
+            <transfer operation="delete" delete-key="XAAUDIT.DB.DATABASE_NAME"/>
+            <transfer operation="delete" delete-key="XAAUDIT.DB.HOSTNAME"/>
+          </definition>
+        </changes>
+      </component>
+    </service>
+
+    <service name="TEZ">
+      <component name="TEZ_CLIENT">
+        <changes>
+          <definition xsi:type="configure"
+                id="hdp_2_3_0_0_tez_client_adjust_properties">
+            <type>tez-site</type>
+            <set key="tez.am.view-acls" value="*"/>
+            <set key="tez.task.generate.counters.per.io" value="true"/>
+          </definition>
+        </changes>
+      </component>
+    </service>
+
+    <service name="HIVE">
+      <component name="HIVE_SERVER">
+        <changes>
+          <definition xsi:type="configure" id="hdp_2_3_0_0_hive_server_set_transport_modes">
+            <condition type="hive-site" key="hive.server2.transport.mode" value="binary">
+              <type>hive-site</type>
+              <key>hive.server2.thrift.port</key>
+              <value>10010</value>
+            </condition>
+            <condition type="hive-site" key="hive.server2.transport.mode" value="http">
+              <type>hive-site</type>
+              <key>hive.server2.http.port</key>
+              <value>10011</value>
+            </condition>
+          </definition>
+
+          <definition xsi:type="configure" id="hdp_2_3_0_0_hive_server_replace_auth_manager" summary="Update Hive Authentication Manager">
+            <type>hiveserver2-site</type>
+            <replace key="hive.security.authorization.manager" find="com.xasecure.authorization.hive.authorizer.XaSecureHiveAuthorizerFactory" replace-with="org.apache.ranger.authorization.hive.authorizer.RangerHiveAuthorizerFactory" />
+          </definition>
+
+          <definition xsi:type="configure" id="hdp_2_3_0_0_hive_server_configure_authentification" summary="Configuring hive authentication">
+            <type>hive-site</type>
+            <transfer operation="delete" delete-key="hive.server2.authentication.ldap.url" if-key="hive.server2.authentication" if-type="hive-site" if-value="NONE"/>
+            <transfer operation="delete" delete-key="hive.server2.authentication.ldap.baseDN" if-key="hive.server2.authentication" if-type="hive-site" if-value="NONE"/>
+            <transfer operation="delete" delete-key="hive.server2.authentication.pam.services" if-key="hive.server2.authentication" if-type="hive-site" if-value="NONE"/>
+            <transfer operation="delete" delete-key="hive.server2.custom.authentication.class" if-key="hive.server2.authentication" if-type="hive-site" if-value="NONE"/>
+            <transfer operation="delete" delete-key="hive.server2.authentication.kerberos.keytab" if-key="hive.server2.authentication" if-type="hive-site" if-value="NONE"/>
+            <transfer operation="delete" delete-key="hive.server2.authentication.kerberos.principal" if-key="hive.server2.authentication" if-type="hive-site" if-value="NONE"/>
+
+            <transfer operation="delete" delete-key="hive.server2.authentication.kerberos.keytab" if-key="hive.server2.authentication" if-type="hive-site" if-value="ldap"/>
+            <transfer operation="delete" delete-key="hive.server2.authentication.kerberos.principal" if-key="hive.server2.authentication" if-type="hive-site" if-value="ldap"/>
+            <transfer operation="delete" delete-key="hive.server2.authentication.pam.services" if-key="hive.server2.authentication" if-type="hive-site" if-value="ldap"/>
+            <transfer operation="delete" delete-key="hive.server2.custom.authentication.class" if-key="hive.server2.authentication" if-type="hive-site" if-value="ldap"/>
+
+            <transfer operation="delete" delete-key="hive.server2.authentication.ldap.url" if-key="hive.server2.authentication" if-type="hive-site" if-value="kerberos"/>
+            <transfer operation="delete" delete-key="hive.server2.authentication.ldap.baseDN" if-key="hive.server2.authentication" if-type="hive-site" if-value="kerberos"/>
+            <transfer operation="delete" delete-key="hive.server2.authentication.pam.services" if-key="hive.server2.authentication" if-type="hive-site" if-value="kerberos"/>
+            <transfer operation="delete" delete-key="hive.server2.custom.authentication.class" if-key="hive.server2.authentication" if-type="hive-site" if-value="kerberos"/>
+
+            <transfer operation="delete" delete-key="hive.server2.authentication.ldap.url" if-key="hive.server2.authentication" if-type="hive-site" if-value="pam"/>
+            <transfer operation="delete" delete-key="hive.server2.authentication.ldap.baseDN" if-key="hive.server2.authentication" if-type="hive-site" if-value="pam"/>
+            <transfer operation="delete" delete-key="hive.server2.custom.authentication.class" if-key="hive.server2.authentication" if-type="hive-site" if-value="pam"/>
+            <transfer operation="delete" delete-key="hive.server2.authentication.kerberos.keytab" if-key="hive.server2.authentication" if-type="hive-site" if-value="pam"/>
+            <transfer operation="delete" delete-key="hive.server2.authentication.kerberos.principal" if-key="hive.server2.authentication" if-type="hive-site" if-value="pam"/>
+
+            <transfer operation="delete" delete-key="hive.server2.authentication.ldap.url" if-key="hive.server2.authentication" if-type="hive-site" if-value="custom"/>
+            <transfer operation="delete" delete-key="hive.server2.authentication.ldap.baseDN" if-key="hive.server2.authentication" if-type="hive-site" if-value="custom"/>
+            <transfer operation="delete" delete-key="hive.server2.authentication.pam.services" if-key="hive.server2.authentication" if-type="hive-site" if-value="custom"/>
+            <transfer operation="delete" delete-key="hive.server2.authentication.kerberos.keytab" if-key="hive.server2.authentication" if-type="hive-site" if-value="custom"/>
+            <transfer operation="delete" delete-key="hive.server2.authentication.kerberos.principal" if-key="hive.server2.authentication" if-type="hive-site" if-value="custom"/>
+          </definition>
+
+          <definition xsi:type="configure" id="hdp_2_3_0_0_hive_server_configure_ranger_policy" summary="Configuring Ranger Hive Policy">
+            <type>ranger-hive-policymgr-ssl</type>
+            <transfer operation="copy" from-type="ranger-hive-plugin-properties" from-key="SSL_KEYSTORE_FILE_PATH" to-key="xasecure.policymgr.clientssl.keystore" default-value="/usr/hdp/current/hive-server2/conf/ranger-plugin-keystore.jks"/>
+            <transfer operation="copy" from-type="ranger-hive-plugin-properties" from-key="SSL_KEYSTORE_PASSWORD" to-key="xasecure.policymgr.clientssl.keystore.password" default-value="myKeyFilePassword" mask="true"/>
+            <transfer operation="copy" from-type="ranger-hive-plugin-properties" from-key="SSL_TRUSTSTORE_FILE_PATH" to-key="xasecure.policymgr.clientssl.truststore" default-value="/usr/hdp/current/hive-server2/conf/ranger-plugin-truststore.jks"/>
+            <transfer operation="copy" from-type="ranger-hive-plugin-properties" from-key="SSL_TRUSTSTORE_PASSWORD" to-key="xasecure.policymgr.clientssl.truststore.password" default-value="changeit" mask="true"/>
+          </definition>
+
+          <definition xsi:type="configure" id="hdp_2_3_0_0_hive_server_configure_ranger_security" summary="Configuring Ranger Hive Security">
+            <type>ranger-hive-security</type>
+            <transfer operation="copy" from-type="ranger-hive-plugin-properties" from-key="UPDATE_XAPOLICIES_ON_GRANT_REVOKE" to-key="xasecure.hive.update.xapolicies.on.grant.revoke" default-value="true"/>
+            <transfer operation="copy" from-type="ranger-hive-plugin-properties" from-key="POLICY_MGR_URL" to-key="ranger.plugin.hive.policy.rest.url" default-value="{{policymgr_mgr_url}}"/>
+            <transfer operation="copy" from-type="ranger-hive-plugin-properties" from-key="REPOSITORY_NAME" to-key="ranger.plugin.hive.service.name" default-value="{{repo_name}}"/>
+          </definition>
+
+          <definition xsi:type="configure" id="hdp_2_3_0_0_hive_server_configure_ranger_audit" summary="Configuring Ranger Hive Audit">
+            <type>ranger-hive-audit</type>
+            <transfer operation="copy" from-type="ranger-hive-plugin-properties" from-key="XAAUDIT.DB.IS_ENABLED" to-key="xasecure.audit.destination.db" default-value="true"/>
+            <transfer operation="copy" from-type="ranger-hive-plugin-properties" from-key="XAAUDIT.HDFS.DESTINATION_DIRECTORY" to-key="xasecure.audit.destination.hdfs.dir" default-value="hdfs://NAMENODE_HOSTNAME:8020/ranger/audit"/>
+            <transfer operation="copy" from-type="ranger-hive-plugin-properties" from-key="XAAUDIT.HDFS.IS_ENABLED" to-key="xasecure.audit.destination.hdfs" default-value="true"/>
+            <transfer operation="copy" from-type="ranger-hive-plugin-properties" from-key="XAAUDIT.HDFS.LOCAL_ARCHIVE_DIRECTORY" to-key="xasecure.audit.destination.hdfs.batch.filespool.dir" default-value="/var/log/hive/audit/hdfs/spool"/>
+            <transfer operation="copy" from-type="ranger-hive-plugin-properties" from-key="XAAUDIT.DB.USER_NAME" to-key="xasecure.audit.destination.db.user" default-value=""/>
+            <transfer operation="copy" from-type="ranger-hive-plugin-properties" from-key="XAAUDIT.DB.PASSWORD" to-key="xasecure.audit.destination.db.password" default-value="" mask="true"/>
+            <set key="xasecure.audit.credential.provider.file" value="jceks://file{{credential_file}}"/>
+            <set key="xasecure.audit.destination.solr" value="false"/>
+            <set key="xasecure.audit.destination.solr.urls" value="{{ranger_audit_solr_urls}}"/>
+            <set key="xasecure.audit.destination.solr.zookeepers" value="none"/>
+            <set key="xasecure.audit.destination.solr.batch.filespool.dir" value="/var/log/hive/audit/solr/spool"/>
+            <set key="xasecure.audit.destination.db.jdbc.driver" value="{{jdbc_driver}}"/>
+            <set key="xasecure.audit.destination.db.jdbc.url" value="{{audit_jdbc_url}}"/>
+            <set key="xasecure.audit.provider.summary.enabled" value="false"/>
+          </definition>
+
+          <definition xsi:type="configure" id="hdp_2_3_0_0_hive_server_remove_deprecated_ranger_properties" summary="Removing Deprecated Ranger Hive Plugin Configurations">
+            <type>ranger-hive-plugin-properties</type>
+            <transfer operation="delete" delete-key="SSL_KEYSTORE_FILE_PATH"/>
+            <transfer operation="delete" delete-key="SSL_KEYSTORE_PASSWORD"/>
+            <transfer operation="delete" delete-key="SSL_TRUSTSTORE_FILE_PATH"/>
+            <transfer operation="delete" delete-key="SSL_TRUSTSTORE_PASSWORD"/>
+            <transfer operation="delete" delete-key="POLICY_MGR_URL"/>
+            <transfer operation="delete" delete-key="REPOSITORY_NAME"/>
+            <transfer operation="delete" delete-key="UPDATE_XAPOLICIES_ON_GRANT_REVOKE"/>
+            <transfer operation="delete" delete-key="XAAUDIT.DB.IS_ENABLED"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINATION_DIRECTORY"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.IS_ENABLED"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_ARCHIVE_DIRECTORY"/>
+            <transfer operation="delete" delete-key="XAAUDIT.DB.USER_NAME"/>
+            <transfer operation="delete" delete-key="XAAUDIT.DB.PASSWORD"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_FILE"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_FLUSH_INTERVAL_SECONDS"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_OPEN_RETRY_INTERVAL_SECONDS"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_ROLLOVER_INTERVAL_SECONDS"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_ARCHIVE_MAX_FILE_COUNT"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_DIRECTORY"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_FILE"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_FLUSH_INTERVAL_SECONDS"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_ROLLOVER_INTERVAL_SECONDS"/>
+            <transfer operation="delete" delete-key="SQL_CONNECTOR_JAR" />
+            <transfer operation="delete" delete-key="XAAUDIT.DB.FLAVOUR" />
+            <transfer operation="delete" delete-key="XAAUDIT.DB.DATABASE_NAME" />
+            <transfer operation="delete" delete-key="XAAUDIT.DB.HOSTNAME" />
+          </definition>
+
+          <definition xsi:type="configure" id="hdp_2_3_0_0_hive_server_restore_transport_mode_on_downgrade">
+            <condition type="hive-site" key="hive.server2.transport.mode" value="binary">
+              <type>hive-site</type>
+              <key>hive.server2.thrift.port</key>
+              <value>10000</value>
+            </condition>
+            <condition type="hive-site" key="hive.server2.transport.mode" value="http">
+              <type>hive-site</type>
+              <key>hive.server2.http.port</key>
+              <value>10001</value>
+            </condition>
+          </definition>
+        </changes>
+      </component>
+
+      <component name="WEBHCAT_SERVER">
+        <changes>
+          <definition xsi:type="configure" id="hdp_2_3_0_0_webhcat_server_update_env">
+            <type>webhcat-env</type>
+            <replace key="content" find="export HADOOP_HOME={{hadoop_home}}" replace-with="export HADOOP_HOME=${HADOOP_HOME:-{{hadoop_home}}}" />
+          </definition>
+
+          <definition xsi:type="configure" id="hdp_2_3_0_0_webhcat_server_update_configuration_paths" summary="Updating Configuration Paths">
+            <type>webhcat-site</type>
+            <replace key="templeton.jar" find="/usr/hdp/current/hive-webhcat" replace-with="/usr/hdp/${hdp.version}/hive"/>
+            <replace key="templeton.libjars" find="/usr/hdp/current/zookeeper-client" replace-with="/usr/hdp/${hdp.version}/zookeeper,/usr/hdp/${hdp.version}/hive/lib/hive-common.jar"/>
+            <replace key="templeton.hadoop" find="/usr/hdp/current/hadoop-client" replace-with="/usr/hdp/${hdp.version}/hadoop"/>
+            <replace key="templeton.hcat" find="/usr/hdp/current/hive-client" replace-with="/usr/hdp/${hdp.version}/hive"/>
+            <set key="templeton.hive.extra.files" value="/usr/hdp/${hdp.version}/tez/conf/tez-site.xml,/usr/hdp/${hdp.version}/tez,/usr/hdp/${hdp.version}/tez/lib"/>
+          </definition>
+        </changes>
+      </component>
+    </service>
+
+    <service name="OOZIE">
+      <component name="OOZIE_SERVER">
+        <changes>
+          <definition xsi:type="configure" id="hdp_2_3_0_0_oozie_remove_redundant_configurations">
+            <summary>Updating oozie-site to remove redundant configurations</summary>
+            <type>oozie-site</type>
+            <transfer operation="delete" delete-key="*" preserve-edits="true">
+              <keep-key>oozie.base.url</keep-key>
+              <keep-key>oozie.services.ext</keep-key>
+              <keep-key>oozie.db.schema.name</keep-key>
+              <keep-key>oozie.service.JPAService.jdbc.username</keep-key>
+              <keep-key>oozie.service.JPAService.jdbc.password</keep-key>
+              <keep-key>oozie.service.JPAService.jdbc.driver</keep-key>
+              <keep-key>oozie.service.JPAService.jdbc.url</keep-key>
+              <keep-key>oozie.service.AuthorizationService.security.enabled</keep-key>
+              <keep-key>oozie.authentication.type</keep-key>
+              <keep-key>oozie.authentication.simple.anonymous.allowed</keep-key>
+              <keep-key>oozie.authentication.kerberos.name.rules</keep-key>
+              <keep-key>oozie.service.HadoopAccessorService.hadoop.configurations</keep-key>
+              <keep-key>oozie.service.HadoopAccessorService.kerberos.enabled</keep-key>
+              <keep-key>oozie.service.URIHandlerService.uri.handlers</keep-key>
+
+              <!-- required by Falcon and should be preserved -->
+              <keep-key>oozie.service.ELService.ext.functions.coord-job-submit-instances</keep-key>
+              <keep-key>oozie.service.ELService.ext.functions.coord-action-create-inst</keep-key>
+              <keep-key>oozie.service.ELService.ext.functions.coord-action-create</keep-key>
+              <keep-key>oozie.service.ELService.ext.functions.coord-job-submit-data</keep-key>
+              <keep-key>oozie.service.ELService.ext.functions.coord-action-start</keep-key>
+              <keep-key>oozie.service.ELService.ext.functions.coord-sla-submit</keep-key>
+              <keep-key>oozie.service.ELService.ext.functions.coord-sla-create</keep-key>
+            </transfer>
+            <set key="oozie.credentials.credentialclasses" value="hcat=org.apache.oozie.action.hadoop.HCatCredentials,hive2=org.apache.oozie.action.hadoop.Hive2Credentials" />
+          </definition>
+        </changes>
+      </component>
+    </service>
+
+    <service name="KNOX">
+      <component name="KNOX_GATEWAY">
+        <changes>
+          <definition xsi:type="configure" id="hdp_2_3_0_0_knox_configure_ranger_policy" summary="Configuring Ranger Knox Policy">
+            <type>ranger-knox-policymgr-ssl</type>
+            <transfer operation="copy" from-type="ranger-knox-plugin-properties" from-key="SSL_KEYSTORE_FILE_PATH" to-key="xasecure.policymgr.clientssl.keystore" default-value="/usr/hdp/current/knox-server/conf/ranger-plugin-keystore.jks"/>
+            <transfer operation="copy" from-type="ranger-knox-plugin-properties" from-key="SSL_KEYSTORE_PASSWORD" to-key="xasecure.policymgr.clientssl.keystore.password" default-value="myKeyFilePassword" mask="true"/>
+            <transfer operation="copy" from-type="ranger-knox-plugin-properties" from-key="SSL_TRUSTSTORE_FILE_PATH" to-key="xasecure.policymgr.clientssl.truststore" default-value="/usr/hdp/current/knox-server/conf/ranger-plugin-truststore.jks"/>
+            <transfer operation="copy" from-type="ranger-knox-plugin-properties" from-key="SSL_TRUSTSTORE_PASSWORD" to-key="xasecure.policymgr.clientssl.truststore.password" default-value="changeit" mask="true"/>
+          </definition>
+
+          <definition xsi:type="configure" id="hdp_2_3_0_0_knox_configure_ranger_knox_audit" summary="Configuring Ranger Knox Audit">
+            <type>ranger-knox-audit</type>
+            <transfer operation="copy" from-type="ranger-knox-plugin-properties" from-key="XAAUDIT.DB.IS_ENABLED" to-key="xasecure.audit.destination.db" default-value="true"/>
+            <transfer operation="copy" from-type="ranger-knox-plugin-properties" from-key="XAAUDIT.HDFS.DESTINATION_DIRECTORY" to-key="xasecure.audit.destination.hdfs.dir" default-value="hdfs://NAMENODE_HOSTNAME:8020/ranger/audit"/>
+            <transfer operation="copy" from-type="ranger-knox-plugin-properties" from-key="XAAUDIT.HDFS.IS_ENABLED" to-key="xasecure.audit.destination.hdfs" default-value="true"/>
+            <transfer operation="copy" from-type="ranger-knox-plugin-properties" from-key="XAAUDIT.HDFS.LOCAL_ARCHIVE_DIRECTORY" to-key="xasecure.audit.destination.hdfs.batch.filespool.dir" default-value="/var/log/knox/audit/hdfs/spool"/>
+            <transfer operation="copy" from-type="ranger-knox-plugin-properties" from-key="XAAUDIT.DB.USER_NAME" to-key="xasecure.audit.destination.db.user" default-value=""/>
+            <transfer operation="copy" from-type="ranger-knox-plugin-properties" from-key="XAAUDIT.DB.PASSWORD" to-key="xasecure.audit.destination.db.passwordr" default-value="" mask="true"/>
+            <set key="xasecure.audit.credential.provider.file" value="jceks://file{{credential_file}}"/>
+            <set key="xasecure.audit.destination.solr" value="false"/>
+            <set key="xasecure.audit.destination.solr.urls" value="{{ranger_audit_solr_urls}}"/>
+            <set key="xasecure.audit.destination.solr.zookeepers" value="none"/>
+            <set key="xasecure.audit.destination.solr.batch.filespool.dir" value="/var/log/knox/audit/solr/spool"/>
+            <set key="xasecure.audit.destination.db.jdbc.driver" value="{{jdbc_driver}}"/>
+            <set key="xasecure.audit.destination.db.jdbc.url" value="{{audit_jdbc_url}}"/>
+            <set key="xasecure.audit.provider.summary.enabled" value="false"/>
+          </definition>
+
+          <definition xsi:type="configure" id="hdp_2_3_0_0_knox_remove_deprecated_ranger_properties" summary="Removing Deprecated Ranger Knox Plugin Configurations">
+            <type>ranger-knox-plugin-properties</type>
+            <transfer operation="delete" delete-key="SSL_KEYSTORE_FILE_PATH"/>
+            <transfer operation="delete" delete-key="SSL_KEYSTORE_PASSWORD"/>
+            <transfer operation="delete" delete-key="SSL_TRUSTSTORE_FILE_PATH"/>
+            <transfer operation="delete" delete-key="SSL_TRUSTSTORE_PASSWORD"/>
+            <transfer operation="delete" delete-key="XAAUDIT.DB.IS_ENABLED"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINATION_DIRECTORY"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.IS_ENABLED"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_ARCHIVE_DIRECTORY"/>
+            <transfer operation="delete" delete-key="XAAUDIT.DB.USER_NAME"/>
+            <transfer operation="delete" delete-key="XAAUDIT.DB.PASSWORD"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_FILE"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_FLUSH_INTERVAL_SECONDS"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_OPEN_RETRY_INTERVAL_SECONDS"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_ROLLOVER_INTERVAL_SECONDS"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_ARCHIVE_MAX_FILE_COUNT"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_DIRECTORY"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_FILE"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_FLUSH_INTERVAL_SECONDS"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_ROLLOVER_INTERVAL_SECONDS"/>
+            <transfer operation="delete" delete-key="SQL_CONNECTOR_JAR" />
+            <transfer operation="delete" delete-key="XAAUDIT.DB.FLAVOUR" />
+            <transfer operation="delete" delete-key="XAAUDIT.DB.DATABASE_NAME" />
+            <transfer operation="delete" delete-key="XAAUDIT.DB.HOSTNAME" />
+            <transfer operation="delete" delete-key="REPOSITORY_NAME" />
+            <transfer operation="delete" delete-key="POLICY_MGR_URL" />
+          </definition>
+        </changes>
+      </component>
+    </service>
+
+    <service name="STORM">
+      <component name="NIMBUS">
+        <changes>
+          <definition xsi:type="configure" id="hdp_2_3_0_0_nimbus_convert_nimbus_host_to_seeds" summary="Converting nimbus.host into nimbus.seeds">
+            <type>storm-site</type>
+            <transfer operation="copy" from-key="nimbus.host" to-key="nimbus.seeds" coerce-to="yaml-array"/>
+            <transfer operation="delete" delete-key="nimbus.host"/>
+            <set key="nimbus.monitor.freq.secs" value="120"/>
+            <replace key="nimbus.authorizer" find="com.xasecure.authorization.storm.authorizer.XaSecureStormAuthorizer" replace-with="org.apache.ranger.authorization.storm.authorizer.RangerStormAuthorizer" />
+          </definition>
+
+          <definition xsi:type="configure" id="hdp_2_3_0_0_nimbus_update_env_vars" summary="Updating Storm home and configuration environment variables">
+            <type>storm-env</type>
+            <replace key="content" find="# export STORM_CONF_DIR=&quot;&quot;" replace-with="export STORM_CONF_DIR={{conf_dir}}"/>
+            <replace key="content" find="export STORM_HOME=/usr/hdp/current/storm-client" replace-with="export STORM_HOME={{storm_component_home_dir}}"/>
+          </definition>
+
+          <definition xsi:type="configure" id="hdp_2_3_0_0_nimbus_configure_ranger_policy" summary="Configuring Ranger Storm Policy">
+            <type>ranger-storm-policymgr-ssl</type>
+            <transfer operation="copy" from-type="ranger-storm-plugin-properties" from-key="SSL_KEYSTORE_FILE_PATH" to-key="xasecure.policymgr.clientssl.keystore" default-value="/usr/hdp/current/storm-client/conf/ranger-plugin-keystore.jks"/>
+            <transfer operation="copy" from-type="ranger-storm-plugin-properties" from-key="SSL_KEYSTORE_PASSWORD" to-key="xasecure.policymgr.clientssl.keystore.password" default-value="myKeyFilePassword" mask="true"/>
+            <transfer operation="copy" from-type="ranger-storm-plugin-properties" from-key="SSL_TRUSTSTORE_FILE_PATH" to-key="xasecure.policymgr.clientssl.truststore" default-value="/usr/hdp/current/storm-client/conf/ranger-plugin-truststore.jks"/>
+            <transfer operation="copy" from-type="ranger-storm-plugin-properties" from-key="SSL_TRUSTSTORE_PASSWORD" to-key="xasecure.policymgr.clientssl.truststore.password" default-value="changeit" mask="true"/>
+          </definition>
+
+          <definition xsi:type="configure" id="hdp_2_3_0_0_nimbus_configure_ranger_audit" summary="Configuring Ranger Storm Audit">
+            <type>ranger-storm-audit</type>
+            <transfer operation="copy" from-type="ranger-storm-plugin-properties" from-key="XAAUDIT.DB.IS_ENABLED" to-key="xasecure.audit.destination.db" default-value="true" />
+            <transfer operation="copy" from-type="ranger-storm-plugin-properties" from-key="XAAUDIT.HDFS.DESTINATION_DIRECTORY" to-key="xasecure.audit.destination.hdfs.dir" default-value="hdfs://NAMENODE_HOSTNAME:8020/ranger/audit" />
+            <transfer operation="copy" from-type="ranger-storm-plugin-properties" from-key="XAAUDIT.HDFS.IS_ENABLED" to-key="xasecure.audit.destination.hdfs" default-value="true" />
+            <transfer operation="copy" from-type="ranger-storm-plugin-properties" from-key="XAAUDIT.HDFS.LOCAL_ARCHIVE_DIRECTORY" to-key="xasecure.audit.destination.hdfs.batch.filespool.dir" default-value="/var/log/storm/audit/hdfs/spool" />
+            <transfer operation="copy" from-type="ranger-storm-plugin-properties" from-key="XAAUDIT.DB.USER_NAME" to-key="xasecure.audit.destination.db.user" default-value=""/>
+            <transfer operation="copy" from-type="ranger-storm-plugin-properties" from-key="XAAUDIT.DB.PASSWORD" to-key="xasecure.audit.destination.db.passwordr" default-value="" mask="true"/>
+            <set key="xasecure.audit.credential.provider.file" value="jceks://file{{credential_file}}"/>
+            <set key="xasecure.audit.destination.solr" value="false"/>
+            <set key="xasecure.audit.destination.solr.urls" value="{{ranger_audit_solr_urls}}"/>
+            <set key="xasecure.audit.destination.solr.zookeepers" value="none"/>
+            <set key="xasecure.audit.destination.solr.batch.filespool.dir" value="/var/log/storm/audit/solr/spool"/>
+            <set key="xasecure.audit.destination.db.jdbc.driver" value="{{jdbc_driver}}"/>
+            <set key="xasecure.audit.destination.db.jdbc.url" value="{{audit_jdbc_url}}"/>
+            <set key="xasecure.audit.provider.summary.enabled" value="false"/>
+          </definition>
+
+          <definition xsi:type="configure" id="hdp_2_3_0_0_nimbus_remove_deprecated_ranger_properties" summary="Removing Deprecated Ranger Storm Plugin Configurations">
+            <type>ranger-storm-plugin-properties</type>
+            <transfer operation="delete" delete-key="SSL_KEYSTORE_FILE_PATH"/>
+            <transfer operation="delete" delete-key="SSL_KEYSTORE_PASSWORD"/>
+            <transfer operation="delete" delete-key="SSL_TRUSTSTORE_FILE_PATH"/>
+            <transfer operation="delete" delete-key="SSL_TRUSTSTORE_PASSWORD"/>
+            <transfer operation="delete" delete-key="XAAUDIT.DB.IS_ENABLED"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINATION_DIRECTORY"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.IS_ENABLED"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_ARCHIVE_DIRECTORY"/>
+            <transfer operation="delete" delete-key="XAAUDIT.DB.USER_NAME"/>
+            <transfer operation="delete" delete-key="XAAUDIT.DB.PASSWORD"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_FILE"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_FLUSH_INTERVAL_SECONDS"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_OPEN_RETRY_INTERVAL_SECONDS"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_ROLLOVER_INTERVAL_SECONDS"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_ARCHIVE_MAX_FILE_COUNT"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_DIRECTORY"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_FILE"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_FLUSH_INTERVAL_SECONDS"/>
+            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_ROLLOVER_INTERVAL_SECONDS"/>
+            <transfer operation="delete" delete-key="SQL_CONNECTOR_JAR" />
+            <transfer operation="delete" delete-key="XAAUDIT.DB.FLAVOUR" />
+            <transfer operation="delete" delete-key="XAAUDIT.DB.DATABASE_NAME" />
+            <transfer operation="delete" delete-key="XAAUDIT.DB.HOSTNAME" />
+            <transfer operation="delete" delete-key="REPOSITORY_NAME" />
+            <transfer operation="delete" delete-key="POLICY_MGR_URL" />
+          </definition>
+        </changes>
+      </component>
+    </service>
+  </services>
+
+</upgrade-config-changes>

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/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 acc65a6..7549b68 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,8 +19,22 @@
 
 <upgrade xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <target>2.3.*.*</target>
+  <target-stack>HDP-2.3</target-stack>
+  <type>ROLLING</type>
   <skip-failures>false</skip-failures>
   <skip-service-check-failures>false</skip-service-check-failures>
+  <prerequisite-checks>
+    <check>org.apache.ambari.server.checks.HiveMultipleMetastoreCheck</check>
+    <check>org.apache.ambari.server.checks.MapReduce2JobHistoryStatePreservingCheck</check>
+    <check>org.apache.ambari.server.checks.SecondaryNamenodeDeletedCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesMapReduceDistributedCacheCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesNamenodeHighAvailabilityCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesNamenodeTruncateCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesTezDistributedCacheCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesYarnWorkPreservingCheck</check>
+    <check>org.apache.ambari.server.checks.YarnRMHighAvailabilityCheck</check>
+    <check>org.apache.ambari.server.checks.YarnTimelineServerStatePreservingCheck</check>
+  </prerequisite-checks>
 
   <order>
     <group xsi:type="cluster" name="PRE_CLUSTER" title="Prepare Upgrade">
@@ -35,7 +49,7 @@
       <execute-stage service="HBASE" component="HBASE_MASTER" title="Pre Upgrade HBase">
         <task xsi:type="execute" hosts="master">
           <script>scripts/hbase_upgrade.py</script>
-          <function>snapshot</function>
+          <function>take_snapshot</function>
         </task>
       </execute-stage>
 
@@ -47,7 +61,7 @@
 
       <execute-stage service="OOZIE" component="OOZIE_SERVER" title="Pre Upgrade Oozie">
         <task xsi:type="manual">
-          <message>Before continuing, please backup the Oozie Server database on {{oozie-env/oozie_hostname}}.</message>
+          <message>Before continuing, please backup the Oozie Server database on {{hosts.all}}.</message>
         </task>
       </execute-stage>
 
@@ -356,13 +370,13 @@
     <service name="ZOOKEEPER">
       <component name="ZOOKEEPER_SERVER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="ZOOKEEPER_CLIENT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -370,13 +384,13 @@
     <service name="RANGER">
       <component name="RANGER_ADMIN">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="RANGER_USERSYNC">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -384,7 +398,7 @@
     <service name="RANGER_KMS">
       <component name="RANGER_KMS_SERVER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -392,37 +406,37 @@
     <service name="HDFS">
       <component name="NAMENODE">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="DATANODE">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="NFS_GATEWAY">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="HDFS_CLIENT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="JOURNALNODE">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="ZKFC">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -430,13 +444,13 @@
     <service name="MAPREDUCE2">
       <component name="HISTORYSERVER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="MAPREDUCE2_CLIENT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -444,25 +458,25 @@
     <service name="YARN">
       <component name="APP_TIMELINE_SERVER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="RESOURCEMANAGER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="NODEMANAGER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="YARN_CLIENT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -470,25 +484,25 @@
     <service name="HBASE">
       <component name="HBASE_MASTER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="HBASE_REGIONSERVER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="HBASE_CLIENT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="PHOENIX_QUERY_SERVER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -496,7 +510,7 @@
     <service name="TEZ">
       <component name="TEZ_CLIENT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -504,7 +518,7 @@
     <service name="PIG">
       <component name="PIG">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -512,7 +526,7 @@
     <service name="SQOOP">
       <component name="SQOOP">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -520,7 +534,7 @@
     <service name="MAHOUT">
       <component name="MAHOUT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -528,7 +542,7 @@
     <service name="HIVE">
       <component name="HIVE_METASTORE">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
@@ -539,18 +553,7 @@
             <message>Please note that the HiveServer port will now change to 10010 if hive is using a binary transfer mode or 10011 if hive is using an http transport mode. You can use "netstat -anp | grep 1001[01]" to determine if the port is available on each of following HiveServer host(s): {{hosts.all}}. If the port is not available, the process using it must be terminated.</message>
           </task>
 
-          <task xsi:type="configure">
-            <condition type="hive-site" key="hive.server2.transport.mode" value="binary">
-              <type>hive-site</type>
-              <key>hive.server2.thrift.port</key>
-              <value>10010</value>
-            </condition>
-            <condition type="hive-site" key="hive.server2.transport.mode" value="http">
-              <type>hive-site</type>
-              <key>hive.server2.http.port</key>
-              <value>10011</value>
-            </condition>
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_hive_server_set_transport_modes"/>
         </pre-upgrade>
 
         <pre-downgrade>
@@ -559,40 +562,29 @@
             <message>Please note that the HiveServer port will now change to 10000 if hive is using a binary transfer mode or 10001 if hive is using an http transport mode. You can use "netstat -anp | grep 1000[01]" to determine if the port is available on each of following HiveServer host(s): {{hosts.all}}. If the port is not available, the process using it must be terminated.</message>
           </task>
 
-          <task xsi:type="configure">
-            <condition type="hive-site" key="hive.server2.transport.mode" value="binary">
-              <type>hive-site</type>
-              <key>hive.server2.thrift.port</key>
-              <value>10000</value>
-            </condition>
-            <condition type="hive-site" key="hive.server2.transport.mode" value="http">
-              <type>hive-site</type>
-              <key>hive.server2.http.port</key>
-              <value>10001</value>
-            </condition>
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_hive_server_restore_transport_mode_on_downgrade" />
         </pre-downgrade>
 
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="WEBHCAT_SERVER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="HIVE_CLIENT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="HCAT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -600,7 +592,7 @@
     <service name="SLIDER">
       <component name="SLIDER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -608,12 +600,12 @@
     <service name="SPARK">
       <component name="SPARK_JOBHISTORYSERVER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
       <component name="SPARK_CLIENT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -645,13 +637,13 @@
         </pre-downgrade>
 
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="OOZIE_CLIENT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -659,12 +651,12 @@
     <service name="FALCON">
       <component name="FALCON_SERVER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
       <component name="FALCON_CLIENT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -672,7 +664,7 @@
     <service name="KAFKA">
       <component name="KAFKA_BROKER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -680,7 +672,7 @@
     <service name="KNOX">
       <component name="KNOX_GATEWAY">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -688,27 +680,27 @@
     <service name="STORM">
       <component name="NIMBUS">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
       <component name="STORM_REST_API">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
       <component name="SUPERVISOR">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
       <component name="STORM_UI_SERVER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
       <component name="DRPC_SERVER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -716,7 +708,7 @@
     <service name="FLUME">
       <component name="FLUME_HANDLER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -724,32 +716,32 @@
     <service name="ACCUMULO">
       <component name="ACCUMULO_MASTER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
       <component name="ACCUMULO_MONITOR">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
       <component name="ACCUMULO_GC">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
       <component name="ACCUMULO_TRACER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
       <component name="ACCUMULO_TSERVER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
       <component name="ACCUMULO_CLIENT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/test/java/org/apache/ambari/server/checks/ConfigurationMergeCheckTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/checks/ConfigurationMergeCheckTest.java b/ambari-server/src/test/java/org/apache/ambari/server/checks/ConfigurationMergeCheckTest.java
index 44bf164..c1d03dc 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/checks/ConfigurationMergeCheckTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/checks/ConfigurationMergeCheckTest.java
@@ -95,6 +95,8 @@ public class ConfigurationMergeCheckTest {
     replay(config);
     cmc.config = config;
 
+    // TODO AMBARI-12698, readd later.
+    /*
     Assert.assertFalse(cmc.isApplicable(request));
 
     final RepositoryVersionDAO repositoryVersionDAO = EasyMock.createMock(RepositoryVersionDAO.class);
@@ -122,10 +124,14 @@ public class ConfigurationMergeCheckTest {
     Assert.assertFalse(cmc.isApplicable(request));
 
     request.setRepositoryVersion("1.1");
+    */
+    
     Assert.assertTrue(cmc.isApplicable(request));
 
+    /*
     request.setRepositoryVersion("1.2");
     Assert.assertFalse(cmc.isApplicable(request));
+    */
   }
 
   @Test

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/test/java/org/apache/ambari/server/checks/HostsMasterMaintenanceCheckTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/checks/HostsMasterMaintenanceCheckTest.java b/ambari-server/src/test/java/org/apache/ambari/server/checks/HostsMasterMaintenanceCheckTest.java
index 961c28d..1c48f06 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/checks/HostsMasterMaintenanceCheckTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/checks/HostsMasterMaintenanceCheckTest.java
@@ -34,6 +34,7 @@ import org.apache.ambari.server.state.stack.PrerequisiteCheck;
 import org.apache.ambari.server.state.stack.UpgradePack;
 import org.apache.ambari.server.state.stack.UpgradePack.ProcessingComponent;
 import org.apache.ambari.server.state.stack.upgrade.RepositoryVersionHelper;
+import org.apache.ambari.server.state.stack.upgrade.UpgradeType;
 import org.junit.Assert;
 import org.junit.Test;
 import org.mockito.Mockito;
@@ -60,8 +61,8 @@ public class HostsMasterMaintenanceCheckTest {
     Mockito.when(config.getRollingUpgradeMaxStack()).thenReturn("");
     hmmc.config = config;
     Assert.assertTrue(hmmc.isApplicable(request));
-
     request.setRepositoryVersion(null);
+    
     HostsMasterMaintenanceCheck hmmc2 = new HostsMasterMaintenanceCheck();
     hmmc2.config = config;
     Assert.assertFalse(hmmc2.isApplicable(request));
@@ -69,6 +70,7 @@ public class HostsMasterMaintenanceCheckTest {
 
   @Test
   public void testPerform() throws Exception {
+    final String upgradePackName = "upgrade_pack";
     final HostsMasterMaintenanceCheck hostsMasterMaintenanceCheck = new HostsMasterMaintenanceCheck();
     hostsMasterMaintenanceCheck.clustersProvider = new Provider<Clusters>() {
 
@@ -100,13 +102,13 @@ public class HostsMasterMaintenanceCheckTest {
     Mockito.when(cluster.getClusterId()).thenReturn(1L);
     Mockito.when(clusters.getCluster("cluster")).thenReturn(cluster);
     Mockito.when(cluster.getDesiredStackVersion()).thenReturn(new StackId("HDP", "1.0"));
-    Mockito.when(repositoryVersionHelper.getUpgradePackageName(Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenReturn(null);
+    Mockito.when(repositoryVersionHelper.getUpgradePackageName(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), (UpgradeType) Mockito.anyObject())).thenReturn(null);
 
     PrerequisiteCheck check = new PrerequisiteCheck(null, null);
     hostsMasterMaintenanceCheck.perform(check, new PrereqCheckRequest("cluster"));
     Assert.assertEquals(PrereqCheckStatus.FAIL, check.getStatus());
 
-    Mockito.when(repositoryVersionHelper.getUpgradePackageName(Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenReturn("upgrade pack");
+    Mockito.when(repositoryVersionHelper.getUpgradePackageName(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), (UpgradeType) Mockito.anyObject())).thenReturn(upgradePackName);
     Mockito.when(ambariMetaInfo.getUpgradePacks(Mockito.anyString(), Mockito.anyString())).thenReturn(new HashMap<String, UpgradePack>());
 
     check = new PrerequisiteCheck(null, null);
@@ -115,7 +117,8 @@ public class HostsMasterMaintenanceCheckTest {
 
     final Map<String, UpgradePack> upgradePacks = new HashMap<String, UpgradePack>();
     final UpgradePack upgradePack = Mockito.mock(UpgradePack.class);
-    upgradePacks.put("upgrade pack", upgradePack);
+    Mockito.when(upgradePack.getName()).thenReturn(upgradePackName);
+    upgradePacks.put(upgradePack.getName(), upgradePack);
     Mockito.when(ambariMetaInfo.getUpgradePacks(Mockito.anyString(), Mockito.anyString())).thenReturn(upgradePacks);
     Mockito.when(upgradePack.getTasks()).thenReturn(new HashMap<String, Map<String,ProcessingComponent>>());
     Mockito.when(cluster.getServices()).thenReturn(new HashMap<String, Service>());

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/test/java/org/apache/ambari/server/checks/SecondaryNamenodeDeletedCheckTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/checks/SecondaryNamenodeDeletedCheckTest.java b/ambari-server/src/test/java/org/apache/ambari/server/checks/SecondaryNamenodeDeletedCheckTest.java
index 5d32f4d..80740b3 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/checks/SecondaryNamenodeDeletedCheckTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/checks/SecondaryNamenodeDeletedCheckTest.java
@@ -18,6 +18,8 @@
 package org.apache.ambari.server.checks;
 
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
 
 import org.apache.ambari.server.ServiceNotFoundException;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
@@ -74,25 +76,25 @@ public class SecondaryNamenodeDeletedCheckTest {
   @Test
   public void testIsApplicable() throws Exception {
     final Cluster cluster = Mockito.mock(Cluster.class);
+    final Map<String, Service> services = new HashMap<>();
+    final Service service = Mockito.mock(Service.class);
+
+    services.put("HDFS", service);
+
     Mockito.when(cluster.getClusterId()).thenReturn(1L);
+    Mockito.when(cluster.getServices()).thenReturn(services);
     Mockito.when(clusters.getCluster("cluster")).thenReturn(cluster);
 
-    final Service service = Mockito.mock(Service.class);
-    Mockito.when(cluster.getService("HDFS")).thenReturn(service);
     Assert.assertTrue(secondaryNamenodeDeletedCheck.isApplicable(new PrereqCheckRequest("cluster")));
 
     PrereqCheckRequest req = new PrereqCheckRequest("cluster");
     req.addResult(CheckDescription.SERVICES_NAMENODE_HA, PrereqCheckStatus.FAIL);
-    Mockito.when(cluster.getService("HDFS")).thenReturn(service);
     Assert.assertFalse(secondaryNamenodeDeletedCheck.isApplicable(req));
 
     req.addResult(CheckDescription.SERVICES_NAMENODE_HA, PrereqCheckStatus.PASS);
-    Mockito.when(cluster.getService("HDFS")).thenReturn(service);
     Assert.assertTrue(secondaryNamenodeDeletedCheck.isApplicable(req));
 
-
-
-    Mockito.when(cluster.getService("HDFS")).thenThrow(new ServiceNotFoundException("no", "service"));
+    services.remove("HDFS");
     Assert.assertFalse(secondaryNamenodeDeletedCheck.isApplicable(new PrereqCheckRequest("cluster")));
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/test/java/org/apache/ambari/server/checks/ServicesMapReduceDistributedCacheCheckTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/checks/ServicesMapReduceDistributedCacheCheckTest.java b/ambari-server/src/test/java/org/apache/ambari/server/checks/ServicesMapReduceDistributedCacheCheckTest.java
index fea82f3..a7c6d58 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/checks/ServicesMapReduceDistributedCacheCheckTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/checks/ServicesMapReduceDistributedCacheCheckTest.java
@@ -64,24 +64,26 @@ public class ServicesMapReduceDistributedCacheCheckTest {
   @Test
   public void testIsApplicable() throws Exception {
     final Cluster cluster = Mockito.mock(Cluster.class);
-    Mockito.when(cluster.getClusterId()).thenReturn(1L);
+    final Map<String, Service> services = new HashMap<>();
+    final Service service = Mockito.mock(Service.class);
+
+    services.put("YARN", service);
+
+    Mockito.when(cluster.getServices()).thenReturn(services);
     Mockito.when(clusters.getCluster("cluster")).thenReturn(cluster);
+    Mockito.when(cluster.getClusterId()).thenReturn(1L);
 
-    final Service service = Mockito.mock(Service.class);
-    Mockito.when(cluster.getService("YARN")).thenReturn(service);
     Assert.assertTrue(servicesMapReduceDistributedCacheCheck.isApplicable(new PrereqCheckRequest("cluster")));
 
     PrereqCheckRequest req = new PrereqCheckRequest("cluster");
     req.addResult(CheckDescription.SERVICES_NAMENODE_HA, PrereqCheckStatus.FAIL);
-    Mockito.when(cluster.getService("YARN")).thenReturn(service);
     Assert.assertFalse(servicesMapReduceDistributedCacheCheck.isApplicable(req));
 
     req.addResult(CheckDescription.SERVICES_NAMENODE_HA, PrereqCheckStatus.PASS);
-    Mockito.when(cluster.getService("YARN")).thenReturn(service);
     Assert.assertTrue(servicesMapReduceDistributedCacheCheck.isApplicable(req));
 
 
-    Mockito.when(cluster.getService("YARN")).thenThrow(new ServiceNotFoundException("no", "service"));
+    services.remove("YARN");
     Assert.assertFalse(servicesMapReduceDistributedCacheCheck.isApplicable(new PrereqCheckRequest("cluster")));
   }
 


[5/9] ambari git commit: AMBARI-13392. Stop-and-Start Upgrade: Merge branch branch-dev-stop-all-upgrade to branch-2.1 for feature Stop-the-World Upgrade, aka Express Upgrade (alejandro, dlysnichenko, Dmytro Grinenko)

Posted by al...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/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 18c7928..c4b7c44 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,9 +20,22 @@
 <upgrade xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <target>2.3.*.*</target>
   <target-stack>HDP-2.3</target-stack>
+  <type>ROLLING</type>
   <skip-failures>false</skip-failures>
   <skip-service-check-failures>false</skip-service-check-failures>
 
+  <prerequisite-checks>
+    <check>org.apache.ambari.server.checks.HiveMultipleMetastoreCheck</check>
+    <check>org.apache.ambari.server.checks.MapReduce2JobHistoryStatePreservingCheck</check>
+    <check>org.apache.ambari.server.checks.SecondaryNamenodeDeletedCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesMapReduceDistributedCacheCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesNamenodeHighAvailabilityCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesNamenodeTruncateCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesTezDistributedCacheCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesYarnWorkPreservingCheck</check>
+    <check>org.apache.ambari.server.checks.YarnRMHighAvailabilityCheck</check>
+    <check>org.apache.ambari.server.checks.YarnTimelineServerStatePreservingCheck</check>
+  </prerequisite-checks>
   <order>
     <group xsi:type="cluster" name="PRE_CLUSTER" title="Prepare Upgrade">
       <direction>UPGRADE</direction>
@@ -37,7 +50,7 @@
       <execute-stage service="HBASE" component="HBASE_MASTER" title="Pre Upgrade HBase">
         <task xsi:type="execute" hosts="master">
           <script>scripts/hbase_upgrade.py</script>
-          <function>snapshot</function>
+          <function>take_snapshot</function>
         </task>
       </execute-stage>
 
@@ -49,7 +62,7 @@
 
       <execute-stage service="OOZIE" component="OOZIE_SERVER" title="Pre Upgrade Oozie">
         <task xsi:type="manual">
-          <message>Before continuing, please backup the Oozie Server database on {{oozie-env/oozie_hostname}}.</message>
+          <message>Before continuing, please backup the Oozie Server database on {{hosts.all}}.</message>
         </task>
       </execute-stage>
 
@@ -357,13 +370,13 @@
     <service name="ZOOKEEPER">
       <component name="ZOOKEEPER_SERVER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="ZOOKEEPER_CLIENT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -372,118 +385,28 @@
       <component name="RANGER_ADMIN">
         <pre-downgrade /> <!--  no-op to prevent config changes on downgrade -->
         <pre-upgrade>
-          <task xsi:type="configure">
-            <type>ranger-env</type>
-            <set key="xml_configurations_supported" value="true" />
-          </task>
-          <task xsi:type="configure" summary="Updating Ranger Admin">
-            <type>ranger-admin-site</type>
-            <transfer operation="copy" from-type="ranger-site" from-key="HTTPS_CLIENT_AUTH" to-key="ranger.service.https.attrib.clientAuth" default-value="" />
-            <transfer operation="copy" from-type="ranger-site" from-key="HTTPS_KEYSTORE_FILE" to-key="ranger.https.attrib.keystore.file" default-value="" />
-            <transfer operation="copy" from-type="ranger-site" from-key="HTTPS_KEYSTORE_PASS" to-key="ranger.service.https.attrib.keystore.pass" default-value="" mask="true" />
-            <transfer operation="copy" from-type="ranger-site" from-key="HTTPS_KEY_ALIAS" to-key="ranger.service.https.attrib.keystore.keyalias" default-value="" />
-            <transfer operation="copy" from-type="ranger-site" from-key="HTTPS_SERVICE_PORT" to-key="ranger.service.https.port" default-value="" />
-            <transfer operation="copy" from-type="ranger-site" from-key="HTTP_ENABLED" to-key="ranger.service.http.enabled" default-value="" />
-            <transfer operation="copy" from-type="ranger-site" from-key="HTTP_SERVICE_PORT" to-key="ranger.service.http.port" default-value="" />
-
-            <transfer operation="copy" from-type="admin-properties" from-key="authServiceHostName" to-key="ranger.unixauth.service.hostname" default-value="" />
-            <transfer operation="copy" from-type="admin-properties" from-key="authServicePort" to-key="ranger.unixauth.service.port" default-value="" />
-            <transfer operation="copy" from-type="admin-properties" from-key="authentication_method" to-key="ranger.authentication.method" default-value="" />
-            <transfer operation="copy" from-type="admin-properties" from-key="remoteLoginEnabled" to-key="ranger.unixauth.remote.login.enabled" default-value="" />
-            <transfer operation="copy" from-type="admin-properties" from-key="xa_ldap_url" to-key="ranger.ldap.url" default-value="" />
-            <transfer operation="copy" from-type="admin-properties" from-key="xa_ldap_userDNpattern" to-key="ranger.ldap.user.dnpattern" default-value="" />
-            <transfer operation="copy" from-type="admin-properties" from-key="xa_ldap_groupSearchBase" to-key="ranger.ldap.group.searchbase" default-value="" />
-            <transfer operation="copy" from-type="admin-properties" from-key="xa_ldap_groupSearchFilter" to-key="ranger.ldap.group.searchfilter" default-value="" />
-            <transfer operation="copy" from-type="admin-properties" from-key="xa_ldap_groupRoleAttribute" to-key="ranger.ldap.group.roleattribute" default-value="" />
-            <transfer operation="copy" from-type="admin-properties" from-key="xa_ldap_ad_domain" to-key="ranger.ldap.ad.domain" default-value="" />
-            <transfer operation="copy" from-type="admin-properties" from-key="xa_ldap_ad_url" to-key="ranger.ldap.ad.url" default-value="" />
-            <transfer operation="copy" from-type="admin-properties" from-key="db_user" to-key="ranger.jpa.jdbc.user" default-value="" />
-            <transfer operation="copy" from-type="admin-properties" from-key="db_password" to-key="ranger.jpa.jdbc.password" default-value="" mask="true" />
-            <transfer operation="copy" from-type="admin-properties" from-key="audit_db_user" to-key="ranger.jpa.audit.jdbc.user" default-value="" />
-            <transfer operation="copy" from-type="admin-properties" from-key="audit_db_password" to-key="ranger.jpa.audit.jdbc.password" default-value="" mask="true" />
-
-            <set key="ranger.externalurl" value="{{ranger_external_url}}" />
-          </task>
-          
+          <task xsi:type="configure" id="hdp_2_3_0_0_update_ranger_env"/>
+          <task xsi:type="configure" id="hdp_2_3_0_0_update_ranger_admin"/>
+
           <task xsi:type="server_action" summary="Calculating Ranger Properties" class="org.apache.ambari.server.serveraction.upgrades.RangerConfigCalculation" />
           
-          <task xsi:type="configure" summary="Updating Ranger Usersync">
-            <type>ranger-ugsync-site</type>
-            <transfer operation="copy" from-type="usersync-properties" from-key="CRED_KEYSTORE_FILENAME" to-key="ranger.usersync.credstore.filename" default-value="/etc/ranger/usersync/ugsync.jceks" />
-            <transfer operation="copy" from-type="usersync-properties" from-key="MIN_UNIX_USER_ID_TO_SYNC" to-key="ranger.usersync.unix.minUserId" default-value="" />
-            <transfer operation="copy" from-type="usersync-properties" from-key="SYNC_INTERVAL" to-key="ranger.usersync.sleeptimeinmillisbetweensynccycle" default-value="60000" />
-            <transfer operation="copy" from-type="usersync-properties" from-key="SYNC_LDAP_BIND_DN" to-key="ranger.usersync.ldap.binddn" default-value="" />
-            <transfer operation="copy" from-type="usersync-properties" from-key="SYNC_LDAP_BIND_PASSWORD" to-key="ranger.usersync.ldap.ldapbindpassword" default-value="" mask="true" />
-            <transfer operation="copy" from-type="usersync-properties" from-key="SYNC_LDAP_GROUPNAME_CASE_CONVERSION" to-key="ranger.usersync.ldap.groupname.caseconversion" default-value="" />
-            <transfer operation="copy" from-type="usersync-properties" from-key="SYNC_LDAP_URL" to-key="ranger.usersync.ldap.url" default-value="" />
-            <transfer operation="copy" from-type="usersync-properties" from-key="SYNC_LDAP_USERNAME_CASE_CONVERSION" to-key="ranger.usersync.ldap.username.caseconversion" default-value="" />
-            <transfer operation="copy" from-type="usersync-properties" from-key="SYNC_LDAP_USER_GROUP_NAME_ATTRIBUTE" to-key="ranger.usersync.ldap.user.groupnameattribute" default-value="" />
-            <transfer operation="copy" from-type="usersync-properties" from-key="SYNC_LDAP_USER_NAME_ATTRIBUTE" to-key="ranger.usersync.ldap.user.nameattribute" default-value="" />
-            <transfer operation="copy" from-type="usersync-properties" from-key="SYNC_LDAP_USER_OBJECT_CLASS" to-key="ranger.usersync.ldap.user.objectclass" default-value="" />
-            <transfer operation="copy" from-type="usersync-properties" from-key="SYNC_LDAP_USER_SEARCH_BASE" to-key="ranger.usersync.ldap.user.searchbase" default-value="" />
-            <transfer operation="copy" from-type="usersync-properties" from-key="SYNC_LDAP_USER_SEARCH_FILTER" to-key="ranger.usersync.ldap.user.searchfilter" default-value="" />
-            <transfer operation="copy" from-type="usersync-properties" from-key="SYNC_LDAP_USER_SEARCH_SCOPE" to-key="ranger.usersync.ldap.user.searchscope" default-value="" />
-            <transfer operation="copy" from-type="usersync-properties" from-key="logdir" to-key="ranger.usersync.logdir" default-value="" />
-            <transfer operation="copy" from-type="usersync-properties" from-key="SYNC_SOURCE" to-key="ranger.usersync.sync.source" default-value="unix" />
-            <transfer operation="copy" from-type="usersync-properties" from-key="POLICY_MGR_URL" to-key="ranger.usersync.policymanager.baseURL" default-value="{{ranger_external_url}}" />
-            <set key="ranger.usersync.source.impl.class" value="" />
-            <set key="ranger.usersync.ldap.searchBase" value="" />
-            <set key="ranger.usersync.group.memberattributename" value="" />
-            <set key="ranger.usersync.group.nameattribute" value="" />
-            <set key="ranger.usersync.group.objectclass" value="" />
-            <set key="ranger.usersync.group.searchbase" value="" />
-            <set key="ranger.usersync.group.searchenabled" value="" />
-            <set key="ranger.usersync.group.searchfilter" value="" />
-            <set key="ranger.usersync.group.searchscope" value="" />
-            <set key="ranger.usersync.group.usermapsyncenabled" value="" />
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_update_ranger_usersync"/>
             
-          <task xsi:type="configure">
-            <type>ranger-site</type>
-            <transfer operation="delete" delete-key="HTTPS_CLIENT_AUTH" />
-            <transfer operation="delete" delete-key="HTTPS_KEYSTORE_FILE" />
-            <transfer operation="delete" delete-key="HTTPS_KEYSTORE_PASS" />
-            <transfer operation="delete" delete-key="HTTPS_KEY_ALIAS" />
-            <transfer operation="delete" delete-key="HTTPS_SERVICE_PORT" />
-            <transfer operation="delete" delete-key="HTTP_ENABLED" />
-            <transfer operation="delete" delete-key="HTTP_SERVICE_PORT" />
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_update_ranger_site"/>
 
-          <task xsi:type="configure">
-            <type>usersync-properties</type>
-            <transfer operation="delete" delete-key="CRED_KEYSTORE_FILENAME" />
-            <transfer operation="delete" delete-key="MIN_UNIX_USER_ID_TO_SYNC" />
-            <transfer operation="delete" delete-key="SYNC_INTERVAL" />
-            <transfer operation="delete" delete-key="SYNC_LDAP_BIND_DN" />
-            <transfer operation="delete" delete-key="SYNC_LDAP_BIND_PASSWORD" />
-            <transfer operation="delete" delete-key="SYNC_LDAP_GROUPNAME_CASE_CONVERSION" />
-            <transfer operation="delete" delete-key="SYNC_LDAP_URL" />
-            <transfer operation="delete" delete-key="SYNC_LDAP_USERNAME_CASE_CONVERSION" />
-            <transfer operation="delete" delete-key="SYNC_LDAP_USER_GROUP_NAME_ATTRIBUTE" />
-            <transfer operation="delete" delete-key="SYNC_LDAP_USER_NAME_ATTRIBUTE" />
-            <transfer operation="delete" delete-key="SYNC_LDAP_USER_OBJECT_CLASS" />
-            <transfer operation="delete" delete-key="SYNC_LDAP_USER_SEARCH_BASE" />
-            <transfer operation="delete" delete-key="SYNC_LDAP_USER_SEARCH_FILTER" />
-            <transfer operation="delete" delete-key="SYNC_LDAP_USER_SEARCH_SCOPE" />
-            <transfer operation="delete" delete-key="logdir" />
-            <transfer operation="delete" delete-key="SYNC_SOURCE" />
-            <transfer operation="delete" delete-key="POLICY_MGR_URL" />
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_update_ranger_usersync_properties"/>
 
-          <task xsi:type="configure">
-            <type>ranger-env</type>
-            <transfer operation="delete" delete-key="oracle_home" />
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_update_ranger_delete_oracle_home"/>
         </pre-upgrade>
       
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="RANGER_USERSYNC">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -493,111 +416,46 @@
         <pre-downgrade /> <!--  no-op to prevent config changes on downgrade -->
         <pre-upgrade>
 
-          <task xsi:type="configure" summary="Modify hadoop-env.sh">
-            <type>hadoop-env</type>
-            <replace key="content" find="# Add libraries required by nodemanager" replace-with="" />
-            <replace key="content" find="MAPREDUCE_LIBS={{mapreduce_libs_path}}" replace-with="" />
-            <replace key="content" find=":${MAPREDUCE_LIBS}" replace-with="" />
-            <replace key="content" find=":/usr/hdp/current/tez-client/*:/usr/hdp/current/tez-client/lib/*:/etc/tez/conf/" replace-with="" />
-            <replace key="content" find=":/usr/hdp/current/tez-client/*:/usr/hdp/current/tez-client/lib/*:/usr/hdp/current/tez-client/conf/" replace-with="" />
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_modify_hadoop_env"/>
 
-          <task xsi:type="configure">
-            <condition type="ranger-hdfs-plugin-properties" key="ranger-hdfs-plugin-enabled" value="Yes">
-              <type>hdfs-site</type>
-              <key>dfs.namenode.inode.attributes.provider.class</key>
-              <value>org.apache.ranger.authorization.hadoop.RangerHdfsAuthorizer</value>
-            </condition>
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_hdfs_adjust_ranger_plugin"/>
 
-          <task xsi:type="configure" summary="Transitioning Ranger HDFS Policy">
-            <type>ranger-hdfs-policymgr-ssl</type>
-            <transfer operation="copy" from-type="ranger-hdfs-plugin-properties" from-key="SSL_KEYSTORE_FILE_PATH" to-key="xasecure.policymgr.clientssl.keystore" default-value="/usr/hdp/current/hadoop-client/conf/ranger-plugin-keystore.jks" />
-            <transfer operation="copy" from-type="ranger-hdfs-plugin-properties" from-key="SSL_KEYSTORE_PASSWORD" to-key="xasecure.policymgr.clientssl.keystore.password" mask="true" default-value="myKeyFilePassword" />
-            <transfer operation="copy" from-type="ranger-hdfs-plugin-properties" from-key="SSL_TRUSTSTORE_FILE_PATH" to-key="xasecure.policymgr.clientssl.truststore" default-value="/usr/hdp/current/hadoop-client/conf/ranger-plugin-truststore.jks" />
-            <transfer operation="copy" from-type="ranger-hdfs-plugin-properties" from-key="SSL_TRUSTSTORE_PASSWORD" to-key="xasecure.policymgr.clientssl.truststore.password" mask="true" default-value="changeit" />
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_hdfs_transition_ranger_hdfs_policy"/>
 
-          <task xsi:type="configure" summary="Transitioning Ranger HDFS Audit">
-            <type>ranger-hdfs-audit</type>
-            <transfer operation="copy" from-type="ranger-hdfs-plugin-properties" from-key="XAAUDIT.DB.IS_ENABLED" to-key="xasecure.audit.destination.db" default-value="false"/>
-            <transfer operation="copy" from-type="ranger-hdfs-plugin-properties" from-key="XAAUDIT.HDFS.DESTINATION_DIRECTORY" to-key="xasecure.audit.destination.hdfs.dir" default-value="hdfs://NAMENODE_HOSTNAME:8020/ranger/audit" />
-            <transfer operation="copy" from-type="ranger-hdfs-plugin-properties" from-key="XAAUDIT.HDFS.IS_ENABLED" to-key="xasecure.audit.destination.hdfs" default-value="true" />
-            <transfer operation="copy" from-type="ranger-hdfs-plugin-properties" from-key="XAAUDIT.HDFS.LOCAL_ARCHIVE_DIRECTORY" to-key="xasecure.audit.destination.hdfs.batch.filespool.dir" default-value="/var/log/hadoop/hdfs/audit/hdfs/spool" />
-            <transfer operation="copy" from-type="ranger-hdfs-plugin-properties" from-key="XAAUDIT.DB.USER_NAME" to-key="xasecure.audit.destination.db.user" default-value="" />
-            <transfer operation="copy" from-type="ranger-hdfs-plugin-properties" from-key="XAAUDIT.DB.PASSWORD" to-key="xasecure.audit.destination.db.password" mask="true" default-value="" />
-            <set key="xasecure.audit.credential.provider.file" value="jceks://file{{credential_file}}"/>
-            <set key="xasecure.audit.destination.solr" value="false" />
-            <set key="xasecure.audit.destination.solr.urls" value="{{ranger_audit_solr_urls}}" />
-            <set key="xasecure.audit.destination.solr.zookeepers" value="none" />
-            <set key="xasecure.audit.destination.solr.batch.filespool.dir" value="/var/log/hadoop/hdfs/audit/solr/spool" />
-            <set key="xasecure.audit.destination.db.jdbc.driver" value="{{jdbc_driver}}" />
-            <set key="xasecure.audit.destination.db.jdbc.url" value="{{audit_jdbc_url}}" />
-            <set key="xasecure.audit.provider.summary.enabled" value="false" />
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_hdfs_transition_ranger_hdfs_audit"/>
           
-          <task xsi:type="configure" summary="Transitioning Ranger HDFS Security">
-            <type>ranger-hdfs-security</type>
-            <transfer operation="copy" from-type="ranger-hdfs-plugin-properties" from-key="REPOSITORY_NAME" to-key="ranger.plugin.hdfs.service.name" default-value="{{repo_name}}" />
-            <transfer operation="copy" from-type="ranger-hdfs-plugin-properties" from-key="POLICY_MGR_URL" to-key="ranger.plugin.hdfs.policy.rest.url" default-value="{{policymgr_mgr_url}}" />
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_hdfs_transition_ranger_hdfs_security"/>
           
-          <task xsi:type="configure">
-            <type>ranger-hdfs-plugin-properties</type>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_FILE" />
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_FLUSH_INTERVAL_SECONDS" />
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_OPEN_RETRY_INTERVAL_SECONDS" />
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_ROLLOVER_INTERVAL_SECONDS" />
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_ARCHIVE_MAX_FILE_COUNT" />
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_DIRECTORY" />
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_FILE" />
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_FLUSH_INTERVAL_SECONDS" />
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_ROLLOVER_INTERVAL_SECONDS" />
-            <transfer operation="delete" delete-key="SQL_CONNECTOR_JAR" />
-            <transfer operation="delete" delete-key="SSL_KEYSTORE_FILE_PATH" />
-            <transfer operation="delete" delete-key="SSL_KEYSTORE_PASSWORD" />
-            <transfer operation="delete" delete-key="SSL_TRUSTSTORE_FILE_PATH" />
-            <transfer operation="delete" delete-key="SSL_TRUSTSTORE_PASSWORD" />
-            <transfer operation="delete" delete-key="XAAUDIT.DB.IS_ENABLED" />
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINATION_DIRECTORY" />
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.IS_ENABLED" />
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_ARCHIVE_DIRECTORY" />
-            <transfer operation="delete" delete-key="XAAUDIT.DB.USER_NAME" />
-            <transfer operation="delete" delete-key="XAAUDIT.DB.PASSWORD" />
-            <transfer operation="delete" delete-key="REPOSITORY_NAME" />
-            <transfer operation="delete" delete-key="POLICY_MGR_URL" />
-            <transfer operation="delete" delete-key="XAAUDIT.DB.FLAVOUR" />
-            <transfer operation="delete" delete-key="XAAUDIT.DB.DATABASE_NAME" />
-            <transfer operation="delete" delete-key="XAAUDIT.DB.HOSTNAME" />
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_hdfs_ranger_hdfs_delete_old_properties"/>
+
         </pre-upgrade>
 
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="DATANODE">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="HDFS_CLIENT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="JOURNALNODE">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="ZKFC">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -606,22 +464,17 @@
       <component name="HISTORYSERVER">
         <pre-downgrade /> <!--  no-op to prevent config changes on downgrade -->
         <pre-upgrade>
-          <task xsi:type="configure">
-            <type>mapred-site</type>
-            <transfer operation="move" from-key="mapreduce.job.speculative.speculativecap" to-key="mapreduce.job.speculative.speculative-cap-running-tasks" default-value="0.1"/>
-            <transfer operation="delete" delete-key="mapreduce.task.tmp.dir" />
-            <set key="mapreduce.fileoutputcommitter.algorithm.version" value="1"/>
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_mapreduce2_adjust_history_server" />
         </pre-upgrade>
 
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="MAPREDUCE2_CLIENT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -630,57 +483,40 @@
       <component name="APP_TIMELINE_SERVER">
         <pre-downgrade /> <!--  no-op to prevent config changes on downgrade -->
         <pre-upgrade>
-          <task xsi:type="configure">
-            <type>yarn-site</type>
-            <set key="yarn.timeline-service.recovery.enabled" value="true"/>
-            <set key="yarn.timeline-service.state-store-class" value="org.apache.hadoop.yarn.server.timeline.recovery.LeveldbTimelineStateStore"/>
-            <transfer operation="copy" from-key="yarn.timeline-service.leveldb-timeline-store.path" to-key="yarn.timeline-service.leveldb-state-store.path" default-value="/hadoop/yarn/timeline"/>
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_yarn_ats_enable_recovery"/>
         </pre-upgrade>
 
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="RESOURCEMANAGER">
         <pre-downgrade /> <!--  no-op to prevent config changes on downgrade -->
         <pre-upgrade>
-          <task xsi:type="configure">
-            <type>yarn-site</type>
-            <set key="yarn.node-labels.enabled" value="false"/>
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_yarn_rm_disable_node_labels"/>
 
-          <task xsi:type="configure">
-            <type>capacity-scheduler</type>
-            <set key="yarn.scheduler.capacity.root.default-node-label-expression" value=""/>
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_yarn_rm_clear_default_node_label_expression"/>
 
-          <task xsi:type="configure" summary="Deleting the Capacity Scheduler root default capacity property">
-            <type>capacity-scheduler</type>
-            <transfer operation="delete" delete-key="yarn.scheduler.capacity.root.accessible-node-labels.default.capacity"/>
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_yarn_rm_check_cs_root_def_capacity"/>
 
-          <task xsi:type="configure" summary="Deleting the Capacity Scheduler root maximum capacity property">
-            <type>capacity-scheduler</type>
-            <transfer operation="delete" delete-key="yarn.scheduler.capacity.root.accessible-node-labels.default.maximum-capacity"/>
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_yarn_rm_check_cs_root_max_capacity"/>
 
         </pre-upgrade>
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="NODEMANAGER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="YARN_CLIENT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -689,121 +525,41 @@
       <component name="HBASE_MASTER">
         <pre-downgrade /> <!--  no-op to prevent config changes on downgrade -->
         <pre-upgrade>
-          <task xsi:type="configure">
-            <condition type="hbase-env" key="phoenix_sql_enabled" value="true">
-              <type>hbase-site</type>
-              <key>hbase.region.server.rpc.scheduler.factory.class</key>
-              <value>org.apache.hadoop.hbase.ipc.PhoenixRpcSchedulerFactory</value>
-            </condition>
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_hbase_master_adjust_phoenix_scheduler_factory"/>
 
-          <task xsi:type="configure">
-            <condition type="hbase-env" key="phoenix_sql_enabled" value="true">
-              <type>hbase-site</type>
-              <key>hbase.rpc.controllerfactory.class</key>
-              <value>org.apache.hadoop.hbase.ipc.controller.ServerRpcControllerFactory</value>
-            </condition>
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_hbase_master_adjust_phoenix_rpc_controller_factory"/>
 
-          <task xsi:type="configure">
-            <type>hbase-site</type>
-            <transfer operation="copy" from-type="hbase-site" from-key="hbase.regionserver.global.memstore.upperLimit" to-key="hbase.regionserver.global.memstore.size" default-value="0.4" />
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_hbase_master_set_global_memstore_size"/>
 
           <task xsi:type="server_action" summary="Calculating HBase Properties" class="org.apache.ambari.server.serveraction.upgrades.HBaseConfigCalculation" />
 
-          <task xsi:type="configure">
-            <condition type="hbase-env" key="phoenix_sql_enabled" value="true">
-              <type>hbase-site</type>
-              <key>hbase.regionserver.wal.codec</key>
-              <value>org.apache.hadoop.hbase.regionserver.wal.IndexedWALEditCodec</value>
-            </condition>
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_hbase_master_adjust_phoenix_indexed_wal_edit_codec"/>
 
-          <task xsi:type="configure" summary="Updating Authorization Coprocessors">
-            <type>hbase-site</type>
-            <replace key="hbase.coprocessor.master.classes" find="com.xasecure.authorization.hbase.XaSecureAuthorizationCoprocessor" replace-with="org.apache.ranger.authorization.hbase.RangerAuthorizationCoprocessor" />
-            <replace key="hbase.coprocessor.region.classes" find="com.xasecure.authorization.hbase.XaSecureAuthorizationCoprocessor" replace-with="org.apache.ranger.authorization.hbase.RangerAuthorizationCoprocessor" />           
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_hbase_master_adjust_authorization_coprocessors"/>
 
-          <task xsi:type="configure" summary="Transitioning Ranger HBase Policy">
-            <type>ranger-hbase-policymgr-ssl</type>
-            <transfer operation="copy" from-type="ranger-hbase-plugin-properties" from-key="SSL_KEYSTORE_FILE_PATH" to-key="xasecure.policymgr.clientssl.keystore" default-value="/usr/hdp/current/hbase-client/conf/ranger-plugin-keystore.jks" />
-            <transfer operation="copy" from-type="ranger-hbase-plugin-properties" from-key="SSL_KEYSTORE_PASSWORD" to-key="xasecure.policymgr.clientssl.keystore.password" mask="true" default-value="myKeyFilePassword" />
-            <transfer operation="copy" from-type="ranger-hbase-plugin-properties" from-key="SSL_TRUSTSTORE_FILE_PATH" to-key="xasecure.policymgr.clientssl.truststore" default-value="/usr/hdp/current/hbase-client/conf/ranger-plugin-truststore.jks" />
-            <transfer operation="copy" from-type="ranger-hbase-plugin-properties" from-key="SSL_TRUSTSTORE_PASSWORD" to-key="xasecure.policymgr.clientssl.truststore.password" mask="true" default-value="changeit" />
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_hbase_master_transition_ranger_hbase_policy"/>
 
-          <task xsi:type="configure" summary="Transitioning Ranger HBase Audit">
-            <type>ranger-hbase-audit</type>
-            <transfer operation="copy" from-type="ranger-hbase-plugin-properties" from-key="XAAUDIT.DB.IS_ENABLED" to-key="xasecure.audit.destination.db" default-value="false" />
-            <transfer operation="copy" from-type="ranger-hbase-plugin-properties" from-key="XAAUDIT.HDFS.DESTINATION_DIRECTORY" to-key="xasecure.audit.destination.hdfs.dir" default-value="hdfs://NAMENODE_HOSTNAME:8020/ranger/audit" />
-            <transfer operation="copy" from-type="ranger-hbase-plugin-properties" from-key="XAAUDIT.HDFS.IS_ENABLED" to-key="xasecure.audit.destination.hdfs" default-value="true" />
-            <transfer operation="copy" from-type="ranger-hbase-plugin-properties" from-key="XAAUDIT.HDFS.LOCAL_ARCHIVE_DIRECTORY" to-key="xasecure.audit.destination.hdfs.batch.filespool.dir" default-value="/var/log/hbase/audit/hdfs/spool" />
-            <transfer operation="copy" from-type="ranger-hbase-plugin-properties" from-key="XAAUDIT.DB.USER_NAME" to-key="xasecure.audit.destination.db.user" default-value="" />
-            <transfer operation="copy" from-type="ranger-hbase-plugin-properties" from-key="XAAUDIT.DB.PASSWORD" to-key="xasecure.audit.destination.db.password" mask="true" default-value="" />
-            <set key="xasecure.audit.credential.provider.file" value="jceks://file{{credential_file}}"/>
-            <set key="xasecure.audit.destination.solr" value="false" />
-            <set key="xasecure.audit.destination.solr.urls" value="{{ranger_audit_solr_urls}}" />
-            <set key="xasecure.audit.destination.solr.zookeepers" value="none" />
-            <set key="xasecure.audit.destination.solr.batch.filespool.dir" value="/var/log/hbase/audit/solr/spool" />
-            <set key="xasecure.audit.destination.db.jdbc.driver" value="{{jdbc_driver}}" />
-            <set key="xasecure.audit.destination.db.jdbc.url" value="{{audit_jdbc_url}}" />
-            <set key="xasecure.audit.provider.summary.enabled" value="true" />
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_hbase_master_transition_ranger_hbase_audit" />
 
-          <task xsi:type="configure">
-            <type>ranger-hbase-security</type>
-            <transfer operation="copy" from-type="ranger-hbase-plugin-properties" from-key="UPDATE_XAPOLICIES_ON_GRANT_REVOKE" to-key="xasecure.hbase.update.xapolicies.on.grant.revoke" default-value="true" />
-            <transfer operation="copy" from-type="ranger-hbase-plugin-properties" from-key="POLICY_MGR_URL" to-key="ranger.plugin.hbase.policy.rest.url" default-value="{{policymgr_mgr_url}}" />
-            <transfer operation="copy" from-type="ranger-hbase-plugin-properties" from-key="REPOSITORY_NAME" to-key="ranger.plugin.hbase.service.name" default-value="{{repo_name}}" />
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_hbase_master_copy_ranger_policies"/>
 
-          <task xsi:type="configure">
-            <type>ranger-hbase-plugin-properties</type>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_FILE" />
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_FLUSH_INTERVAL_SECONDS" />
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_OPEN_RETRY_INTERVAL_SECONDS" />
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_ROLLOVER_INTERVAL_SECONDS" />
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_ARCHIVE_MAX_FILE_COUNT" />
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_DIRECTORY" />
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_FILE" />
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_FLUSH_INTERVAL_SECONDS" />
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_ROLLOVER_INTERVAL_SECONDS" />
-            <transfer operation="delete" delete-key="SQL_CONNECTOR_JAR" />
-            <transfer operation="delete" delete-key="REPOSITORY_NAME" />
-            <transfer operation="delete" delete-key="POLICY_MGR_URL" />
-            <transfer operation="delete" delete-key="UPDATE_XAPOLICIES_ON_GRANT_REVOKE" />
-            <transfer operation="delete" delete-key="SSL_KEYSTORE_FILE_PATH" />
-            <transfer operation="delete" delete-key="SSL_KEYSTORE_PASSWORD" />
-            <transfer operation="delete" delete-key="SSL_TRUSTSTORE_FILE_PATH" />
-            <transfer operation="delete" delete-key="SSL_TRUSTSTORE_PASSWORD" />
-            <transfer operation="delete" delete-key="XAAUDIT.DB.IS_ENABLED" />
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINATION_DIRECTORY" />
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.IS_ENABLED" />
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_ARCHIVE_DIRECTORY" />
-            <transfer operation="delete" delete-key="XAAUDIT.DB.USER_NAME" />
-            <transfer operation="delete" delete-key="XAAUDIT.DB.PASSWORD" />
-            <transfer operation="delete" delete-key="XAAUDIT.DB.FLAVOUR" />
-            <transfer operation="delete" delete-key="XAAUDIT.DB.DATABASE_NAME" />
-            <transfer operation="delete" delete-key="XAAUDIT.DB.HOSTNAME" />
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_hbase_master_delete_old_ranger_properties"/>
         </pre-upgrade>
 
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="HBASE_REGIONSERVER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="HBASE_CLIENT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -811,14 +567,10 @@
     <service name="TEZ">
       <component name="TEZ_CLIENT">
         <pre-upgrade>
-          <task xsi:type="configure">
-            <type>tez-site</type>
-            <set key="tez.am.view-acls" value="*"/>
-            <set key="tez.task.generate.counters.per.io" value="true"/>
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_tez_client_adjust_properties"/>
         </pre-upgrade>
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -826,7 +578,7 @@
     <service name="PIG">
       <component name="PIG">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -834,7 +586,7 @@
     <service name="SQOOP">
       <component name="SQOOP">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -842,7 +594,7 @@
     <service name="HIVE">
       <component name="HIVE_METASTORE">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
@@ -853,118 +605,19 @@
             <message>Please note that the HiveServer port will now change to 10010 if hive is using a binary transfer mode or 10011 if hive is using an http transport mode. You can use "netstat -anp | grep 1001[01]" to determine if the port is available on each of following HiveServer host(s): {{hosts.all}}. If the port is not available, the process using it must be terminated.</message>
           </task>
 
-          <task xsi:type="configure">
-            <condition type="hive-site" key="hive.server2.transport.mode" value="binary">
-              <type>hive-site</type>
-              <key>hive.server2.thrift.port</key>
-              <value>10010</value>
-            </condition>
-            <condition type="hive-site" key="hive.server2.transport.mode" value="http">
-              <type>hive-site</type>
-              <key>hive.server2.http.port</key>
-              <value>10011</value>
-            </condition>
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_hive_server_set_transport_modes"/>
           
-          <task xsi:type="configure" summary="Update Hive Authentication Manager">
-            <type>hiveserver2-site</type>
-            <replace key="hive.security.authorization.manager" find="com.xasecure.authorization.hive.authorizer.XaSecureHiveAuthorizerFactory" replace-with="org.apache.ranger.authorization.hive.authorizer.RangerHiveAuthorizerFactory" />
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_hive_server_replace_auth_manager"/>
 
-          <task xsi:type="configure" summary="Configuring hive authentication">
-            <type>hive-site</type>
-            <transfer operation="delete" delete-key="hive.server2.authentication.ldap.url" if-key="hive.server2.authentication" if-type="hive-site" if-value="NONE"/>
-            <transfer operation="delete" delete-key="hive.server2.authentication.ldap.baseDN" if-key="hive.server2.authentication" if-type="hive-site" if-value="NONE"/>
-            <transfer operation="delete" delete-key="hive.server2.authentication.pam.services" if-key="hive.server2.authentication" if-type="hive-site" if-value="NONE"/>
-            <transfer operation="delete" delete-key="hive.server2.custom.authentication.class" if-key="hive.server2.authentication" if-type="hive-site" if-value="NONE"/>
-            <transfer operation="delete" delete-key="hive.server2.authentication.kerberos.keytab" if-key="hive.server2.authentication" if-type="hive-site" if-value="NONE"/>
-            <transfer operation="delete" delete-key="hive.server2.authentication.kerberos.principal" if-key="hive.server2.authentication" if-type="hive-site" if-value="NONE"/>
-
-            <transfer operation="delete" delete-key="hive.server2.authentication.kerberos.keytab" if-key="hive.server2.authentication" if-type="hive-site" if-value="ldap"/>
-            <transfer operation="delete" delete-key="hive.server2.authentication.kerberos.principal" if-key="hive.server2.authentication" if-type="hive-site" if-value="ldap"/>
-            <transfer operation="delete" delete-key="hive.server2.authentication.pam.services" if-key="hive.server2.authentication" if-type="hive-site" if-value="ldap"/>
-            <transfer operation="delete" delete-key="hive.server2.custom.authentication.class" if-key="hive.server2.authentication" if-type="hive-site" if-value="ldap"/>
-
-            <transfer operation="delete" delete-key="hive.server2.authentication.ldap.url" if-key="hive.server2.authentication" if-type="hive-site" if-value="kerberos"/>
-            <transfer operation="delete" delete-key="hive.server2.authentication.ldap.baseDN" if-key="hive.server2.authentication" if-type="hive-site" if-value="kerberos"/>
-            <transfer operation="delete" delete-key="hive.server2.authentication.pam.services" if-key="hive.server2.authentication" if-type="hive-site" if-value="kerberos"/>
-            <transfer operation="delete" delete-key="hive.server2.custom.authentication.class" if-key="hive.server2.authentication" if-type="hive-site" if-value="kerberos"/>
-
-            <transfer operation="delete" delete-key="hive.server2.authentication.ldap.url" if-key="hive.server2.authentication" if-type="hive-site" if-value="pam"/>
-            <transfer operation="delete" delete-key="hive.server2.authentication.ldap.baseDN" if-key="hive.server2.authentication" if-type="hive-site" if-value="pam"/>
-            <transfer operation="delete" delete-key="hive.server2.custom.authentication.class" if-key="hive.server2.authentication" if-type="hive-site" if-value="pam"/>
-            <transfer operation="delete" delete-key="hive.server2.authentication.kerberos.keytab" if-key="hive.server2.authentication" if-type="hive-site" if-value="pam"/>
-            <transfer operation="delete" delete-key="hive.server2.authentication.kerberos.principal" if-key="hive.server2.authentication" if-type="hive-site" if-value="pam"/>
-
-            <transfer operation="delete" delete-key="hive.server2.authentication.ldap.url" if-key="hive.server2.authentication" if-type="hive-site" if-value="custom"/>
-            <transfer operation="delete" delete-key="hive.server2.authentication.ldap.baseDN" if-key="hive.server2.authentication" if-type="hive-site" if-value="custom"/>
-            <transfer operation="delete" delete-key="hive.server2.authentication.pam.services" if-key="hive.server2.authentication" if-type="hive-site" if-value="custom"/>
-            <transfer operation="delete" delete-key="hive.server2.authentication.kerberos.keytab" if-key="hive.server2.authentication" if-type="hive-site" if-value="custom"/>
-            <transfer operation="delete" delete-key="hive.server2.authentication.kerberos.principal" if-key="hive.server2.authentication" if-type="hive-site" if-value="custom"/>
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_hive_server_configure_authentification"/>
 
-          <task xsi:type="configure" summary="Configuring Ranger Hive Policy">
-            <type>ranger-hive-policymgr-ssl</type>
-            <transfer operation="copy" from-type="ranger-hive-plugin-properties" from-key="SSL_KEYSTORE_FILE_PATH" to-key="xasecure.policymgr.clientssl.keystore" default-value="/usr/hdp/current/hive-server2/conf/ranger-plugin-keystore.jks"/>
-            <transfer operation="copy" from-type="ranger-hive-plugin-properties" from-key="SSL_KEYSTORE_PASSWORD" to-key="xasecure.policymgr.clientssl.keystore.password" default-value="myKeyFilePassword" mask="true"/>
-            <transfer operation="copy" from-type="ranger-hive-plugin-properties" from-key="SSL_TRUSTSTORE_FILE_PATH" to-key="xasecure.policymgr.clientssl.truststore" default-value="/usr/hdp/current/hive-server2/conf/ranger-plugin-truststore.jks"/>
-            <transfer operation="copy" from-type="ranger-hive-plugin-properties" from-key="SSL_TRUSTSTORE_PASSWORD" to-key="xasecure.policymgr.clientssl.truststore.password" default-value="changeit" mask="true"/>
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_hive_server_configure_ranger_policy"/>
 
-          <task xsi:type="configure" summary="Configuring Ranger Hive Security">
-            <type>ranger-hive-security</type>
-            <transfer operation="copy" from-type="ranger-hive-plugin-properties" from-key="UPDATE_XAPOLICIES_ON_GRANT_REVOKE" to-key="xasecure.hive.update.xapolicies.on.grant.revoke" default-value="true"/>
-            <transfer operation="copy" from-type="ranger-hive-plugin-properties" from-key="POLICY_MGR_URL" to-key="ranger.plugin.hive.policy.rest.url" default-value="{{policymgr_mgr_url}}"/>
-            <transfer operation="copy" from-type="ranger-hive-plugin-properties" from-key="REPOSITORY_NAME" to-key="ranger.plugin.hive.service.name" default-value="{{repo_name}}"/>
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_hive_server_configure_ranger_security"/>
 
-          <task xsi:type="configure" summary="Configuring Ranger Hive Audit">
-            <type>ranger-hive-audit</type>
-            <transfer operation="copy" from-type="ranger-hive-plugin-properties" from-key="XAAUDIT.DB.IS_ENABLED" to-key="xasecure.audit.destination.db" default-value="true"/>
-            <transfer operation="copy" from-type="ranger-hive-plugin-properties" from-key="XAAUDIT.HDFS.DESTINATION_DIRECTORY" to-key="xasecure.audit.destination.hdfs.dir" default-value="hdfs://NAMENODE_HOSTNAME:8020/ranger/audit"/>
-            <transfer operation="copy" from-type="ranger-hive-plugin-properties" from-key="XAAUDIT.HDFS.IS_ENABLED" to-key="xasecure.audit.destination.hdfs" default-value="true"/>
-            <transfer operation="copy" from-type="ranger-hive-plugin-properties" from-key="XAAUDIT.HDFS.LOCAL_ARCHIVE_DIRECTORY" to-key="xasecure.audit.destination.hdfs.batch.filespool.dir" default-value="/var/log/hive/audit/hdfs/spool"/>
-            <transfer operation="copy" from-type="ranger-hive-plugin-properties" from-key="XAAUDIT.DB.USER_NAME" to-key="xasecure.audit.destination.db.user" default-value=""/>
-            <transfer operation="copy" from-type="ranger-hive-plugin-properties" from-key="XAAUDIT.DB.PASSWORD" to-key="xasecure.audit.destination.db.password" default-value="" mask="true"/>
-            <set key="xasecure.audit.credential.provider.file" value="jceks://file{{credential_file}}"/>
-            <set key="xasecure.audit.destination.solr" value="false"/>
-            <set key="xasecure.audit.destination.solr.urls" value="{{ranger_audit_solr_urls}}"/>
-            <set key="xasecure.audit.destination.solr.zookeepers" value="none"/>
-            <set key="xasecure.audit.destination.solr.batch.filespool.dir" value="/var/log/hive/audit/solr/spool"/>
-            <set key="xasecure.audit.destination.db.jdbc.driver" value="{{jdbc_driver}}"/>
-            <set key="xasecure.audit.destination.db.jdbc.url" value="{{audit_jdbc_url}}"/>
-            <set key="xasecure.audit.provider.summary.enabled" value="false"/>
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_hive_server_configure_ranger_audit"/>
 
-          <task xsi:type="configure" summary="Removing Deprecated Ranger Hive Plugin Configurations">
-            <type>ranger-hive-plugin-properties</type>
-            <transfer operation="delete" delete-key="SSL_KEYSTORE_FILE_PATH"/>
-            <transfer operation="delete" delete-key="SSL_KEYSTORE_PASSWORD"/>
-            <transfer operation="delete" delete-key="SSL_TRUSTSTORE_FILE_PATH"/>
-            <transfer operation="delete" delete-key="SSL_TRUSTSTORE_PASSWORD"/>
-            <transfer operation="delete" delete-key="POLICY_MGR_URL"/>
-            <transfer operation="delete" delete-key="REPOSITORY_NAME"/>
-            <transfer operation="delete" delete-key="UPDATE_XAPOLICIES_ON_GRANT_REVOKE"/>
-            <transfer operation="delete" delete-key="XAAUDIT.DB.IS_ENABLED"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINATION_DIRECTORY"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.IS_ENABLED"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_ARCHIVE_DIRECTORY"/>
-            <transfer operation="delete" delete-key="XAAUDIT.DB.USER_NAME"/>
-            <transfer operation="delete" delete-key="XAAUDIT.DB.PASSWORD"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_FILE"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_FLUSH_INTERVAL_SECONDS"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_OPEN_RETRY_INTERVAL_SECONDS"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_ROLLOVER_INTERVAL_SECONDS"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_ARCHIVE_MAX_FILE_COUNT"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_DIRECTORY"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_FILE"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_FLUSH_INTERVAL_SECONDS"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_ROLLOVER_INTERVAL_SECONDS"/>
-            <transfer operation="delete" delete-key="SQL_CONNECTOR_JAR" />
-            <transfer operation="delete" delete-key="XAAUDIT.DB.FLAVOUR" />
-            <transfer operation="delete" delete-key="XAAUDIT.DB.DATABASE_NAME" />
-            <transfer operation="delete" delete-key="XAAUDIT.DB.HOSTNAME" />            
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_hive_server_remove_deprecated_ranger_properties"/>
         </pre-upgrade>
 
         <pre-downgrade>
@@ -973,56 +626,35 @@
             <message>Please note that the HiveServer port will now change to 10000 if hive is using a binary transfer mode or 10001 if hive is using an http transport mode. You can use "netstat -anp | grep 1000[01]" to determine if the port is available on each of following HiveServer host(s): {{hosts.all}}. If the port is not available, the process using it must be terminated.</message>
           </task>
 
-          <task xsi:type="configure">
-            <condition type="hive-site" key="hive.server2.transport.mode" value="binary">
-              <type>hive-site</type>
-              <key>hive.server2.thrift.port</key>
-              <value>10000</value>
-            </condition>
-            <condition type="hive-site" key="hive.server2.transport.mode" value="http">
-              <type>hive-site</type>
-              <key>hive.server2.http.port</key>
-              <value>10001</value>
-            </condition>
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_hive_server_restore_transport_mode_on_downgrade"/>
         </pre-downgrade>
 
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="WEBHCAT_SERVER">
         <pre-upgrade>
-          <task xsi:type="configure">
-            <type>webhcat-env</type>
-            <replace key="content" find="export HADOOP_HOME={{hadoop_home}}" replace-with="export HADOOP_HOME=${HADOOP_HOME:-{{hadoop_home}}}" />
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_webhcat_server_update_env"/>
 
-          <task xsi:type="configure" summary="Updating Configuration Paths">
-            <type>webhcat-site</type>
-            <replace key="templeton.jar" find="/usr/hdp/current/hive-webhcat" replace-with="/usr/hdp/${hdp.version}/hive"/>
-            <replace key="templeton.libjars" find="/usr/hdp/current/zookeeper-client" replace-with="/usr/hdp/${hdp.version}/zookeeper,/usr/hdp/${hdp.version}/hive/lib/hive-common.jar"/>
-            <replace key="templeton.hadoop" find="/usr/hdp/current/hadoop-client" replace-with="/usr/hdp/${hdp.version}/hadoop"/>
-            <replace key="templeton.hcat" find="/usr/hdp/current/hive-client" replace-with="/usr/hdp/${hdp.version}/hive"/>
-            <set key="templeton.hive.extra.files" value="/usr/hdp/${hdp.version}/tez/conf/tez-site.xml,/usr/hdp/${hdp.version}/tez,/usr/hdp/${hdp.version}/tez/lib"/>
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_webhcat_server_update_configuration_paths"/>
         </pre-upgrade>
 
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="HIVE_CLIENT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="HCAT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -1030,7 +662,7 @@
     <service name="SLIDER">
       <component name="SLIDER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -1038,12 +670,12 @@
     <service name="SPARK">
       <component name="SPARK_JOBHISTORYSERVER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
       <component name="SPARK_CLIENT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -1051,36 +683,7 @@
     <service name="OOZIE">
       <component name="OOZIE_SERVER">
         <pre-upgrade>
-          <task xsi:type="configure">
-            <summary>Updating oozie-site to remove redundant configurations</summary>
-            <type>oozie-site</type>
-            <transfer operation="delete" delete-key="*" preserve-edits="true">
-              <keep-key>oozie.base.url</keep-key>
-              <keep-key>oozie.services.ext</keep-key>
-              <keep-key>oozie.db.schema.name</keep-key>
-              <keep-key>oozie.service.JPAService.jdbc.username</keep-key>
-              <keep-key>oozie.service.JPAService.jdbc.password</keep-key>
-              <keep-key>oozie.service.JPAService.jdbc.driver</keep-key>
-              <keep-key>oozie.service.JPAService.jdbc.url</keep-key>
-              <keep-key>oozie.service.AuthorizationService.security.enabled</keep-key>
-              <keep-key>oozie.authentication.type</keep-key>
-              <keep-key>oozie.authentication.simple.anonymous.allowed</keep-key>
-              <keep-key>oozie.authentication.kerberos.name.rules</keep-key>
-              <keep-key>oozie.service.HadoopAccessorService.hadoop.configurations</keep-key>
-              <keep-key>oozie.service.HadoopAccessorService.kerberos.enabled</keep-key>
-              <keep-key>oozie.service.URIHandlerService.uri.handlers</keep-key>
-
-              <!-- required by Falcon and should be preserved -->
-              <keep-key>oozie.service.ELService.ext.functions.coord-job-submit-instances</keep-key>
-              <keep-key>oozie.service.ELService.ext.functions.coord-action-create-inst</keep-key>
-              <keep-key>oozie.service.ELService.ext.functions.coord-action-create</keep-key>
-              <keep-key>oozie.service.ELService.ext.functions.coord-job-submit-data</keep-key>
-              <keep-key>oozie.service.ELService.ext.functions.coord-action-start</keep-key>
-              <keep-key>oozie.service.ELService.ext.functions.coord-sla-submit</keep-key>
-              <keep-key>oozie.service.ELService.ext.functions.coord-sla-create</keep-key>
-            </transfer>
-            <set key="oozie.credentials.credentialclasses" value="hcat=org.apache.oozie.action.hadoop.HCatCredentials,hive2=org.apache.oozie.action.hadoop.Hive2Credentials" />
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_oozie_remove_redundant_configurations"/>
 
           <task xsi:type="execute" hosts="all" summary="Shut down all Oozie servers">
             <script>scripts/oozie_server.py</script>
@@ -1106,13 +709,13 @@
         </pre-downgrade>
 
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
       <component name="OOZIE_CLIENT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -1120,12 +723,12 @@
     <service name="FALCON">
       <component name="FALCON_SERVER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
       <component name="FALCON_CLIENT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -1133,7 +736,7 @@
     <service name="KAFKA">
       <component name="KAFKA_BROKER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -1142,63 +745,14 @@
       <component name="KNOX_GATEWAY">
         <pre-downgrade /> <!--  no-op to prevent config changes on downgrade -->
         <pre-upgrade>
-          <task xsi:type="configure" summary="Configuring Ranger Knox Policy">
-            <type>ranger-knox-policymgr-ssl</type>
-            <transfer operation="copy" from-type="ranger-knox-plugin-properties" from-key="SSL_KEYSTORE_FILE_PATH" to-key="xasecure.policymgr.clientssl.keystore" default-value="/usr/hdp/current/knox-server/conf/ranger-plugin-keystore.jks"/>
-            <transfer operation="copy" from-type="ranger-knox-plugin-properties" from-key="SSL_KEYSTORE_PASSWORD" to-key="xasecure.policymgr.clientssl.keystore.password" default-value="myKeyFilePassword" mask="true"/>
-            <transfer operation="copy" from-type="ranger-knox-plugin-properties" from-key="SSL_TRUSTSTORE_FILE_PATH" to-key="xasecure.policymgr.clientssl.truststore" default-value="/usr/hdp/current/knox-server/conf/ranger-plugin-truststore.jks"/>
-            <transfer operation="copy" from-type="ranger-knox-plugin-properties" from-key="SSL_TRUSTSTORE_PASSWORD" to-key="xasecure.policymgr.clientssl.truststore.password" default-value="changeit" mask="true"/>
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_knox_configure_ranger_policy"/>
 
-          <task xsi:type="configure" summary="Configuring Ranger Knox Audit">
-            <type>ranger-knox-audit</type>
-            <transfer operation="copy" from-type="ranger-knox-plugin-properties" from-key="XAAUDIT.DB.IS_ENABLED" to-key="xasecure.audit.destination.db" default-value="true"/>
-            <transfer operation="copy" from-type="ranger-knox-plugin-properties" from-key="XAAUDIT.HDFS.DESTINATION_DIRECTORY" to-key="xasecure.audit.destination.hdfs.dir" default-value="hdfs://NAMENODE_HOSTNAME:8020/ranger/audit"/>
-            <transfer operation="copy" from-type="ranger-knox-plugin-properties" from-key="XAAUDIT.HDFS.IS_ENABLED" to-key="xasecure.audit.destination.hdfs" default-value="true"/>
-            <transfer operation="copy" from-type="ranger-knox-plugin-properties" from-key="XAAUDIT.HDFS.LOCAL_ARCHIVE_DIRECTORY" to-key="xasecure.audit.destination.hdfs.batch.filespool.dir" default-value="/var/log/knox/audit/hdfs/spool"/>
-            <transfer operation="copy" from-type="ranger-knox-plugin-properties" from-key="XAAUDIT.DB.USER_NAME" to-key="xasecure.audit.destination.db.user" default-value=""/>
-            <transfer operation="copy" from-type="ranger-knox-plugin-properties" from-key="XAAUDIT.DB.PASSWORD" to-key="xasecure.audit.destination.db.passwordr" default-value="" mask="true"/>
-            <set key="xasecure.audit.credential.provider.file" value="jceks://file{{credential_file}}"/>
-            <set key="xasecure.audit.destination.solr" value="false"/>
-            <set key="xasecure.audit.destination.solr.urls" value="{{ranger_audit_solr_urls}}"/>
-            <set key="xasecure.audit.destination.solr.zookeepers" value="none"/>
-            <set key="xasecure.audit.destination.solr.batch.filespool.dir" value="/var/log/knox/audit/solr/spool"/>
-            <set key="xasecure.audit.destination.db.jdbc.driver" value="{{jdbc_driver}}"/>
-            <set key="xasecure.audit.destination.db.jdbc.url" value="{{audit_jdbc_url}}"/>
-            <set key="xasecure.audit.provider.summary.enabled" value="false"/>
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_knox_configure_ranger_knox_audit"/>
 
-          <task xsi:type="configure" summary="Removing Deprecated Ranger Knox Plugin Configurations">
-            <type>ranger-knox-plugin-properties</type>
-            <transfer operation="delete" delete-key="SSL_KEYSTORE_FILE_PATH"/>
-            <transfer operation="delete" delete-key="SSL_KEYSTORE_PASSWORD"/>
-            <transfer operation="delete" delete-key="SSL_TRUSTSTORE_FILE_PATH"/>
-            <transfer operation="delete" delete-key="SSL_TRUSTSTORE_PASSWORD"/>
-            <transfer operation="delete" delete-key="XAAUDIT.DB.IS_ENABLED"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINATION_DIRECTORY"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.IS_ENABLED"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_ARCHIVE_DIRECTORY"/>
-            <transfer operation="delete" delete-key="XAAUDIT.DB.USER_NAME"/>
-            <transfer operation="delete" delete-key="XAAUDIT.DB.PASSWORD"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_FILE"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_FLUSH_INTERVAL_SECONDS"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_OPEN_RETRY_INTERVAL_SECONDS"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_ROLLOVER_INTERVAL_SECONDS"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_ARCHIVE_MAX_FILE_COUNT"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_DIRECTORY"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_FILE"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_FLUSH_INTERVAL_SECONDS"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_ROLLOVER_INTERVAL_SECONDS"/>
-            <transfer operation="delete" delete-key="SQL_CONNECTOR_JAR" />
-            <transfer operation="delete" delete-key="XAAUDIT.DB.FLAVOUR" />
-            <transfer operation="delete" delete-key="XAAUDIT.DB.DATABASE_NAME" />
-            <transfer operation="delete" delete-key="XAAUDIT.DB.HOSTNAME" />
-            <transfer operation="delete" delete-key="REPOSITORY_NAME" />
-            <transfer operation="delete" delete-key="POLICY_MGR_URL" />
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_knox_remove_deprecated_ranger_properties"/>
         </pre-upgrade>
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -1236,81 +790,18 @@
             <function>delete_storm_local_data</function>
           </task>
 
-          <task xsi:type="configure" summary="Updating nimbus.monitor.freq.secs">
-            <type>storm-site</type>
-            <set key="nimbus.monitor.freq.secs" value="120" />
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_nimbus_convert_nimbus_host_to_seeds"/>
 
-          <task xsi:type="configure" summary="Converting nimbus.host into nimbus.seeds">
-            <type>storm-site</type>
-            <transfer operation="copy" from-key="nimbus.host" to-key="nimbus.seeds" coerce-to="yaml-array"/>
-            <transfer operation="delete" delete-key="nimbus.host"/>
-            <replace key="nimbus.authorizer" find="com.xasecure.authorization.storm.authorizer.XaSecureStormAuthorizer" replace-with="org.apache.ranger.authorization.storm.authorizer.RangerStormAuthorizer" />
-          </task>
-
-          <task xsi:type="configure" summary="Updating Storm home and configuration environment variables">
-            <type>storm-env</type>
-            <replace key="content" find="# export STORM_CONF_DIR=&quot;&quot;" replace-with="export STORM_CONF_DIR={{conf_dir}}"/>
-            <replace key="content" find="export STORM_HOME=/usr/hdp/current/storm-client" replace-with="export STORM_HOME={{storm_component_home_dir}}"/>
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_nimbus_update_env_vars"/>
 
-          <task xsi:type="configure" summary="Configuring Ranger Storm Policy">
-            <type>ranger-storm-policymgr-ssl</type>
-            <transfer operation="copy" from-type="ranger-storm-plugin-properties" from-key="SSL_KEYSTORE_FILE_PATH" to-key="xasecure.policymgr.clientssl.keystore" default-value="/usr/hdp/current/storm-client/conf/ranger-plugin-keystore.jks"/>
-            <transfer operation="copy" from-type="ranger-storm-plugin-properties" from-key="SSL_KEYSTORE_PASSWORD" to-key="xasecure.policymgr.clientssl.keystore.password" default-value="myKeyFilePassword" mask="true"/>
-            <transfer operation="copy" from-type="ranger-storm-plugin-properties" from-key="SSL_TRUSTSTORE_FILE_PATH" to-key="xasecure.policymgr.clientssl.truststore" default-value="/usr/hdp/current/storm-client/conf/ranger-plugin-truststore.jks"/>
-            <transfer operation="copy" from-type="ranger-storm-plugin-properties" from-key="SSL_TRUSTSTORE_PASSWORD" to-key="xasecure.policymgr.clientssl.truststore.password" default-value="changeit" mask="true"/>
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_nimbus_configure_ranger_policy"/>
 
-          <task xsi:type="configure" summary="Configuring Ranger Storm Audit">
-            <type>ranger-storm-audit</type>
-            <transfer operation="copy" from-type="ranger-storm-plugin-properties" from-key="XAAUDIT.DB.IS_ENABLED" to-key="xasecure.audit.destination.db" default-value="true" />
-            <transfer operation="copy" from-type="ranger-storm-plugin-properties" from-key="XAAUDIT.HDFS.DESTINATION_DIRECTORY" to-key="xasecure.audit.destination.hdfs.dir" default-value="hdfs://NAMENODE_HOSTNAME:8020/ranger/audit" />
-            <transfer operation="copy" from-type="ranger-storm-plugin-properties" from-key="XAAUDIT.HDFS.IS_ENABLED" to-key="xasecure.audit.destination.hdfs" default-value="true" />
-            <transfer operation="copy" from-type="ranger-storm-plugin-properties" from-key="XAAUDIT.HDFS.LOCAL_ARCHIVE_DIRECTORY" to-key="xasecure.audit.destination.hdfs.batch.filespool.dir" default-value="/var/log/storm/audit/hdfs/spool" />
-            <transfer operation="copy" from-type="ranger-storm-plugin-properties" from-key="XAAUDIT.DB.USER_NAME" to-key="xasecure.audit.destination.db.user" default-value=""/>
-            <transfer operation="copy" from-type="ranger-storm-plugin-properties" from-key="XAAUDIT.DB.PASSWORD" to-key="xasecure.audit.destination.db.passwordr" default-value="" mask="true"/>
-            <set key="xasecure.audit.credential.provider.file" value="jceks://file{{credential_file}}"/>
-            <set key="xasecure.audit.destination.solr" value="false"/>
-            <set key="xasecure.audit.destination.solr.urls" value="{{ranger_audit_solr_urls}}"/>
-            <set key="xasecure.audit.destination.solr.zookeepers" value="none"/>
-            <set key="xasecure.audit.destination.solr.batch.filespool.dir" value="/var/log/storm/audit/solr/spool"/>
-            <set key="xasecure.audit.destination.db.jdbc.driver" value="{{jdbc_driver}}"/>
-            <set key="xasecure.audit.destination.db.jdbc.url" value="{{audit_jdbc_url}}"/>
-            <set key="xasecure.audit.provider.summary.enabled" value="false"/>
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_nimbus_configure_ranger_audit"/>
 
-          <task xsi:type="configure" summary="Removing Deprecated Ranger Storm Plugin Configurations">
-            <type>ranger-storm-plugin-properties</type>
-            <transfer operation="delete" delete-key="SSL_KEYSTORE_FILE_PATH"/>
-            <transfer operation="delete" delete-key="SSL_KEYSTORE_PASSWORD"/>
-            <transfer operation="delete" delete-key="SSL_TRUSTSTORE_FILE_PATH"/>
-            <transfer operation="delete" delete-key="SSL_TRUSTSTORE_PASSWORD"/>
-            <transfer operation="delete" delete-key="XAAUDIT.DB.IS_ENABLED"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINATION_DIRECTORY"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.IS_ENABLED"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_ARCHIVE_DIRECTORY"/>
-            <transfer operation="delete" delete-key="XAAUDIT.DB.USER_NAME"/>
-            <transfer operation="delete" delete-key="XAAUDIT.DB.PASSWORD"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_FILE"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_FLUSH_INTERVAL_SECONDS"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_OPEN_RETRY_INTERVAL_SECONDS"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.DESTINTATION_ROLLOVER_INTERVAL_SECONDS"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_ARCHIVE_MAX_FILE_COUNT"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_DIRECTORY"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_FILE"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_FLUSH_INTERVAL_SECONDS"/>
-            <transfer operation="delete" delete-key="XAAUDIT.HDFS.LOCAL_BUFFER_ROLLOVER_INTERVAL_SECONDS"/>
-            <transfer operation="delete" delete-key="SQL_CONNECTOR_JAR" />
-            <transfer operation="delete" delete-key="XAAUDIT.DB.FLAVOUR" />
-            <transfer operation="delete" delete-key="XAAUDIT.DB.DATABASE_NAME" />
-            <transfer operation="delete" delete-key="XAAUDIT.DB.HOSTNAME" />
-            <transfer operation="delete" delete-key="REPOSITORY_NAME" />
-            <transfer operation="delete" delete-key="POLICY_MGR_URL" />
-          </task>
+          <task xsi:type="configure" id="hdp_2_3_0_0_nimbus_remove_deprecated_ranger_properties"/>
         </pre-upgrade>
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
@@ -1322,7 +813,7 @@
           </task>
         </pre-upgrade>
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
@@ -1334,7 +825,7 @@
           </task>
         </pre-upgrade>
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
@@ -1347,7 +838,7 @@
         </pre-upgrade>
 
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
 
@@ -1360,7 +851,7 @@
         </pre-upgrade>
 
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
 
         <post-upgrade>
@@ -1374,7 +865,7 @@
     <service name="FLUME">
       <component name="FLUME_HANDLER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>
@@ -1382,32 +873,32 @@
     <service name="ACCUMULO">
       <component name="ACCUMULO_MASTER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
       <component name="ACCUMULO_MONITOR">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
       <component name="ACCUMULO_GC">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
       <component name="ACCUMULO_TRACER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
       <component name="ACCUMULO_TSERVER">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
       <component name="ACCUMULO_CLIENT">
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
       </component>
     </service>

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/resources/stacks/HDP/2.3/repos/repoinfo.xml.orig
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/repos/repoinfo.xml.orig b/ambari-server/src/main/resources/stacks/HDP/2.3/repos/repoinfo.xml.orig
deleted file mode 100644
index 5c845f1..0000000
--- a/ambari-server/src/main/resources/stacks/HDP/2.3/repos/repoinfo.xml.orig
+++ /dev/null
@@ -1,92 +0,0 @@
-<?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.
--->
-<reposinfo>
-  <latest>http://public-repo-1.hortonworks.com/HDP/hdp_urlinfo.json</latest>
-  <os family="redhat6">
-    <repo>
-      <baseurl>http://public-repo-1.hortonworks.com/HDP/centos6/2.x/updates/2.3.0.0</baseurl>
-      <repoid>HDP-2.3</repoid>
-      <reponame>HDP</reponame>
-    </repo>
-    <repo>
-      <baseurl>http://public-repo-1.hortonworks.com/HDP-UTILS-1.1.0.20/repos/centos6</baseurl>
-      <repoid>HDP-UTILS-1.1.0.20</repoid>
-      <reponame>HDP-UTILS</reponame>
-    </repo>
-  </os>
-  <os family="redhat7">
-    <repo>
-      <baseurl>http://public-repo-1.hortonworks.com/HDP/centos7/2.x/updates/2.3.0.0</baseurl>
-      <repoid>HDP-2.3</repoid>
-      <reponame>HDP</reponame>
-    </repo>
-    <repo>
-      <baseurl>http://public-repo-1.hortonworks.com/HDP-UTILS-1.1.0.20/repos/centos7</baseurl>
-      <repoid>HDP-UTILS-1.1.0.20</repoid>
-      <reponame>HDP-UTILS</reponame>
-    </repo>
-  </os>
-  <os family="suse11">
-    <repo>
-      <baseurl>http://public-repo-1.hortonworks.com/HDP/suse11sp3/2.x/updates/2.3.0.0</baseurl>
-      <repoid>HDP-2.3</repoid>
-      <reponame>HDP</reponame>
-    </repo>
-    <repo>
-      <baseurl>http://public-repo-1.hortonworks.com/HDP-UTILS-1.1.0.20/repos/suse11sp3</baseurl>
-      <repoid>HDP-UTILS-1.1.0.20</repoid>
-      <reponame>HDP-UTILS</reponame>
-    </repo>
-  </os>
-  <os family="ubuntu12">
-    <repo>
-      <baseurl>http://s3.amazonaws.com/dev.hortonworks.com/HDP/ubuntu12/2.x/updates/2.3.0.0</baseurl>
-      <repoid>HDP-2.3</repoid>
-      <reponame>HDP</reponame>
-    </repo>
-    <repo>
-      <baseurl>http://public-repo-1.hortonworks.com/HDP-UTILS-1.1.0.20/repos/ubuntu12</baseurl>
-      <repoid>HDP-UTILS-1.1.0.20</repoid>
-      <reponame>HDP-UTILS</reponame>
-    </repo>
-  </os>
-  <os family="debian7">
-    <repo>
-      <baseurl>http://s3.amazonaws.com/dev.hortonworks.com/HDP/debian7/2.x/updates/2.3.0.0</baseurl>
-      <repoid>HDP-2.3</repoid>
-      <reponame>HDP</reponame>
-    </repo>
-    <repo>
-      <baseurl>http://public-repo-1.hortonworks.com/HDP-UTILS-1.1.0.20/repos/debian6</baseurl>
-      <repoid>HDP-UTILS-1.1.0.20</repoid>
-      <reponame>HDP-UTILS</reponame>
-    </repo>
-  </os>
-  <os family="ubuntu14">
-    <repo>
-      <baseurl>http://s3.amazonaws.com/dev.hortonworks.com/HDP/ubuntu12/2.x/updates/2.3.0.0</baseurl>
-      <repoid>HDP-2.3</repoid>
-      <reponame>HDP</reponame>
-    </repo>
-    <repo>
-      <baseurl>http://public-repo-1.hortonworks.com/HDP-UTILS-1.1.0.20/repos/ubuntu12</baseurl>
-      <repoid>HDP-UTILS-1.1.0.20</repoid>
-      <reponame>HDP-UTILS</reponame>
-    </repo>
-  </os>
-</reposinfo>


[8/9] ambari git commit: AMBARI-13392. Stop-and-Start Upgrade: Merge branch branch-dev-stop-all-upgrade to branch-2.1 for feature Stop-the-World Upgrade, aka Express Upgrade (alejandro, dlysnichenko, Dmytro Grinenko)

Posted by al...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/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 c00e64b..bf7647e 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
@@ -90,6 +90,7 @@ import org.apache.ambari.server.state.StackInfo;
 import org.apache.ambari.server.state.UpgradeContext;
 import org.apache.ambari.server.state.UpgradeHelper;
 import org.apache.ambari.server.state.UpgradeHelper.UpgradeGroupHolder;
+import org.apache.ambari.server.state.stack.ConfigUpgradePack;
 import org.apache.ambari.server.state.stack.PrereqCheckStatus;
 import org.apache.ambari.server.state.stack.UpgradePack;
 import org.apache.ambari.server.state.stack.upgrade.ConfigureTask;
@@ -100,6 +101,8 @@ import org.apache.ambari.server.state.stack.upgrade.ServerSideActionTask;
 import org.apache.ambari.server.state.stack.upgrade.StageWrapper;
 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.UpdateStackGrouping;
+import org.apache.ambari.server.state.stack.upgrade.UpgradeType;
 import org.apache.ambari.server.state.svccomphost.ServiceComponentHostServerActionEvent;
 import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
@@ -117,6 +120,8 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
 
   protected static final String UPGRADE_CLUSTER_NAME = "Upgrade/cluster_name";
   protected static final String UPGRADE_VERSION = "Upgrade/repository_version";
+  protected static final String UPGRADE_TYPE = "Upgrade/type";
+  protected static final String UPGRADE_PACK = "Upgrade/pack";
   protected static final String UPGRADE_REQUEST_ID = "Upgrade/request_id";
   protected static final String UPGRADE_FROM_VERSION = "Upgrade/from_version";
   protected static final String UPGRADE_TO_VERSION = "Upgrade/to_version";
@@ -156,6 +161,8 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
   private static final String COMMAND_PARAM_VERSION = VERSION;
   private static final String COMMAND_PARAM_CLUSTER_NAME = "clusterName";
   private static final String COMMAND_PARAM_DIRECTION = "upgrade_direction";
+  // TODO AMBARI-12698, change this variable name since it is no longer always a restart. Possible values are rolling_upgrade or nonrolling_upgrade
+  // This will involve changing Script.py
   private static final String COMMAND_PARAM_RESTART_TYPE = "restart_type";
   private static final String COMMAND_PARAM_TASKS = "tasks";
   private static final String COMMAND_PARAM_STRUCT_OUT = "structured_out";
@@ -222,6 +229,8 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     // properties
     PROPERTY_IDS.add(UPGRADE_CLUSTER_NAME);
     PROPERTY_IDS.add(UPGRADE_VERSION);
+    PROPERTY_IDS.add(UPGRADE_TYPE);
+    PROPERTY_IDS.add(UPGRADE_PACK);
     PROPERTY_IDS.add(UPGRADE_REQUEST_ID);
     PROPERTY_IDS.add(UPGRADE_FROM_VERSION);
     PROPERTY_IDS.add(UPGRADE_TO_VERSION);
@@ -443,6 +452,8 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     ResourceImpl resource = new ResourceImpl(Resource.Type.Upgrade);
 
     setResourceProperty(resource, UPGRADE_CLUSTER_NAME, clusterName, requestedIds);
+    setResourceProperty(resource, UPGRADE_TYPE, entity.getUpgradeType().toString(), requestedIds);
+    setResourceProperty(resource, UPGRADE_PACK, entity.getUpgradePackage(), requestedIds);
     setResourceProperty(resource, UPGRADE_REQUEST_ID, entity.getRequestId(), requestedIds);
     setResourceProperty(resource, UPGRADE_FROM_VERSION, entity.getFromVersion(), requestedIds);
     setResourceProperty(resource, UPGRADE_TO_VERSION, entity.getToVersion(), requestedIds);
@@ -467,6 +478,16 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     boolean skipPrereqChecks = Boolean.parseBoolean((String) requestMap.get(UPGRADE_SKIP_PREREQUISITE_CHECKS));
     boolean failOnCheckWarnings = Boolean.parseBoolean((String) requestMap.get(UPGRADE_FAIL_ON_CHECK_WARNINGS));
 
+    /**
+     * For the unit tests tests, there are multiple upgrade packs for the same type, so
+     * allow picking one of them. In prod, this is empty.
+     */
+    String preferredUpgradePackName = (String) requestMap.get(UPGRADE_PACK);
+
+    // Default to ROLLING upgrade, but attempt to read from properties.
+    final UpgradeType upgradeType = requestMap.containsKey(UPGRADE_TYPE) ?
+        UpgradeType.valueOf((String) requestMap.get(UPGRADE_TYPE)) : UpgradeType.ROLLING;
+
     if (null == clusterName) {
       throw new AmbariException(String.format("%s is required", UPGRADE_CLUSTER_NAME));
     }
@@ -475,6 +496,9 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
       throw new AmbariException(String.format("%s is required", UPGRADE_VERSION));
     }
 
+    return s_upgradeHelper.suggestUpgradePack(clusterName, versionForUpgradePack, version, direction, upgradeType);
+    // TODO AMBARI-12698, reconcile these changes.
+    /*
     Cluster cluster = getManagementController().getClusters().getCluster(clusterName);
 
     // !!! find upgrade packs based on current stack. This is where to upgrade
@@ -494,26 +518,33 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     }
 
     Map<String, UpgradePack> packs = s_metaProvider.get().getUpgradePacks(stack.getStackName(),
-        stack.getStackVersion());
+            stack.getStackVersion());
 
-    UpgradePack up = packs.get(versionEntity.getUpgradePackage());
+    UpgradePack pack = null;
+    if (preferredUpgradePackName != null && !preferredUpgradePackName.isEmpty() && packs.containsKey(preferredUpgradePackName)) {
+      pack = packs.get(preferredUpgradePackName);
+    }
 
-    if (null == up) {
+    if (null == pack) {
       // !!! in case there is an upgrade pack that doesn't match the name
       String repoStackId = versionEntity.getStackId().getStackId();
       for (UpgradePack upgradePack : packs.values()) {
-        if (null != upgradePack.getTargetStack()
-            && upgradePack.getTargetStack().equals(repoStackId)) {
-          up = upgradePack;
-          break;
+        if (null != upgradePack.getTargetStack() && upgradePack.getTargetStack().equals(repoStackId) && upgradeType == upgradePack.getType()) {
+          if (null == pack) {
+            pack = upgradePack;
+          } else {
+            throw new AmbariException(
+                String.format("Unable to perform %s. Found multiple upgrade packs for type %s and target version %s",
+                    direction.getText(false), upgradeType.toString(), repoVersion));
+          }
         }
       }
     }
 
-    if (null == up) {
+    if (null == pack) {
       throw new AmbariException(
-          String.format("Unable to perform %s.  Could not locate upgrade pack %s for version %s",
-              direction.getText(false), versionEntity.getUpgradePackage(), repoVersion));
+          String.format("Unable to perform %s. Could not locate %s upgrade pack for version %s",
+              direction.getText(false), upgradeType.toString(), repoVersion));
     }
 
     // Validate there isn't an direction == upgrade/downgrade already in progress.
@@ -572,7 +603,8 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
       }
     }
 
-    return up;
+    return pack;
+    */
   }
 
   /**
@@ -648,7 +680,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     }
 
     UpgradeContext ctx = new UpgradeContext(resolver, sourceStackId, targetStackId, version,
-        direction);
+        direction, pack.getType());
 
     if (direction.isDowngrade()) {
       if (requestMap.containsKey(UPGRADE_FROM_VERSION)) {
@@ -688,9 +720,39 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     List<UpgradeGroupEntity> groupEntities = new ArrayList<UpgradeGroupEntity>();
     RequestStageContainer req = createRequest(direction, version);
 
-    // desired configs must be set before creating stages because the config tag
-    // names are read and set on the command for filling in later
-    processConfigurations(targetStackId.getStackName(), cluster, version, direction, pack);
+    /**
+    During a Rolling Upgrade, change the desired Stack Id if jumping across
+    major stack versions (e.g., HDP 2.2 -> 2.3), and then set config changes
+    so they are applied on the newer stack.
+
+    During a {@link UpgradeType.NON_ROLLING} upgrade, the stack is applied during the middle of the upgrade (after
+    stopping all services), and the configs are applied immediately before starting the services.
+    The Upgrade Pack is responsible for calling {@link org.apache.ambari.server.serveraction.upgrades.UpdateDesiredStackAction}
+    at the appropriate moment during the orchestration.
+    **/
+    if (pack.getType() == UpgradeType.ROLLING) {
+      // Desired configs must be set before creating stages because the config tag
+      // names are read and set on the command for filling in later
+      applyStackAndProcessConfigurations(targetStackId.getStackName(), cluster, version, direction, pack);
+    }
+
+    // Resolve or build a proper config upgrade pack
+    List<UpgradePack.IntermediateStack> intermediateStacks = pack.getIntermediateStacks();
+    ConfigUpgradePack configUpgradePack;
+    if (intermediateStacks == null || intermediateStacks.isEmpty()) { // No intermediate stacks
+      configUpgradePack = s_metaProvider.get().getConfigUpgradePack(
+              targetStackId.getStackName(), targetStackId.getStackVersion());
+    } else {
+      // For cross-stack upgrade, follow all major stacks and merge a new config upgrade pack from all
+      // target stacks involved into upgrade
+      ArrayList<ConfigUpgradePack> intermediateConfigUpgradePacks = new ArrayList<>();
+      for (UpgradePack.IntermediateStack intermediateStack : intermediateStacks) {
+        ConfigUpgradePack intermediateConfigUpgradePack = s_metaProvider.get().getConfigUpgradePack(
+                targetStackId.getStackName(), intermediateStack.version);
+        intermediateConfigUpgradePacks.add(intermediateConfigUpgradePack);
+      }
+      configUpgradePack = ConfigUpgradePack.merge(intermediateConfigUpgradePacks);
+    }
 
     for (UpgradeGroupHolder group : groups) {
       UpgradeGroupEntity groupEntity = new UpgradeGroupEntity();
@@ -713,11 +775,17 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
               itemEntity.setTasks(wrapper.getTasksJson());
               itemEntity.setHosts(wrapper.getHostsJson());
               itemEntities.add(itemEntity);
+              
+              // At this point, need to change the effective Stack Id so that subsequent tasks run on the newer value.
+              // TODO AMBARI-12698, check if this works during a Stop-the-World Downgrade.
+              if (UpdateStackGrouping.class.equals(group.groupClass)) {
+                ctx.setEffectiveStackId(ctx.getTargetStackId());
+              }
 
               injectVariables(configHelper, cluster, itemEntity);
 
               makeServerSideStage(ctx, req, itemEntity, (ServerSideActionTask) task, skippable,
-                  allowRetry);
+                  allowRetry, configUpgradePack);
             }
           }
         } else {
@@ -742,8 +810,10 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     entity.setFromVersion(cluster.getCurrentClusterVersion().getRepositoryVersion().getVersion());
     entity.setToVersion(version);
     entity.setUpgradeGroups(groupEntities);
-    entity.setClusterId(Long.valueOf(cluster.getClusterId()));
+    entity.setClusterId(cluster.getClusterId());
     entity.setDirection(direction);
+    entity.setUpgradePackage(pack.getName());
+    entity.setUpgradeType(pack.getType());
 
     req.getRequestStatusResponse();
 
@@ -790,7 +860,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
    *          which services are effected.
    * @throws AmbariException
    */
-  void processConfigurations(String stackName, Cluster cluster, String version, Direction direction, UpgradePack upgradePack)
+  void applyStackAndProcessConfigurations(String stackName, Cluster cluster, String version, Direction direction, UpgradePack upgradePack)
       throws AmbariException {
     RepositoryVersionEntity targetRve = s_repoVersionDAO.findByStackNameAndVersion(stackName, version);
     if (null == targetRve) {
@@ -822,6 +892,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     Map<String, Map<String, String>> newConfigurationsByType = null;
     ConfigHelper configHelper = getManagementController().getConfigHelper();
 
+    // TODO AMBARI-12698, handle jumping across several stacks
     if (direction == Direction.UPGRADE) {
       // populate a map of default configurations for the old stack (this is
       // used when determining if a property has been customized and should be
@@ -890,7 +961,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
           continue;
         }
 
-        // NPE sanity, althought shouldn't even happen since we are iterating
+        // NPE sanity, although shouldn't even happen since we are iterating
         // over the desired configs to start with
         Config currentClusterConfig = cluster.getDesiredConfigByType(configurationType);
         if (null == currentClusterConfig) {
@@ -977,8 +1048,10 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
           throws AmbariException {
 
     switch (wrapper.getType()) {
+      case START:
+      case STOP:
       case RESTART:
-        makeRestartStage(context, request, entity, wrapper, skippable, allowRetry);
+        makeCommandStage(context, request, entity, wrapper, skippable, allowRetry);
         break;
       case RU_TASKS:
         makeActionStage(context, request, entity, wrapper, skippable, allowRetry);
@@ -1018,7 +1091,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     // service, it is necessary to set the
     // service_package_folder and hooks_folder params.
     AmbariMetaInfo ambariMetaInfo = s_metaProvider.get();
-    StackId stackId = cluster.getDesiredStackVersion();
+    StackId stackId = context.getEffectiveStackId();
 
     StackInfo stackInfo = ambariMetaInfo.getStack(stackId.getStackName(),
         stackId.getStackVersion());
@@ -1041,7 +1114,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     actionContext.setAutoSkipFailures(context.isComponentFailureAutoSkipped());
 
     ExecuteCommandJson jsons = s_commandExecutionHelper.get().getCommandJson(actionContext,
-        cluster);
+        cluster, context.getEffectiveStackId());
 
     Stage stage = s_stageFactory.get().createNew(request.getId().longValue(), "/tmp/ambari",
         cluster.getClusterName(), cluster.getClusterId(), entity.getText(),
@@ -1070,7 +1143,17 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     request.addStages(Collections.singletonList(stage));
   }
 
-  private void makeRestartStage(UpgradeContext context, RequestStageContainer request,
+  /**
+   * Used to create a stage for restart, start, or stop.
+   * @param context Upgrade Context
+   * @param request Container for stage
+   * @param entity Upgrade Item
+   * @param wrapper Stage
+   * @param skippable Whether the item can be skipped
+   * @param allowRetry Whether the item is allowed to be retried
+   * @throws AmbariException
+   */
+  private void makeCommandStage(UpgradeContext context, RequestStageContainer request,
       UpgradeItemEntity entity, StageWrapper wrapper, boolean skippable, boolean allowRetry)
           throws AmbariException {
 
@@ -1084,23 +1167,43 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
           new ArrayList<String>(tw.getHosts())));
     }
 
-    Map<String, String> restartCommandParams = getNewParameterMap();
-    restartCommandParams.put(COMMAND_PARAM_RESTART_TYPE, "rolling_upgrade");
-    restartCommandParams.put(COMMAND_PARAM_VERSION, context.getVersion());
-    restartCommandParams.put(COMMAND_PARAM_DIRECTION, context.getDirection().name().toLowerCase());
-    restartCommandParams.put(COMMAND_PARAM_ORIGINAL_STACK,context.getOriginalStackId().getStackId());
-    restartCommandParams.put(COMMAND_PARAM_TARGET_STACK, context.getTargetStackId().getStackId());
-    restartCommandParams.put(COMMAND_DOWNGRADE_FROM_VERSION, context.getDowngradeFromVersion());
+    String function = null;
+    switch (wrapper.getType()) {
+      case START:
+      case STOP:
+      case RESTART:
+        function = wrapper.getType().name();
+        break;
+      default:
+        function = "UNKNOWN";
+        break;
+    }
+
+    Map<String, String> commandParams = getNewParameterMap();
+
+    // TODO AMBARI-12698, change COMMAND_PARAM_RESTART_TYPE to something that isn't "RESTART" specific.
+    if (context.getType() == UpgradeType.ROLLING) {
+      commandParams.put(COMMAND_PARAM_RESTART_TYPE, "rolling_upgrade");
+    }
+    if (context.getType() == UpgradeType.NON_ROLLING) {
+      commandParams.put(COMMAND_PARAM_RESTART_TYPE, "nonrolling_upgrade");
+    }
+
+    commandParams.put(COMMAND_PARAM_VERSION, context.getVersion());
+    commandParams.put(COMMAND_PARAM_DIRECTION, context.getDirection().name().toLowerCase());
+    commandParams.put(COMMAND_PARAM_ORIGINAL_STACK, context.getOriginalStackId().getStackId());
+    commandParams.put(COMMAND_PARAM_TARGET_STACK, context.getTargetStackId().getStackId());
+    commandParams.put(COMMAND_DOWNGRADE_FROM_VERSION, context.getDowngradeFromVersion());
 
     ActionExecutionContext actionContext = new ActionExecutionContext(cluster.getClusterName(),
-        "RESTART", filters, restartCommandParams);
+        function, filters, commandParams);
     actionContext.setTimeout(Short.valueOf(s_configuration.getDefaultAgentTaskTimeout(false)));
     actionContext.setIgnoreMaintenance(true);
     actionContext.setRetryAllowed(allowRetry);
     actionContext.setAutoSkipFailures(context.isComponentFailureAutoSkipped());
 
     ExecuteCommandJson jsons = s_commandExecutionHelper.get().getCommandJson(actionContext,
-        cluster);
+        cluster, context.getEffectiveStackId());
 
     Stage stage = s_stageFactory.get().createNew(request.getId().longValue(), "/tmp/ambari",
         cluster.getClusterName(), cluster.getClusterId(), entity.getText(),
@@ -1118,7 +1221,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     entity.setStageId(Long.valueOf(stageId));
 
     Map<String, String> requestParams = new HashMap<String, String>();
-    requestParams.put("command", "RESTART");
+    requestParams.put("command", function);
 
     s_commandExecutionHelper.get().addExecutionCommandsToStage(actionContext, stage, requestParams);
 
@@ -1153,7 +1256,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     actionContext.setAutoSkipFailures(context.isServiceCheckFailureAutoSkipped());
 
     ExecuteCommandJson jsons = s_commandExecutionHelper.get().getCommandJson(actionContext,
-        cluster);
+        cluster, context.getEffectiveStackId());
 
     Stage stage = s_stageFactory.get().createNew(request.getId().longValue(), "/tmp/ambari",
         cluster.getClusterName(), cluster.getClusterId(), entity.getText(),
@@ -1176,8 +1279,22 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     request.addStages(Collections.singletonList(stage));
   }
 
+  /**
+   * Creates a stage consisting of server side actions
+   * @param context upgrade context
+   * @param request upgrade request
+   * @param entity a single of upgrade
+   * @param task server-side task (if any)
+   * @param skippable if user can skip stage on failure
+   * @param allowRetry if user can retry running stage on failure
+   * @param configUpgradePack a runtime-generated config upgrade pack that
+   * contains all config change definitions from all stacks involved into
+   * upgrade
+   * @throws AmbariException
+   */
   private void makeServerSideStage(UpgradeContext context, RequestStageContainer request,
-      UpgradeItemEntity entity, ServerSideActionTask task, boolean skippable, boolean allowRetry)
+      UpgradeItemEntity entity, ServerSideActionTask task, boolean skippable, boolean allowRetry,
+      ConfigUpgradePack configUpgradePack)
           throws AmbariException {
 
     Cluster cluster = context.getCluster();
@@ -1225,7 +1342,8 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
       }
       case CONFIGURE: {
         ConfigureTask ct = (ConfigureTask) task;
-        Map<String, String> configurationChanges = ct.getConfigurationChanges(cluster);
+        Map<String, String> configurationChanges =
+                ct.getConfigurationChanges(cluster, configUpgradePack);
 
         // add all configuration changes to the command params
         commandParams.putAll(configurationChanges);
@@ -1262,7 +1380,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     actionContext.setAutoSkipFailures(context.isComponentFailureAutoSkipped());
 
     ExecuteCommandJson jsons = s_commandExecutionHelper.get().getCommandJson(actionContext,
-        cluster);
+        cluster, context.getEffectiveStackId());
 
     Stage stage = s_stageFactory.get().createNew(request.getId().longValue(), "/tmp/ambari",
         cluster.getClusterName(), cluster.getClusterId(), stageText, jsons.getClusterHostInfo(),

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/metadata/ActionMetadata.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/metadata/ActionMetadata.java b/ambari-server/src/main/java/org/apache/ambari/server/metadata/ActionMetadata.java
index e821827..f5642a0 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/metadata/ActionMetadata.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/metadata/ActionMetadata.java
@@ -58,8 +58,10 @@ public class ActionMetadata {
 
   private void fillHostComponentCommands() {
     //Standart commands for any host component
-    // TODO: Add START/STOP/INSTALL commands
     defaultHostComponentCommands.add("RESTART");
+    defaultHostComponentCommands.add("START");
+    defaultHostComponentCommands.add("STOP");
+    defaultHostComponentCommands.add("INSTALL");
     defaultHostComponentCommands.add("CONFIGURE");
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterVersionDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterVersionDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterVersionDAO.java
index d3326b1..8d4c5ee 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterVersionDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterVersionDAO.java
@@ -23,8 +23,11 @@ import javax.persistence.NoResultException;
 import javax.persistence.NonUniqueResultException;
 import javax.persistence.TypedQuery;
 
+import com.google.inject.persist.Transactional;
 import org.apache.ambari.server.orm.RequiresSession;
+import org.apache.ambari.server.orm.entities.ClusterEntity;
 import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
+import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 import org.apache.ambari.server.state.RepositoryVersionState;
 import org.apache.ambari.server.state.StackId;
 
@@ -153,4 +156,24 @@ public class ClusterVersionDAO extends CrudDAO<ClusterVersionEntity, Long>{
 
     return daoUtils.selectList(query);
   }
+
+  /**
+   * Construct a Cluster Version and return it. This is primarily used to be able to construct the object and mock
+   * the function call.
+   * @param cluster Cluster
+   * @param repositoryVersion Repository Version
+   * @param state Initial State
+   * @param startTime Start Time
+   * @param endTime End Time
+   * @param userName Username, such as "admin"
+   * @return Return new ClusterVersion object.
+   */
+  @Transactional
+  public ClusterVersionEntity create(ClusterEntity cluster, RepositoryVersionEntity repositoryVersion,
+                                     RepositoryVersionState state, long startTime, long endTime, String userName) {
+    ClusterVersionEntity clusterVersionEntity = new ClusterVersionEntity(cluster,
+        repositoryVersion, state, startTime, endTime, userName);
+    this.create(clusterVersionEntity);
+    return clusterVersionEntity;
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/CrudDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/CrudDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/CrudDAO.java
index 4382f59..ed0a931 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/CrudDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/CrudDAO.java
@@ -73,6 +73,21 @@ public class CrudDAO<E, K> {
   }
 
   /**
+   * Retrieves the maximum ID from the entities.
+   *
+   * @param idColName name of the column that corresponds to the ID.
+   * @return maximum ID, or 0 if none exist.
+   */
+  @RequiresSession
+  public Long findMaxId(String idColName) {
+    final TypedQuery<Long> query = entityManagerProvider.get().createQuery("SELECT MAX(entity." + idColName + ") FROM "
+        + entityClass.getSimpleName() + " entity", Long.class);
+    // May be null if no results.
+    Long result = daoUtils.selectOne(query);
+    return result == null ? 0 : result;
+  }
+
+  /**
    * Creates entity.
    *
    * @param entity entity to create

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java
index a2ff211..ad617af 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java
@@ -43,21 +43,17 @@ import com.google.inject.persist.Transactional;
  * {@link org.apache.ambari.server.state.RepositoryVersionState#UPGRADING}.
  */
 @Singleton
-public class HostVersionDAO {
+public class HostVersionDAO extends CrudDAO<HostVersionEntity, Long> {
   @Inject
   Provider<EntityManager> entityManagerProvider;
   @Inject
   DaoUtils daoUtils;
 
   /**
-   * Get the object with the given id.
-   *
-   * @param id Primary key id
-   * @return Return the object with the given primary key
+   * Constructor.
    */
-  @RequiresSession
-  public HostVersionEntity findByPK(long id) {
-    return entityManagerProvider.get().find(HostVersionEntity.class, id);
+  public HostVersionDAO() {
+    super(HostVersionEntity.class);
   }
 
   /**
@@ -189,31 +185,6 @@ public class HostVersionDAO {
     return daoUtils.selectSingle(query);
   }
 
-  @RequiresSession
-  public List<HostVersionEntity> findAll() {
-    return daoUtils.selectAll(entityManagerProvider.get(), HostVersionEntity.class);
-  }
-
-  @Transactional
-  public void refresh(HostVersionEntity hostVersionEntity) {
-    entityManagerProvider.get().refresh(hostVersionEntity);
-  }
-
-  @Transactional
-  public void create(HostVersionEntity hostVersionEntity) {
-    entityManagerProvider.get().persist(hostVersionEntity);
-  }
-
-  @Transactional
-  public HostVersionEntity merge(HostVersionEntity hostVersionEntity) {
-    return entityManagerProvider.get().merge(hostVersionEntity);
-  }
-
-  @Transactional
-  public void remove(HostVersionEntity hostVersionEntity) {
-    entityManagerProvider.get().remove(merge(hostVersionEntity));
-  }
-
   @Transactional
   public void removeByHostName(String hostName) {
     Collection<HostVersionEntity> hostVersions = this.findByHost(hostName);
@@ -221,9 +192,4 @@ public class HostVersionDAO {
       this.remove(hostVersion);
     }
   }
-
-  @Transactional
-  public void removeByPK(long id) {
-    remove(findByPK(id));
-  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAO.java
index 4ac1314..9f5f6f1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAO.java
@@ -129,15 +129,13 @@ public class RepositoryVersionDAO extends CrudDAO<RepositoryVersionEntity, Long>
    * @param stackEntity Stack entity.
    * @param version Stack version, e.g., 2.2 or 2.2.0.1-885
    * @param displayName Unique display name
-   * @param upgradePack Optional upgrade pack, e.g, upgrade-2.2
    * @param operatingSystems JSON structure of repository URLs for each OS
    * @return Returns the object created if successful, and throws an exception otherwise.
    * @throws AmbariException
    */
   @Transactional
   public RepositoryVersionEntity create(StackEntity stackEntity,
-      String version, String displayName, String upgradePack,
-      String operatingSystems) throws AmbariException {
+      String version, String displayName, String operatingSystems) throws AmbariException {
 
     if (stackEntity == null || version == null || version.isEmpty()
         || displayName == null || displayName.isEmpty()) {
@@ -164,7 +162,7 @@ public class RepositoryVersionDAO extends CrudDAO<RepositoryVersionEntity, Long>
     }
 
     RepositoryVersionEntity newEntity = new RepositoryVersionEntity(
-        stackEntity, version, displayName, upgradePack, operatingSystems);
+        stackEntity, version, displayName, operatingSystems);
     this.create(newEntity);
     return newEntity;
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/UpgradeDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/UpgradeDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/UpgradeDAO.java
index bc0652c..06f6ac1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/UpgradeDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/UpgradeDAO.java
@@ -48,6 +48,18 @@ public class UpgradeDAO {
   private DaoUtils daoUtils;
 
   /**
+   * Get all items.
+   * @return List of all of the UpgradeEntity items.
+   */
+  @RequiresSession
+  public List<UpgradeEntity> findAll() {
+    TypedQuery<UpgradeEntity> query = entityManagerProvider.get().createNamedQuery(
+        "UpgradeEntity.findAll", UpgradeEntity.class);
+
+    return daoUtils.selectList(query);
+  }
+
+  /**
    * @param clusterId the cluster id
    * @return the list of upgrades initiated for the cluster
    */
@@ -157,8 +169,7 @@ public class UpgradeDAO {
   }
 
   /**
-   * @param requestId the request id
-   * @param stageId the stage id
+   * @param clusterId the cluster id
    * @return the upgrade entity, or {@code null} if not found
    */
   @RequiresSession
@@ -174,4 +185,8 @@ public class UpgradeDAO {
     return daoUtils.selectSingle(query);
   }
 
+  @Transactional
+  public UpgradeEntity merge(UpgradeEntity upgradeEntity) {
+    return entityManagerProvider.get().merge(upgradeEntity);
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryVersionEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryVersionEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryVersionEntity.java
index 0fb2f10..16b7c1c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryVersionEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryVersionEntity.java
@@ -90,9 +90,6 @@ public class RepositoryVersionEntity {
   @Column(name = "display_name")
   private String displayName;
 
-  @Column(name = "upgrade_package")
-  private String upgradePackage;
-
   @Lob
   @Column(name = "repositories")
   private String operatingSystems;
@@ -110,11 +107,10 @@ public class RepositoryVersionEntity {
   }
 
   public RepositoryVersionEntity(StackEntity stack, String version,
-      String displayName, String upgradePackage, String operatingSystems) {
+      String displayName, String operatingSystems) {
     this.stack = stack;
     this.version = version;
     this.displayName = displayName;
-    this.upgradePackage = upgradePackage;
     this.operatingSystems = operatingSystems;
   }
 
@@ -161,14 +157,6 @@ public class RepositoryVersionEntity {
     this.displayName = displayName;
   }
 
-  public String getUpgradePackage() {
-    return upgradePackage;
-  }
-
-  public void setUpgradePackage(String upgradePackage) {
-    this.upgradePackage = upgradePackage;
-  }
-
   public String getOperatingSystemsJson() {
     return operatingSystems;
   }
@@ -233,9 +221,6 @@ public class RepositoryVersionEntity {
     if (displayName != null ? !displayName.equals(that.displayName) : that.displayName != null) {
       return false;
     }
-    if (upgradePackage != null ? !upgradePackage.equals(that.upgradePackage) : that.upgradePackage != null) {
-      return false;
-    }
     if (operatingSystems != null ? !operatingSystems.equals(that.operatingSystems) : that.operatingSystems != null) {
       return false;
     }
@@ -249,7 +234,6 @@ public class RepositoryVersionEntity {
     result = 31 * result + (stack != null ? stack.hashCode() : 0);
     result = 31 * result + (version != null ? version.hashCode() : 0);
     result = 31 * result + (displayName != null ? displayName.hashCode() : 0);
-    result = 31 * result + (upgradePackage != null ? upgradePackage.hashCode() : 0);
     result = 31 * result + (operatingSystems != null ? operatingSystems.hashCode() : 0);
     return result;
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradeEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradeEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradeEntity.java
index 802ea03..ad9073a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradeEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradeEntity.java
@@ -34,6 +34,7 @@ import javax.persistence.Table;
 import javax.persistence.TableGenerator;
 
 import org.apache.ambari.server.state.stack.upgrade.Direction;
+import org.apache.ambari.server.state.stack.upgrade.UpgradeType;
 
 /**
  * Models the data representation of an upgrade
@@ -44,6 +45,8 @@ import org.apache.ambari.server.state.stack.upgrade.Direction;
     table = "ambari_sequences", pkColumnName = "sequence_name", valueColumnName = "sequence_value",
     pkColumnValue = "upgrade_id_seq", initialValue = 0)
 @NamedQueries({
+  @NamedQuery(name = "UpgradeEntity.findAll",
+      query = "SELECT u FROM UpgradeEntity u"),
   @NamedQuery(name = "UpgradeEntity.findAllForCluster",
       query = "SELECT u FROM UpgradeEntity u WHERE u.clusterId = :clusterId"),
   @NamedQuery(name = "UpgradeEntity.findUpgrade",
@@ -74,6 +77,13 @@ public class UpgradeEntity {
   @Enumerated(value = EnumType.STRING)
   private Direction direction = Direction.UPGRADE;
 
+  @Column(name="upgrade_package", nullable = false)
+  private String upgradePackage;
+
+  @Column(name="upgrade_type", nullable = false)
+  @Enumerated(value = EnumType.STRING)
+  private UpgradeType upgradeType;
+
   @OneToMany(mappedBy = "upgradeEntity", cascade = { CascadeType.ALL })
   private List<UpgradeGroupEntity> upgradeGroupEntities;
 
@@ -179,5 +189,84 @@ public class UpgradeEntity {
     this.direction = direction;
   }
 
+  /**
+   * @return the upgrade type, such as rolling or non_rolling
+   */
+  public UpgradeType getUpgradeType() {
+    return upgradeType;
+  }
+
+  /**
+   * @param upgradeType the upgrade type to set
+   */
+  public void setUpgradeType(UpgradeType upgradeType) {
+    this.upgradeType = upgradeType;
+  }
+
+  /**
+   * @return the upgrade package name, without the extension.
+   */
+  public String getUpgradePackage() {
+    return upgradePackage;
+  }
+
+  /**
+   * @param upgradePackage the upgrade pack to set
+   */
+  public void setUpgradePackage(String upgradePackage) {
+    this.upgradePackage = upgradePackage;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+
+    UpgradeEntity that = (UpgradeEntity) o;
+
+    if (upgradeId != null ? !upgradeId.equals(that.upgradeId) : that.upgradeId != null) {
+      return false;
+    }
+    if (clusterId != null ? !clusterId.equals(that.clusterId) : that.clusterId != null) {
+      return false;
+    }
+    if (requestId != null ? !requestId.equals(that.requestId) : that.requestId != null) {
+      return false;
+    }
+    if (fromVersion != null ? !fromVersion.equals(that.fromVersion) : that.fromVersion != null) {
+      return false;
+    }
+    if (toVersion != null ? !toVersion.equals(that.toVersion) : that.toVersion != null) {
+      return false;
+    }
+    if (direction != null ? !direction.equals(that.direction) : that.direction != null) {
+      return false;
+    }
+    if (upgradeType != null ? !upgradeType.equals(that.upgradeType) : that.upgradeType != null) {
+      return false;
+    }
+    if (upgradePackage != null ? !upgradePackage.equals(that.upgradePackage) : that.upgradePackage != null) {
+      return false;
+    }
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = upgradeId != null ? upgradeId.hashCode() : 0;
+    result = 31 * result + (clusterId != null ? clusterId.hashCode() : 0);
+    result = 31 * result + (requestId != null ? requestId.hashCode() : 0);
+    result = 31 * result + (fromVersion != null ? fromVersion.hashCode() : 0);
+    result = 31 * result + (toVersion != null ? toVersion.hashCode() : 0);
+    result = 31 * result + (direction != null ? direction.hashCode() : 0);
+    result = 31 * result + (upgradeType != null ? upgradeType.hashCode() : 0);
+    result = 31 * result + (upgradePackage != null ? upgradePackage.hashCode() : 0);
+    return result;
+  }
 
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/ConfigureAction.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/ConfigureAction.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/ConfigureAction.java
index c717582..ef21a2a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/ConfigureAction.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/ConfigureAction.java
@@ -46,7 +46,10 @@ import org.apache.ambari.server.state.DesiredConfig;
 import org.apache.ambari.server.state.PropertyInfo;
 import org.apache.ambari.server.state.StackId;
 import org.apache.ambari.server.state.stack.upgrade.ConfigureTask;
-import org.apache.ambari.server.state.stack.upgrade.ConfigureTask.ConfigurationKeyValue;
+import org.apache.ambari.server.state.stack.upgrade.ConfigUpgradeChangeDefinition.ConfigurationKeyValue;
+import org.apache.ambari.server.state.stack.upgrade.ConfigUpgradeChangeDefinition.Transfer;
+import org.apache.ambari.server.state.stack.upgrade.ConfigUpgradeChangeDefinition.Replace;
+import org.apache.ambari.server.state.stack.upgrade.ConfigUpgradeChangeDefinition.Masked;
 import org.apache.commons.lang.StringUtils;
 
 import com.google.gson.Gson;
@@ -176,27 +179,27 @@ public class ConfigureAction extends AbstractServerAction {
     String configType = commandParameters.get(ConfigureTask.PARAMETER_CONFIG_TYPE);
 
     // extract transfers
-    List<ConfigureTask.ConfigurationKeyValue> keyValuePairs = Collections.emptyList();
+    List<ConfigurationKeyValue> keyValuePairs = Collections.emptyList();
     String keyValuePairJson = commandParameters.get(ConfigureTask.PARAMETER_KEY_VALUE_PAIRS);
     if (null != keyValuePairJson) {
       keyValuePairs = m_gson.fromJson(
-          keyValuePairJson, new TypeToken<List<ConfigureTask.ConfigurationKeyValue>>(){}.getType());
+          keyValuePairJson, new TypeToken<List<ConfigurationKeyValue>>(){}.getType());
     }
 
     // extract transfers
-    List<ConfigureTask.Transfer> transfers = Collections.emptyList();
+    List<Transfer> transfers = Collections.emptyList();
     String transferJson = commandParameters.get(ConfigureTask.PARAMETER_TRANSFERS);
     if (null != transferJson) {
       transfers = m_gson.fromJson(
-        transferJson, new TypeToken<List<ConfigureTask.Transfer>>(){}.getType());
+        transferJson, new TypeToken<List<Transfer>>(){}.getType());
     }
 
     // extract replacements
-    List<ConfigureTask.Replace> replacements = Collections.emptyList();
+    List<Replace> replacements = Collections.emptyList();
     String replaceJson = commandParameters.get(ConfigureTask.PARAMETER_REPLACEMENTS);
     if (null != replaceJson) {
       replacements = m_gson.fromJson(
-          replaceJson, new TypeToken<List<ConfigureTask.Replace>>(){}.getType());
+          replaceJson, new TypeToken<List<Replace>>(){}.getType());
     }
 
     // if there is nothing to do, then skip the task
@@ -240,7 +243,7 @@ public class ConfigureAction extends AbstractServerAction {
 
     // !!! do transfers first before setting defined values
     StringBuilder outputBuffer = new StringBuilder(250);
-    for (ConfigureTask.Transfer transfer : transfers) {
+    for (Transfer transfer : transfers) {
       switch (transfer.operation) {
         case COPY:
           String valueToCopy = null;
@@ -400,7 +403,7 @@ public class ConfigureAction extends AbstractServerAction {
     }
 
     // !!! string replacements happen only on the new values.
-    for (ConfigureTask.Replace replacement : replacements) {
+    for (Replace replacement : replacements) {
       if (newValues.containsKey(replacement.key)) {
         String toReplace = newValues.get(replacement.key);
 
@@ -534,7 +537,7 @@ public class ConfigureAction extends AbstractServerAction {
     return result;
   }
 
-  private static String mask(ConfigureTask.Masked mask, String value) {
+  private static String mask(Masked mask, String value) {
     if (mask.mask) {
       return StringUtils.repeat("*", value.length());
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/UpdateDesiredStackAction.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/UpdateDesiredStackAction.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/UpdateDesiredStackAction.java
new file mode 100644
index 0000000..b676c9b
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/UpdateDesiredStackAction.java
@@ -0,0 +1,139 @@
+/**
+ * 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 com.google.inject.Inject;
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.actionmanager.HostRoleStatus;
+import org.apache.ambari.server.agent.CommandReport;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.serveraction.AbstractServerAction;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.StackInfo;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * Action that represents updating the Desired Stack Id during the middle of a stack upgrade (typically NonRolling).
+ * In a {@link org.apache.ambari.server.state.stack.upgrade.UpgradeType#NON_ROLLING}, the effective Stack Id is
+ * actually changed half-way through calculating the Actions, and this serves to update the database to make it
+ * evident to the user at which point it changed.
+ */
+public class UpdateDesiredStackAction extends AbstractServerAction {
+
+  /**
+   * The original "current" stack of the cluster before the upgrade started.
+   * This is the same regardless of whether the current direction is
+   * {@link org.apache.ambari.server.state.stack.upgrade.Direction#UPGRADE} or {@link org.apache.ambari.server.state.stack.upgrade.Direction#DOWNGRADE}.
+   */
+  public static final String ORIGINAL_STACK_KEY = "original_stack";
+
+  /**
+   * The target upgrade stack before the upgrade started. This is the same
+   * regardless of whether the current direction is {@link org.apache.ambari.server.state.stack.upgrade.Direction#UPGRADE} or
+   * {@link org.apache.ambari.server.state.stack.upgrade.Direction#DOWNGRADE}.
+   */
+  public static final String TARGET_STACK_KEY = "target_stack";
+
+  /**
+   * The Cluster that this ServerAction implementation is executing on.
+   */
+  @Inject
+  private Clusters clusters;
+
+  @Inject
+  private AmbariMetaInfo ambariMetaInfo;
+
+  @Override
+  public CommandReport execute(ConcurrentMap<String, Object> requestSharedDataContext)
+      throws AmbariException, InterruptedException {
+    Map<String, String> commandParams = getExecutionCommand().getCommandParams();
+
+    StackId originalStackId = new StackId(commandParams.get(ORIGINAL_STACK_KEY));
+    StackId targetStackId = new StackId(commandParams.get(TARGET_STACK_KEY));
+    String clusterName = getExecutionCommand().getClusterName();
+
+    return updateDesiredStack(clusterName, originalStackId, targetStackId);
+  }
+
+  /**
+   * Set the cluster's Desired Stack Id during an upgrade.
+   *
+   * @param clusterName the name of the cluster the action is meant for
+   * @paran originalStackId the stack Id of the cluster before the upgrade.
+   * @paran targetStackId the stack Id that was desired for this upgrade.
+   * @return the command report to return
+   */
+  private CommandReport updateDesiredStack(String clusterName, StackId originalStackId, StackId targetStackId)
+      throws AmbariException, InterruptedException {
+    StringBuilder out = new StringBuilder();
+    StringBuilder err = new StringBuilder();
+
+    try {
+      Cluster cluster = clusters.getCluster(clusterName);
+      StackId currentClusterStackId = cluster.getCurrentStackVersion();
+
+      out.append(String.format("Checking if can update the Desired Stack Id to %s. The cluster's current Stack Id is %s\n", targetStackId.getStackId(), currentClusterStackId.getStackId()));
+
+      // Ensure that the target stack id exist
+      StackInfo desiredClusterStackInfo = ambariMetaInfo.getStack(targetStackId.getStackName(), targetStackId.getStackVersion());
+      if (null == desiredClusterStackInfo) {
+        String message = String.format("Parameter %s has an invalid value: %s. That Stack Id does not exist.\n",
+            TARGET_STACK_KEY, targetStackId.getStackId());
+        err.append(message);
+        out.append(message);
+        return createCommandReport(-1, HostRoleStatus.FAILED, "{}", out.toString(), err.toString());
+      }
+
+      // Ensure that the current Stack Id coincides with the parameter that the user passed in.
+      if (!currentClusterStackId.equals(originalStackId)) {
+        String message = String.format("Parameter %s has invalid value: %s. " +
+            "The cluster is currently on stack %s, " + currentClusterStackId.getStackId() +
+            ", yet the parameter to this function indicates a different value.\n", ORIGINAL_STACK_KEY, targetStackId.getStackId(), currentClusterStackId.getStackId());
+        err.append(message);
+        out.append(message);
+        return createCommandReport(-1, HostRoleStatus.FAILED, "{}", out.toString(), err.toString());
+      }
+
+      // Check for a no-op
+      if (currentClusterStackId.equals(targetStackId)) {
+        String message = String.format("Success! The cluster's Desired Stack Id was already set to %s\n", targetStackId.getStackId());
+        out.append(message);
+        return createCommandReport(0, HostRoleStatus.COMPLETED, "{}", out.toString(), err.toString());
+      }
+
+      cluster.setDesiredStackVersion(targetStackId, true);
+      String message = String.format("Success! Set cluster's %s Desired Stack Id to %s.\n", clusterName, targetStackId.getStackId());
+      out.append(message);
+
+      return createCommandReport(0, HostRoleStatus.COMPLETED, "{}", out.toString(), err.toString());
+    } catch (Exception e) {
+      StringWriter sw = new StringWriter();
+      e.printStackTrace(new PrintWriter(sw));
+      err.append(sw.toString());
+
+      return createCommandReport(-1, HostRoleStatus.FAILED, "{}", out.toString(), err.toString());
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/stack/ModuleFileUnmarshaller.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/ModuleFileUnmarshaller.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/ModuleFileUnmarshaller.java
index aa8e17b..9e2f997 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/ModuleFileUnmarshaller.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/ModuleFileUnmarshaller.java
@@ -18,6 +18,7 @@
 
 package org.apache.ambari.server.stack;
 
+import org.apache.ambari.server.state.stack.ConfigUpgradePack;
 import org.apache.ambari.server.state.stack.ConfigurationXml;
 import org.apache.ambari.server.state.stack.RepositoryXml;
 import org.apache.ambari.server.state.stack.ServiceMetainfoXml;
@@ -63,12 +64,13 @@ class ModuleFileUnmarshaller {
     try {
       // three classes define the top-level element "metainfo", so we need 3 contexts.
       JAXBContext ctx = JAXBContext.newInstance(StackMetainfoXml.class, RepositoryXml.class,
-          ConfigurationXml.class, UpgradePack.class);
+          ConfigurationXml.class, UpgradePack.class, ConfigUpgradePack.class);
 
       jaxbContexts.put(StackMetainfoXml.class, ctx);
       jaxbContexts.put(RepositoryXml.class, ctx);
       jaxbContexts.put(ConfigurationXml.class, ctx);
       jaxbContexts.put(UpgradePack.class, ctx);
+      jaxbContexts.put(ConfigUpgradePack.class, ctx);
       jaxbContexts.put(ServiceMetainfoXml.class, JAXBContext.newInstance(ServiceMetainfoXml.class));
     } catch (JAXBException e) {
       throw new RuntimeException (e);

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDefinitionDirectory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDefinitionDirectory.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDefinitionDirectory.java
index 8f81b5a..c739211 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDefinitionDirectory.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDefinitionDirectory.java
@@ -37,6 +37,8 @@ public abstract class StackDefinitionDirectory {
     }
   };
 
+  protected static final String CONFIG_UPGRADE_XML_FILENAME_PREFIX = "config-upgrade.xml";
+
   /**
    * underlying directory
    */

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDirectory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDirectory.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDirectory.java
index 89c10c6..515d031 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDirectory.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDirectory.java
@@ -23,6 +23,7 @@ import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.state.stack.RepositoryXml;
 import org.apache.ambari.server.state.stack.StackMetainfoXml;
 import org.apache.ambari.server.state.stack.StackRoleCommandOrder;
+import org.apache.ambari.server.state.stack.ConfigUpgradePack;
 import org.apache.ambari.server.state.stack.UpgradePack;
 import org.apache.commons.io.FilenameUtils;
 import org.codehaus.jackson.map.ObjectMapper;
@@ -95,10 +96,14 @@ public class StackDirectory extends StackDefinitionDirectory {
   /**
    * map of upgrade pack name to upgrade pack
    */
-  //todo: should be a collection but upgrade pack doesn't have a name attribute
   private Map<String, UpgradePack> upgradePacks;
 
   /**
+   * Config delta from prev stack
+   */
+  private ConfigUpgradePack configUpgradePack;
+
+  /**
    * metainfo file representation
    */
   private StackMetainfoXml metaInfoXml;
@@ -255,6 +260,13 @@ public class StackDirectory extends StackDefinitionDirectory {
   }
 
   /**
+   * @return Config delta from prev stack or null if no config upgrade patches available
+   */
+  public ConfigUpgradePack getConfigUpgradePack() {
+    return configUpgradePack;
+  }
+
+  /**
    * Obtain the object representation of the stack role_command_order.json file
    *
    * @return object representation of the stack role_command_order.json file
@@ -405,18 +417,35 @@ public class StackDirectory extends StackDefinitionDirectory {
    * @throws AmbariException if unable to parse stack upgrade file
    */
   private void parseUpgradePacks(Collection<String> subDirs) throws AmbariException {
-    Map<String, UpgradePack> upgradeMap = new HashMap<String, UpgradePack>();
+    Map<String, UpgradePack> upgradeMap = new HashMap<>();
+    ConfigUpgradePack configUpgradePack = null;
     if (subDirs.contains(UPGRADE_PACK_FOLDER_NAME)) {
       File f = new File(getAbsolutePath() + File.separator + UPGRADE_PACK_FOLDER_NAME);
       if (f.isDirectory()) {
         upgradesDir = f.getAbsolutePath();
         for (File upgradeFile : f.listFiles(XML_FILENAME_FILTER)) {
-          try {
-            upgradeMap.put(FilenameUtils.removeExtension(upgradeFile.getName()),
-                unmarshaller.unmarshal(UpgradePack.class, upgradeFile));
-          } catch (JAXBException e) {
-            throw new AmbariException("Unable to parse stack upgrade file at location: " +
-                upgradeFile.getAbsolutePath(), e);
+          if (upgradeFile.getName().toLowerCase().startsWith(CONFIG_UPGRADE_XML_FILENAME_PREFIX)) {
+            try { // Parse config upgrade pack
+              if (configUpgradePack == null) {
+                configUpgradePack = unmarshaller.unmarshal(ConfigUpgradePack.class, upgradeFile);
+              } else { // If user messed things up with lower/upper case filenames
+                throw new AmbariException(String.format("There are multiple files with name like %s" +
+                        upgradeFile.getAbsolutePath()));
+              }
+            } catch (JAXBException e) {
+              throw new AmbariException("Unable to parse stack upgrade file at location: " +
+                      upgradeFile.getAbsolutePath(), e);
+            }
+          } else {
+            try {
+              String upgradePackName = FilenameUtils.removeExtension(upgradeFile.getName());
+              UpgradePack pack = unmarshaller.unmarshal(UpgradePack.class, upgradeFile);
+              pack.setName(upgradePackName);
+              upgradeMap.put(upgradePackName, pack);
+            } catch (JAXBException e) {
+              throw new AmbariException("Unable to parse stack upgrade file at location: " +
+                      upgradeFile.getAbsolutePath(), e);
+            }
           }
         }
       }
@@ -429,6 +458,13 @@ public class StackDirectory extends StackDefinitionDirectory {
     if (! upgradeMap.isEmpty()) {
       upgradePacks = upgradeMap;
     }
+
+    if (configUpgradePack != null) {
+      this.configUpgradePack = configUpgradePack;
+    } else {
+      LOG.info("Stack '{}' doesn't contain config upgrade pack file", getPath());
+    }
+
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
index 4fe7ed7..def33f0 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
@@ -22,7 +22,6 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -422,6 +421,7 @@ public class StackModule extends BaseModule<StackModule, StackInfo> implements V
       stackInfo.setWidgetsDescriptorFileLocation(stackDirectory.getWidgetsDescriptorFilePath());
       stackInfo.setUpgradesFolder(stackDirectory.getUpgradesDir());
       stackInfo.setUpgradePacks(stackDirectory.getUpgradePacks());
+      stackInfo.setConfigUpgradePack(stackDirectory.getConfigUpgradePack());
       stackInfo.setRoleCommandOrder(stackDirectory.getRoleCommandOrder());
       populateConfigurationModules();
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java
index 8e9d092..e3ac3e0 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java
@@ -31,6 +31,7 @@ import java.util.Set;
 import org.apache.ambari.server.controller.StackVersionResponse;
 import org.apache.ambari.server.stack.Validable;
 import org.apache.ambari.server.state.stack.StackRoleCommandOrder;
+import org.apache.ambari.server.state.stack.ConfigUpgradePack;
 import org.apache.ambari.server.state.stack.UpgradePack;
 
 public class StackInfo implements Comparable<StackInfo>, Validable{
@@ -67,6 +68,7 @@ public class StackInfo implements Comparable<StackInfo>, Validable{
   private List<PropertyInfo> properties;
   private Map<String, Map<String, Map<String, String>>> configTypes;
   private Map<String, UpgradePack> upgradePacks;
+  private ConfigUpgradePack configUpgradePack;
   private StackRoleCommandOrder roleCommandOrder;
   private boolean valid = true;
 
@@ -373,23 +375,40 @@ public class StackInfo implements Comparable<StackInfo>, Validable{
   }
 
   /**
+   * Obtain all stack upgrade packs.
+   *
+   * @return map of upgrade pack name to upgrade pack or {@code null} if no packs
+   */
+  public Map<String, UpgradePack> getUpgradePacks() {
+    return upgradePacks;
+  }
+
+  /**
    * Set upgrade packs.
    *
-   * @param upgradePacks  map of upgrade packs
+   * @param upgradePacks map of upgrade packs
    */
   public void setUpgradePacks(Map<String, UpgradePack> upgradePacks) {
     this.upgradePacks = upgradePacks;
   }
 
   /**
-   * Obtain all stack upgrade packs.
-   *
-   * @return map of upgrade pack name to upgrade pack or {@code null} of no packs
+   * Get config upgrade pack for stack
+   * @return config upgrade pack for stack or null if it is
+   * not defined
    */
-  public Map<String, UpgradePack> getUpgradePacks() {
-    return upgradePacks;
+  public ConfigUpgradePack getConfigUpgradePack() {
+    return configUpgradePack;
   }
 
+  /**
+   * Set config upgrade pack for stack
+   * @param configUpgradePack config upgrade pack for stack or null if it is
+   * not defined
+   */
+  public void setConfigUpgradePack(ConfigUpgradePack configUpgradePack) {
+    this.configUpgradePack = configUpgradePack;
+  }
 
   @Override
   public int compareTo(StackInfo o) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeContext.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeContext.java b/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeContext.java
index b10db9e..15559a3 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeContext.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeContext.java
@@ -25,6 +25,7 @@ import java.util.Map;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.stack.MasterHostResolver;
 import org.apache.ambari.server.state.stack.upgrade.Direction;
+import org.apache.ambari.server.state.stack.upgrade.UpgradeType;
 
 /**
  * Used to hold various helper objects required to process an upgrade pack.
@@ -41,6 +42,14 @@ public class UpgradeContext {
   private StackId m_originalStackId;
 
   /**
+   * The stack currently used to start/restart services during an upgrade.This is the same
+   * During a {@link UpgradeType#ROLLING} upgrade, this is always the {@link this.m_targetStackId},
+   * During a {@link UpgradeType#NON_ROLLING} upgrade, this is initially the {@link this.m_sourceStackId} while
+   * stopping services, and then changes to the {@link this.m_targetStackId} when starting services.
+   */
+  private StackId m_effectiveStackId;
+
+  /**
    * The target upgrade stack before the upgrade started. This is the same
    * regardless of whether the current direction is {@link Direction#UPGRADE} or
    * {@link Direction#DOWNGRADE}.
@@ -54,6 +63,7 @@ public class UpgradeContext {
   private Map<String, String> m_serviceNames = new HashMap<String, String>();
   private Map<String, String> m_componentNames = new HashMap<String, String>();
   private String m_downgradeFromVersion = null;
+  private UpgradeType m_type = null;
 
   /**
    * {@code true} if slave/client component failures should be automatically
@@ -88,15 +98,31 @@ public class UpgradeContext {
    *          the target version to upgrade to
    * @param direction
    *          the direction for the upgrade
+   * @param type
+   *          the type of upgrade, either rolling or non_rolling
    */
   public UpgradeContext(MasterHostResolver resolver, StackId sourceStackId,
       StackId targetStackId, String version,
-      Direction direction) {
+      Direction direction, UpgradeType type) {
     m_version = version;
     m_originalStackId = sourceStackId;
+
+    switch (type) {
+      case ROLLING:
+        m_effectiveStackId = targetStackId;
+        break;
+      case NON_ROLLING:
+        m_effectiveStackId = sourceStackId;
+        break;
+      default:
+        m_effectiveStackId = targetStackId;
+        break;
+    }
+
     m_targetStackId = targetStackId;
     m_direction = direction;
     m_resolver = resolver;
+    m_type = type;
   }
 
   /**
@@ -121,6 +147,13 @@ public class UpgradeContext {
   }
 
   /**
+   * @return the type of upgrade.
+   */
+  public UpgradeType getType() {
+    return m_type;
+  }
+
+  /**
    * @return the resolver
    */
   public MasterHostResolver getResolver() {
@@ -164,6 +197,21 @@ public class UpgradeContext {
   }
 
   /**
+   * @return the effectiveStackId that is currently in use.
+   */
+  public StackId getEffectiveStackId() {
+    return m_effectiveStackId;
+  }
+
+  /**
+   * @param effectiveStackId the effectiveStackId to set
+   */
+  public void setEffectiveStackId(StackId effectiveStackId) {
+    m_effectiveStackId = effectiveStackId;
+  }
+
+
+  /**
    * @return the targetStackId
    */
   public StackId getTargetStackId() {
@@ -237,7 +285,7 @@ public class UpgradeContext {
 
   /**
    * This method returns the non-finalized version we are downgrading from.
-   *
+   * 
    * @return version cluster is downgrading from
    */
   public String getDowngradeFromVersion() {
@@ -246,11 +294,11 @@ public class UpgradeContext {
 
   /**
    * Set the HDP stack version we are downgrading from.
-   *
+   *  
    * @param downgradeFromVersion
    */
   public void setDowngradeFromVersion(String downgradeFromVersion) {
-    m_downgradeFromVersion = downgradeFromVersion;
+    this.m_downgradeFromVersion = downgradeFromVersion;
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/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 75c04da..f0b383c 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
@@ -17,6 +17,7 @@
  */
 package org.apache.ambari.server.state;
 
+import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.LinkedHashSet;
@@ -42,6 +43,8 @@ import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
 import org.apache.ambari.server.controller.utilities.ClusterControllerHelper;
 import org.apache.ambari.server.controller.utilities.PredicateBuilder;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
+import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 import org.apache.ambari.server.stack.HostsType;
 import org.apache.ambari.server.stack.MasterHostResolver;
 import org.apache.ambari.server.state.stack.UpgradePack;
@@ -49,11 +52,18 @@ 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.UpgradeType;
 import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -171,6 +181,68 @@ public class UpgradeHelper {
   @Inject
   private Provider<AmbariMetaInfo> m_ambariMetaInfo;
 
+  @Inject
+  private Provider<Clusters> clusters;
+
+  @Inject
+  private Provider<RepositoryVersionDAO> s_repoVersionDAO;
+
+
+  /**
+   * Get right Upgrade Pack, depends on stack, direction and upgrade type information
+   * @param clusterName The name of the cluster
+   * @param upgradeFromVersion Current stack version
+   * @param upgradeToVersion Target stack version
+   * @param direction {@code Direction} of the upgrade
+   * @param upgradeType The {@code UpgradeType}
+   * @return {@code UpgradeType} object
+   * @throws AmbariException
+   */
+  public UpgradePack suggestUpgradePack(String clusterName, String upgradeFromVersion, String upgradeToVersion,
+    Direction direction, UpgradeType upgradeType) throws AmbariException {
+
+    // !!! find upgrade packs based on current stack. This is where to upgrade from
+    Cluster cluster = clusters.get().getCluster(clusterName);
+    StackId stack =  cluster.getCurrentStackVersion();
+
+    String repoVersion = upgradeToVersion;
+
+    // ToDo: AMBARI-12706. Here we need to check, how this would work with SWU Downgrade
+    if (direction.isDowngrade() && null != upgradeFromVersion) {
+      repoVersion = upgradeFromVersion;
+    }
+
+    RepositoryVersionEntity versionEntity = s_repoVersionDAO.get().findByStackNameAndVersion(stack.getStackName(), repoVersion);
+
+    if (versionEntity == null) {
+      throw new AmbariException(String.format("Repository version %s was not found", repoVersion));
+    }
+
+    Map<String, UpgradePack> packs = m_ambariMetaInfo.get().getUpgradePacks(stack.getStackName(), stack.getStackVersion());
+    UpgradePack pack = null;
+
+    String repoStackId = versionEntity.getStackId().getStackId();
+    for (UpgradePack upgradePack : packs.values()) {
+      if (upgradePack.getTargetStack() != null && upgradePack.getTargetStack().equals(repoStackId) &&
+           upgradeType == upgradePack.getType()) {
+        if (pack == null) {
+          pack = upgradePack;
+        } else {
+          throw new AmbariException(
+            String.format("Found multiple upgrade packs for type %s and target version %s",
+              upgradeType.toString(), repoVersion));
+        }
+      }
+    }
+
+    if (pack == null) {
+      throw new AmbariException(String.format("No upgrade pack found for type %s and target version %s",
+        upgradeType.toString(),repoVersion));
+    }
+
+   return pack;
+  }
+
 
   /**
    * Generates a list of UpgradeGroupHolder items that are used to execute either
@@ -189,14 +261,16 @@ public class UpgradeHelper {
     Cluster cluster = context.getCluster();
     MasterHostResolver mhr = context.getResolver();
 
+    // Note, only a Rolling Upgrade uses processing tasks.
     Map<String, Map<String, ProcessingComponent>> allTasks = upgradePack.getTasks();
-    List<UpgradeGroupHolder> groups = new ArrayList<UpgradeGroupHolder>();
+    List<UpgradeGroupHolder> groups = new ArrayList<>();
 
     for (Grouping group : upgradePack.getGroups(context.getDirection())) {
 
       UpgradeGroupHolder groupHolder = new UpgradeGroupHolder();
       groupHolder.name = group.name;
       groupHolder.title = group.title;
+      groupHolder.groupClass = group.getClass();
       groupHolder.skippable = group.skippable;
       groupHolder.allowRetry = group.allowRetry;
 
@@ -205,29 +279,52 @@ public class UpgradeHelper {
         groupHolder.skippable = true;
       }
 
+      // 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;
+      }
+
       StageWrapperBuilder builder = group.getBuilder();
 
       List<UpgradePack.OrderService> services = group.services;
 
-      if (context.getDirection().isDowngrade() && !services.isEmpty()) {
-        List<UpgradePack.OrderService> reverse = new ArrayList<UpgradePack.OrderService>(services);
-        Collections.reverse(reverse);
-        services = reverse;
+      // Rolling Downgrade must reverse the order of services.
+      if (upgradePack.getType() == UpgradeType.ROLLING) {
+        if (context.getDirection().isDowngrade() && !services.isEmpty()) {
+          List<UpgradePack.OrderService> reverse = new ArrayList<>(services);
+          Collections.reverse(reverse);
+          services = reverse;
+        }
       }
 
       // !!! cluster and service checks are empty here
       for (UpgradePack.OrderService service : services) {
 
-        if (!allTasks.containsKey(service.serviceName)) {
+        if (upgradePack.getType() == UpgradeType.ROLLING && !allTasks.containsKey(service.serviceName)) {
           continue;
         }
+        
+        // Attempt to get the function of the group, during a NonRolling Upgrade
+        Task.Type functionName = null;
+
+        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();
+        }
 
         for (String component : service.components) {
-          if (!allTasks.get(service.serviceName).containsKey(component)) {
+          if (upgradePack.getType() == UpgradeType.ROLLING && !allTasks.get(service.serviceName).containsKey(component)) {
             continue;
           }
-
+          
           HostsType hostsType = mhr.getMasterAndHosts(service.serviceName, component);
+          // TODO AMBARI-12698, how does this impact SECONDARY NAMENODE if there's no NameNode HA?
           if (null == hostsType) {
             continue;
           }
@@ -237,7 +334,31 @@ public class UpgradeHelper {
           }
 
           Service svc = cluster.getService(service.serviceName);
-          ProcessingComponent pc = allTasks.get(service.serviceName).get(component);
+
+          ProcessingComponent pc = null;
+          if (upgradePack.getType() == UpgradeType.ROLLING) {
+            pc = allTasks.get(service.serviceName).get(component);
+          } else if (upgradePack.getType() == UpgradeType.NON_ROLLING) {
+            // Construct a processing task on-the-fly
+            if (null != functionName) {
+              pc = new ProcessingComponent();
+              pc.name = component;
+              pc.tasks = new ArrayList<>();
+
+              if (functionName == Type.START) {
+                pc.tasks.add(new StartTask());
+              } else if (functionName == Type.STOP) {
+                pc.tasks.add(new StopTask());
+              } else if (functionName == Type.RESTART) {
+                pc.tasks.add(new RestartTask());
+              }
+            }
+          }
+
+          if (pc == null) {
+            LOG.error(MessageFormat.format("Couldn't create a processing component for service {0} and component {1}.", service.serviceName, component));
+            continue;
+          }
 
           setDisplayNames(context, service.serviceName, component);
 
@@ -246,7 +367,7 @@ public class UpgradeHelper {
             // !!! revisit if needed
             if (!hostsType.hosts.isEmpty() && hostsType.master != null && hostsType.secondary != null) {
               // The order is important, first do the standby, then the active namenode.
-              LinkedHashSet<String> order = new LinkedHashSet<String>();
+              LinkedHashSet<String> order = new LinkedHashSet<>();
 
               order.add(hostsType.secondary);
               order.add(hostsType.master);
@@ -342,7 +463,7 @@ public class UpgradeHelper {
 
     String result = source;
 
-    List<String> tokens = new ArrayList<String>(5);
+    List<String> tokens = new ArrayList<>(5);
     Matcher matcher = PLACEHOLDER_REGEX.matcher(source);
     while (matcher.find()) {
       tokens.add(matcher.group(1));
@@ -424,6 +545,9 @@ public class UpgradeHelper {
      */
     public String title;
 
+
+    public Class<? extends Grouping> groupClass;
+
     /**
      * Indicate whether retry is allowed for the stages in this group.
      */
@@ -438,7 +562,7 @@ public class UpgradeHelper {
     /**
      * List of stages for the group
      */
-    public List<StageWrapper> items = new ArrayList<StageWrapper>();
+    public List<StageWrapper> items = new ArrayList<>();
 
     /**
      * {@inheritDoc}
@@ -521,8 +645,5 @@ public class UpgradeHelper {
     } catch (AmbariException e) {
       LOG.debug("Could not get service detail", e);
     }
-
-
   }
-
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/state/stack/ConfigUpgradePack.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/ConfigUpgradePack.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/ConfigUpgradePack.java
new file mode 100644
index 0000000..f2e2e61
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/ConfigUpgradePack.java
@@ -0,0 +1,192 @@
+/**
+ * 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;
+
+import org.apache.ambari.server.state.stack.upgrade.ConfigUpgradeChangeDefinition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Represents a pack of changes that should be applied to configs
+ * when upgrading from a previous stack. In other words, it's a config delta
+ * from prev stack.
+ *
+ * After first call of enumerateConfigChangesByID() method, instance contains
+ * a cache of data, so it should not be modified in runtime (otherwise
+ * the cache will become outdated).
+ */
+@XmlRootElement(name="upgrade-config-changes")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class ConfigUpgradePack {
+
+  /**
+   * Defines per-service config changes.
+   */
+  @XmlElementWrapper(name="services")
+  @XmlElement(name="service")
+  public List<AffectedService> services;
+
+  /**
+   * Contains a cached mapping of <change id, change definition>.
+   */
+  private Map<String, ConfigUpgradeChangeDefinition> changesById;
+
+  private static Logger LOG = LoggerFactory.getLogger(ConfigUpgradePack.class);
+
+  /**
+   * no-arg default constructor for JAXB
+   */
+  public ConfigUpgradePack() {
+  }
+
+  public ConfigUpgradePack(List<AffectedService> services) {
+    this.services = services;
+  }
+
+  /**
+   * @return a map of <service name, AffectedService>.
+   */
+  public Map<String, AffectedService> getServiceMap() {
+    Map<String, AffectedService> result = new HashMap<>();
+    for (AffectedService service : services) {
+      result.put(service.name, service);
+    }
+    return result;
+  }
+
+  /**
+   * @return a map of <change id, change definition>. Map is built once and
+   * cached
+   */
+  public Map<String, ConfigUpgradeChangeDefinition> enumerateConfigChangesByID() {
+    if (changesById == null) {
+      changesById = new HashMap<>();
+      for(AffectedService service : services) {
+        for(AffectedComponent component: service.components) {
+          for (ConfigUpgradeChangeDefinition changeDefinition : component.changes) {
+            if (changeDefinition.id == null) {
+              LOG.warn(String.format("Config upgrade change definition for service %s," +
+                      " component %s has no id", service.name, component.name));
+            } else if (changesById.containsKey(changeDefinition.id)) {
+              LOG.warn("Duplicate config upgrade change definition with ID " +
+                      changeDefinition.id);
+            }
+            changesById.put(changeDefinition.id, changeDefinition);
+          }
+        }
+      }
+    }
+    return changesById;
+  }
+
+  /**
+   * Merges few config upgrade packs into one and returs result. During merge,
+   * a deep copy of AffectedService and AffectedComponent lists is added to resulting
+   * config upgrade pack. The only level that is not copied deeply is a list of
+   * per-component config changes.
+   * @param cups list of source config upgrade packs
+   * @return merged config upgrade pack that is a deep copy of source
+   * config upgrade packs
+   */
+  public static ConfigUpgradePack merge(ArrayList<ConfigUpgradePack> cups) {
+    // Map <service_name, <component_name, component_changes>>
+    Map<String, Map<String, AffectedComponent>> mergedServiceMap = new HashMap<>();
+
+    for (ConfigUpgradePack configUpgradePack : cups) {
+      for (AffectedService service : configUpgradePack.services) {
+        if (! mergedServiceMap.containsKey(service.name)) {
+          mergedServiceMap.put(service.name, new HashMap<String, AffectedComponent>());
+        }
+        Map<String, AffectedComponent> mergedComponentMap = mergedServiceMap.get(service.name);
+
+        for (AffectedComponent component : service.components) {
+          if (! mergedComponentMap.containsKey(component.name)) {
+            AffectedComponent mergedComponent = new AffectedComponent();
+            mergedComponent.name = component.name;
+            mergedComponent.changes = new ArrayList<>();
+            mergedComponentMap.put(component.name, mergedComponent);
+          }
+          AffectedComponent mergedComponent = mergedComponentMap.get(component.name);
+          mergedComponent.changes.addAll(component.changes);
+        }
+
+      }
+    }
+    // Convert merged maps into new ConfigUpgradePack
+    ArrayList<AffectedService> mergedServices = new ArrayList<>();
+    for (String serviceName : mergedServiceMap.keySet()) {
+      AffectedService mergedService = new AffectedService();
+      Map<String, AffectedComponent> mergedComponentMap = mergedServiceMap.get(serviceName);
+      mergedService.name = serviceName;
+      mergedService.components = new ArrayList<>(mergedComponentMap.values());
+      mergedServices.add(mergedService);
+    }
+
+    return new ConfigUpgradePack(mergedServices);
+  }
+
+  /**
+   * A service definition in the 'services' element.
+   */
+  public static class AffectedService {
+
+    @XmlAttribute
+    public String name;
+
+    @XmlElement(name="component")
+    public List<AffectedComponent> components;
+
+    /**
+     * @return a map of <component name, AffectedService>
+     */
+    public Map<String, AffectedComponent> getComponentMap() {
+      Map<String, AffectedComponent> result = new HashMap<>();
+      for (AffectedComponent component : components) {
+        result.put(component.name, component);
+      }
+      return result;
+    }
+  }
+
+  /**
+   * A component definition in the 'services/service' path.
+   */
+  public static class AffectedComponent {
+
+    @XmlAttribute
+    public String name;
+
+    @XmlElementWrapper(name="changes")
+    @XmlElement(name="definition")
+    public List<ConfigUpgradeChangeDefinition> changes;
+
+  }
+}


[2/9] ambari git commit: AMBARI-13392. Stop-and-Start Upgrade: Merge branch branch-dev-stop-all-upgrade to branch-2.1 for feature Stop-the-World Upgrade, aka Express Upgrade (alejandro, dlysnichenko, Dmytro Grinenko)

Posted by al...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/test/java/org/apache/ambari/server/state/stack/ConfigUpgradePackTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/stack/ConfigUpgradePackTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/stack/ConfigUpgradePackTest.java
new file mode 100644
index 0000000..388a81f
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/stack/ConfigUpgradePackTest.java
@@ -0,0 +1,198 @@
+/**
+ * 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;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.persist.PersistService;
+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.state.stack.upgrade.*;
+import org.apache.ambari.server.state.stack.upgrade.ClusterGrouping.ExecuteStage;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import static org.apache.ambari.server.state.stack.ConfigUpgradePack.AffectedService;
+import static org.apache.ambari.server.state.stack.ConfigUpgradePack.AffectedComponent;
+import static org.junit.Assert.*;
+
+/**
+ * Tests for the config upgrade pack
+ */
+public class ConfigUpgradePackTest {
+
+  private Injector injector;
+  private AmbariMetaInfo ambariMetaInfo;
+
+  @Before
+  public void before() throws Exception {
+    injector = Guice.createInjector(new InMemoryDefaultTestModule());
+    injector.getInstance(GuiceJpaInitializer.class);
+
+    ambariMetaInfo = injector.getInstance(AmbariMetaInfo.class);
+  }
+
+  @After
+  public void teardown() {
+    injector.getInstance(PersistService.class).stop();
+  }
+
+  @Test
+  public void testMerge() {
+    // Generate test data - 3 config upgrade packs, 2 services, 2 components, 2 config changes each
+    ArrayList<ConfigUpgradePack> cups = new ArrayList<>();
+    for (int cupIndex = 0; cupIndex < 3; cupIndex++) {
+
+      ArrayList<AffectedService> services = new ArrayList<>();
+      for (int serviceIndex = 0; serviceIndex < 2; serviceIndex++) {
+        String serviceName;
+        if (serviceIndex == 0) {
+          serviceName = "HDFS";  // For checking merge of existing services
+        } else {
+          serviceName = String.format("SOME_SERVICE_%s", cupIndex);
+        }
+        ArrayList<AffectedComponent> components = new ArrayList<>();
+        for (int componentIndex = 0; componentIndex < 2; componentIndex++) {
+          String componentName;
+          if (componentIndex == 0) {
+            componentName = "NAMENODE";  // For checking merge of existing components
+          } else {
+            componentName = "SOME_COMPONENT_" + cupIndex;
+          }
+
+          ArrayList<ConfigUpgradeChangeDefinition> changeDefinitions = new ArrayList<>();
+          for (int changeIndex = 0; changeIndex < 2; changeIndex++) {
+            String change_id = String.format(
+                    "CHANGE_%s_%s_%s_%s", cupIndex, serviceIndex, componentIndex, changeIndex);
+            ConfigUpgradeChangeDefinition changeDefinition = new ConfigUpgradeChangeDefinition();
+            changeDefinition.id = change_id;
+            changeDefinitions.add(changeDefinition);
+          }
+          AffectedComponent component = new AffectedComponent();
+          component.name = componentName;
+          component.changes = changeDefinitions;
+          components.add(component);
+        }
+        AffectedService service = new AffectedService();
+        service.name = serviceName;
+        service.components = components;
+        services.add(service);
+      }
+      ConfigUpgradePack cupI = new ConfigUpgradePack();
+      cupI.services = services;
+      cups.add(cupI);
+    }
+
+    // Merge
+
+    ConfigUpgradePack result = ConfigUpgradePack.merge(cups);
+
+
+    // Check test results
+
+    assertEquals(result.enumerateConfigChangesByID().entrySet().size(), 24);
+
+    assertEquals(result.getServiceMap().get("HDFS").getComponentMap().get("NAMENODE").changes.get(0).id, "CHANGE_0_0_0_0");
+    assertEquals(result.getServiceMap().get("HDFS").getComponentMap().get("NAMENODE").changes.get(1).id, "CHANGE_0_0_0_1");
+    assertEquals(result.getServiceMap().get("HDFS").getComponentMap().get("NAMENODE").changes.get(2).id, "CHANGE_1_0_0_0");
+    assertEquals(result.getServiceMap().get("HDFS").getComponentMap().get("NAMENODE").changes.get(3).id, "CHANGE_1_0_0_1");
+    assertEquals(result.getServiceMap().get("HDFS").getComponentMap().get("NAMENODE").changes.get(4).id, "CHANGE_2_0_0_0");
+    assertEquals(result.getServiceMap().get("HDFS").getComponentMap().get("NAMENODE").changes.get(5).id, "CHANGE_2_0_0_1");
+
+
+    assertEquals(result.getServiceMap().get("HDFS").getComponentMap().get("SOME_COMPONENT_0").changes.get(0).id, "CHANGE_0_0_1_0");
+    assertEquals(result.getServiceMap().get("HDFS").getComponentMap().get("SOME_COMPONENT_0").changes.get(1).id, "CHANGE_0_0_1_1");
+
+    assertEquals(result.getServiceMap().get("HDFS").getComponentMap().get("SOME_COMPONENT_1").changes.get(0).id, "CHANGE_1_0_1_0");
+    assertEquals(result.getServiceMap().get("HDFS").getComponentMap().get("SOME_COMPONENT_1").changes.get(1).id, "CHANGE_1_0_1_1");
+
+    assertEquals(result.getServiceMap().get("HDFS").getComponentMap().get("SOME_COMPONENT_2").changes.get(0).id, "CHANGE_2_0_1_0");
+    assertEquals(result.getServiceMap().get("HDFS").getComponentMap().get("SOME_COMPONENT_2").changes.get(1).id, "CHANGE_2_0_1_1");
+
+
+    assertEquals(result.getServiceMap().get("SOME_SERVICE_0").getComponentMap().get("NAMENODE").changes.get(0).id, "CHANGE_0_1_0_0");
+    assertEquals(result.getServiceMap().get("SOME_SERVICE_0").getComponentMap().get("NAMENODE").changes.get(1).id, "CHANGE_0_1_0_1");
+    assertEquals(result.getServiceMap().get("SOME_SERVICE_0").getComponentMap().get("SOME_COMPONENT_0").changes.get(0).id, "CHANGE_0_1_1_0");
+    assertEquals(result.getServiceMap().get("SOME_SERVICE_0").getComponentMap().get("SOME_COMPONENT_0").changes.get(1).id, "CHANGE_0_1_1_1");
+
+    assertEquals(result.getServiceMap().get("SOME_SERVICE_1").getComponentMap().get("NAMENODE").changes.get(0).id, "CHANGE_1_1_0_0");
+    assertEquals(result.getServiceMap().get("SOME_SERVICE_1").getComponentMap().get("NAMENODE").changes.get(1).id, "CHANGE_1_1_0_1");
+    assertEquals(result.getServiceMap().get("SOME_SERVICE_1").getComponentMap().get("SOME_COMPONENT_1").changes.get(0).id, "CHANGE_1_1_1_0");
+    assertEquals(result.getServiceMap().get("SOME_SERVICE_1").getComponentMap().get("SOME_COMPONENT_1").changes.get(1).id, "CHANGE_1_1_1_1");
+
+    assertEquals(result.getServiceMap().get("SOME_SERVICE_2").getComponentMap().get("NAMENODE").changes.get(0).id, "CHANGE_2_1_0_0");
+    assertEquals(result.getServiceMap().get("SOME_SERVICE_2").getComponentMap().get("NAMENODE").changes.get(1).id, "CHANGE_2_1_0_1");
+    assertEquals(result.getServiceMap().get("SOME_SERVICE_2").getComponentMap().get("SOME_COMPONENT_2").changes.get(0).id, "CHANGE_2_1_1_0");
+    assertEquals(result.getServiceMap().get("SOME_SERVICE_2").getComponentMap().get("SOME_COMPONENT_2").changes.get(1).id, "CHANGE_2_1_1_1");
+
+  }
+
+  @Test
+  public void testConfigUpgradeDefinitionParsing() throws Exception {
+    ConfigUpgradePack cup = ambariMetaInfo.getConfigUpgradePack("HDP", "2.1.1");
+    Map<String, ConfigUpgradeChangeDefinition> changesByID = cup.enumerateConfigChangesByID();
+
+    ConfigUpgradeChangeDefinition hdp_2_1_1_nm_pre_upgrade = changesByID.get("hdp_2_1_1_nm_pre_upgrade");
+    assertEquals("core-site", hdp_2_1_1_nm_pre_upgrade.getConfigType());
+    assertEquals(4, hdp_2_1_1_nm_pre_upgrade.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>
+    */
+    ConfigUpgradeChangeDefinition.Transfer t1 = hdp_2_1_1_nm_pre_upgrade.getTransfers().get(0);
+    assertEquals(TransferOperation.COPY, t1.operation);
+    assertEquals("copy-key", t1.fromKey);
+    assertEquals("copy-key-to", t1.toKey);
+
+    ConfigUpgradeChangeDefinition.Transfer t2 = hdp_2_1_1_nm_pre_upgrade.getTransfers().get(1);
+    assertEquals(TransferOperation.COPY, t2.operation);
+    assertEquals("my-site", t2.fromType);
+    assertEquals("my-copy-key", t2.fromKey);
+    assertEquals("my-copy-key-to", t2.toKey);
+    assertTrue(t2.keepKeys.isEmpty());
+
+    ConfigUpgradeChangeDefinition.Transfer t3 = hdp_2_1_1_nm_pre_upgrade.getTransfers().get(2);
+    assertEquals(TransferOperation.MOVE, t3.operation);
+    assertEquals("move-key", t3.fromKey);
+    assertEquals("move-key-to", t3.toKey);
+
+    ConfigUpgradeChangeDefinition.Transfer t4 = hdp_2_1_1_nm_pre_upgrade.getTransfers().get(3);
+    assertEquals(TransferOperation.DELETE, t4.operation);
+    assertEquals("delete-key", t4.deleteKey);
+    assertNull(t4.toKey);
+    assertTrue(t4.preserveEdits);
+    assertEquals(1, t4.keepKeys.size());
+    assertEquals("important-key", t4.keepKeys.get(0));
+
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/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 9ae78c4..0cd734e 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
@@ -36,13 +36,17 @@ import org.apache.ambari.server.state.stack.UpgradePack.ProcessingComponent;
 import org.apache.ambari.server.state.stack.upgrade.ClusterGrouping;
 import org.apache.ambari.server.state.stack.upgrade.ClusterGrouping.ExecuteStage;
 import org.apache.ambari.server.state.stack.upgrade.ConfigureTask;
-import org.apache.ambari.server.state.stack.upgrade.ConfigureTask.Transfer;
+import org.apache.ambari.server.state.stack.upgrade.ConfigUpgradeChangeDefinition.Transfer;
 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.RestartGrouping;
 import org.apache.ambari.server.state.stack.upgrade.RestartTask;
+import org.apache.ambari.server.state.stack.upgrade.StopGrouping;
 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.apache.ambari.server.state.stack.upgrade.UpdateStackGrouping;
+import org.apache.ambari.server.state.stack.upgrade.UpgradeType;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -88,9 +92,8 @@ public class UpgradePackTest {
     Map<String, UpgradePack> upgrades = ambariMetaInfo.getUpgradePacks("HDP", "2.1.1");
     assertTrue(upgrades.size() > 0);
     assertTrue(upgrades.containsKey("upgrade_test"));
-
-    UpgradePack up = upgrades.get("upgrade_test");
-    assertEquals("2.2.*", up.getTarget());
+    UpgradePack upgrade = upgrades.get("upgrade_test");
+    assertEquals("2.2.*.*", upgrade.getTarget());
 
     Map<String, List<String>> expectedStages = new LinkedHashMap<String, List<String>>() {{
       put("ZOOKEEPER", Arrays.asList("ZOOKEEPER_SERVER"));
@@ -100,24 +103,24 @@ public class UpgradePackTest {
     // !!! test the tasks
     int i = 0;
     for (Entry<String, List<String>> entry : expectedStages.entrySet()) {
-      assertTrue(up.getTasks().containsKey(entry.getKey()));
-      assertEquals(i++, indexOf(up.getTasks(), entry.getKey()));
+      assertTrue(upgrade.getTasks().containsKey(entry.getKey()));
+      assertEquals(i++, indexOf(upgrade.getTasks(), entry.getKey()));
 
       // check that the number of components matches
-      assertEquals(entry.getValue().size(), up.getTasks().get(entry.getKey()).size());
+      assertEquals(entry.getValue().size(), upgrade.getTasks().get(entry.getKey()).size());
 
       // check component ordering
       int j = 0;
       for (String comp : entry.getValue()) {
-        assertEquals(j++, indexOf(up.getTasks().get(entry.getKey()), comp));
+        assertEquals(j++, indexOf(upgrade.getTasks().get(entry.getKey()), comp));
       }
     }
 
     // !!! test specific tasks
-    assertTrue(up.getTasks().containsKey("HDFS"));
-    assertTrue(up.getTasks().get("HDFS").containsKey("NAMENODE"));
+    assertTrue(upgrade.getTasks().containsKey("HDFS"));
+    assertTrue(upgrade.getTasks().get("HDFS").containsKey("NAMENODE"));
 
-    ProcessingComponent pc = up.getTasks().get("HDFS").get("NAMENODE");
+    ProcessingComponent pc = upgrade.getTasks().get("HDFS").get("NAMENODE");
     assertNotNull(pc.preTasks);
     assertNotNull(pc.postTasks);
     assertNotNull(pc.tasks);
@@ -129,17 +132,17 @@ public class UpgradePackTest {
     assertEquals(RestartTask.class, pc.tasks.get(0).getClass());
 
 
-    assertTrue(up.getTasks().containsKey("ZOOKEEPER"));
-    assertTrue(up.getTasks().get("ZOOKEEPER").containsKey("ZOOKEEPER_SERVER"));
+    assertTrue(upgrade.getTasks().containsKey("ZOOKEEPER"));
+    assertTrue(upgrade.getTasks().get("ZOOKEEPER").containsKey("ZOOKEEPER_SERVER"));
 
-    pc = up.getTasks().get("HDFS").get("DATANODE");
+    pc = upgrade.getTasks().get("HDFS").get("DATANODE");
     assertNotNull(pc.preDowngradeTasks);
     assertEquals(0, pc.preDowngradeTasks.size());
     assertNotNull(pc.postDowngradeTasks);
     assertEquals(1, pc.postDowngradeTasks.size());
 
 
-    pc = up.getTasks().get("ZOOKEEPER").get("ZOOKEEPER_SERVER");
+    pc = upgrade.getTasks().get("ZOOKEEPER").get("ZOOKEEPER_SERVER");
     assertNotNull(pc.preTasks);
     assertEquals(1, pc.preTasks.size());
     assertNotNull(pc.postTasks);
@@ -147,56 +150,22 @@ public class UpgradePackTest {
     assertNotNull(pc.tasks);
     assertEquals(1, pc.tasks.size());
 
-    pc = up.getTasks().get("YARN").get("NODEMANAGER");
+    pc = upgrade.getTasks().get("YARN").get("NODEMANAGER");
     assertNotNull(pc.preTasks);
     assertEquals(2, pc.preTasks.size());
     Task t = pc.preTasks.get(1);
     assertEquals(ConfigureTask.class, t.getClass());
     ConfigureTask ct = (ConfigureTask) t;
-    assertEquals("core-site", ct.getConfigType());
-    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 t1 = ct.getTransfers().get(0);
-    assertEquals(TransferOperation.COPY, t1.operation);
-    assertEquals("copy-key", t1.fromKey);
-    assertEquals("copy-key-to", t1.toKey);
-
-    Transfer t2 = ct.getTransfers().get(1);
-    assertEquals(TransferOperation.COPY, t2.operation);
-    assertEquals("my-site", t2.fromType);
-    assertEquals("my-copy-key", t2.fromKey);
-    assertEquals("my-copy-key-to", t2.toKey);
-    assertTrue(t2.keepKeys.isEmpty());
-
-    Transfer t3 = ct.getTransfers().get(2);
-    assertEquals(TransferOperation.MOVE, t3.operation);
-    assertEquals("move-key", t3.fromKey);
-    assertEquals("move-key-to", t3.toKey);
-
-    Transfer t4 = ct.getTransfers().get(3);
-    assertEquals(TransferOperation.DELETE, t4.operation);
-    assertEquals("delete-key", t4.deleteKey);
-    assertNull(t4.toKey);
-    assertTrue(t4.preserveEdits);
-    assertEquals(1, t4.keepKeys.size());
-    assertEquals("important-key", t4.keepKeys.get(0));
+    // check that the Configure task successfully parsed id
+    assertEquals("hdp_2_1_1_nm_pre_upgrade", ct.getId());
   }
 
   @Test
-  public void testGroupOrders() {
+  public void testGroupOrdersForRolling() {
     Map<String, UpgradePack> upgrades = ambariMetaInfo.getUpgradePacks("HDP", "2.1.1");
     assertTrue(upgrades.size() > 0);
     assertTrue(upgrades.containsKey("upgrade_test_checks"));
-
-    UpgradePack up = upgrades.get("upgrade_test_checks");
+    UpgradePack upgrade = upgrades.get("upgrade_test_checks");
 
     List<String> expected_up = Arrays.asList(
         "PRE_CLUSTER",
@@ -219,7 +188,7 @@ public class UpgradePackTest {
     Grouping serviceCheckGroup = null;
 
     int i = 0;
-    List<Grouping> groups = up.getGroups(Direction.UPGRADE);
+    List<Grouping> groups = upgrade.getGroups(Direction.UPGRADE);
     for (Grouping g : groups) {
       assertEquals(expected_up.get(i), g.name);
       i++;
@@ -245,7 +214,7 @@ public class UpgradePackTest {
 
 
     i = 0;
-    groups = up.getGroups(Direction.DOWNGRADE);
+    groups = upgrade.getGroups(Direction.DOWNGRADE);
     for (Grouping g : groups) {
       assertEquals(expected_down.get(i), g.name);
       i++;
@@ -253,15 +222,44 @@ public class UpgradePackTest {
 
   }
 
+  // TODO AMBARI-12698, add the Downgrade case
   @Test
-  public void testDirection() throws Exception {
+  public void testGroupOrdersForNonRolling() {
     Map<String, UpgradePack> upgrades = ambariMetaInfo.getUpgradePacks("HDP", "2.1.1");
     assertTrue(upgrades.size() > 0);
-    assertTrue(upgrades.containsKey("upgrade_direction"));
+    assertTrue(upgrades.containsKey("upgrade_test_nonrolling"));
+    UpgradePack upgrade = upgrades.get("upgrade_test_nonrolling");
 
-    UpgradePack up = upgrades.get("upgrade_direction");
+    List<String> expected_up = Arrays.asList(
+        "PRE_CLUSTER",
+        "Stop High-Level Daemons",
+        "Backups",
+        "Stop Low-Level Daemons",
+        "UPDATE_DESIRED_STACK_ID",
+        "ALL_HOST_OPS",
+        "ZOOKEEPER",
+        "HDFS",
+        "MR and YARN",
+        "POST_CLUSTER");
 
-    List<Grouping> groups = up.getGroups(Direction.UPGRADE);
+    int i = 0;
+    List<Grouping> groups = upgrade.getGroups(Direction.UPGRADE);
+    for (Grouping g : groups) {
+      assertEquals(expected_up.get(i), g.name);
+      i++;
+    }
+  }
+  
+  @Test
+  public void testDirectionForRolling() throws Exception {
+    Map<String, UpgradePack> upgrades = ambariMetaInfo.getUpgradePacks("HDP", "2.1.1");
+    assertTrue(upgrades.size() > 0);
+    assertTrue(upgrades.containsKey("upgrade_direction"));
+    
+    UpgradePack upgrade = upgrades.get("upgrade_direction");
+    assertTrue(upgrade.getType() == UpgradeType.ROLLING);
+
+    List<Grouping> groups = upgrade.getGroups(Direction.UPGRADE);
     assertEquals(4, groups.size());
     Grouping group = groups.get(2);
     assertEquals(ClusterGrouping.class, group.getClass());
@@ -274,7 +272,7 @@ public class UpgradePackTest {
     assertNotNull(stages.get(0).intendedDirection);
     assertEquals(Direction.DOWNGRADE, stages.get(0).intendedDirection);
 
-    groups = up.getGroups(Direction.DOWNGRADE);
+    groups = upgrade.getGroups(Direction.DOWNGRADE);
     assertEquals(3, groups.size());
     // there are two clustergroupings at the end
     group = groups.get(1);
@@ -300,7 +298,75 @@ public class UpgradePackTest {
     Assert.assertTrue(upgradePack.isComponentFailureAutoSkipped());
     Assert.assertTrue(upgradePack.isServiceCheckFailureAutoSkipped());
   }
+  
+  @Test
+  public void testDirectionForNonRolling() throws Exception {
+    Map<String, UpgradePack> upgrades = ambariMetaInfo.getUpgradePacks("HDP", "2.1.1");
+    assertTrue(upgrades.size() > 0);
+    assertTrue(upgrades.containsKey("upgrade_test_nonrolling"));
+    
+    UpgradePack upgrade = upgrades.get("upgrade_test_nonrolling");
+    assertTrue(upgrade.getType() == UpgradeType.NON_ROLLING);
 
+    List<Grouping> groups = upgrade.getGroups(Direction.UPGRADE);
+    assertEquals(10, groups.size());
+
+    Grouping group = null;
+    ClusterGrouping clusterGroup = null;
+    UpdateStackGrouping updateStackGroup = null;
+    StopGrouping stopGroup = null;
+    RestartGrouping restartGroup = null;
+
+    group = groups.get(0);
+    assertEquals(ClusterGrouping.class, group.getClass());
+    clusterGroup = (ClusterGrouping) group;
+    assertEquals("Prepare Upgrade", clusterGroup.title);
+
+    group = groups.get(1);
+    assertEquals(StopGrouping.class, group.getClass());
+    stopGroup = (StopGrouping) group;
+    assertEquals("Stop Daemons for High-Level Services", stopGroup.title);
+
+    group = groups.get(2);
+    assertEquals(ClusterGrouping.class, group.getClass());
+    clusterGroup = (ClusterGrouping) group;
+    assertEquals("Take Backups", clusterGroup.title);
+
+    group = groups.get(3);
+    assertEquals(StopGrouping.class, group.getClass());
+    stopGroup = (StopGrouping) group;
+    assertEquals("Stop Daemons for Low-Level Services", stopGroup.title);
+
+    group = groups.get(4);
+    assertEquals(UpdateStackGrouping.class, group.getClass());
+    updateStackGroup = (UpdateStackGrouping) group;
+    assertEquals("Update Desired Stack Id", updateStackGroup.title);
+
+    group = groups.get(5);
+    assertEquals(ClusterGrouping.class, group.getClass());
+    clusterGroup = (ClusterGrouping) group;
+    assertEquals("Set Version On All Hosts", clusterGroup.title);
+
+    group = groups.get(6);
+    assertEquals(RestartGrouping.class, group.getClass());
+    restartGroup = (RestartGrouping) group;
+    assertEquals("Zookeeper", restartGroup.title);
+
+    group = groups.get(7);
+    assertEquals(RestartGrouping.class, group.getClass());
+    restartGroup = (RestartGrouping) group;
+    assertEquals("HDFS", restartGroup.title);
+
+    group = groups.get(8);
+    assertEquals(RestartGrouping.class, group.getClass());
+    restartGroup = (RestartGrouping) group;
+    assertEquals("MR and YARN", restartGroup.title);
+
+    group = groups.get(9);
+    assertEquals(ClusterGrouping.class, group.getClass());
+    clusterGroup = (ClusterGrouping) group;
+    assertEquals("Finalize {{direction.text.proper}}", clusterGroup.title);
+  }
 
   private int indexOf(Map<String, ?> map, String keyToFind) {
     int result = -1;
@@ -315,6 +381,4 @@ public class UpgradePackTest {
 
     return result;
   }
-
-
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/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
index e2a3995..bac00d4 100644
--- 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
@@ -43,7 +43,7 @@ public class StageWrapperBuilderTest {
    */
   @Test
   public void testBuildOrder() throws Exception {
-    UpgradeContext upgradeContext = new UpgradeContext(null, null, null, null, Direction.UPGRADE);
+    UpgradeContext upgradeContext = new UpgradeContext(null, null, null, null, Direction.UPGRADE, UpgradeType.ROLLING);
     MockStageWrapperBuilder builder = new MockStageWrapperBuilder(null);
     List<StageWrapper> stageWrappers = builder.build(upgradeContext);
     List<Integer> invocationOrder = builder.getInvocationOrder();
@@ -64,7 +64,7 @@ public class StageWrapperBuilderTest {
    */
   @Test
   public void testAutoSkipCheckInserted() throws Exception {
-    UpgradeContext upgradeContext = new UpgradeContext(null, null, null, null, Direction.UPGRADE);
+    UpgradeContext upgradeContext = new UpgradeContext(null, null, null, null, Direction.UPGRADE, UpgradeType.ROLLING);
     upgradeContext.setAutoSkipComponentFailures(true);
     upgradeContext.setAutoSkipServiceCheckFailures(true);
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog213Test.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog213Test.java b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog213Test.java
index 73b3a18..b3c8543 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog213Test.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog213Test.java
@@ -18,11 +18,15 @@
 
 package org.apache.ambari.server.upgrade;
 
+import static org.easymock.EasyMock.anyLong;
+import static org.easymock.EasyMock.anyObject;
 import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.capture;
 import static org.easymock.EasyMock.createMockBuilder;
 import static org.easymock.EasyMock.createNiceMock;
 import static org.easymock.EasyMock.createStrictMock;
 import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.eq;
 import static org.easymock.EasyMock.expectLastCall;
 import static org.easymock.EasyMock.replay;
 import static org.easymock.EasyMock.reset;
@@ -30,37 +34,64 @@ import static org.easymock.EasyMock.verify;
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
 import javax.persistence.EntityManager;
 
 import com.google.inject.AbstractModule;
+import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.orm.DBAccessor;
 import org.apache.ambari.server.orm.GuiceJpaInitializer;
 import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
+import org.apache.ambari.server.orm.dao.ClusterDAO;
+import org.apache.ambari.server.orm.dao.ClusterVersionDAO;
+import org.apache.ambari.server.orm.dao.DaoUtils;
+import org.apache.ambari.server.orm.dao.HostVersionDAO;
+import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
 import org.apache.ambari.server.orm.dao.StackDAO;
+import org.apache.ambari.server.orm.entities.ClusterEntity;
+import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
+import org.apache.ambari.server.orm.entities.HostEntity;
+import org.apache.ambari.server.orm.entities.HostVersionEntity;
+import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 import org.apache.ambari.server.orm.entities.StackEntity;
+import org.apache.ambari.server.stack.StackManagerFactory;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.Config;
 import org.apache.ambari.server.state.ConfigHelper;
+import org.apache.ambari.server.state.RepositoryVersionState;
+import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.StackInfo;
 import org.apache.ambari.server.state.stack.OsFamily;
+import org.apache.ambari.server.state.stack.upgrade.RepositoryVersionHelper;
 import org.easymock.EasyMock;
 import org.easymock.EasyMockSupport;
+import org.easymock.Capture;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 
+import java.lang.reflect.Field;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
 import com.google.inject.Binder;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Module;
 import com.google.inject.Provider;
 import com.google.inject.persist.PersistService;
+import org.apache.ambari.server.configuration.Configuration;
 
 /**
  * {@link org.apache.ambari.server.upgrade.UpgradeCatalog213} unit tests.
@@ -71,6 +102,13 @@ public class UpgradeCatalog213Test {
   private EntityManager entityManager = createNiceMock(EntityManager.class);
   private UpgradeCatalogHelper upgradeCatalogHelper;
   private StackEntity desiredStackEntity;
+  private AmbariManagementController amc = createNiceMock(AmbariManagementController.class);
+  private AmbariMetaInfo metaInfo = createNiceMock(AmbariMetaInfo.class);
+  private StackDAO stackDAO = createNiceMock(StackDAO.class);
+  private RepositoryVersionDAO repositoryVersionDAO = createNiceMock(RepositoryVersionDAO.class);
+  private ClusterVersionDAO clusterVersionDAO = createNiceMock(ClusterVersionDAO.class);
+  private HostVersionDAO hostVersionDAO = createNiceMock(HostVersionDAO.class);
+  private ClusterDAO clusterDAO = createNiceMock(ClusterDAO.class);
 
   @Before
   public void init() {
@@ -94,7 +132,51 @@ public class UpgradeCatalog213Test {
   }
 
   @Test
+  public void testExecuteDDLUpdates() throws Exception {
+    final DBAccessor dbAccessor = createNiceMock(DBAccessor.class);
+    UpgradeCatalog213 upgradeCatalog = (UpgradeCatalog213) getUpgradeCatalog(dbAccessor);
+
+    upgradeCatalog.executeDDLUpdates();
+  }
+
+  @Test
   public void testExecuteDMLUpdates() throws Exception {
+    // TODO AMBARI-13001, readd unit test section.
+    /*
+    final DBAccessor dbAccessor = createNiceMock(DBAccessor.class);
+    Configuration configuration = createNiceMock(Configuration.class);
+    Connection connection = createNiceMock(Connection.class);
+    Statement statement = createNiceMock(Statement.class);
+    ResultSet resultSet = createNiceMock(ResultSet.class);
+    expect(configuration.getDatabaseUrl()).andReturn(Configuration.JDBC_IN_MEMORY_URL).anyTimes();
+    dbAccessor.getConnection();
+    expectLastCall().andReturn(connection).anyTimes();
+    connection.createStatement();
+    expectLastCall().andReturn(statement).anyTimes();
+    statement.executeQuery(anyObject(String.class));
+    expectLastCall().andReturn(resultSet).anyTimes();
+
+    // Technically, this is a DDL, but it has to be ran during the DML portion
+    // because it requires the persistence layer to be started.
+    UpgradeSectionDDL upgradeSectionDDL = new UpgradeSectionDDL();
+
+    // Execute any DDL schema changes
+    upgradeSectionDDL.execute(dbAccessor);
+
+    // Begin DML verifications
+    verifyBootstrapHDP21();
+
+    // Replay main sections
+    replay(dbAccessor, configuration, resultSet, connection, statement);
+
+
+    AbstractUpgradeCatalog upgradeCatalog = getUpgradeCatalog(dbAccessor);
+    Class<?> c = AbstractUpgradeCatalog.class;
+    Field f = c.getDeclaredField("configuration");
+    f.setAccessible(true);
+    f.set(upgradeCatalog, configuration);
+    */
+
     Method addMissingConfigs = UpgradeCatalog213.class.getDeclaredMethod("addMissingConfigs");
     Method updateAMSConfigs = UpgradeCatalog213.class.getDeclaredMethod("updateAMSConfigs");
     Method updateAlertDefinitions = UpgradeCatalog213.class.getDeclaredMethod("updateAlertDefinitions");
@@ -117,8 +199,97 @@ public class UpgradeCatalog213Test {
     upgradeCatalog213.executeDMLUpdates();
 
     verify(upgradeCatalog213);
+    
+    //verify(dbAccessor, configuration, resultSet, connection, statement);
+
+    // Verify sections
+    //upgradeSectionDDL.verify(dbAccessor);
+  }
+
+  /**
+   * Verify that when bootstrapping HDP 2.1, records get inserted into the
+   * repo_version, cluster_version, and host_version tables.
+   * @throws AmbariException
+   */
+  private void verifyBootstrapHDP21() throws Exception, AmbariException {
+    final String stackName = "HDP";
+    final String stackVersion = "2.1";
+    final String stackNameAndVersion = stackName + "-" + stackVersion;
+    final String buildNumber = "2.1.0.0-0001";
+    final String stackAndBuild = stackName + "-" + buildNumber;
+    final String clusterName = "c1";
+
+    expect(amc.getAmbariMetaInfo()).andReturn(metaInfo);
+
+    // Mock the actions to bootstrap if using HDP 2.1
+    Clusters clusters = createNiceMock(Clusters.class);
+    expect(amc.getClusters()).andReturn(clusters);
+
+    Map<String, Cluster> clusterHashMap = new HashMap<String, Cluster>();
+    Cluster cluster = createNiceMock(Cluster.class);
+    clusterHashMap.put(clusterName, cluster);
+    expect(clusters.getClusters()).andReturn(clusterHashMap);
+
+    StackId stackId = new StackId(stackNameAndVersion);
+    expect(cluster.getCurrentStackVersion()).andReturn(stackId);
+
+    StackInfo stackInfo = new StackInfo();
+    stackInfo.setVersion(buildNumber);
+    expect(metaInfo.getStack(stackName, stackVersion)).andReturn(stackInfo);
+
+    StackEntity stackEntity = createNiceMock(StackEntity.class);
+    expect(stackEntity.getStackName()).andReturn(stackName);
+    expect(stackEntity.getStackVersion()).andReturn(stackVersion);
+
+    expect(stackDAO.find(stackName, stackVersion)).andReturn(stackEntity);
+
+    replay(amc, metaInfo, clusters, cluster, stackEntity, stackDAO);
+
+    // Mock more function calls
+    // Repository Version
+    RepositoryVersionEntity repositoryVersionEntity = createNiceMock(RepositoryVersionEntity.class);
+    expect(repositoryVersionDAO.findByDisplayName(stackAndBuild)).andReturn(null);
+    expect(repositoryVersionDAO.findMaxId("id")).andReturn(0L);
+    expect(repositoryVersionDAO.findAll()).andReturn(Collections.<RepositoryVersionEntity>emptyList());
+    expect(repositoryVersionDAO.create(anyObject(StackEntity.class), anyObject(String.class), anyObject(String.class), anyObject(String.class))).andReturn(repositoryVersionEntity);
+    expect(repositoryVersionEntity.getId()).andReturn(1L);
+    expect(repositoryVersionEntity.getVersion()).andReturn(buildNumber);
+    replay(repositoryVersionDAO, repositoryVersionEntity);
+
+    // Cluster Version
+    ClusterVersionEntity clusterVersionEntity = createNiceMock(ClusterVersionEntity.class);
+    expect(clusterVersionEntity.getId()).andReturn(1L);
+    expect(clusterVersionEntity.getState()).andReturn(RepositoryVersionState.CURRENT);
+    expect(clusterVersionEntity.getRepositoryVersion()).andReturn(repositoryVersionEntity);
+
+    expect(clusterVersionDAO.findByClusterAndStackAndVersion(anyObject(String.class), anyObject(StackId.class), anyObject(String.class))).andReturn(null);
+    expect(clusterVersionDAO.findMaxId("id")).andReturn(0L);
+    expect(clusterVersionDAO.findAll()).andReturn(Collections.<ClusterVersionEntity>emptyList());
+    expect(clusterVersionDAO.create(anyObject(ClusterEntity.class), anyObject(RepositoryVersionEntity.class), anyObject(RepositoryVersionState.class), anyLong(), anyLong(), anyObject(String.class))).andReturn(clusterVersionEntity);
+    replay(clusterVersionDAO, clusterVersionEntity);
+
+    // Host Version
+    ClusterEntity clusterEntity = createNiceMock(ClusterEntity.class);
+    expect(clusterEntity.getClusterName()).andReturn(clusterName).anyTimes();
+    expect(clusterDAO.findByName(anyObject(String.class))).andReturn(clusterEntity);
+
+    Collection<HostEntity> hostEntities = new ArrayList<HostEntity>();
+    HostEntity hostEntity1 = createNiceMock(HostEntity.class);
+    HostEntity hostEntity2 = createNiceMock(HostEntity.class);
+    expect(hostEntity1.getHostName()).andReturn("host1");
+    expect(hostEntity2.getHostName()).andReturn("host2");
+    hostEntities.add(hostEntity1);
+    hostEntities.add(hostEntity2);
+    expect(clusterEntity.getHostEntities()).andReturn(hostEntities);
+
+    expect(hostVersionDAO.findByClusterStackVersionAndHost(anyObject(String.class), anyObject(StackId.class), anyObject(String.class), anyObject(String.class))).andReturn(null);
+    expect(hostVersionDAO.findMaxId("id")).andReturn(0L);
+    expect(hostVersionDAO.findAll()).andReturn(Collections.<HostVersionEntity>emptyList());
+
+    replay(clusterEntity, clusterDAO, hostVersionDAO, hostEntity1, hostEntity2);
   }
 
+
   @Test
   public void testUpdateStormSiteConfigs() throws Exception {
     EasyMockSupport easyMockSupport = new EasyMockSupport();
@@ -292,9 +463,19 @@ public class UpgradeCatalog213Test {
         binder.bind(DBAccessor.class).toInstance(dbAccessor);
         binder.bind(EntityManager.class).toInstance(entityManager);
         binder.bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
+        binder.bind(DaoUtils.class).toInstance(createNiceMock(DaoUtils.class));
+        binder.bind(ClusterDAO.class).toInstance(clusterDAO);
+        binder.bind(RepositoryVersionHelper.class).toInstance(createNiceMock(RepositoryVersionHelper.class));
+        binder.bind(Clusters.class).toInstance(createNiceMock(Clusters.class));
+        binder.bind(AmbariManagementController.class).toInstance(amc);
+        binder.bind(AmbariMetaInfo.class).toInstance(metaInfo);
+        binder.bind(StackManagerFactory.class).toInstance(createNiceMock(StackManagerFactory.class));
+        binder.bind(StackDAO.class).toInstance(stackDAO);
+        binder.bind(RepositoryVersionDAO.class).toInstance(repositoryVersionDAO);
+        binder.bind(ClusterVersionDAO.class).toInstance(clusterVersionDAO);
+        binder.bind(HostVersionDAO.class).toInstance(hostVersionDAO);
       }
     };
-
     Injector injector = Guice.createInjector(module);
     return injector.getInstance(UpgradeCatalog213.class);
   }
@@ -313,4 +494,41 @@ public class UpgradeCatalog213Test {
 
     Assert.assertEquals("2.1.3", upgradeCatalog.getTargetVersion());
   }
+
+  // *********** Inner Classes that represent sections of the DDL ***********
+  // ************************************************************************
+
+  /**
+   * Verify that the upgrade table has two columns added to it.
+   */
+  class UpgradeSectionDDL implements SectionDDL {
+
+    Capture<DBAccessor.DBColumnInfo> upgradeTablePackageNameColumnCapture = new Capture<DBAccessor.DBColumnInfo>();
+    Capture<DBAccessor.DBColumnInfo> upgradeTableUpgradeTypeColumnCapture = new Capture<DBAccessor.DBColumnInfo>();
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void execute(DBAccessor dbAccessor) throws SQLException {
+      // Add columns
+      dbAccessor.addColumn(eq("upgrade"), capture(upgradeTablePackageNameColumnCapture));
+      dbAccessor.addColumn(eq("upgrade"), capture(upgradeTableUpgradeTypeColumnCapture));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void verify(DBAccessor dbAccessor) throws SQLException {
+      // Verification section
+      DBAccessor.DBColumnInfo packageNameCol = upgradeTablePackageNameColumnCapture.getValue();
+      Assert.assertEquals(String.class, packageNameCol.getType());
+      Assert.assertEquals("upgrade_package", packageNameCol.getName());
+
+      DBAccessor.DBColumnInfo upgradeTypeCol = upgradeTableUpgradeTypeColumnCapture.getValue();
+      Assert.assertEquals(String.class, upgradeTypeCol.getType());
+      Assert.assertEquals("upgrade_type", upgradeTypeCol.getName());
+    }
+  }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/test/python/stacks/2.0.6/HBASE/test_hbase_master.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.0.6/HBASE/test_hbase_master.py b/ambari-server/src/test/python/stacks/2.0.6/HBASE/test_hbase_master.py
index f96d8a7..04dd3bb 100644
--- a/ambari-server/src/test/python/stacks/2.0.6/HBASE/test_hbase_master.py
+++ b/ambari-server/src/test/python/stacks/2.0.6/HBASE/test_hbase_master.py
@@ -727,7 +727,7 @@ class TestHBaseMaster(RMFTestCase):
   def test_upgrade_backup(self):
     self.executeScript(self.COMMON_SERVICES_PACKAGE_DIR + "/scripts/hbase_upgrade.py",
                    classname = "HbaseMasterUpgrade",
-                   command = "snapshot",
+                   command = "take_snapshot",
                    config_file="hbase-preupgrade.json",
                    hdp_stack_version = self.STACK_VERSION,
                    target = RMFTestCase.TARGET_COMMON_SERVICES)

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/test/python/stacks/2.1/configs/secured-storm-start.json.orig
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.1/configs/secured-storm-start.json.orig b/ambari-server/src/test/python/stacks/2.1/configs/secured-storm-start.json.orig
deleted file mode 100644
index 9dad8e1..0000000
--- a/ambari-server/src/test/python/stacks/2.1/configs/secured-storm-start.json.orig
+++ /dev/null
@@ -1,374 +0,0 @@
-{
-    "configuration_attributes": {
-        "storm-site": {}, 
-        "hdfs-site": {
-            "final": {
-                "dfs.support.append": "true", 
-                "dfs.namenode.http-address": "true"
-            }
-        }, 
-        "storm-env": {}, 
-        "core-site": {
-            "final": {
-                "fs.defaultFS": "true"
-            }
-        }, 
-        "hadoop-policy": {}, 
-        "hdfs-log4j": {}, 
-        "hadoop-env": {}, 
-        "zookeeper-env": {}, 
-        "zookeeper-log4j": {}, 
-        "cluster-env": {}
-    }, 
-    "commandParams": {
-        "command_timeout": "600", 
-        "script": "scripts/nimbus.py", 
-        "script_type": "PYTHON", 
-        "service_package_folder": "HDP/2.1/services/STORM/package", 
-        "hooks_folder": "HDP/2.0.6/hooks"
-    }, 
-    "roleCommand": "START", 
-    "clusterName": "pacan", 
-    "hostname": "c6402.ambari.apache.org", 
-    "hostLevelParams": {
-        "jdk_location": "http://c6401.ambari.apache.org:8080/resources/", 
-        "ambari_db_rca_password": "mapred", 
-        "java_home": "/usr/jdk64/jdk1.7.0_45", 
-        "ambari_db_rca_url": "jdbc:postgresql://c6401.ambari.apache.org/ambarirca", 
-        "jce_name": "UnlimitedJCEPolicyJDK7.zip", 
-        "oracle_jdbc_url": "http://c6401.ambari.apache.org:8080/resources//ojdbc6.jar", 
-        "repo_info": "[{\"baseUrl\":\"http://s3.amazonaws.com/dev.hortonworks.com/HDP/centos6/2.x/updates/2.2.0.0\",\"osType\":\"redhat6\",\"repoId\":\"HDP-2.2\",\"repoName\":\"HDP\",\"defaultBaseUrl\":\"http://s3.amazonaws.com/dev.hortonworks.com/HDP/centos6/2.x/updates/2.2.0.0\",\"latestBaseUrl\":\"http://s3.amazonaws.com/dev.hortonworks.com/HDP/centos6/2.x/updates/2.2.0.0\"},{\"baseUrl\":\"http://s3.amazonaws.com/dev.hortonworks.com/HDP-UTILS-1.1.0.20/repos/centos6\",\"osType\":\"redhat6\",\"repoId\":\"HDP-UTILS-1.1.0.20\",\"repoName\":\"HDP-UTILS\",\"defaultBaseUrl\":\"http://s3.amazonaws.com/dev.hortonworks.com/HDP-UTILS-1.1.0.20/repos/centos6\",\"latestBaseUrl\":\"http://s3.amazonaws.com/dev.hortonworks.com/HDP-UTILS-1.1.0.20/repos/centos6\"}]", 
-        "group_list": "[\"hadoop\",\"users\"]", 
-        "package_list": "[{\"name\":\"storm_2_2_0_0_*\"}]", 
-        "stack_version": "2.2", 
-        "stack_name": "HDP", 
-        "db_name": "ambari", 
-        "ambari_db_rca_driver": "org.postgresql.Driver", 
-        "jdk_name": "jdk-7u45-linux-x64.tar.gz", 
-        "ambari_db_rca_username": "mapred", 
-        "db_driver_filename": "mysql-connector-java.jar", 
-        "user_list": "[\"ambari-qa\",\"zookeeper\",\"hdfs\",\"storm\"]", 
-        "mysql_jdbc_url": "http://c6401.ambari.apache.org:8080/resources//mysql-connector-java.jar"
-    }, 
-    "commandType": "EXECUTION_COMMAND", 
-    "roleParams": {}, 
-    "serviceName": "STORM", 
-    "role": "NIMBUS", 
-    "forceRefreshConfigTags": [], 
-    "taskId": 54, 
-    "public_hostname": "c6402.ambari.apache.org", 
-    "configurations": {
-        "storm-site": {
-            "topology.tuple.serializer": "backtype.storm.serialization.types.ListDelegateSerializer", 
-            "topology.workers": "1", 
-            "drpc.worker.threads": "64", 
-            "storm.zookeeper.servers": "['c6402.ambari.apache.org']", 
-            "supervisor.heartbeat.frequency.secs": "5", 
-            "topology.executor.send.buffer.size": "1024", 
-            "drpc.childopts": "-Xmx768m", 
-            "nimbus.thrift.port": "6627", 
-            "storm.zookeeper.retry.intervalceiling.millis": "30000", 
-            "storm.local.dir": "/hadoop/storm", 
-            "topology.receiver.buffer.size": "8", 
-            "storm.messaging.netty.client_worker_threads": "1", 
-            "transactional.zookeeper.root": "/transactional", 
-            "topology.skip.missing.kryo.registrations": "false", 
-            "worker.heartbeat.frequency.secs": "1", 
-            "zmq.hwm": "0", 
-            "storm.zookeeper.connection.timeout": "15000", 
-            "_storm.thrift.secure.transport": "SECURED_TRANSPORT_CLASS", 
-            "storm.messaging.netty.server_worker_threads": "1", 
-            "supervisor.worker.start.timeout.secs": "120", 
-            "zmq.threads": "1", 
-            "topology.acker.executors": "null", 
-            "storm.local.mode.zmq": "false", 
-            "topology.max.task.parallelism": "null", 
-            "topology.max.error.report.per.interval": "5", 
-            "storm.zookeeper.port": "2181", 
-            "drpc.queue.size": "128", 
-            "worker.childopts": "-Xmx768m _JAAS_PLACEHOLDER -javaagent:/usr/hdp/current/storm/contrib/storm-jmxetric/lib/jmxetric-1.0.4.jar=host=localhost,port=8650,wireformat31x=true,mode=multicast,config=/usr/hdp/current/storm/contrib/storm-jmxetric/conf/jmxetric-conf.xml,process=Worker_%ID%_JVM", 
-            "nimbus.childopts": "-Xmx1024m _JAAS_PLACEHOLDER -javaagent:/usr/hdp/current/storm/contrib/storm-jmxetric/lib/jmxetric-1.0.4.jar=host=localhost,port=8649,wireformat31x=true,mode=multicast,config=/usr/hdp/current/storm/contrib/storm-jmxetric/conf/jmxetric-conf.xml,process=Nimbus_JVM", 
-            "storm.zookeeper.retry.times": "5", 
-            "nimbus.monitor.freq.secs": "10", 
-            "storm.cluster.mode": "distributed", 
-            "dev.zookeeper.path": "/tmp/dev-storm-zookeeper", 
-            "drpc.invocations.port": "3773", 
-            "_storm.thrift.nonsecure.transport": "NON_SECURED_TRANSPORT_CLASS", 
-            "storm.zookeeper.root": "/storm", 
-            "logviewer.childopts": "-Xmx128m", 
-            "transactional.zookeeper.port": "null", 
-            "topology.worker.childopts": "null", 
-            "topology.max.spout.pending": "1000",
-            "nimbus.cleanup.inbox.freq.secs": "600", 
-            "storm.messaging.netty.min_wait_ms": "100", 
-            "nimbus.task.timeout.secs": "30", 
-            "nimbus.thrift.max_buffer_size": "1048576", 
-            "topology.sleep.spout.wait.strategy.time.ms": "1", 
-            "topology.optimize": "true", 
-            "nimbus.reassign": "true", 
-            "storm.messaging.transport": "backtype.storm.messaging.netty.Context", 
-            "logviewer.appender.name": "A1", 
-            "nimbus.host": "c6402.ambari.apache.org", 
-            "ui.port": "8744", 
-            "supervisor.slots.ports": "[6700, 6701]", 
-            "nimbus.file.copy.expiration.secs": "600", 
-            "supervisor.monitor.frequency.secs": "3", 
-            "ui.childopts": "-Xmx768m _JAAS_PLACEHOLDER", 
-            "transactional.zookeeper.servers": "null", 
-            "zmq.linger.millis": "5000", 
-            "topology.error.throttle.interval.secs": "10", 
-            "topology.worker.shared.thread.pool.size": "4", 
-            "java.library.path": "/usr/local/lib:/opt/local/lib:/usr/lib:/usr/hdp/current/storm/lib", 
-            "topology.spout.wait.strategy": "backtype.storm.spout.SleepSpoutWaitStrategy", 
-            "task.heartbeat.frequency.secs": "3", 
-            "topology.transfer.buffer.size": "1024", 
-            "storm.zookeeper.session.timeout": "20000", 
-            "topology.executor.receive.buffer.size": "1024", 
-            "topology.stats.sample.rate": "0.05", 
-            "topology.fall.back.on.java.serialization": "true", 
-            "supervisor.childopts": "-Xmx256m _JAAS_PLACEHOLDER -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.port=56431 -javaagent:/usr/hdp/current/storm/contrib/storm-jmxetric/lib/jmxetric-1.0.4.jar=host=localhost,port=8650,wireformat31x=true,mode=multicast,config=/usr/hdp/current/storm/contrib/storm-jmxetric/conf/jmxetric-conf.xml,process=Supervisor_JVM", 
-            "topology.enable.message.timeouts": "true", 
-            "storm.messaging.netty.max_wait_ms": "1000", 
-            "nimbus.topology.validator": "backtype.storm.nimbus.DefaultTopologyValidator", 
-            "nimbus.supervisor.timeout.secs": "60", 
-            "topology.disruptor.wait.strategy": "com.lmax.disruptor.BlockingWaitStrategy", 
-            "nimbus.inbox.jar.expiration.secs": "3600", 
-            "drpc.port": "3772", 
-            "topology.kryo.factory": "backtype.storm.serialization.DefaultKryoFactory", 
-            "storm.zookeeper.retry.interval": "1000", 
-            "storm.messaging.netty.max_retries": "30", 
-            "topology.tick.tuple.freq.secs": "null", 
-            "drpc.request.timeout.secs": "600", 
-            "nimbus.task.launch.secs": "120", 
-            "task.refresh.poll.secs": "10", 
-            "topology.message.timeout.secs": "30", 
-            "storm.messaging.netty.buffer_size": "5242880", 
-            "topology.state.synchronization.timeout.secs": "60", 
-            "supervisor.worker.timeout.secs": "30", 
-            "topology.trident.batch.emit.interval.millis": "500", 
-            "topology.builtin.metrics.bucket.size.secs": "60", 
-            "logviewer.port": "8000", 
-            "topology.debug": "false"
-        }, 
-        "hdfs-site": {
-            "dfs.namenode.avoid.write.stale.datanode": "true", 
-            "dfs.namenode.kerberos.internal.spnego.principal": "${dfs.web.authentication.kerberos.principal}", 
-            "dfs.namenode.checkpoint.txns": "1000000", 
-            "dfs.block.access.token.enable": "true", 
-            "dfs.support.append": "true", 
-            "dfs.datanode.address": "0.0.0.0:1019", 
-            "dfs.cluster.administrators": " hdfs", 
-            "dfs.journalnode.kerberos.principal": "jn/_HOST@EXAMPLE.COM", 
-            "dfs.datanode.balance.bandwidthPerSec": "6250000", 
-            "dfs.namenode.safemode.threshold-pct": "1.0f", 
-            "dfs.namenode.checkpoint.edits.dir": "${dfs.namenode.checkpoint.dir}", 
-            "dfs.permissions.enabled": "true", 
-            "dfs.namenode.kerberos.principal": "nn/_HOST@EXAMPLE.COM", 
-            "dfs.namenode.checkpoint.dir": "/hadoop/hdfs/namesecondary", 
-            "dfs.https.port": "50470", 
-            "dfs.namenode.https-address": "c6402.ambari.apache.org:50470", 
-            "dfs.secondary.namenode.kerberos.https.principal": "HTTP/_HOST@EXAMPLE.COM", 
-            "dfs.blockreport.initialDelay": "120", 
-            "dfs.journalnode.edits.dir": "/grid/0/hdfs/journal", 
-            "dfs.blocksize": "134217728", 
-            "dfs.client.read.shortcircuit": "true", 
-            "dfs.datanode.max.transfer.threads": "1024", 
-            "dfs.heartbeat.interval": "3", 
-            "dfs.replication": "3", 
-            "dfs.namenode.handler.count": "40", 
-            "dfs.web.authentication.kerberos.keytab": "/etc/security/keytabs/spnego.service.keytab", 
-            "fs.permissions.umask-mode": "022", 
-            "dfs.namenode.stale.datanode.interval": "30000", 
-            "dfs.datanode.ipc.address": "0.0.0.0:8010", 
-            "dfs.namenode.name.dir": "/hadoop/hdfs/namenode", 
-            "dfs.secondary.namenode.kerberos.internal.spnego.principal": "${dfs.web.authentication.kerberos.principal}", 
-            "dfs.datanode.data.dir": "/hadoop/hdfs/data", 
-            "dfs.namenode.http-address": "c6402.ambari.apache.org:50070", 
-            "dfs.webhdfs.enabled": "true", 
-            "dfs.datanode.failed.volumes.tolerated": "0", 
-            "dfs.namenode.accesstime.precision": "0", 
-            "dfs.namenode.avoid.read.stale.datanode": "true", 
-            "dfs.namenode.secondary.http-address": "c6402.ambari.apache.org:50090", 
-            "dfs.datanode.kerberos.principal": "dn/_HOST@EXAMPLE.COM", 
-            "dfs.journalnode.keytab.file": "/etc/security/keytabs/jn.service.keytab", 
-            "dfs.datanode.http.address": "0.0.0.0:1022", 
-            "dfs.datanode.du.reserved": "1073741824", 
-            "dfs.client.read.shortcircuit.streams.cache.size": "4096", 
-            "dfs.namenode.kerberos.https.principal": "HTTP/_HOST@EXAMPLE.COM", 
-            "dfs.secondary.namenode.keytab.file": "/etc/security/keytabs/nn.service.keytab", 
-            "dfs.web.authentication.kerberos.principal": "HTTP/_HOST@EXAMPLE.COM", 
-            "dfs.secondary.namenode.kerberos.principal": "nn/_HOST@EXAMPLE.COM", 
-            "dfs.datanode.keytab.file": "/etc/security/keytabs/dn.service.keytab", 
-            "dfs.namenode.keytab.file": "/etc/security/keytabs/nn.service.keytab", 
-            "dfs.permissions.superusergroup": "hdfs", 
-            "dfs.journalnode.http-address": "0.0.0.0:8480", 
-            "dfs.journalnode.kerberos.internal.spnego.principal": "HTTP/_HOST@EXAMPLE.COM", 
-            "dfs.domain.socket.path": "/var/lib/hadoop-hdfs/dn_socket", 
-            "dfs.namenode.write.stale.datanode.ratio": "1.0f", 
-            "dfs.hosts.exclude": "/etc/hadoop/conf/dfs.exclude", 
-            "dfs.datanode.data.dir.perm": "750", 
-            "dfs.namenode.name.dir.restore": "true", 
-            "dfs.replication.max": "50", 
-            "dfs.namenode.checkpoint.period": "21600",
-            "dfs.http.policy": "HTTP_ONLY"
-        }, 
-        "storm-env": {
-            "storm_log_dir": "/var/log/storm", 
-            "storm_principal_name": "storm@EXAMPLE.COM", 
-            "storm_pid_dir": "/var/run/storm", 
-            "storm_user": "storm", 
-            "content": "\n#!/bin/bash\n\n# Set Storm specific environment variables here.\n\n# The java implementation to use.\nexport JAVA_HOME={{java64_home}}\n\n# export STORM_CONF_DIR=\"\"", 
-            "nimbus_principal_name": "nimbus/_HOST@EXAMPLE.COM", 
-            "storm_ui_keytab": "/etc/security/keytabs/http.storm.service.keytab",
-            "nimbus_keytab": "/etc/security/keytabs/nimbus.service.keytab", 
-            "storm_keytab": "/etc/security/keytabs/storm.headless.keytab",
-            "storm_ui_principal_name": "HTTP/_HOST"
-        }, 
-        "core-site": {
-            "io.serializations": "org.apache.hadoop.io.serializer.WritableSerialization", 
-            "fs.trash.interval": "360", 
-            "hadoop.security.authentication": "kerberos", 
-            "io.compression.codecs": "org.apache.hadoop.io.compress.GzipCodec,org.apache.hadoop.io.compress.DefaultCodec", 
-            "hadoop.proxyuser.falcon.hosts": "*", 
-            "mapreduce.jobtracker.webinterface.trusted": "false", 
-            "hadoop.security.authorization": "true", 
-            "fs.defaultFS": "hdfs://c6402.ambari.apache.org:8020", 
-            "ipc.server.tcpnodelay": "true", 
-            "ipc.client.connect.max.retries": "50", 
-            "ipc.client.idlethreshold": "8000", 
-            "io.file.buffer.size": "131072", 
-            "hadoop.security.auth_to_local": "RULE:[2:$1@$0](rm@.*EXAMPLE.COM)s/.*/yarn/\nRULE:[2:$1@$0](nm@.*EXAMPLE.COM)s/.*/yarn/\nRULE:[2:$1@$0](nn@.*EXAMPLE.COM)s/.*/hdfs/\nRULE:[2:$1@$0](dn@.*EXAMPLE.COM)s/.*/hdfs/\nRULE:[2:$1@$0](jn/_HOST@.*EXAMPLE.COM)s/.*/hdfs/\nRULE:[2:$1@$0](falcon@.*EXAMPLE.COM)s/.*/falcon/\nDEFAULT", 
-            "ipc.client.connection.maxidletime": "30000", 
-            "hadoop.proxyuser.falcon.groups": "users"
-        }, 
-        "hadoop-policy": {
-            "security.job.client.protocol.acl": "*", 
-            "security.job.task.protocol.acl": "*", 
-            "security.datanode.protocol.acl": "*", 
-            "security.namenode.protocol.acl": "*", 
-            "security.client.datanode.protocol.acl": "*", 
-            "security.inter.tracker.protocol.acl": "*", 
-            "security.refresh.usertogroups.mappings.protocol.acl": "hadoop", 
-            "security.client.protocol.acl": "*", 
-            "security.refresh.policy.protocol.acl": "hadoop", 
-            "security.admin.operations.protocol.acl": "hadoop", 
-            "security.inter.datanode.protocol.acl": "*"
-        }, 
-        "hdfs-log4j": {
-            "content": "\n#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n#  http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n# KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n#\n\n\n# Define some default values that can be overridden by system properties\n# To change daemon root logger use hadoop_root_logger in hadoop-env\nhadoop.root.lo
 gger=INFO,console\nhadoop.log.dir=.\nhadoop.log.file=hadoop.log\n\n\n# Define the root logger to the system property \"hadoop.root.logger\".\nlog4j.rootLogger=${hadoop.root.logger}, EventCounter\n\n# Logging Threshold\nlog4j.threshhold=ALL\n\n#\n# Daily Rolling File Appender\n#\n\nlog4j.appender.DRFA=org.apache.log4j.DailyRollingFileAppender\nlog4j.appender.DRFA.File=${hadoop.log.dir}/${hadoop.log.file}\n\n# Rollver at midnight\nlog4j.appender.DRFA.DatePattern=.yyyy-MM-dd\n\n# 30-day backup\n#log4j.appender.DRFA.MaxBackupIndex=30\nlog4j.appender.DRFA.layout=org.apache.log4j.PatternLayout\n\n# Pattern format: Date LogLevel LoggerName LogMessage\nlog4j.appender.DRFA.layout.ConversionPattern=%d{ISO8601} %p %c: %m%n\n# Debugging Pattern format\n#log4j.appender.DRFA.layout.ConversionPattern=%d{ISO8601} %-5p %c{2} (%F:%M(%L)) - %m%n\n\n\n#\n# console\n# Add \"console\" to rootlogger above if you want to use this\n#\n\nlog4j.appender.console=org.apache.log4j.ConsoleAppender\nlog4j.appender
 .console.target=System.err\nlog4j.appender.console.layout=org.apache.log4j.PatternLayout\nlog4j.appender.console.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %p %c{2}: %m%n\n\n#\n# TaskLog Appender\n#\n\n#Default values\nhadoop.tasklog.taskid=null\nhadoop.tasklog.iscleanup=false\nhadoop.tasklog.noKeepSplits=4\nhadoop.tasklog.totalLogFileSize=100\nhadoop.tasklog.purgeLogSplits=true\nhadoop.tasklog.logsRetainHours=12\n\nlog4j.appender.TLA=org.apache.hadoop.mapred.TaskLogAppender\nlog4j.appender.TLA.taskId=${hadoop.tasklog.taskid}\nlog4j.appender.TLA.isCleanup=${hadoop.tasklog.iscleanup}\nlog4j.appender.TLA.totalLogFileSize=${hadoop.tasklog.totalLogFileSize}\n\nlog4j.appender.TLA.layout=org.apache.log4j.PatternLayout\nlog4j.appender.TLA.layout.ConversionPattern=%d{ISO8601} %p %c: %m%n\n\n#\n#Security audit appender\n#\nhadoop.security.logger=INFO,console\nhadoop.security.log.maxfilesize=256MB\nhadoop.security.log.maxbackupindex=20\nlog4j.category.SecurityLogger=${hadoop.security.logg
 er}\nhadoop.security.log.file=SecurityAuth.audit\nlog4j.appender.DRFAS=org.apache.log4j.DailyRollingFileAppender\nlog4j.appender.DRFAS.File=${hadoop.log.dir}/${hadoop.security.log.file}\nlog4j.appender.DRFAS.layout=org.apache.log4j.PatternLayout\nlog4j.appender.DRFAS.layout.ConversionPattern=%d{ISO8601} %p %c: %m%n\nlog4j.appender.DRFAS.DatePattern=.yyyy-MM-dd\n\nlog4j.appender.RFAS=org.apache.log4j.RollingFileAppender\nlog4j.appender.RFAS.File=${hadoop.log.dir}/${hadoop.security.log.file}\nlog4j.appender.RFAS.layout=org.apache.log4j.PatternLayout\nlog4j.appender.RFAS.layout.ConversionPattern=%d{ISO8601} %p %c: %m%n\nlog4j.appender.RFAS.MaxFileSize=${hadoop.security.log.maxfilesize}\nlog4j.appender.RFAS.MaxBackupIndex=${hadoop.security.log.maxbackupindex}\n\n#\n# hdfs audit logging\n#\nhdfs.audit.logger=INFO,console\nlog4j.logger.org.apache.hadoop.hdfs.server.namenode.FSNamesystem.audit=${hdfs.audit.logger}\nlog4j.additivity.org.apache.hadoop.hdfs.server.namenode.FSNamesystem.audit=
 false\nlog4j.appender.DRFAAUDIT=org.apache.log4j.DailyRollingFileAppender\nlog4j.appender.DRFAAUDIT.File=${hadoop.log.dir}/hdfs-audit.log\nlog4j.appender.DRFAAUDIT.layout=org.apache.log4j.PatternLayout\nlog4j.appender.DRFAAUDIT.layout.ConversionPattern=%d{ISO8601} %p %c{2}: %m%n\nlog4j.appender.DRFAAUDIT.DatePattern=.yyyy-MM-dd\n\n#\n# mapred audit logging\n#\nmapred.audit.logger=INFO,console\nlog4j.logger.org.apache.hadoop.mapred.AuditLogger=${mapred.audit.logger}\nlog4j.additivity.org.apache.hadoop.mapred.AuditLogger=false\nlog4j.appender.MRAUDIT=org.apache.log4j.DailyRollingFileAppender\nlog4j.appender.MRAUDIT.File=${hadoop.log.dir}/mapred-audit.log\nlog4j.appender.MRAUDIT.layout=org.apache.log4j.PatternLayout\nlog4j.appender.MRAUDIT.layout.ConversionPattern=%d{ISO8601} %p %c{2}: %m%n\nlog4j.appender.MRAUDIT.DatePattern=.yyyy-MM-dd\n\n#\n# Rolling File Appender\n#\n\nlog4j.appender.RFA=org.apache.log4j.RollingFileAppender\nlog4j.appender.RFA.File=${hadoop.log.dir}/${hadoop.log.fi
 le}\n\n# Logfile size and and 30-day backups\nlog4j.appender.RFA.MaxFileSize=256MB\nlog4j.appender.RFA.MaxBackupIndex=10\n\nlog4j.appender.RFA.layout=org.apache.log4j.PatternLayout\nlog4j.appender.RFA.layout.ConversionPattern=%d{ISO8601} %-5p %c{2} - %m%n\nlog4j.appender.RFA.layout.ConversionPattern=%d{ISO8601} %-5p %c{2} (%F:%M(%L)) - %m%n\n\n\n# Custom Logging levels\n\nhadoop.metrics.log.level=INFO\n#log4j.logger.org.apache.hadoop.mapred.JobTracker=DEBUG\n#log4j.logger.org.apache.hadoop.mapred.TaskTracker=DEBUG\n#log4j.logger.org.apache.hadoop.fs.FSNamesystem=DEBUG\nlog4j.logger.org.apache.hadoop.metrics2=${hadoop.metrics.log.level}\n\n# Jets3t library\nlog4j.logger.org.jets3t.service.impl.rest.httpclient.RestS3Service=ERROR\n\n#\n# Null Appender\n# Trap security logger on the hadoop client side\n#\nlog4j.appender.NullAppender=org.apache.log4j.varia.NullAppender\n\n#\n# Event Counter Appender\n# Sends counts of logging messages at different severity levels to Hadoop Metrics.\n#\n
 log4j.appender.EventCounter=org.apache.hadoop.log.metrics.EventCounter\n\n# Removes \"deprecated\" messages\nlog4j.logger.org.apache.hadoop.conf.Configuration.deprecation=WARN"
-        }, 
-        "hadoop-env": {
-            "namenode_opt_maxnewsize": "200m", 
-            "hdfs_log_dir_prefix": "/var/log/hadoop", 
-            "namenode_heapsize": "1024m", 
-            "proxyuser_group": "users", 
-            "hdfs_user_keytab": "/etc/security/keytabs/hdfs.headless.keytab", 
-            "content": "\n# Set Hadoop-specific environment variables here.\n\n# The only required environment variable is JAVA_HOME.  All others are\n# optional.  When running a distributed configuration it is best to\n# set JAVA_HOME in this file, so that it is correctly defined on\n# remote nodes.\n\n# The java implementation to use.  Required.\nexport JAVA_HOME={{java_home}}\nexport HADOOP_HOME_WARN_SUPPRESS=1\n\n# Hadoop home directory\nexport HADOOP_HOME=${HADOOP_HOME:-/usr/lib/hadoop}\n\n# Hadoop Configuration Directory\n#TODO: if env var set that can cause problems\nexport HADOOP_CONF_DIR=${HADOOP_CONF_DIR:-{{hadoop_conf_dir}}}\n\n{# this is different for HDP1 #}\n# Path to jsvc required by secure HDP 2.0 datanode\nexport JSVC_HOME={{jsvc_path}}\n\n\n# The maximum amount of heap to use, in MB. Default is 1000.\nexport HADOOP_HEAPSIZE=\"{{hadoop_heapsize}}\"\n\nexport HADOOP_NAMENODE_INIT_HEAPSIZE=\"-Xms{{namenode_heapsize}}\"\n\n# Extra Java runtime options.  Empty by defaul
 t.\nexport HADOOP_OPTS=\"-Djava.net.preferIPv4Stack=true ${HADOOP_OPTS}\"\n\n# Command specific options appended to HADOOP_OPTS when specified\nexport HADOOP_NAMENODE_OPTS=\"-server -XX:ParallelGCThreads=8 -XX:+UseConcMarkSweepGC -XX:ErrorFile={{hdfs_log_dir_prefix}}/$USER/hs_err_pid%p.log -XX:NewSize={{namenode_opt_newsize}} -XX:MaxNewSize={{namenode_opt_maxnewsize}} -XX:PermSize={{namenode_opt_permsize}} -XX:MaxPermSize={{namenode_opt_maxpermsize}} -Xloggc:{{hdfs_log_dir_prefix}}/$USER/gc.log-`date +'%Y%m%d%H%M'` -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xms{{namenode_heapsize}} -Xmx{{namenode_heapsize}} -Dhadoop.security.logger=INFO,DRFAS -Dhdfs.audit.logger=INFO,DRFAAUDIT ${HADOOP_NAMENODE_OPTS}\"\nHADOOP_JOBTRACKER_OPTS=\"-server -XX:ParallelGCThreads=8 -XX:+UseConcMarkSweepGC -XX:ErrorFile={{hdfs_log_dir_prefix}}/$USER/hs_err_pid%p.log -XX:NewSize={{jtnode_opt_newsize}} -XX:MaxNewSize={{jtnode_opt_maxnewsize}} -Xloggc:{{hdfs_log_dir_prefix}
 }/$USER/gc.log-`date +'%Y%m%d%H%M'` -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xmx{{jtnode_heapsize}} -Dhadoop.security.logger=INFO,DRFAS -Dmapred.audit.logger=INFO,MRAUDIT -Dhadoop.mapreduce.jobsummary.logger=INFO,JSA ${HADOOP_JOBTRACKER_OPTS}\"\n\nHADOOP_TASKTRACKER_OPTS=\"-server -Xmx{{ttnode_heapsize}} -Dhadoop.security.logger=ERROR,console -Dmapred.audit.logger=ERROR,console ${HADOOP_TASKTRACKER_OPTS}\"\nHADOOP_DATANODE_OPTS=\"-Xmx{{dtnode_heapsize}} -Dhadoop.security.logger=ERROR,DRFAS ${HADOOP_DATANODE_OPTS}\"\nHADOOP_BALANCER_OPTS=\"-server -Xmx{{hadoop_heapsize}}m ${HADOOP_BALANCER_OPTS}\"\n\nexport HADOOP_SECONDARYNAMENODE_OPTS=\"-server -XX:ParallelGCThreads=8 -XX:+UseConcMarkSweepGC -XX:ErrorFile={{hdfs_log_dir_prefix}}/$USER/hs_err_pid%p.log -XX:NewSize={{namenode_opt_newsize}} -XX:MaxNewSize={{namenode_opt_maxnewsize}} -XX:PermSize={{namenode_opt_permsize}} -XX:MaxPermSize={{namenode_opt_maxpermsize}} -Xloggc:{{hdfs_log_dir_prefix}}/
 $USER/gc.log-`date +'%Y%m%d%H%M'` -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps ${HADOOP_NAMENODE_INIT_HEAPSIZE} -Xmx{{namenode_heapsize}} -Dhadoop.security.logger=INFO,DRFAS -Dhdfs.audit.logger=INFO,DRFAAUDIT ${HADOOP_SECONDARYNAMENODE_OPTS}\"\n\n# The following applies to multiple commands (fs, dfs, fsck, distcp etc)\nexport HADOOP_CLIENT_OPTS=\"-Xmx${HADOOP_HEAPSIZE}m $HADOOP_CLIENT_OPTS\"\n# On secure datanodes, user to run the datanode as after dropping privileges\nexport HADOOP_SECURE_DN_USER={{hdfs_user}}\n\n# Extra ssh options.  Empty by default.\nexport HADOOP_SSH_OPTS=\"-o ConnectTimeout=5 -o SendEnv=HADOOP_CONF_DIR\"\n\n# Where log files are stored.  $HADOOP_HOME/logs by default.\nexport HADOOP_LOG_DIR={{hdfs_log_dir_prefix}}/$USER\n\n# History server logs\nexport HADOOP_MAPRED_LOG_DIR={{mapred_log_dir_prefix}}/$USER\n\n# Where log files are stored in the secure data environment.\nexport HADOOP_SECURE_DN_LOG_DIR={{hdfs_log_dir_prefix}}/$HAD
 OOP_SECURE_DN_USER\n\n# File naming remote slave hosts.  $HADOOP_HOME/conf/slaves by default.\n# export HADOOP_SLAVES=${HADOOP_HOME}/conf/slaves\n\n# host:path where hadoop code should be rsync'd from.  Unset by default.\n# export HADOOP_MASTER=master:/home/$USER/src/hadoop\n\n# Seconds to sleep between slave commands.  Unset by default.  This\n# can be useful in large clusters, where, e.g., slave rsyncs can\n# otherwise arrive faster than the master can service them.\n# export HADOOP_SLAVE_SLEEP=0.1\n\n# The directory where pid files are stored. /tmp by default.\nexport HADOOP_PID_DIR={{hadoop_pid_dir_prefix}}/$USER\nexport HADOOP_SECURE_DN_PID_DIR={{hadoop_pid_dir_prefix}}/$HADOOP_SECURE_DN_USER\n\n# History server pid\nexport HADOOP_MAPRED_PID_DIR={{mapred_pid_dir_prefix}}/$USER\n\nYARN_RESOURCEMANAGER_OPTS=\"-Dyarn.server.resourcemanager.appsummary.logger=INFO,RMSUMMARY\"\n\n# A string representing this instance of hadoop. $USER by default.\nexport HADOOP_IDENT_STRING=$USER\n\n#
  The scheduling priority for daemon processes.  See 'man nice'.\n\n# export HADOOP_NICENESS=10\n\n# Use libraries from standard classpath\nJAVA_JDBC_LIBS=\"\"\n#Add libraries required by mysql connector\nfor jarFile in `ls /usr/share/java/*mysql* 2>/dev/null`\ndo\n  JAVA_JDBC_LIBS=${JAVA_JDBC_LIBS}:$jarFile\ndone\n#Add libraries required by oracle connector\nfor jarFile in `ls /usr/share/java/*ojdbc* 2>/dev/null`\ndo\n  JAVA_JDBC_LIBS=${JAVA_JDBC_LIBS}:$jarFile\ndone\n#Add libraries required by nodemanager\nMAPREDUCE_LIBS={{mapreduce_libs_path}}\nexport HADOOP_CLASSPATH=${HADOOP_CLASSPATH}${JAVA_JDBC_LIBS}:${MAPREDUCE_LIBS}\n\nif [ -d \"/usr/lib/tez\" ]; then\n  export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:/usr/lib/tez/*:/usr/lib/tez/lib/*:/etc/tez/conf\nfi\n\n# Setting path to hdfs command line\nexport HADOOP_LIBEXEC_DIR={{hadoop_libexec_dir}}\n\n#Mostly required for hadoop 2.0\nexport JAVA_LIBRARY_PATH=${JAVA_LIBRARY_PATH}:/usr/lib/hadoop/lib/native/Linux-amd64-64\n\n#Hadoop logging 
 options\nexport HADOOP_ROOT_LOGGER={{hadoop_root_logger}}", 
-            "hdfs_user": "hdfs", 
-            "namenode_opt_newsize": "200m",
-            "namenode_opt_permsize" : "128m",
-            "namenode_opt_maxpermsize" : "256m", 
-            "dtnode_heapsize": "1024m", 
-            "hadoop_root_logger": "INFO,RFA", 
-            "hadoop_heapsize": "1024", 
-            "hadoop_pid_dir_prefix": "/var/run/hadoop", 
-            "hdfs_principal_name": "hdfs"
-        }, 
-        "zookeeper-env": {
-            "clientPort": "2181", 
-            "zookeeper_keytab_path": "/etc/security/keytabs/zk.service.keytab", 
-            "zk_user": "zookeeper", 
-            "zk_log_dir": "/var/log/zookeeper", 
-            "syncLimit": "5", 
-            "content": "\nexport JAVA_HOME={{java64_home}}\nexport ZOO_LOG_DIR={{zk_log_dir}}\nexport ZOOPIDFILE={{zk_pid_file}}\nexport SERVER_JVMFLAGS={{zk_server_heapsize}}\nexport JAVA=$JAVA_HOME/bin/java\nexport CLASSPATH=$CLASSPATH:/usr/share/zookeeper/*\n\n{% if security_enabled %}\nexport SERVER_JVMFLAGS=\"$SERVER_JVMFLAGS -Djava.security.auth.login.config={{zk_server_jaas_file}}\"\nexport CLIENT_JVMFLAGS=\"$CLIENT_JVMFLAGS -Djava.security.auth.login.config={{zk_client_jaas_file}}\"\n{% endif %}", 
-            "initLimit": "10", 
-            "zk_pid_dir": "/var/run/zookeeper", 
-            "zk_data_dir": "/hadoop/zookeeper", 
-            "zookeeper_principal_name": "zookeeper/_HOST@EXAMPLE.COM", 
-            "tickTime": "2000"
-        }, 
-        "zookeeper-log4j": {
-            "content": "\n#\n#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n#   http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n# KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n#\n#\n#\n\n#\n# ZooKeeper Logging Configuration\n#\n\n# DEFAULT: console appender only\nlog4j.rootLogger=INFO, CONSOLE\n\n# Example with rolling log file\n#log4
 j.rootLogger=DEBUG, CONSOLE, ROLLINGFILE\n\n# Example with rolling log file and tracing\n#log4j.rootLogger=TRACE, CONSOLE, ROLLINGFILE, TRACEFILE\n\n#\n# Log INFO level and above messages to the console\n#\nlog4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender\nlog4j.appender.CONSOLE.Threshold=INFO\nlog4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout\nlog4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} - %-5p [%t:%C{1}@%L] - %m%n\n\n#\n# Add ROLLINGFILE to rootLogger to get log file output\n#    Log DEBUG level and above messages to a log file\nlog4j.appender.ROLLINGFILE=org.apache.log4j.RollingFileAppender\nlog4j.appender.ROLLINGFILE.Threshold=DEBUG\nlog4j.appender.ROLLINGFILE.File=zookeeper.log\n\n# Max log file size of 10MB\nlog4j.appender.ROLLINGFILE.MaxFileSize=10MB\n# uncomment the next line to limit number of backup files\n#log4j.appender.ROLLINGFILE.MaxBackupIndex=10\n\nlog4j.appender.ROLLINGFILE.layout=org.apache.log4j.PatternLayout\nlog4j.appender.ROLLIN
 GFILE.layout.ConversionPattern=%d{ISO8601} - %-5p [%t:%C{1}@%L] - %m%n\n\n\n#\n# Add TRACEFILE to rootLogger to get log file output\n#    Log DEBUG level and above messages to a log file\nlog4j.appender.TRACEFILE=org.apache.log4j.FileAppender\nlog4j.appender.TRACEFILE.Threshold=TRACE\nlog4j.appender.TRACEFILE.File=zookeeper_trace.log\n\nlog4j.appender.TRACEFILE.layout=org.apache.log4j.PatternLayout\n### Notice we are including log4j's NDC here (%x)\nlog4j.appender.TRACEFILE.layout.ConversionPattern=%d{ISO8601} - %-5p [%t:%C{1}@%L][%x] - %m%n"
-        }, 
-        "cluster-env": {
-            "security_enabled": "true", 
-            "ignore_groupsusers_create": "false", 
-            "smokeuser_keytab": "/etc/security/keytabs/smokeuser.headless.keytab", 
-            "kerberos_domain": "EXAMPLE.COM", 
-            "kinit_path_local": "/usr/bin", 
-            "user_group": "hadoop", 
-            "smokeuser": "ambari-qa"
-        }
-    }, 
-    "configurationTags": {
-        "storm-site": {
-            "tag": "version1412001710682"
-        }, 
-        "hdfs-site": {
-            "tag": "version1412001710682"
-        }, 
-        "storm-env": {
-            "tag": "version1412001710682"
-        }, 
-        "core-site": {
-            "tag": "version1412001710682"
-        }, 
-        "hadoop-policy": {
-            "tag": "version1411996371868"
-        }, 
-        "hdfs-log4j": {
-            "tag": "version1411996371868"
-        }, 
-        "hadoop-env": {
-            "tag": "version1412001710682"
-        }, 
-        "zookeeper-env": {
-            "tag": "version1412001710682"
-        }, 
-        "zookeeper-log4j": {
-            "tag": "version1"
-        }, 
-        "cluster-env": {
-            "tag": "version1412001710681"
-        }
-    }, 
-    "commandId": "12-1", 
-    "clusterHostInfo": {
-        "snamenode_host": [
-            "c6402.ambari.apache.org"
-        ], 
-        "drpc_server_hosts": [
-            "c6402.ambari.apache.org"
-        ], 
-        "nimbus_hosts": [
-            "c6402.ambari.apache.org"
-        ], 
-        "all_ping_ports": [
-            "8670"
-        ], 
-        "all_hosts": [
-            "c6402.ambari.apache.org"
-        ], 
-        "slave_hosts": [
-            "c6402.ambari.apache.org"
-        ], 
-        "namenode_host": [
-            "c6402.ambari.apache.org"
-        ], 
-        "storm_ui_server_hosts": [
-            "c6402.ambari.apache.org"
-        ], 
-        "storm_rest_api_hosts": [
-            "c6402.ambari.apache.org"
-        ], 
-        "ambari_server_host": [
-            "c6401.ambari.apache.org"
-        ], 
-        "zookeeper_hosts": [
-            "c6402.ambari.apache.org"
-        ], 
-        "supervisor_hosts": [
-            "c6402.ambari.apache.org"
-        ]
-    }
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/config-upgrade.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/config-upgrade.xml b/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/config-upgrade.xml
new file mode 100644
index 0000000..1301f9d
--- /dev/null
+++ b/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/config-upgrade.xml
@@ -0,0 +1,101 @@
+<?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-config-changes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+  <services>
+    <service name="ZOOKEEPER">
+      <component name="ZOOKEEPER_SERVER">
+        <changes>
+          <definition xsi:type="configure" id="hdp_2_1_1_zk_post_upgrade">
+          </definition>
+        </changes>
+      </component>
+    </service>
+
+    <service name="HDFS">
+      <component name="NAMENODE">
+        <changes>
+          <definition xsi:type="configure" id="hdp_2_1_1_nn_pre_upgrade">
+            <type>hdfs-site</type>
+            <set key="myproperty" value="mynewvalue"/>
+          </definition>
+        </changes>
+      </component>
+    </service>
+
+    <service name="YARN">
+      <component name="NODEMANAGER">
+        <changes>
+          <definition xsi:type="configure" id="hdp_2_1_1_nm_pre_upgrade">
+            <type>core-site</type>
+            <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"
+                      preserve-edits="true">
+              <keep-key>important-key</keep-key>
+            </transfer>
+          </definition>
+        </changes>
+      </component>
+    </service>
+
+    <service name="HIVE">
+      <component name="HIVE_SERVER">
+        <changes>
+          <definition xsi:type="configure" id="hdp_2_1_1_set_transport_mode">
+            <condition type="hive-site" key="hive.server2.transport.mode" value="binary">
+              <type>hive-site</type>
+              <key>hive.server2.thrift.port</key>
+              <value>10010</value>
+            </condition>
+            <condition type="hive-site" key="hive.server2.transport.mode" value="http">
+              <type>hive-site</type>
+              <key>hive.server2.http.port</key>
+              <value>10011</value>
+            </condition>
+          </definition>
+
+          <definition xsi:type="configure" id="hdp_2_1_1_hive_server_foo">
+            <type>hive-site</type>
+            <set key="fooKey" value="fooValue"/>
+            <set key="fooKey2" value="fooValue2"/>
+            <set key="fooKey3" value="fooValue3"/>
+            <transfer operation="copy" from-key="copy-key" to-key="copy-key-to" />
+            <transfer operation="move" from-key="move-key" to-key="move-key-to" />
+            <transfer operation="delete" delete-key="delete-key" />
+            <transfer operation="delete" delete-key="delete-http" if-key="hive.server2.transport.mode" if-type="hive-site" if-value="http" />
+            <transfer operation="delete" delete-key="delete-https-fail" if-key="hive.server2.transport.mode" if-type="hive-site" if-value="https" />
+            <transfer operation="delete" delete-key="delete-prop-fail" if-key="non.existent" if-type="hive-site" if-value="https" />
+            <transfer operation="delete" delete-key="delete-type-fail" if-key="non.existent" if-type="non.existent" if-value="" />
+            <transfer operation="delete" delete-key="delete-null-if-value" if-key="non.existent" if-type="non.existent" />
+            <transfer operation="delete" delete-key="delete-blank-if-key" if-key="" if-type="non.existent" />
+            <transfer operation="delete" delete-key="delete-blank-if-type" if-key="non.existent" if-type="" />
+            <transfer operation="delete" delete-key="delete-thrift" if-key="hive.server2.thrift.port" if-type="hive-site" if-value="10001" />
+          </definition>
+        </changes>
+      </component>
+    </service>
+  </services>
+
+</upgrade-config-changes>

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_bucket_test.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_bucket_test.xml b/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_bucket_test.xml
index 92e8c6a..0e6d914 100644
--- a/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_bucket_test.xml
+++ b/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_bucket_test.xml
@@ -16,8 +16,21 @@
    limitations under the License.
 -->
 <upgrade xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-  <target>2.2.*</target>
-  
+  <target>2.2.*.*</target>
+  <target-stack>HDP-2.2.6</target-stack>
+  <type>ROLLING</type>
+  <prerequisite-checks>
+    <check>org.apache.ambari.server.checks.HiveMultipleMetastoreCheck</check>
+    <check>org.apache.ambari.server.checks.MapReduce2JobHistoryStatePreservingCheck</check>
+    <check>org.apache.ambari.server.checks.SecondaryNamenodeDeletedCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesMapReduceDistributedCacheCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesNamenodeHighAvailabilityCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesNamenodeTruncateCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesTezDistributedCacheCheck</check>
+    <check>org.apache.ambari.server.checks.ServicesYarnWorkPreservingCheck</check>
+    <check>org.apache.ambari.server.checks.YarnRMHighAvailabilityCheck</check>
+    <check>org.apache.ambari.server.checks.YarnTimelineServerStatePreservingCheck</check>
+  </prerequisite-checks>
   <order>
   
     <group name="ZOOKEEPER" title="Zookeeper">

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_direction.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_direction.xml b/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_direction.xml
index 89a9e4f..e12fcd9 100644
--- a/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_direction.xml
+++ b/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_direction.xml
@@ -16,7 +16,9 @@
    limitations under the License.
 -->
 <upgrade xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-  <target>2.2.*</target>
+  <target>2.2.*.*</target>
+  <target-stack>HDP-2.2.5</target-stack>
+  <type>ROLLING</type>
   
   <order>
     <group name="ZOOKEEPER" title="Zookeeper">
@@ -75,7 +77,7 @@
           </task>
         </pre-upgrade>
         <upgrade>
-          <task xsi:type="restart" />
+          <task xsi:type="restart-task" />
         </upgrade>
         <post-upgrade>
           <task xsi:type="configure" />


[7/9] ambari git commit: AMBARI-13392. Stop-and-Start Upgrade: Merge branch branch-dev-stop-all-upgrade to branch-2.1 for feature Stop-the-World Upgrade, aka Express Upgrade (alejandro, dlysnichenko, Dmytro Grinenko)

Posted by al...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/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 5b65732..5a8031b 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
@@ -22,6 +22,7 @@ import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.regex.Pattern;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
@@ -36,6 +37,7 @@ 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.ServiceCheckGrouping;
 import org.apache.ambari.server.state.stack.upgrade.Task;
+import org.apache.ambari.server.state.stack.upgrade.UpgradeType;
 
 /**
  * Represents an upgrade pack.
@@ -44,16 +46,37 @@ import org.apache.ambari.server.state.stack.upgrade.Task;
 @XmlAccessorType(XmlAccessType.FIELD)
 public class UpgradePack {
 
+  /**
+   * Name of the file without the extension, such as upgrade-2.2
+   */
+  private String name;
+
   @XmlElement(name="target")
   private String target;
 
   @XmlElement(name="target-stack")
   private String targetStack;
 
+  @XmlElement(name="type", defaultValue="rolling")
+  private UpgradeType type;
+
+  @XmlElementWrapper(name="upgrade-path")
+  @XmlElement(name="intermediate-stack")
+  private List<IntermediateStack> intermediateStacks;
+
   @XmlElementWrapper(name="order")
   @XmlElement(name="group")
   private List<Grouping> groups;
 
+  @XmlElementWrapper(name="prerequisite-checks")
+  @XmlElement(name="check", type=String.class)
+  private List<String> prerequisiteChecks = new ArrayList<String>();
+
+  /**
+   * In the case of a rolling upgrade, will specify processing logic for a particular component.
+   * NonRolling upgrades are simpler so the "processing" is embedded into the  group's "type", which is a function like
+   * "stop" or "start".
+   */
   @XmlElementWrapper(name="processing")
   @XmlElement(name="service")
   private List<ProcessingService> processing;
@@ -81,7 +104,13 @@ public class UpgradePack {
   @XmlTransient
   private boolean m_resolvedGroups = false;
 
+  public String getName() {
+    return name;
+  }
 
+  public void setName(String name) {
+    this.name = name;
+  }
   /**
    * @return the target version for the upgrade pack
    */
@@ -116,29 +145,66 @@ 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
+   * @return the type of upgrade, e.g., "ROLLING" or "NON_ROLLING"
+   */
+  public UpgradeType getType() {
+    return type;
+  }
+
+  /**
+   * @return the preCheck name, e.g. "CheckDescription"
+   */
+  public List<String> getPrerequisiteChecks() {
+    return new ArrayList<String>(prerequisiteChecks);
+  }
+
+  /**
+   * @return a list for intermediate stacks for cross-stack upgrade, or null if no any
+   */
+  public List<IntermediateStack> getIntermediateStacks() {
+    return intermediateStacks;
+  }
+
+  /**
+   * 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) {
-    List<Grouping> list = direction.isUpgrade() ? groups : getDowngradeGroups();
+    List<Grouping> list = new ArrayList<Grouping>();
+    if (direction.isUpgrade()) {
+      list = groups;
+    } else {
+      if (type == UpgradeType.ROLLING) {
+        list = getDowngradeGroupsForRolling();
+      } else if (type == UpgradeType.NON_ROLLING) {
+        list = getDowngradeGroupsForNonrolling();
+      }
+    }
 
     List<Grouping> checked = new ArrayList<Grouping>();
     for (Grouping group : list) {
       if (null == group.intendedDirection || direction == group.intendedDirection) {
         checked.add(group);
       }
-
     }
 
     return checked;
   }
 
+  public boolean canBeApplied(String targetVersion){
+    // check that upgrade pack can be applied to selected stack
+    // converting 2.2.*.* -> 2\.2(\.\d+)?(\.\d+)?(-\d+)?
+
+    String regexPattern = getTarget().replaceAll("\\.", "\\\\."); // . -> \.
+    regexPattern = regexPattern.replaceAll("\\\\\\.\\*", "(\\\\\\.\\\\d+)?"); // \.* -> (\.\d+)?
+    regexPattern = regexPattern.concat("(-\\d+)?");
+    return Pattern.matches(regexPattern, targetVersion);
+  }
+
   /**
-   * Calculates the group orders when performing a downgrade
+   * Calculates the group orders when performing a rolling downgrade
    * <ul>
    *   <li>ClusterGroupings must remain at the same positions (first/last).</li>
    *   <li>When there is a ServiceCheck group, it must ALWAYS follow the same</li>
@@ -169,7 +235,7 @@ public class UpgradePack {
    * </ol>
    * @return the list of groups, reversed appropriately for a downgrade.
    */
-  private List<Grouping> getDowngradeGroups() {
+  private List<Grouping> getDowngradeGroupsForRolling() {
     List<Grouping> reverse = new ArrayList<Grouping>();
 
     int idx = 0;
@@ -199,6 +265,17 @@ public class UpgradePack {
     return reverse;
   }
 
+  private List<Grouping> getDowngradeGroupsForNonrolling() {
+    throw new UnsupportedOperationException("TODO AMBARI-12698");
+    /*
+    List<Grouping> list = new ArrayList<Grouping>();
+    for (Grouping g : groups) {
+      list.add(g);
+    }
+    return list;
+    */
+  }
+
   /**
    * Gets the tasks by which services and components should be upgraded.
    * @return a map of service_name -> map(component_name -> process).
@@ -208,15 +285,17 @@ public class UpgradePack {
     if (null == m_process) {
       m_process = new LinkedHashMap<String, Map<String, ProcessingComponent>>();
 
-      for (ProcessingService svc : processing) {
-        if (!m_process.containsKey(svc.name)) {
-          m_process.put(svc.name, new LinkedHashMap<String, ProcessingComponent>());
-        }
+      if (processing != null) {
+        for (ProcessingService svc : processing) {
+          if (!m_process.containsKey(svc.name)) {
+            m_process.put(svc.name, new LinkedHashMap<String, ProcessingComponent>());
+          }
 
-        Map<String, ProcessingComponent> componentMap = m_process.get(svc.name);
+          Map<String, ProcessingComponent> componentMap = m_process.get(svc.name);
 
-        for (ProcessingComponent pc : svc.components) {
-          componentMap.put(pc.name, pc);
+          for (ProcessingComponent pc : svc.components) {
+            componentMap.put(pc.name, pc);
+          }
         }
       }
     }
@@ -248,8 +327,6 @@ public class UpgradePack {
     public List<ProcessingComponent> components;
   }
 
-
-
   /**
    * A component definition in the 'processing/service' path.
    */
@@ -279,4 +356,14 @@ public class UpgradePack {
     @XmlElement(name="task")
     public List<Task> postDowngradeTasks;
   }
+
+  /**
+   * An intermediate stack definition in
+   * upgrade/upgrade-path/intermediate-stack path
+   */
+  public static class IntermediateStack {
+
+    @XmlAttribute
+    public String version;
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/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 eff1b13..ba44408 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
@@ -53,7 +53,7 @@ import com.google.gson.JsonPrimitive;
 public class ClusterGrouping extends Grouping {
 
   /**
-   * Stages against a Service and Component, or the Server
+   * Stages against a Service and Component, or the Server, that doesn't need a Processing Component.
    */
   @XmlElement(name="execute-stage")
   public List<ExecuteStage> executionStages;
@@ -166,6 +166,12 @@ public class ClusterGrouping extends Grouping {
     }
   }
 
+  /**
+   * Return a Stage Wrapper for a manual task that runs on the server.
+   * @param ctx Upgrade Context
+   * @param execution Execution Stage
+   * @return Returns a Stage Wrapper
+   */
   private StageWrapper getManualStageWrapper(UpgradeContext ctx, ExecuteStage execution) {
 
     String service   = execution.service;
@@ -204,6 +210,12 @@ public class ClusterGrouping extends Grouping {
         new TaskWrapper(service, component, realHosts, task));
   }
 
+  /**
+   * Return a Stage Wrapper for a task meant to execute code, typically on Ambari Server.
+   * @param ctx Upgrade Context
+   * @param execution Execution Stage
+   * @return Returns a Stage Wrapper, or null if a valid one could not be created.
+   */
   private StageWrapper getExecuteStageWrapper(UpgradeContext ctx, ExecuteStage execution) {
     String service   = execution.service;
     String component = execution.component;
@@ -251,15 +263,18 @@ public class ClusterGrouping extends Grouping {
       return new StageWrapper(
           StageWrapper.Type.RU_TASKS, execution.title,
           new TaskWrapper(service, component, hostNames, et));
-
     }
     return null;
   }
 
-  private void fillHostDetails(ManualTask mt, Map<String, List<String>> unhealthy) {
-
+  /**
+   * Populates the manual task, mt, with information about the list of hosts.
+   * @param mt Manual Task
+   * @param hostToComponents Map from host name to list of components
+   */
+  private void fillHostDetails(ManualTask mt, Map<String, List<String>> hostToComponents) {
     JsonArray arr = new JsonArray();
-    for (Entry<String, List<String>> entry : unhealthy.entrySet()) {
+    for (Entry<String, List<String>> entry : hostToComponents.entrySet()) {
       JsonObject hostObj = new JsonObject();
       hostObj.addProperty("host", entry.getKey());
 
@@ -276,7 +291,5 @@ public class ClusterGrouping extends Grouping {
     obj.add("unhealthy", arr);
 
     mt.structuredOut = obj.toString();
-
   }
-
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ConfigUpgradeChangeDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ConfigUpgradeChangeDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ConfigUpgradeChangeDefinition.java
new file mode 100644
index 0000000..780f96d
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ConfigUpgradeChangeDefinition.java
@@ -0,0 +1,420 @@
+/**
+ * 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 com.google.gson.Gson;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.xml.bind.annotation.XmlAccessType;
+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.XmlType;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * The {@link ConfigUpgradeChangeDefinition} represents a configuration change. This change can be
+ * defined with conditional statements that will only set values if a condition
+ * passes:
+ * <p/>
+ *
+ * <pre>
+ * {@code
+ * <definition>
+ *   <condition type="hive-site" key="hive.server2.transport.mode" value="binary">
+ *     <type>hive-site</type>
+ *     <key>hive.server2.thrift.port</key>
+ *     <value>10010</value>
+ *   </condition>
+ *   <condition type="hive-site" key="hive.server2.transport.mode" value="http">
+ *     <type>hive-site</type>
+ *     <key>hive.server2.http.port</key>
+ *     <value>10011</value>
+ *   </condition>
+ * </definition>
+ * }
+ * </pre>
+ *
+ * It's also possible to simple set values directly without a precondition
+ * check.
+ *
+ * <pre>
+ * {@code
+ * <definition xsi:type="configure">
+ *   <type>hive-site</type>
+ *   <set key="hive.server2.thrift.port" value="10010"/>
+ *   <set key="foo" value="bar"/>
+ *   <set key="foobar" value="baz"/>
+ * </definition>
+ * }
+ * </pre>
+ *
+ */
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.FIELD)
+public class ConfigUpgradeChangeDefinition {
+
+  private static Logger LOG = LoggerFactory.getLogger(ConfigUpgradeChangeDefinition.class);
+
+  /**
+   * The key that represents the configuration type to change (ie hdfs-site).
+   */
+  public static final String PARAMETER_CONFIG_TYPE = "configure-task-config-type";
+
+  /**
+   * Setting key/value pairs can be several per task, so they're passed in as a
+   * json-ified list of objects.
+   */
+  public static final String PARAMETER_KEY_VALUE_PAIRS = "configure-task-key-value-pairs";
+
+  /**
+   * Transfers can be several per task, so they're passed in as a json-ified
+   * list of objects.
+   */
+  public static final String PARAMETER_TRANSFERS = "configure-task-transfers";
+
+  /**
+   * Replacements can be several per task, so they're passed in as a json-ified list of
+   * objects.
+   */
+  public static final String PARAMETER_REPLACEMENTS = "configure-task-replacements";
+
+  public static final String actionVerb = "Configuring";
+
+  public static final Float DEFAULT_PRIORITY = 1.0f;
+
+  /**
+   * Gson
+   */
+  private Gson m_gson = new Gson();
+
+  /**
+   * An optional brief description of config changes.
+   */
+  @XmlAttribute(name = "summary")
+  public String summary;
+
+  @XmlAttribute(name = "id", required = true)
+  public String id;
+
+  @XmlElement(name="type")
+  private String configType;
+
+  @XmlElement(name = "set")
+  private List<ConfigurationKeyValue> keyValuePairs;
+
+  @XmlElement(name = "condition")
+  private List<Condition> conditions;
+
+  @XmlElement(name = "transfer")
+  private List<Transfer> transfers;
+
+  @XmlElement(name="replace")
+  private List<Replace> replacements;
+
+  /**
+   * @return the config type
+   */
+  public String getConfigType() {
+    return configType;
+  }
+
+  /**
+   * @return the list of <set key=foo value=bar/> items
+   */
+  public List<ConfigurationKeyValue> getKeyValuePairs() {
+    return keyValuePairs;
+  }
+
+  /**
+   * @return the list of conditions
+   */
+  public List<Condition> getConditions() {
+    return conditions;
+  }
+
+  /**
+   * @return the list of transfers, checking for appropriate null fields.
+   */
+  public List<Transfer> getTransfers() {
+    if (null == transfers) {
+      return Collections.emptyList();
+    }
+
+    List<Transfer> list = new ArrayList<>();
+    for (Transfer t : transfers) {
+      switch (t.operation) {
+        case COPY:
+        case MOVE:
+          if (null != t.fromKey && null != t.toKey) {
+            list.add(t);
+          } else {
+            LOG.warn(String.format("Transfer %s is invalid", t));
+          }
+          break;
+        case DELETE:
+          if (null != t.deleteKey) {
+            list.add(t);
+          } else {
+            LOG.warn(String.format("Transfer %s is invalid", t));
+          }
+
+          break;
+      }
+    }
+
+    return list;
+  }
+
+  /**
+   * @return the replacement tokens, never {@code null}
+   */
+  public List<Replace> getReplacements() {
+    if (null == replacements) {
+      return Collections.emptyList();
+    }
+
+    List<Replace> list = new ArrayList<>();
+    for (Replace r : replacements) {
+      if (null == r.key || null == r.find || null == r.replaceWith) {
+        LOG.warn(String.format("Replacement %s is invalid", r));
+        continue;
+      }
+      list.add(r);
+    }
+
+    return list;
+  }
+
+  /**
+   * Used for configuration updates that should mask their values from being
+   * printed in plain text.
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  public static class Masked {
+    @XmlAttribute(name = "mask")
+    public boolean mask = false;
+  }
+
+
+  /**
+   * A key/value pair to set in the type specified by {@link ConfigUpgradeChangeDefinition#configType}
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "set")
+  public static class ConfigurationKeyValue extends Masked {
+    @XmlAttribute(name = "key")
+    public String key;
+
+    @XmlAttribute(name = "value")
+    public String value;
+  }
+
+  /**
+   * A conditional element that will only perform the configuration if the
+   * condition is met.
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "condition")
+  public static class Condition {
+    @XmlAttribute(name = "type")
+    private String conditionConfigType;
+
+    @XmlAttribute(name = "key")
+    private String conditionKey;
+
+    @XmlAttribute(name = "value")
+    private String conditionValue;
+
+    @XmlElement(name = "type")
+    private String configType;
+
+    @XmlElement(name = "key")
+    private String key;
+
+    @XmlElement(name = "value")
+    private String value;
+
+    public String getConditionConfigType() {
+      return conditionConfigType;
+    }
+
+    public String getConditionKey() {
+      return conditionKey;
+    }
+
+    public String getConditionValue() {
+      return conditionValue;
+    }
+
+    public String getConfigType() {
+      return configType;
+    }
+
+    public String getKey() {
+      return key;
+    }
+
+    public String getValue() {
+      return value;
+    }
+  }
+
+  /**
+   * A {@code transfer} element will copy, move, or delete the value of one type/key to another type/key.
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "transfer")
+  public static class Transfer extends Masked {
+    /**
+     * The type of operation, such as COPY or DELETE.
+     */
+    @XmlAttribute(name = "operation")
+    public TransferOperation operation;
+
+    /**
+     * The configuration type to copy or move from.
+     */
+    @XmlAttribute(name = "from-type")
+    public String fromType;
+
+    /**
+     * The key to copy or move the configuration from.
+     */
+    @XmlAttribute(name = "from-key")
+    public String fromKey;
+
+    /**
+     * The key to copy the configuration value to.
+     */
+    @XmlAttribute(name = "to-key")
+    public String toKey;
+
+    /**
+     * The configuration key to delete, or "*" for all.
+     */
+    @XmlAttribute(name = "delete-key")
+    public String deleteKey;
+
+    /**
+     * If {@code true}, this will ensure that any changed properties are not
+     * removed during a {@link TransferOperation#DELETE}.
+     */
+    @XmlAttribute(name = "preserve-edits")
+    public boolean preserveEdits = false;
+
+    /**
+     * A default value to use when the configurations don't contain the
+     * {@link #fromKey}.
+     */
+    @XmlAttribute(name = "default-value")
+    public String defaultValue;
+
+    /**
+     * A data type to convert the configuration value to when the action is
+     * {@link TransferOperation#COPY}.
+     */
+    @XmlAttribute(name = "coerce-to")
+    public TransferCoercionType coerceTo;
+
+    // if the condition is true apply the transfer action
+    // only supported conditional action is DELETE
+    // if-type/if-key == if-value
+    /**
+     * The key to read for the if condition.
+     */
+    @XmlAttribute(name = "if-key")
+    public String ifKey;
+
+    /**
+     * The config type to read for the if condition.
+     */
+    @XmlAttribute(name = "if-type")
+    public String ifType;
+
+    /**
+     * The property value to compare against for the if condition.
+     */
+    @XmlAttribute(name = "if-value")
+    public String ifValue;
+
+    /**
+     * The keys to keep when the action is {@link TransferOperation#DELETE}.
+     */
+    @XmlElement(name = "keep-key")
+    public List<String> keepKeys = new ArrayList<String>();
+
+    @Override
+    public String toString() {
+      return "Transfer{" +
+              "operation=" + operation +
+              ", fromType='" + fromType + '\'' +
+              ", fromKey='" + fromKey + '\'' +
+              ", toKey='" + toKey + '\'' +
+              ", deleteKey='" + deleteKey + '\'' +
+              ", preserveEdits=" + preserveEdits +
+              ", defaultValue='" + defaultValue + '\'' +
+              ", coerceTo=" + coerceTo +
+              ", ifKey='" + ifKey + '\'' +
+              ", ifType='" + ifType + '\'' +
+              ", ifValue='" + ifValue + '\'' +
+              ", keepKeys=" + keepKeys +
+              '}';
+    }
+  }
+
+  /**
+   * Used to replace strings in a key with other strings.  More complex
+   * scenarios will be possible with regex (when needed)
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "replace")
+  public static class Replace extends Masked {
+    /**
+     * The key name
+     */
+    @XmlAttribute(name="key")
+    public String key;
+
+    /**
+     * The string to find
+     */
+    @XmlAttribute(name="find")
+    public String find;
+
+    /**
+     * The string to replace
+     */
+    @XmlAttribute(name="replace-with")
+    public String replaceWith;
+
+    @Override
+    public String toString() {
+      return "Replace{" +
+              "key='" + key + '\'' +
+              ", find='" + find + '\'' +
+              ", replaceWith='" + replaceWith + '\'' +
+              '}';
+    }
+  }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ConfigureTask.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ConfigureTask.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ConfigureTask.java
index 8a9e2e5..1164335 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ConfigureTask.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ConfigureTask.java
@@ -18,7 +18,6 @@
 package org.apache.ambari.server.state.stack.upgrade;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -26,11 +25,10 @@ import java.util.Map;
 import javax.xml.bind.annotation.XmlAccessType;
 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.state.stack.ConfigUpgradePack;
 import org.apache.commons.lang.StringUtils;
 import org.apache.ambari.server.serveraction.upgrades.ConfigureAction;
 import org.apache.ambari.server.state.Cluster;
@@ -40,41 +38,21 @@ import org.apache.ambari.server.state.DesiredConfig;
 import com.google.gson.Gson;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import static org.apache.ambari.server.state.stack.upgrade.ConfigUpgradeChangeDefinition.Transfer;
+import static org.apache.ambari.server.state.stack.upgrade.ConfigUpgradeChangeDefinition.Replace;
+import static org.apache.ambari.server.state.stack.upgrade.ConfigUpgradeChangeDefinition.Condition;
+import static org.apache.ambari.server.state.stack.upgrade.ConfigUpgradeChangeDefinition.ConfigurationKeyValue;
 
 /**
- * The {@link ConfigureTask} represents a configuration change. This task can be
- * defined with conditional statements that will only set values if a condition
- * passes:
+ * The {@link ConfigureTask} represents a configuration change. This task
+ * contains id of change. Change definitions are located in a separate file (config
+ * upgrade pack). IDs of change definitions share the same namespace within all
+ * stacks
  * <p/>
  *
  * <pre>
  * {@code
- * <task xsi:type="configure">
- *   <condition type="hive-site" key="hive.server2.transport.mode" value="binary">
- *     <type>hive-site</type>
- *     <key>hive.server2.thrift.port</key>
- *     <value>10010</value>
- *   </condition>
- *   <condition type="hive-site" key="hive.server2.transport.mode" value="http">
- *     <type>hive-site</type>
- *     <key>hive.server2.http.port</key>
- *     <value>10011</value>
- *   </condition>
- * </task>
- * }
- * </pre>
- *
- * It's also possible to simple set values directly without a precondition
- * check.
- *
- * <pre>
- * {@code
- * <task xsi:type="configure">
- *   <type>hive-site</type>
- *   <set key="hive.server2.thrift.port" value="10010"/>
- *   <set key="foo" value="bar"/>
- *   <set key="foobar" value="baz"/>
- * </task>
+ * <task xsi:type="configure" id="hdp_2_3_0_0-UpdateHiveConfig"/>
  * }
  * </pre>
  *
@@ -109,6 +87,8 @@ public class ConfigureTask extends ServerSideActionTask {
    */
   public static final String PARAMETER_REPLACEMENTS = "configure-task-replacements";
 
+  public static final String actionVerb = "Configuring";
+  
   /**
    * Gson
    */
@@ -116,29 +96,15 @@ public class ConfigureTask extends ServerSideActionTask {
 
   /**
    * Constructor.
-   *
    */
   public ConfigureTask() {
     implClass = ConfigureAction.class.getName();
   }
 
-  @XmlTransient
   private Task.Type type = Task.Type.CONFIGURE;
 
-  @XmlElement(name="type")
-  private String configType;
-
-  @XmlElement(name = "set")
-  private List<ConfigurationKeyValue> keyValuePairs;
-
-  @XmlElement(name = "condition")
-  private List<Condition> conditions;
-
-  @XmlElement(name = "transfer")
-  private List<Transfer> transfers;
-
-  @XmlElement(name="replace")
-  private List<Replace> replacements;
+  @XmlAttribute(name = "id")
+  public String id;
 
   /**
    * {@inheritDoc}
@@ -148,220 +114,23 @@ public class ConfigureTask extends ServerSideActionTask {
     return type;
   }
 
-  /**
-   * @return the config type
-   */
-  public String getConfigType() {
-    return configType;
-  }
-
-  /**
-   * Used for configuration updates that should mask their values from being
-   * printed in plain text.
-   */
-  @XmlAccessorType(XmlAccessType.FIELD)
-  public static class Masked {
-    @XmlAttribute(name = "mask")
-    public boolean mask = false;
-  }
-
-
-  /**
-   * A key/value pair to set in the type specified by {@link ConfigureTask#type}
-   */
-  @XmlAccessorType(XmlAccessType.FIELD)
-  @XmlType(name = "set")
-  public static class ConfigurationKeyValue extends Masked {
-    @XmlAttribute(name = "key")
-    public String key;
-
-    @XmlAttribute(name = "value")
-    public String value;
-  }
-
-  /**
-   * A conditional element that will only perform the configuration if the
-   * condition is met.
-   */
-  @XmlAccessorType(XmlAccessType.FIELD)
-  @XmlType(name = "condition")
-  public static class Condition {
-    @XmlAttribute(name = "type")
-    private String conditionConfigType;
-
-    @XmlAttribute(name = "key")
-    private String conditionKey;
-
-    @XmlAttribute(name = "value")
-    private String conditionValue;
-
-    @XmlElement(name = "type")
-    private String configType;
-
-    @XmlElement(name = "key")
-    private String key;
-
-    @XmlElement(name = "value")
-    private String value;
-  }
-
-  /**
-   * A {@code transfer} element will copy, move, or delete the value of one type/key to another type/key.
-   */
-  @XmlAccessorType(XmlAccessType.FIELD)
-  @XmlType(name = "transfer")
-  public static class Transfer extends Masked {
-    /**
-     * The type of operation, such as COPY or DELETE.
-     */
-    @XmlAttribute(name = "operation")
-    public TransferOperation operation;
-
-    /**
-     * The configuration type to copy or move from.
-     */
-    @XmlAttribute(name = "from-type")
-    public String fromType;
-
-    /**
-     * The key to copy or move the configuration from.
-     */
-    @XmlAttribute(name = "from-key")
-    public String fromKey;
-
-    /**
-     * The key to copy the configuration value to.
-     */
-    @XmlAttribute(name = "to-key")
-    public String toKey;
-
-    /**
-     * The configuration key to delete, or "*" for all.
-     */
-    @XmlAttribute(name = "delete-key")
-    public String deleteKey;
-
-    /**
-     * If {@code true}, this will ensure that any changed properties are not
-     * removed during a {@link TransferOperation#DELETE}.
-     */
-    @XmlAttribute(name = "preserve-edits")
-    public boolean preserveEdits = false;
-
-    /**
-     * A default value to use when the configurations don't contain the
-     * {@link #fromKey}.
-     */
-    @XmlAttribute(name = "default-value")
-    public String defaultValue;
-
-    /**
-     * A data type to convert the configuration value to when the action is
-     * {@link TransferOperation#COPY}.
-     */
-    @XmlAttribute(name = "coerce-to")
-    public TransferCoercionType coerceTo;
-
-    // if the condition is true apply the transfer action
-    // only supported conditional action is DELETE
-    // if-type/if-key == if-value
-    /**
-     * The key to read for the if condition.
-     */
-    @XmlAttribute(name = "if-key")
-    public String ifKey;
-
-    /**
-     * The config type to read for the if condition.
-     */
-    @XmlAttribute(name = "if-type")
-    public String ifType;
-
-    /**
-     * The property value to compare against for the if condition.
-     */
-    @XmlAttribute(name = "if-value")
-    public String ifValue;
-
-    /**
-     * The keys to keep when the action is {@link TransferOperation#DELETE}.
-     */
-    @XmlElement(name = "keep-key")
-    public List<String> keepKeys = new ArrayList<String>();
-  }
-
-  /**
-   * @return the list of transfers, checking for appropriate null fields.
-   */
-  public List<Transfer> getTransfers() {
-    if (null == transfers) {
-      return Collections.<Transfer>emptyList();
-    }
-
-    List<Transfer> list = new ArrayList<Transfer>();
-    for (Transfer t : transfers) {
-      switch (t.operation) {
-        case COPY:
-        case MOVE:
-          if (null != t.fromKey && null != t.toKey) {
-            list.add(t);
-          }
-          break;
-        case DELETE:
-          if (null != t.deleteKey) {
-            list.add(t);
-          }
-
-          break;
-      }
-    }
-
-    return list;
+  @Override
+  public StageWrapper.Type getStageWrapperType() {
+    return StageWrapper.Type.SERVER_SIDE_ACTION;
   }
 
-  /**
-   * Used to replace strings in a key with other strings.  More complex
-   * scenarios will be possible with regex (when needed)
-   */
-  @XmlAccessorType(XmlAccessType.FIELD)
-  @XmlType(name = "replace")
-  public static class Replace extends Masked {
-    /**
-     * The key name
-     */
-    @XmlAttribute(name="key")
-    public String key;
-
-    /**
-     * The string to find
-     */
-    @XmlAttribute(name="find")
-    public String find;
-
-    /**
-     * The string to replace
-     */
-    @XmlAttribute(name="replace-with")
-    public String replaceWith;
+  @Override
+  public String getActionVerb() {
+    return actionVerb;
   }
 
   /**
-   * @return the replacement tokens, never {@code null}
+   * This getter is intended to be used only from tests. In production,
+   * getConfigurationChanges() logic should be used instead
+   * @return id of config upgrade change definition as defined in upgrade pack
    */
-  public List<Replace> getReplacements() {
-    if (null == replacements) {
-      return Collections.emptyList();
-    }
-
-    List<Replace> list = new ArrayList<Replace>();
-    for (Replace r : replacements) {
-      if (null == r.key || null == r.find || null == r.replaceWith) {
-        continue;
-      }
-      list.add(r);
-    }
-
-    return list;
+  public String getId() {
+    return id;
   }
 
   /**
@@ -385,21 +154,41 @@ public class ConfigureTask extends ServerSideActionTask {
    *         handle a configuration task that is unable to set any configuration
    *         values.
    */
-  public Map<String, String> getConfigurationChanges(Cluster cluster) {
-    Map<String, String> configParameters = new HashMap<String, String>();
+  public Map<String, String> getConfigurationChanges(Cluster cluster,
+                                                     ConfigUpgradePack configUpgradePack) {
+    Map<String, String> configParameters = new HashMap<>();
+
+    if (this.id == null || this.id.isEmpty()) {
+      LOG.warn("Config task id is not defined, skipping config change");
+      return configParameters;
+    }
+
+    if (configUpgradePack == null) {
+      LOG.warn("Config upgrade pack is not defined, skipping config change");
+      return configParameters;
+    }
+
+    // extract config change definition, referenced by current ConfigureTask
+    ConfigUpgradeChangeDefinition definition = configUpgradePack.enumerateConfigChangesByID().get(this.id);
+    if (definition == null) {
+      LOG.warn(String.format("Can not resolve config change definition by id %s, " +
+              "skipping config change", this.id));
+      return configParameters;
+    }
 
     // the first matched condition will win; conditions make configuration tasks singular in
     // the properties that can be set - when there is a condition the task will only contain
     // conditions
+    List<Condition> conditions = definition.getConditions();
     if( null != conditions && !conditions.isEmpty() ){
       for (Condition condition : conditions) {
-        String conditionConfigType = condition.conditionConfigType;
-        String conditionKey = condition.conditionKey;
-        String conditionValue = condition.conditionValue;
+        String conditionConfigType = condition.getConditionConfigType();
+        String conditionKey = condition.getConditionKey();
+        String conditionValue = condition.getConditionValue();
 
         // always add the condition's target type just so that we have one to
         // return even if none of the conditions match
-        configParameters.put(PARAMETER_CONFIG_TYPE, condition.configType);
+        configParameters.put(PARAMETER_CONFIG_TYPE, condition.getConfigType());
 
         // check the condition; if it passes, set the configuration properties
         // and break
@@ -407,10 +196,10 @@ public class ConfigureTask extends ServerSideActionTask {
             conditionConfigType, conditionKey);
 
         if (conditionValue.equals(checkValue)) {
-          List<ConfigurationKeyValue> configurations = new ArrayList<ConfigurationKeyValue>(1);
+          List<ConfigurationKeyValue> configurations = new ArrayList<>(1);
           ConfigurationKeyValue keyValue = new ConfigurationKeyValue();
-          keyValue.key = condition.key;
-          keyValue.value = condition.value;
+          keyValue.key = condition.getKey();
+          keyValue.value = condition.getValue();
           configurations.add(keyValue);
 
           configParameters.put(ConfigureTask.PARAMETER_KEY_VALUE_PAIRS,
@@ -422,20 +211,21 @@ public class ConfigureTask extends ServerSideActionTask {
     }
 
     // this task is not a condition task, so process the other elements normally
-    if (null != configType) {
-      configParameters.put(PARAMETER_CONFIG_TYPE, configType);
+    if (null != definition.getConfigType()) {
+      configParameters.put(PARAMETER_CONFIG_TYPE, definition.getConfigType());
     }
 
     // for every <set key=foo value=bar/> add it to this list
-    if (null != keyValuePairs && !keyValuePairs.isEmpty()) {
+    if (null != definition.getKeyValuePairs() && !definition.getKeyValuePairs().isEmpty()) {
       configParameters.put(ConfigureTask.PARAMETER_KEY_VALUE_PAIRS,
-          m_gson.toJson(keyValuePairs));
+          m_gson.toJson(definition.getKeyValuePairs()));
     }
 
     // transfers
+    List<Transfer> transfers = definition.getTransfers();
     if (null != transfers && !transfers.isEmpty()) {
 
-      List<Transfer> allowedTransfers = new ArrayList<Transfer>();
+      List<Transfer> allowedTransfers = new ArrayList<>();
       for (Transfer transfer : transfers) {
         if (transfer.operation == TransferOperation.DELETE) {
           if (StringUtils.isNotBlank(transfer.ifKey) &&
@@ -450,7 +240,7 @@ public class ConfigureTask extends ServerSideActionTask {
             if (!ifValue.toLowerCase().equals(StringUtils.lowerCase(checkValue))) {
               // skip adding
               LOG.info("Skipping property delete for {}/{} as the value {} for {}/{} is not equal to {}",
-                       this.getConfigType(), transfer.deleteKey, checkValue, ifConfigType, ifKey, ifValue);
+                       definition.getConfigType(), transfer.deleteKey, checkValue, ifConfigType, ifKey, ifValue);
               continue;
             }
           }
@@ -461,6 +251,7 @@ public class ConfigureTask extends ServerSideActionTask {
     }
 
     // replacements
+    List<Replace> replacements = definition.getReplacements();
     if( null != replacements && !replacements.isEmpty() ){
       configParameters.put(ConfigureTask.PARAMETER_REPLACEMENTS, m_gson.toJson(replacements));
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ExecuteTask.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ExecuteTask.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ExecuteTask.java
index a0afdfb..d175a13 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ExecuteTask.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ExecuteTask.java
@@ -66,8 +66,20 @@ public class ExecuteTask extends Task {
   @XmlElement(name="command")
   public String command;
 
+  public static final String actionVerb = "Executing";
+
   @Override
   public Task.Type getType() {
     return type;
   }
+
+  @Override
+  public StageWrapper.Type getStageWrapperType() {
+    return StageWrapper.Type.RU_TASKS;
+  }
+
+  @Override
+  public String getActionVerb() {
+    return actionVerb;
+  }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/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 cd27722..8f23803 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
@@ -36,7 +36,7 @@ import org.apache.commons.lang.StringUtils;
 /**
  *
  */
-@XmlSeeAlso(value = { ColocatedGrouping.class, ClusterGrouping.class, ServiceCheckGrouping.class })
+@XmlSeeAlso(value = { ColocatedGrouping.class, ClusterGrouping.class, UpdateStackGrouping.class, ServiceCheckGrouping.class, RestartGrouping.class, StartGrouping.class, StopGrouping.class })
 public class Grouping {
 
   @XmlAttribute(name="name")
@@ -60,7 +60,6 @@ public class Grouping {
   @XmlElement(name="direction")
   public Direction intendedDirection = null;
 
-
   /**
    * Gets the default builder.
    */
@@ -68,11 +67,11 @@ public class Grouping {
     return new DefaultBuilder(this, performServiceCheck);
   }
 
-
   private static class DefaultBuilder extends StageWrapperBuilder {
 
     private List<StageWrapper> m_stages = new ArrayList<StageWrapper>();
     private Set<String> m_servicesToCheck = new HashSet<String>();
+
     private boolean m_serviceCheck = true;
 
     private DefaultBuilder(Grouping grouping, boolean serviceCheck) {
@@ -85,14 +84,14 @@ public class Grouping {
      * E.g., preupgrade, restart hosts(0), ..., restart hosts(n-1), postupgrade
      * @param hostsType the order collection of hosts, which may have a master and secondary
      * @param service the service name
-     * @param pc the ProcessingComponent derived from the upgrade pack.
+     * @param pc the AffectedComponent derived from the upgrade pack.
      */
     @Override
     public void add(UpgradeContext ctx, HostsType hostsType, String service,
        boolean clientOnly, ProcessingComponent pc) {
-
       boolean forUpgrade = ctx.getDirection().isUpgrade();
 
+      // Construct the pre tasks during Upgrade/Downgrade direction.
       List<TaskBucket> buckets = buckets(resolveTasks(forUpgrade, true, pc));
       for (TaskBucket bucket : buckets) {
         List<TaskWrapper> preTasks = TaskWrapperBuilder.getTaskList(service, pc.name, hostsType, bucket.tasks);
@@ -108,19 +107,20 @@ public class Grouping {
       }
 
       // !!! FIXME upgrade definition have only one step, and it better be a restart
+      // Add the processing component
       if (null != pc.tasks && 1 == pc.tasks.size()) {
         Task t = pc.tasks.get(0);
-        if (RestartTask.class.isInstance(t)) {
-          for (String hostName : hostsType.hosts) {
-            StageWrapper stage = new StageWrapper(
-                StageWrapper.Type.RESTART,
-                getStageText("Restarting", ctx.getComponentDisplay(service, pc.name), Collections.singleton(hostName)),
-                new TaskWrapper(service, pc.name, Collections.singleton(hostName), t));
-            m_stages.add(stage);
-          }
+
+        for (String hostName : hostsType.hosts) {
+          StageWrapper stage = new StageWrapper(
+              t.getStageWrapperType(),
+              getStageText(t.getActionVerb(), ctx.getComponentDisplay(service, pc.name), Collections.singleton(hostName)),
+              new TaskWrapper(service, pc.name, Collections.singleton(hostName), t));
+          m_stages.add(stage);
         }
       }
 
+      // Construct the post tasks during Upgrade/Downgrade direction.
       buckets = buckets(resolveTasks(forUpgrade, false, pc));
       for (TaskBucket bucket : buckets) {
         List<TaskWrapper> postTasks = TaskWrapperBuilder.getTaskList(service, pc.name, hostsType, bucket.tasks);
@@ -135,7 +135,8 @@ public class Grouping {
         }
       }
 
-      if (!clientOnly) {
+      // Potentially add a service check
+      if (this.m_serviceCheck && !clientOnly) {
         m_servicesToCheck.add(service);
       }
     }
@@ -163,7 +164,6 @@ public class Grouping {
 
       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]));
 
@@ -202,12 +202,14 @@ public class Grouping {
     }
 
     return holders;
-
   }
 
   private static class TaskBucket {
+
     private StageWrapper.Type type;
+
     private List<Task> tasks = new ArrayList<Task>();
+
     private TaskBucket(Task initial) {
       switch (initial.getType()) {
         case CONFIGURE:
@@ -221,6 +223,12 @@ public class Grouping {
         case RESTART:
           type = StageWrapper.Type.RESTART;
           break;
+        case START:
+          type = StageWrapper.Type.START;
+          break;
+        case STOP:
+          type = StageWrapper.Type.STOP;
+          break;
         case SERVICE_CHECK:
           type = StageWrapper.Type.SERVICE_CHECK;
           break;

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ManualTask.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ManualTask.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ManualTask.java
index 2b1ba56..a0a347a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ManualTask.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ManualTask.java
@@ -52,4 +52,8 @@ public class ManualTask extends ServerSideActionTask {
     return type;
   }
 
+  @Override
+  public StageWrapper.Type getStageWrapperType() {
+    return StageWrapper.Type.SERVER_SIDE_ACTION;
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RepositoryVersionHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RepositoryVersionHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RepositoryVersionHelper.java
index 2e17cf4..6a36522 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RepositoryVersionHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RepositoryVersionHelper.java
@@ -22,7 +22,6 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
-import java.util.regex.Pattern;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
@@ -159,47 +158,29 @@ public class RepositoryVersionHelper {
    * @param stackName stack name
    * @param stackVersion stack version
    * @param repositoryVersion target repository version
+   * @param upgradeType if not {@code null} null, will only return upgrade packs whose type matches.
    * @return upgrade pack name
    * @throws AmbariException if no upgrade packs suit the requirements
    */
-  public String getUpgradePackageName(String stackName, String stackVersion, String repositoryVersion) throws AmbariException {
+  public String getUpgradePackageName(String stackName, String stackVersion, String repositoryVersion, UpgradeType upgradeType) throws AmbariException {
     final Map<String, UpgradePack> upgradePacks = ambariMetaInfo.getUpgradePacks(stackName, stackVersion);
-    for (Entry<String, UpgradePack> upgradePackEntry : upgradePacks.entrySet()) {
-      final UpgradePack upgradePack = upgradePackEntry.getValue();
-      final String upgradePackName = upgradePackEntry.getKey();
+    for (UpgradePack upgradePack : upgradePacks.values()) {
+      final String upgradePackName = upgradePack.getName();
+
+      if (null != upgradeType && upgradePack.getType() != upgradeType) {
+        continue;
+      }
+
       // check that upgrade pack has <target> node
       if (StringUtils.isBlank(upgradePack.getTarget())) {
         LOG.error("Upgrade pack " + upgradePackName + " is corrupted, it should contain <target> node");
         continue;
       }
-
-      // check that upgrade pack can be applied to selected stack
-      // converting 2.2.*.* -> 2\.2(\.\d+)?(\.\d+)?(-\d+)?
-      String regexPattern = upgradePack.getTarget();
-      regexPattern = regexPattern.replaceAll("\\.", "\\\\."); // . -> \.
-      regexPattern = regexPattern.replaceAll("\\\\\\.\\*", "(\\\\\\.\\\\d+)?"); // \.* -> (\.\d+)?
-      regexPattern = regexPattern.concat("(-\\d+)?");
-      if (Pattern.matches(regexPattern, repositoryVersion)) {
+      if (upgradePack.canBeApplied(repositoryVersion)) {
         return upgradePackName;
       }
     }
-    throw new AmbariException("There were no suitable upgrade packs for stack " + stackName + " " + stackVersion);
-  }
-
-  /**
-   * Scans the given stack for upgrade packages which can be applied to update the cluster to given repository version.
-   * Returns NONE if there were no suitable packages.
-   *
-   * @param stackName stack name
-   * @param stackVersion stack version
-   * @param repositoryVersion target repository version
-   * @return upgrade pack name or NONE
-   */
-  public String getUpgradePackageNameSafe(String stackName, String stackVersion, String repositoryVersion) {
-    try {
-      return getUpgradePackageName(stackName, stackVersion, repositoryVersion);
-    } catch (AmbariException ex) {
-      return "NONE";
-    }
+    throw new AmbariException("There were no suitable upgrade packs for stack " + stackName + " " + stackVersion +
+        ((null != upgradeType) ? " and upgrade type " + upgradeType : ""));
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RestartGrouping.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RestartGrouping.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RestartGrouping.java
new file mode 100644
index 0000000..529cadd
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RestartGrouping.java
@@ -0,0 +1,36 @@
+/**
+ * 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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * Used for a group that restarts services.
+ */
+@XmlType(name="restart")
+public class RestartGrouping extends Grouping implements UpgradeFunction {
+
+  private static Logger LOG = LoggerFactory.getLogger(RestartGrouping.class);
+
+  @Override
+  public Task.Type getFunction() {
+    return Task.Type.RESTART;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RestartTask.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RestartTask.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RestartTask.java
index 1b69b5b..fac0179 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RestartTask.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RestartTask.java
@@ -28,14 +28,26 @@ import javax.xml.bind.annotation.XmlType;
  */
 @XmlRootElement
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name="restart")
+@XmlType(name="restart-task")
 public class RestartTask extends Task {
 
   @XmlTransient
   private Task.Type type = Task.Type.RESTART;
 
+  public static final String actionVerb = "Restarting";
+
   @Override
   public Task.Type getType() {
     return type;
   }
+
+  @Override
+  public StageWrapper.Type getStageWrapperType() {
+    return StageWrapper.Type.RESTART;
+  }
+
+  @Override
+  public String getActionVerb() {
+    return actionVerb;
+  }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/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 74144b7..5f6438c 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
@@ -39,4 +39,8 @@ public class ServerActionTask extends ServerSideActionTask {
     return type;
   }
 
+  @Override
+  public StageWrapper.Type getStageWrapperType() {
+    return StageWrapper.Type.SERVER_SIDE_ACTION;
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ServerSideActionTask.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ServerSideActionTask.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ServerSideActionTask.java
index 97981ae..595465d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ServerSideActionTask.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ServerSideActionTask.java
@@ -27,7 +27,14 @@ public abstract class ServerSideActionTask extends Task {
   @XmlAttribute(name="class")
   protected String implClass;
 
+  public static final String actionVerb = "Executing";
+
   public String getImplementationClass() {
     return implClass;
   }
+
+  @Override
+  public String getActionVerb() {
+    return actionVerb;
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/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 6061895..af63656 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
@@ -50,10 +50,17 @@ public class ServiceCheckGrouping extends Grouping {
 
   private static Logger LOG = LoggerFactory.getLogger(ServiceCheckGrouping.class);
 
+  /**
+   * During a Rolling Upgrade, the priority services are ran first, then the remaining services in the cluster.
+   * During a Stop-and-Start Upgrade, only the priority services are ran.
+   */
   @XmlElementWrapper(name="priority")
   @XmlElement(name="service")
   private Set<String> priorityServices = new LinkedHashSet<String>();
 
+  /**
+   * During a Rolling Upgrade, exclude certain services.
+   */
   @XmlElementWrapper(name="exclude")
   @XmlElement(name="service")
   private Set<String> excludeServices = new HashSet<String>();
@@ -132,19 +139,20 @@ public class ServiceCheckGrouping extends Grouping {
         }
       }
 
-      // create stages for everything else, as long it is valid
-      for (String service : clusterServices) {
-        if (excludeServices.contains(service)) {
-          continue;
-        }
-
-        if (checkServiceValidity(upgradeContext, service, serviceMap)) {
-          StageWrapper wrapper = new StageWrapper(
-              StageWrapper.Type.SERVICE_CHECK,
-              "Service Check " + upgradeContext.getServiceDisplay(service),
-              new TaskWrapper(service, "", Collections.<String>emptySet(),
-                  new ServiceCheckTask()));
-          result.add(wrapper);
+      if (upgradeContext.getType() == UpgradeType.ROLLING) {
+        // During Rolling Upgrade, create stages for everything else, as long it is valid
+        for (String service : clusterServices) {
+          if (ServiceCheckGrouping.this.excludeServices.contains(service)) {
+            continue;
+          }
+          if (checkServiceValidity(upgradeContext, service, serviceMap)) {
+            StageWrapper wrapper = new StageWrapper(
+                StageWrapper.Type.SERVICE_CHECK,
+                "Service Check " + upgradeContext.getServiceDisplay(service),
+                new TaskWrapper(service, "", Collections.<String>emptySet(),
+                    new ServiceCheckTask()));
+            result.add(wrapper);
+          }
         }
       }
       return result;

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ServiceCheckTask.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ServiceCheckTask.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ServiceCheckTask.java
index 5893edf..d6c19b8 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ServiceCheckTask.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ServiceCheckTask.java
@@ -34,8 +34,20 @@ public class ServiceCheckTask extends Task {
   @XmlTransient
   private Task.Type type = Task.Type.SERVICE_CHECK;
 
+  public static final String actionVerb = "Running";
+
   @Override
   public Task.Type getType() {
     return type;
   }
+
+  @Override
+  public StageWrapper.Type getStageWrapperType() {
+    return StageWrapper.Type.SERVICE_CHECK;
+  }
+
+  @Override
+  public String getActionVerb() {
+    return actionVerb;
+  }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/StageWrapper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/StageWrapper.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/StageWrapper.java
index eac5ce5..92df3b5 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/StageWrapper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/StageWrapper.java
@@ -92,7 +92,7 @@ public class StageWrapper {
   }
 
   /**
-   * @param text the new text for the stage
+   * @param newText the new text for the stage
    */
   public void setText(String newText) {
     text = newText;
@@ -113,6 +113,8 @@ public class StageWrapper {
     SERVER_SIDE_ACTION,
     RESTART,
     RU_TASKS,
-    SERVICE_CHECK
+    SERVICE_CHECK,
+    STOP,
+    START
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/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 57cd41f..47a28d7 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
@@ -28,7 +28,7 @@ import org.apache.ambari.server.state.UpgradeContext;
 import org.apache.ambari.server.state.stack.UpgradePack.ProcessingComponent;
 
 /**
- * Defines how to build stages.
+ * Defines how to build stages for an Upgrade or Downgrade.
  */
 public abstract class StageWrapperBuilder {
 
@@ -55,7 +55,7 @@ public abstract class StageWrapperBuilder {
   /**
    * Adds a processing component that will be built into stage wrappers.
    *
-   * @param upgradeContext
+   * @param ctx
    *          the upgrade context
    * @param hostsType
    *          the hosts, along with their type
@@ -64,9 +64,9 @@ public abstract class StageWrapperBuilder {
    * @param clientOnly
    *          whether the service is client only, no service checks
    * @param pc
-   *          the ProcessingComponent derived from the upgrade pack
+   *          the AffectedComponent derived from the upgrade pack
    */
-  public abstract void add(UpgradeContext upgradeContext, HostsType hostsType, String service,
+  public abstract void add(UpgradeContext ctx, HostsType hostsType, String service,
       boolean clientOnly, ProcessingComponent pc);
 
   /**
@@ -182,9 +182,14 @@ public abstract class StageWrapperBuilder {
    * @param forUpgrade  {@code true} if resolving for an upgrade, {@code false} for downgrade
    * @param preTasks    {@code true} if loading pre-upgrade or pre-downgrade
    * @param pc          the processing component holding task definitions
-   * @return
+   * @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.
    */
   protected List<Task> resolveTasks(boolean forUpgrade, boolean preTasks, ProcessingComponent pc) {
+    if (null == pc) {
+      return Collections.emptyList();
+    }
+
     if (forUpgrade) {
       return preTasks ? pc.preTasks : pc.postTasks;
     } else {
@@ -193,6 +198,4 @@ public abstract class StageWrapperBuilder {
         (null == pc.postDowngradeTasks ? pc.postTasks : pc.postDowngradeTasks);
     }
   }
-
-
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/StartGrouping.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/StartGrouping.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/StartGrouping.java
new file mode 100644
index 0000000..7237599
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/StartGrouping.java
@@ -0,0 +1,36 @@
+/**
+ * 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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ *  Used for a group that starts services.
+ */
+@XmlType(name="start")
+public class StartGrouping extends Grouping implements UpgradeFunction {
+
+  private static Logger LOG = LoggerFactory.getLogger(StartGrouping.class);
+
+  @Override
+  public Task.Type  getFunction() {
+    return Task.Type.START;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/StartTask.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/StartTask.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/StartTask.java
new file mode 100644
index 0000000..4d05dcb
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/StartTask.java
@@ -0,0 +1,53 @@
+/**
+ * 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 javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * Used to represent a start of a component.
+ */
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name="start-task")
+public class StartTask extends Task {
+
+  @XmlTransient
+  private Type type = Type.START;
+
+  public static final String actionVerb = "Starting";
+
+  @Override
+  public Type getType() {
+    return type;
+  }
+
+  @Override
+  public StageWrapper.Type getStageWrapperType() {
+    return StageWrapper.Type.START;
+  }
+
+  @Override
+  public String getActionVerb() {
+    return actionVerb;
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/StopGrouping.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/StopGrouping.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/StopGrouping.java
new file mode 100644
index 0000000..5cf1149
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/StopGrouping.java
@@ -0,0 +1,36 @@
+/**
+ * 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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ *  Used for a group that stops services.
+ */
+@XmlType(name="stop")
+public class StopGrouping extends Grouping implements UpgradeFunction {
+
+  private static Logger LOG = LoggerFactory.getLogger(StopGrouping.class);
+
+  @Override
+  public Task.Type getFunction() {
+    return Task.Type.STOP;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/StopTask.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/StopTask.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/StopTask.java
new file mode 100644
index 0000000..30a557f
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/StopTask.java
@@ -0,0 +1,53 @@
+/**
+ * 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 javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * Used to represent a stop of a component.
+ */
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name="stop-task")
+public class StopTask extends Task {
+
+  @XmlTransient
+  private Type type = Type.STOP;
+
+  public static final String actionVerb = "Stopping";
+
+  @Override
+  public Type getType() {
+    return type;
+  }
+
+  @Override
+  public StageWrapper.Type getStageWrapperType() {
+    return StageWrapper.Type.STOP;
+  }
+
+  @Override
+  public String getActionVerb() {
+    return actionVerb;
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/Task.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/Task.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/Task.java
index 6416b57..f443e53 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/Task.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/Task.java
@@ -24,7 +24,7 @@ import javax.xml.bind.annotation.XmlSeeAlso;
 /**
  * Base class to identify the items that could possibly occur during an upgrade
  */
-@XmlSeeAlso(value={ExecuteTask.class, ConfigureTask.class, ManualTask.class, RestartTask.class, ServerActionTask.class})
+@XmlSeeAlso(value={ExecuteTask.class, ConfigureTask.class, ManualTask.class, RestartTask.class, StartTask.class, StopTask.class, ServerActionTask.class})
 public abstract class Task {
 
   /**
@@ -38,6 +38,16 @@ public abstract class Task {
    */
   public abstract Type getType();
 
+  /**
+   * @return when a single Task is constructed, this is the type of stage it should belong to.
+   */
+  public abstract StageWrapper.Type getStageWrapperType();
+
+  /**
+   * @return a verb to display that describes the type of task, e.g., "executing".
+   */
+  public abstract String getActionVerb();
+
   @Override
   public String toString() {
     return getType().toString();
@@ -64,6 +74,14 @@ public abstract class Task {
      */
     RESTART,
     /**
+     * Task that is a start command.
+     */
+    START,
+    /**
+     * Task that is a stop command.
+     */
+    STOP,
+    /**
      * Task that is a service check
      */
     SERVICE_CHECK,
@@ -83,7 +101,7 @@ public abstract class Task {
      * @return {@code true} if the task is a command type (as opposed to an action)
      */
     public boolean isCommand() {
-      return this == RESTART || this == SERVICE_CHECK;
+      return this == RESTART || this == START || this == STOP || this == SERVICE_CHECK;
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/UpdateStackGrouping.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/UpdateStackGrouping.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/UpdateStackGrouping.java
new file mode 100644
index 0000000..9dc9af8
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/UpdateStackGrouping.java
@@ -0,0 +1,36 @@
+/**
+ * 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 javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * Used to represent operations that update the Stack.
+ * This is primarily needed during a {@link UpgradeType#NON_ROLLING} upgrade.
+ */
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name="update-stack")
+public class UpdateStackGrouping extends ClusterGrouping {
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/UpgradeFunction.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/UpgradeFunction.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/UpgradeFunction.java
new file mode 100644
index 0000000..d58316d
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/UpgradeFunction.java
@@ -0,0 +1,26 @@
+/**
+ * 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;
+
+public interface UpgradeFunction {
+
+  /**
+   * @return Return the function that the group must provide.
+   */
+  public Task.Type getFunction();
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/UpgradeType.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/UpgradeType.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/UpgradeType.java
new file mode 100644
index 0000000..3acfb9f
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/UpgradeType.java
@@ -0,0 +1,36 @@
+/**
+ * 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 javax.xml.bind.annotation.XmlEnumValue;
+
+/**
+ * Indicates the type of Upgrade performed.
+ */
+public enum UpgradeType {
+  /**
+   * Services are up the entire time
+   */
+  @XmlEnumValue("ROLLING")
+  ROLLING,
+  /**
+   * All services are stopped, then started
+   */
+  @XmlEnumValue("NON_ROLLING")
+  NON_ROLLING;
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
index 71d0581..c0804ff 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
@@ -1577,7 +1577,6 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
         stackEntity,
         version,
         stackId.getStackName() + "-" + version,
-        repositoryVersionHelper.getUpgradePackageNameSafe(stackId.getStackName(), stackId.getStackVersion(), version),
         repositoryVersionHelper.serializeOperatingSystems(stackInfo.getRepositories()));
   }
 


[9/9] ambari git commit: AMBARI-13392. Stop-and-Start Upgrade: Merge branch branch-dev-stop-all-upgrade to branch-2.1 for feature Stop-the-World Upgrade, aka Express Upgrade (alejandro, dlysnichenko, Dmytro Grinenko)

Posted by al...@apache.org.
AMBARI-13392. Stop-and-Start Upgrade: Merge branch branch-dev-stop-all-upgrade to branch-2.1 for feature Stop-the-World Upgrade, aka Express Upgrade (alejandro, dlysnichenko, Dmytro Grinenko)


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

Branch: refs/heads/branch-2.1
Commit: ff8a56af6dda0895369dd1515d3142faebe775ef
Parents: 1abf2ae
Author: Alejandro Fernandez <af...@hortonworks.com>
Authored: Thu Aug 20 17:24:48 2015 -0700
Committer: Alejandro Fernandez <af...@hortonworks.com>
Committed: Mon Oct 12 14:04:08 2015 -0700

----------------------------------------------------------------------
 .../server/api/services/AmbariMetaInfo.java     |  21 +-
 .../server/checks/AbstractCheckDescriptor.java  |  56 +-
 .../server/checks/ClientRetryPropertyCheck.java |  17 +-
 .../server/checks/ConfigurationMergeCheck.java  |  29 +-
 .../HiveDynamicServiceDiscoveryCheck.java       |  15 +-
 .../checks/HiveMultipleMetastoreCheck.java      |  13 +-
 .../server/checks/HostsHeartbeatCheck.java      |   2 +-
 .../checks/HostsMasterMaintenanceCheck.java     |  15 +-
 .../checks/HostsRepositoryVersionCheck.java     |  11 +-
 ...apReduce2JobHistoryStatePreservingCheck.java |   7 +-
 .../checks/SecondaryNamenodeDeletedCheck.java   |  15 +-
 .../checks/ServicesMaintenanceModeCheck.java    |   3 +-
 .../ServicesMapReduceDistributedCacheCheck.java |  10 +-
 .../ServicesNamenodeHighAvailabilityCheck.java  |  13 +-
 .../checks/ServicesNamenodeTruncateCheck.java   |  11 +-
 .../ServicesTezDistributedCacheCheck.java       |  10 +-
 .../ambari/server/checks/ServicesUpCheck.java   |   2 +-
 .../checks/ServicesYarnWorkPreservingCheck.java |  14 +-
 .../ambari/server/checks/UpgradeCheck.java      |   8 +
 .../server/checks/UpgradeCheckRegistry.java     |  19 +
 .../checks/YarnRMHighAvailabilityCheck.java     |  13 +-
 .../YarnTimelineServerStatePreservingCheck.java |   7 +-
 .../AmbariCustomCommandExecutionHelper.java     |  13 +-
 .../AmbariManagementControllerImpl.java         |   6 +-
 .../server/controller/PrereqCheckRequest.java   |  20 +-
 .../ClusterStackVersionResourceProvider.java    |   4 +-
 ...atibleRepositoryVersionResourceProvider.java |   3 -
 .../PreUpgradeCheckResourceProvider.java        |  48 +-
 .../RepositoryVersionResourceProvider.java      |  96 ++-
 .../internal/UpgradeResourceProvider.java       | 192 ++++-
 .../ambari/server/metadata/ActionMetadata.java  |   4 +-
 .../server/orm/dao/ClusterVersionDAO.java       |  23 +
 .../apache/ambari/server/orm/dao/CrudDAO.java   |  15 +
 .../ambari/server/orm/dao/HostVersionDAO.java   |  42 +-
 .../server/orm/dao/RepositoryVersionDAO.java    |   6 +-
 .../ambari/server/orm/dao/UpgradeDAO.java       |  19 +-
 .../orm/entities/RepositoryVersionEntity.java   |  18 +-
 .../server/orm/entities/UpgradeEntity.java      |  89 +++
 .../serveraction/upgrades/ConfigureAction.java  |  23 +-
 .../upgrades/UpdateDesiredStackAction.java      | 139 ++++
 .../server/stack/ModuleFileUnmarshaller.java    |   4 +-
 .../server/stack/StackDefinitionDirectory.java  |   2 +
 .../ambari/server/stack/StackDirectory.java     |  52 +-
 .../apache/ambari/server/stack/StackModule.java |   2 +-
 .../apache/ambari/server/state/StackInfo.java   |  31 +-
 .../ambari/server/state/UpgradeContext.java     |  56 +-
 .../ambari/server/state/UpgradeHelper.java      | 151 +++-
 .../server/state/stack/ConfigUpgradePack.java   | 192 +++++
 .../ambari/server/state/stack/UpgradePack.java  | 123 ++-
 .../state/stack/upgrade/ClusterGrouping.java    |  27 +-
 .../upgrade/ConfigUpgradeChangeDefinition.java  | 420 ++++++++++
 .../state/stack/upgrade/ConfigureTask.java      | 333 ++------
 .../server/state/stack/upgrade/ExecuteTask.java |  12 +
 .../server/state/stack/upgrade/Grouping.java    |  40 +-
 .../server/state/stack/upgrade/ManualTask.java  |   4 +
 .../stack/upgrade/RepositoryVersionHelper.java  |  43 +-
 .../state/stack/upgrade/RestartGrouping.java    |  36 +
 .../server/state/stack/upgrade/RestartTask.java |  14 +-
 .../state/stack/upgrade/ServerActionTask.java   |   4 +
 .../stack/upgrade/ServerSideActionTask.java     |   7 +
 .../stack/upgrade/ServiceCheckGrouping.java     |  34 +-
 .../state/stack/upgrade/ServiceCheckTask.java   |  12 +
 .../state/stack/upgrade/StageWrapper.java       |   6 +-
 .../stack/upgrade/StageWrapperBuilder.java      |  17 +-
 .../state/stack/upgrade/StartGrouping.java      |  36 +
 .../server/state/stack/upgrade/StartTask.java   |  53 ++
 .../state/stack/upgrade/StopGrouping.java       |  36 +
 .../server/state/stack/upgrade/StopTask.java    |  53 ++
 .../ambari/server/state/stack/upgrade/Task.java |  22 +-
 .../stack/upgrade/UpdateStackGrouping.java      |  36 +
 .../state/stack/upgrade/UpgradeFunction.java    |  26 +
 .../server/state/stack/upgrade/UpgradeType.java |  36 +
 .../svccomphost/ServiceComponentHostImpl.java   |   1 -
 .../server/upgrade/UpgradeCatalog213.java       | 369 ++++++++-
 .../main/resources/Ambari-DDL-MySQL-CREATE.sql  |   3 +-
 .../main/resources/Ambari-DDL-Oracle-CREATE.sql |   3 +-
 .../resources/Ambari-DDL-Postgres-CREATE.sql    |   3 +-
 .../Ambari-DDL-Postgres-EMBEDDED-CREATE.sql     |   3 +-
 .../resources/Ambari-DDL-SQLServer-CREATE.sql   |   3 +-
 .../0.96.0.2.0/package/scripts/hbase_upgrade.py |   6 +-
 .../HDFS/2.1.0.2.0/package/scripts/namenode.py  |  15 +
 .../HDP/2.1/upgrades/nonrolling-upgrade-2.3.xml | 382 +++++++++
 .../stacks/HDP/2.2/upgrades/config-upgrade.xml  |  55 ++
 .../HDP/2.2/upgrades/nonrolling-upgrade-2.2.xml | 469 +++++++++++
 .../stacks/HDP/2.2/upgrades/upgrade-2.2.xml     | 123 ++-
 .../stacks/HDP/2.2/upgrades/upgrade-2.3.xml     | 731 +++--------------
 .../stacks/HDP/2.3/repos/repoinfo.xml.orig      |  92 ---
 .../stacks/HDP/2.3/upgrades/config-upgrade.xml  | 800 +++++++++++++++++++
 .../stacks/HDP/2.3/upgrades/upgrade-2.3.xml     | 146 ++--
 .../checks/ConfigurationMergeCheckTest.java     |   6 +
 .../checks/HostsMasterMaintenanceCheckTest.java |  11 +-
 .../SecondaryNamenodeDeletedCheckTest.java      |  16 +-
 ...vicesMapReduceDistributedCacheCheckTest.java |  14 +-
 ...rvicesNamenodeHighAvailabilityCheckTest.java |  10 +-
 .../ServicesNamenodeTruncateCheckTest.java      |   8 +-
 .../ServicesTezDistributedCacheCheckTest.java   |  15 +-
 .../ServicesYarnWorkPreservingCheckTest.java    |  10 +-
 .../checks/UpgradeCheckStackVersionTest.java    | 170 ----
 .../AmbariManagementControllerTest.java         |   2 +-
 ...leRepositoryVersionResourceProviderTest.java |  16 +
 .../RepositoryVersionResourceProviderTest.java  | 110 ++-
 .../UpgradeResourceProviderHDP22Test.java       |   4 +-
 .../internal/UpgradeResourceProviderTest.java   |  71 +-
 .../apache/ambari/server/orm/OrmTestHelper.java |   2 +-
 .../ambari/server/orm/dao/CrudDAOTest.java      |   1 -
 .../orm/dao/RepositoryVersionDAOTest.java       |   8 +-
 .../ambari/server/orm/dao/UpgradeDAOTest.java   |  10 +-
 .../upgrades/ConfigureActionTest.java           |  39 +-
 .../upgrades/UpgradeActionTest.java             |   6 +-
 .../ambari/server/state/UpgradeHelperTest.java  | 202 +++--
 .../state/stack/ConfigUpgradePackTest.java      | 198 +++++
 .../server/state/stack/UpgradePackTest.java     | 190 +++--
 .../stack/upgrade/StageWrapperBuilderTest.java  |   4 +-
 .../server/upgrade/UpgradeCatalog213Test.java   | 220 ++++-
 .../stacks/2.0.6/HBASE/test_hbase_master.py     |   2 +-
 .../2.1/configs/secured-storm-start.json.orig   | 374 ---------
 .../HDP/2.1.1/upgrades/config-upgrade.xml       | 101 +++
 .../HDP/2.1.1/upgrades/upgrade_bucket_test.xml  |  17 +-
 .../HDP/2.1.1/upgrades/upgrade_direction.xml    |   6 +-
 .../stacks/HDP/2.1.1/upgrades/upgrade_test.xml  |  61 +-
 .../HDP/2.1.1/upgrades/upgrade_test_checks.xml  |  30 +-
 .../2.1.1/upgrades/upgrade_test_nonrolling.xml  | 182 +++++
 .../HDP/2.1.1/upgrades/upgrade_to_new_stack.xml |  24 +-
 .../HDP/2.2.0/upgrades/config-upgrade.xml       | 101 +++
 .../stacks/HDP/2.2.0/upgrades/upgrade_test.xml  |  21 +-
 .../HDP/2.2.0/upgrades/upgrade_test_checks.xml  |  30 +-
 .../browser/HiveBrowserService.java.orig        | 282 -------
 .../hive/resources/jobs/JobService.java.orig    | 476 -----------
 128 files changed, 5958 insertions(+), 3287 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
index 561b3f4..e35e7ac 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
@@ -60,6 +60,7 @@ import org.apache.ambari.server.state.kerberos.KerberosServiceDescriptorFactory;
 import org.apache.ambari.server.state.stack.Metric;
 import org.apache.ambari.server.state.stack.MetricDefinition;
 import org.apache.ambari.server.state.stack.OsFamily;
+import org.apache.ambari.server.state.stack.ConfigUpgradePack;
 import org.apache.ambari.server.state.stack.UpgradePack;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -997,7 +998,7 @@ public class AmbariMetaInfo {
     }
 
     return alertDefinitionFactory.getAlertDefinitions(alertsFile,
-        service.getName());
+            service.getName());
   }
 
   /**
@@ -1206,6 +1207,24 @@ public class AmbariMetaInfo {
   }
 
   /**
+   * Get all upgrade config pack if it is available for a stack.
+   *
+   * @param stackName the stack name
+   * @param stackVersion the stack version
+   * @return config upgrade pack for stack or null if it is
+   * not defined for stack
+   */
+  public ConfigUpgradePack getConfigUpgradePack(String stackName, String stackVersion) {
+    try {
+      StackInfo stack = getStack(stackName, stackVersion);
+      return stack.getConfigUpgradePack();
+    } catch (AmbariException e) {
+      LOG.debug("Cannot load config upgrade pack for non-existent stack {}-{}", stackName, stackVersion, e);
+      return null;
+    }
+  }
+
+  /**
    * Gets the fully compiled Kerberos descriptor for the relevant stack and version.
    * <p/>
    * All of the kerberos.json files from the specified stack (and version) are read, parsed and

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/checks/AbstractCheckDescriptor.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/AbstractCheckDescriptor.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/AbstractCheckDescriptor.java
index 2f0bc94..760a971 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/AbstractCheckDescriptor.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/AbstractCheckDescriptor.java
@@ -18,7 +18,9 @@
 package org.apache.ambari.server.checks;
 
 import java.util.LinkedHashSet;
+import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
@@ -82,7 +84,7 @@ public abstract class AbstractCheckDescriptor {
 
   /**
    * Tests if the prerequisite check is applicable to given cluster. This
-   * method's defautl logic is to ensure that the cluster stack source and
+   * method's default logic is to ensure that the cluster stack source and
    * target are compatible with the prerequisite check. When overridding this
    * method, call {@code super#isApplicable(PrereqCheckRequest)}.
    *
@@ -94,26 +96,36 @@ public abstract class AbstractCheckDescriptor {
    *           if server error happens
    */
   public boolean isApplicable(PrereqCheckRequest request) throws AmbariException {
-    StackId sourceStackId = getSourceStack();
-    StackId targetStackId = getTargetStack();
-
-    if( null == sourceStackId && null == targetStackId ) {
-      return true;
-    }
-
-    StackId requestSourceStack = request.getSourceStackId();
-    if (null != sourceStackId && null != requestSourceStack
-        && sourceStackId.compareTo(requestSourceStack) > 0) {
-      return false;
-    }
+    // this is default behaviour
+   return true;
+  }
 
-    StackId requestTargetStack = request.getTargetStackId();
-    if (null != targetStackId && null != requestTargetStack
-        && targetStackId.compareTo(requestTargetStack) < 0) {
-      return false;
+  /**
+   * Same like {@code isApplicable(PrereqCheckRequest request)}, but with service presence check
+   * @param request
+   *          prerequisite check request
+   * @param requiredServices
+   *          set of services, which need to be present to allow check execution
+   * @param requiredAll
+   *          require all services in the list or at least one need to present
+   * @return true if check should be performed
+   * @throws org.apache.ambari.server.AmbariException
+   *           if server error happens
+   */
+  public boolean isApplicable(PrereqCheckRequest request, List<String> requiredServices, boolean requiredAll) throws AmbariException {
+    final Cluster cluster = clustersProvider.get().getCluster(request.getClusterName());
+    Set<String> services = cluster.getServices().keySet();
+    boolean serviceFound = false;
+
+    for (String service : requiredServices) {
+      if (services.contains(service) && !requiredAll) {
+        serviceFound = true;
+      } else if (!services.contains(service) && requiredAll) {
+        return false;
+      }
     }
 
-    return true;
+    return !(!serviceFound && !requiredAll);
   }
 
   /**
@@ -292,4 +304,12 @@ public abstract class AbstractCheckDescriptor {
 
     return formatted.toString();
   }
+
+  /**
+   * Return the optionality flag of the Upgrade Check
+   * @return
+   */
+  public Boolean isRequired(){
+      return getClass().getAnnotation(UpgradeCheck.class).required();
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/checks/ClientRetryPropertyCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/ClientRetryPropertyCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/ClientRetryPropertyCheck.java
index 52fca40..368bcb8 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/ClientRetryPropertyCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/ClientRetryPropertyCheck.java
@@ -18,6 +18,7 @@
 package org.apache.ambari.server.checks;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 
@@ -36,7 +37,7 @@ import com.google.inject.Singleton;
  * client retry properties for HDFS, HIVE, and OOZIE are set.
  */
 @Singleton
-@UpgradeCheck(group = UpgradeCheckGroup.CLIENT_RETRY_PROPERTY)
+@UpgradeCheck(group = UpgradeCheckGroup.CLIENT_RETRY_PROPERTY, required = true)
 public class ClientRetryPropertyCheck extends AbstractCheckDescriptor {
 
   static final String HIVE_CLIENT_RETRY_MISSING_KEY = "hive.client.retry.missing.key";
@@ -54,19 +55,7 @@ public class ClientRetryPropertyCheck extends AbstractCheckDescriptor {
    */
   @Override
   public boolean isApplicable(PrereqCheckRequest request) throws AmbariException {
-    if (!super.isApplicable(request)) {
-      return false;
-    }
-
-    final Cluster cluster = clustersProvider.get().getCluster(request.getClusterName());
-    Map<String, Service> services = cluster.getServices();
-
-    if (services.containsKey("HDFS") || services.containsKey("HIVE")
-        || services.containsKey("OOZIE")) {
-      return true;
-    }
-
-    return false;
+    return super.isApplicable(request, Arrays.asList("HDFS", "HIVE", "OOZIE"), false);
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/checks/ConfigurationMergeCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/ConfigurationMergeCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/ConfigurationMergeCheck.java
index b81ca11..a47512e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/ConfigurationMergeCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/ConfigurationMergeCheck.java
@@ -39,7 +39,7 @@ import com.google.inject.Singleton;
  * Checks for configuration merge conflicts.
  */
 @Singleton
-@UpgradeCheck(order = 99.0f)
+@UpgradeCheck(order = 99.0f, required = true)
 public class ConfigurationMergeCheck extends AbstractCheckDescriptor {
 
   @Inject
@@ -49,33 +49,6 @@ public class ConfigurationMergeCheck extends AbstractCheckDescriptor {
     super(CheckDescription.CONFIG_MERGE);
   }
 
-  @Override
-  public boolean isApplicable(PrereqCheckRequest request) throws AmbariException {
-    if (!super.isApplicable(request)) {
-      return false;
-    }
-
-    String stackName = request.getTargetStackId().getStackName();
-    String repoVersion = request.getRepositoryVersion();
-    if (null == repoVersion) {
-      return false;
-    }
-
-    RepositoryVersionEntity rve = repositoryVersionDaoProvider.get().findByStackNameAndVersion(stackName, repoVersion);
-    if (null == rve) {
-      return false;
-    }
-
-    Cluster cluster = clustersProvider.get().getCluster(request.getClusterName());
-
-    if (rve.getStackId().equals(cluster.getCurrentStackVersion())) {
-      return false;
-    }
-
-    return true;
-  }
-
-
   /**
    * The following logic determines if a warning is generated for config merge
    * issues:

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/checks/HiveDynamicServiceDiscoveryCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/HiveDynamicServiceDiscoveryCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/HiveDynamicServiceDiscoveryCheck.java
index 4ea5484..d8f51a2 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/HiveDynamicServiceDiscoveryCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/HiveDynamicServiceDiscoveryCheck.java
@@ -18,6 +18,7 @@
 package org.apache.ambari.server.checks;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 
@@ -37,7 +38,7 @@ import com.google.inject.Singleton;
  * is properly configured for dynamic discovery.
  */
 @Singleton
-@UpgradeCheck(group = UpgradeCheckGroup.DEFAULT, order = 1.0f)
+@UpgradeCheck(group = UpgradeCheckGroup.DEFAULT, order = 1.0f, required = true)
 public class HiveDynamicServiceDiscoveryCheck extends AbstractCheckDescriptor {
 
   static final String HIVE_DYNAMIC_SERVICE_DISCOVERY_ENABLED_KEY = "hive.dynamic-service.discovery.enabled.key";
@@ -56,17 +57,7 @@ public class HiveDynamicServiceDiscoveryCheck extends AbstractCheckDescriptor {
    */
   @Override
   public boolean isApplicable(PrereqCheckRequest request) throws AmbariException {
-    if (!super.isApplicable(request)) {
-      return false;
-    }
-
-    final Cluster cluster = clustersProvider.get().getCluster(request.getClusterName());
-    Map<String, Service> services = cluster.getServices();
-    if (services.containsKey("HIVE")) {
-      return true;
-    }
-
-    return false;
+    return super.isApplicable(request, Arrays.asList("HIVE"), true);
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/checks/HiveMultipleMetastoreCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/HiveMultipleMetastoreCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/HiveMultipleMetastoreCheck.java
index c387a4b..14b8435 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/HiveMultipleMetastoreCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/HiveMultipleMetastoreCheck.java
@@ -17,6 +17,7 @@
  */
 package org.apache.ambari.server.checks;
 
+import java.util.Arrays;
 import java.util.Map;
 
 import org.apache.ambari.server.AmbariException;
@@ -51,17 +52,7 @@ public class HiveMultipleMetastoreCheck extends AbstractCheckDescriptor {
    */
   @Override
   public boolean isApplicable(PrereqCheckRequest request) throws AmbariException {
-    if (!super.isApplicable(request)) {
-      return false;
-    }
-
-    final Cluster cluster = clustersProvider.get().getCluster(request.getClusterName());
-    Map<String, Service> services = cluster.getServices();
-    if (!services.containsKey("HIVE")) {
-      return false;
-    }
-
-    return true;
+    return super.isApplicable(request, Arrays.asList("HIVE"), true);
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsHeartbeatCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsHeartbeatCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsHeartbeatCheck.java
index a8600c4..a6811cb 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsHeartbeatCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsHeartbeatCheck.java
@@ -43,7 +43,7 @@ import com.google.inject.Singleton;
  * {@link PrereqCheckStatus#WARNING} for any hosts in maintenance mode.
  */
 @Singleton
-@UpgradeCheck(group = UpgradeCheckGroup.LIVELINESS, order = 1.0f)
+@UpgradeCheck(group = UpgradeCheckGroup.LIVELINESS, order = 1.0f, required = true)
 public class HostsHeartbeatCheck extends AbstractCheckDescriptor {
 
   static final String KEY_HOSTS_IN_MM_WARNING = "key.hosts.in.mm.warning";

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsMasterMaintenanceCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsMasterMaintenanceCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsMasterMaintenanceCheck.java
index ef93337..39ab39f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsMasterMaintenanceCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsMasterMaintenanceCheck.java
@@ -40,7 +40,7 @@ import com.google.inject.Singleton;
  * Checks that all hosts in maintenance state do not have master components.
  */
 @Singleton
-@UpgradeCheck(group = UpgradeCheckGroup.MAINTENANCE_MODE, order = 1.0f)
+@UpgradeCheck(group = UpgradeCheckGroup.MAINTENANCE_MODE, order = 1.0f, required = true)
 public class HostsMasterMaintenanceCheck extends AbstractCheckDescriptor {
 
   static final String KEY_NO_UPGRADE_NAME = "no_upgrade_name";
@@ -54,21 +54,14 @@ public class HostsMasterMaintenanceCheck extends AbstractCheckDescriptor {
   }
 
   @Override
-  public boolean isApplicable(PrereqCheckRequest request) throws AmbariException {
-    if (!super.isApplicable(request)) {
-      return false;
-    }
-
-    return request.getRepositoryVersion() != null;
-  }
-
-  @Override
   public void perform(PrerequisiteCheck prerequisiteCheck, PrereqCheckRequest request) throws AmbariException {
     final String clusterName = request.getClusterName();
     final Cluster cluster = clustersProvider.get().getCluster(clusterName);
     final StackId stackId = cluster.getDesiredStackVersion();
     final Set<String> hostsWithMasterComponent = new HashSet<String>();
-    final String upgradePackName = repositoryVersionHelper.get().getUpgradePackageName(stackId.getStackName(), stackId.getStackVersion(), request.getRepositoryVersion());
+
+    // TODO AMBARI-12698, need to pass the upgrade pack to use in the request, or at least the type.
+    final String upgradePackName = repositoryVersionHelper.get().getUpgradePackageName(stackId.getStackName(), stackId.getStackVersion(), request.getRepositoryVersion(), null);
     if (upgradePackName == null) {
       prerequisiteCheck.setStatus(PrereqCheckStatus.FAIL);
       String fail = getFailReason(KEY_NO_UPGRADE_NAME, prerequisiteCheck, request);

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsRepositoryVersionCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsRepositoryVersionCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsRepositoryVersionCheck.java
index eaa0096..00862ac 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsRepositoryVersionCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsRepositoryVersionCheck.java
@@ -41,7 +41,7 @@ import com.google.inject.Singleton;
  * orchstration, so no warning is required.
  */
 @Singleton
-@UpgradeCheck(group = UpgradeCheckGroup.REPOSITORY_VERSION)
+@UpgradeCheck(group = UpgradeCheckGroup.REPOSITORY_VERSION, required = true)
 public class HostsRepositoryVersionCheck extends AbstractCheckDescriptor {
 
   static final String KEY_NO_REPO_VERSION = "no_repo_version";
@@ -54,15 +54,6 @@ public class HostsRepositoryVersionCheck extends AbstractCheckDescriptor {
   }
 
   @Override
-  public boolean isApplicable(PrereqCheckRequest request) throws AmbariException {
-    if (!super.isApplicable(request)) {
-      return false;
-    }
-
-    return request.getRepositoryVersion() != null;
-  }
-
-  @Override
   public void perform(PrerequisiteCheck prerequisiteCheck, PrereqCheckRequest request)
       throws AmbariException {
     final String clusterName = request.getClusterName();

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/checks/MapReduce2JobHistoryStatePreservingCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/MapReduce2JobHistoryStatePreservingCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/MapReduce2JobHistoryStatePreservingCheck.java
index 5f02c4f..af134d8 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/MapReduce2JobHistoryStatePreservingCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/MapReduce2JobHistoryStatePreservingCheck.java
@@ -28,6 +28,7 @@ import org.apache.ambari.server.utils.VersionUtils;
 import org.apache.commons.lang.StringUtils;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 
@@ -87,15 +88,11 @@ public class MapReduce2JobHistoryStatePreservingCheck extends AbstractCheckDescr
    */
   @Override
   public boolean isApplicable(PrereqCheckRequest request) throws AmbariException {
-    if (!super.isApplicable(request)) {
+    if (!super.isApplicable(request, Arrays.asList("MAPREDUCE2"), true)) {
       return false;
     }
 
     final Cluster cluster = clustersProvider.get().getCluster(request.getClusterName());
-    Map<String, Service> services = cluster.getServices();
-    if (!services.containsKey("MAPREDUCE2")) {
-      return false;
-    }
 
     // Applicable only if stack not defined in MinimumApplicableStackVersion, or
     // version equals or exceeds the enumerated version.

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/checks/SecondaryNamenodeDeletedCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/SecondaryNamenodeDeletedCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/SecondaryNamenodeDeletedCheck.java
index 493042f..d7c27d7 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/SecondaryNamenodeDeletedCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/SecondaryNamenodeDeletedCheck.java
@@ -17,6 +17,7 @@
  */
 package org.apache.ambari.server.checks;
 
+import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -53,14 +54,7 @@ public class SecondaryNamenodeDeletedCheck extends AbstractCheckDescriptor {
 
   @Override
   public boolean isApplicable(PrereqCheckRequest request) throws AmbariException {
-    if (!super.isApplicable(request)) {
-      return false;
-    }
-
-    final Cluster cluster = clustersProvider.get().getCluster(request.getClusterName());
-    try {
-      cluster.getService("HDFS");
-    } catch (ServiceNotFoundException ex) {
+    if (!super.isApplicable(request, Arrays.asList("HDFS"), true)) {
       return false;
     }
 
@@ -72,6 +66,11 @@ public class SecondaryNamenodeDeletedCheck extends AbstractCheckDescriptor {
     return true;
   }
 
+  // TODO AMBARI-12698, there are 2 ways to filter the prechecks.
+  // 1. Explictly mention them in each upgrade pack, which is more flexible, but requires adding the name of checks
+  //   to perform in each upgrade pack.
+  // 2. Make each upgrade check class call a function before perform() that will determine if the check is appropriate
+  //   given the type of upgrade. The PrereqCheckRequest object has a field for the type of upgrade.
   @Override
   public void perform(PrerequisiteCheck prerequisiteCheck, PrereqCheckRequest request) throws AmbariException {
     Set<String> hosts = new HashSet<String>();

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesMaintenanceModeCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesMaintenanceModeCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesMaintenanceModeCheck.java
index 5108afd..8d578d8 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesMaintenanceModeCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesMaintenanceModeCheck.java
@@ -24,7 +24,6 @@ import org.apache.ambari.server.controller.PrereqCheckRequest;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.MaintenanceState;
 import org.apache.ambari.server.state.Service;
-import org.apache.ambari.server.state.State;
 import org.apache.ambari.server.state.stack.PrereqCheckStatus;
 import org.apache.ambari.server.state.stack.PrerequisiteCheck;
 
@@ -34,7 +33,7 @@ import com.google.inject.Singleton;
  * Checks that services are in the maintenance mode.
  */
 @Singleton
-@UpgradeCheck(group = UpgradeCheckGroup.MAINTENANCE_MODE, order = 2.0f)
+@UpgradeCheck(group = UpgradeCheckGroup.MAINTENANCE_MODE, order = 2.0f, required = true)
 public class ServicesMaintenanceModeCheck extends AbstractCheckDescriptor {
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesMapReduceDistributedCacheCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesMapReduceDistributedCacheCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesMapReduceDistributedCacheCheck.java
index be5d11a..2359919 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesMapReduceDistributedCacheCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesMapReduceDistributedCacheCheck.java
@@ -18,6 +18,7 @@
 package org.apache.ambari.server.checks;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 
@@ -48,14 +49,7 @@ public class ServicesMapReduceDistributedCacheCheck extends AbstractCheckDescrip
   public boolean isApplicable(PrereqCheckRequest request)
     throws AmbariException {
 
-    if (!super.isApplicable(request)) {
-      return false;
-    }
-
-    final Cluster cluster = clustersProvider.get().getCluster(request.getClusterName());
-    try {
-      cluster.getService("YARN");
-    } catch (ServiceNotFoundException ex) {
+    if (!super.isApplicable(request, Arrays.asList("YARN"), true)) {
       return false;
     }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesNamenodeHighAvailabilityCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesNamenodeHighAvailabilityCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesNamenodeHighAvailabilityCheck.java
index d92f12d..44e183d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesNamenodeHighAvailabilityCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesNamenodeHighAvailabilityCheck.java
@@ -17,6 +17,7 @@
  */
 package org.apache.ambari.server.checks;
 
+import java.util.Arrays;
 import java.util.Map;
 
 import org.apache.ambari.server.AmbariException;
@@ -46,17 +47,7 @@ public class ServicesNamenodeHighAvailabilityCheck extends AbstractCheckDescript
 
   @Override
   public boolean isApplicable(PrereqCheckRequest request) throws AmbariException {
-    if (!super.isApplicable(request)) {
-      return false;
-    }
-
-    final Cluster cluster = clustersProvider.get().getCluster(request.getClusterName());
-    try {
-      cluster.getService("HDFS");
-    } catch (ServiceNotFoundException ex) {
-      return false;
-    }
-    return true;
+    return super.isApplicable(request, Arrays.asList("HDFS"), true);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesNamenodeTruncateCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesNamenodeTruncateCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesNamenodeTruncateCheck.java
index 51369c9..3761d99 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesNamenodeTruncateCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesNamenodeTruncateCheck.java
@@ -28,6 +28,8 @@ import org.apache.ambari.server.utils.VersionUtils;
 
 import com.google.inject.Singleton;
 
+import java.util.Arrays;
+
 /**
  * Checks that namenode high availability is enabled.
  */
@@ -44,14 +46,7 @@ public class ServicesNamenodeTruncateCheck extends AbstractCheckDescriptor {
 
   @Override
   public boolean isApplicable(PrereqCheckRequest request) throws AmbariException {
-    if (!super.isApplicable(request)) {
-      return false;
-    }
-
-    final Cluster cluster = clustersProvider.get().getCluster(request.getClusterName());
-    try {
-      cluster.getService("HDFS");
-    } catch (ServiceNotFoundException ex) {
+    if (!super.isApplicable(request, Arrays.asList("HDFS"), true)) {
       return false;
     }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesTezDistributedCacheCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesTezDistributedCacheCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesTezDistributedCacheCheck.java
index 68a7103..70a9b1b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesTezDistributedCacheCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesTezDistributedCacheCheck.java
@@ -18,6 +18,7 @@
 package org.apache.ambari.server.checks;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 
@@ -48,14 +49,7 @@ public class ServicesTezDistributedCacheCheck extends AbstractCheckDescriptor {
 
   @Override
   public boolean isApplicable(PrereqCheckRequest request) throws AmbariException {
-    if (!super.isApplicable(request)) {
-      return false;
-    }
-
-    final Cluster cluster = clustersProvider.get().getCluster(request.getClusterName());
-    try {
-      cluster.getService("TEZ");
-    } catch (ServiceNotFoundException ex) {
+    if (!super.isApplicable(request, Arrays.asList("TEZ"), true)) {
       return false;
     }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesUpCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesUpCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesUpCheck.java
index 70b8884..ea8569c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesUpCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesUpCheck.java
@@ -44,7 +44,7 @@ import com.google.inject.Singleton;
  * Checks that services are up.
  */
 @Singleton
-@UpgradeCheck(group = UpgradeCheckGroup.LIVELINESS, order = 2.0f)
+@UpgradeCheck(group = UpgradeCheckGroup.LIVELINESS, order = 2.0f, required = true)
 public class ServicesUpCheck extends AbstractCheckDescriptor {
 
   private static final float SLAVE_THRESHOLD = 0.5f;

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesYarnWorkPreservingCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesYarnWorkPreservingCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesYarnWorkPreservingCheck.java
index a0b2b59..062c11f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesYarnWorkPreservingCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesYarnWorkPreservingCheck.java
@@ -27,6 +27,8 @@ import org.apache.commons.lang.BooleanUtils;
 
 import com.google.inject.Singleton;
 
+import java.util.Arrays;
+
 /**
  * Checks that YARN has work-preserving restart enabled.
  */
@@ -46,17 +48,7 @@ public class ServicesYarnWorkPreservingCheck extends AbstractCheckDescriptor {
    */
   @Override
   public boolean isApplicable(PrereqCheckRequest request) throws AmbariException {
-    if (!super.isApplicable(request)) {
-      return false;
-    }
-
-    final Cluster cluster = clustersProvider.get().getCluster(request.getClusterName());
-    try {
-      cluster.getService("YARN");
-    } catch (ServiceNotFoundException ex) {
-      return false;
-    }
-    return true;
+    return super.isApplicable(request, Arrays.asList("YARN"), true);
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheck.java
index 9fa8916..9e43560 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheck.java
@@ -55,4 +55,12 @@ public @interface UpgradeCheck {
    * @return the order, or {@code 1.0f} if not specified.
    */
   float order() default 1.0f;
+
+  /**
+   * Gets whether the pre-upgrade check is required.
+   * By default, a pre-upgrade check needs to be declared in the upgrade pack. This flag will override that setting.
+   *
+   * @return  flag state, or {@code true} if not specified
+   */
+  boolean required() default false;
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheckRegistry.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheckRegistry.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheckRegistry.java
index 8be572c..4ed345c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheckRegistry.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/UpgradeCheckRegistry.java
@@ -24,6 +24,7 @@ import java.util.Set;
 import java.util.TreeSet;
 
 import com.google.inject.Singleton;
+import org.apache.ambari.server.state.stack.UpgradePack;
 
 /**
  * The {@link UpgradeCheckRegistry} contains the ordered list of all pre-upgrade
@@ -59,6 +60,24 @@ public class UpgradeCheckRegistry {
   }
 
   /**
+   * Gets an ordered and filtered list of the upgrade checks.
+   * @param upgradePack Upgrade pack object with the list of required checks to be included
+   * @return
+   */
+  public List<AbstractCheckDescriptor> getFilteredUpgradeChecks(UpgradePack upgradePack){
+    List<String> prerequisiteChecks = upgradePack.getPrerequisiteChecks();
+    List<AbstractCheckDescriptor> resultCheckDescriptor = new ArrayList<AbstractCheckDescriptor>();
+    for (AbstractCheckDescriptor descriptor: m_upgradeChecks){
+      if (descriptor.isRequired()){
+        resultCheckDescriptor.add(descriptor);
+      } else if (prerequisiteChecks.contains(descriptor.getClass().getName())){
+        resultCheckDescriptor.add(descriptor);
+      }
+    }
+    return resultCheckDescriptor;
+  }
+
+  /**
    * THe {@link PreUpgradeCheckComparator} class is used to compare
    * {@link AbstractCheckDescriptor} based on their {@link UpgradeCheck}
    * annotations.

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/checks/YarnRMHighAvailabilityCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/YarnRMHighAvailabilityCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/YarnRMHighAvailabilityCheck.java
index bf25f9f..9f3bd6e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/YarnRMHighAvailabilityCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/YarnRMHighAvailabilityCheck.java
@@ -17,6 +17,7 @@
  */
 package org.apache.ambari.server.checks;
 
+import java.util.Arrays;
 import java.util.Map;
 
 import org.apache.ambari.server.AmbariException;
@@ -49,17 +50,7 @@ public class YarnRMHighAvailabilityCheck extends AbstractCheckDescriptor {
    */
   @Override
   public boolean isApplicable(PrereqCheckRequest request) throws AmbariException {
-    if (!super.isApplicable(request)) {
-      return false;
-    }
-
-    final Cluster cluster = clustersProvider.get().getCluster(request.getClusterName());
-    Map<String, Service> services = cluster.getServices();
-    if (!services.containsKey("YARN")) {
-      return false;
-    }
-
-    return true;
+    return super.isApplicable(request, Arrays.asList("YARN"), true);
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/checks/YarnTimelineServerStatePreservingCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/YarnTimelineServerStatePreservingCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/YarnTimelineServerStatePreservingCheck.java
index eca0967..03528c2 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/YarnTimelineServerStatePreservingCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/YarnTimelineServerStatePreservingCheck.java
@@ -17,6 +17,7 @@
  */
 package org.apache.ambari.server.checks;
 
+import java.util.Arrays;
 import java.util.Map;
 
 import org.apache.ambari.server.AmbariException;
@@ -81,15 +82,11 @@ public class YarnTimelineServerStatePreservingCheck extends AbstractCheckDescrip
    */
   @Override
   public boolean isApplicable(PrereqCheckRequest request) throws AmbariException {
-    if (!super.isApplicable(request)) {
+    if (!super.isApplicable(request, Arrays.asList("YARN"), true)) {
       return false;
     }
 
     final Cluster cluster = clustersProvider.get().getCluster(request.getClusterName());
-    Map<String, Service> services = cluster.getServices();
-    if (!services.containsKey("YARN")) {
-      return false;
-    }
 
     // Applicable only if stack not defined in MinimumApplicableStackVersion, or
     // version equals or exceeds the enumerated version.

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
index 2bda16e..c515e46 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
@@ -900,7 +900,7 @@ public class AmbariCustomCommandExecutionHelper {
 
         String commandDetail = getReadableCustomCommandDetail(actionExecutionContext, resourceFilter);
 
-        Map<String, String> extraParams = new HashMap<String, String>();;
+        Map<String, String> extraParams = new HashMap<String, String>();
         String componentName = (null == resourceFilter.getComponentName()) ? null :
             resourceFilter.getComponentName().toLowerCase();
 
@@ -1024,11 +1024,12 @@ public class AmbariCustomCommandExecutionHelper {
    *
    * @param actionExecContext  the context
    * @param cluster            the cluster for the command
+   * @param stackId            the effective stack id to use.
    *
    * @return a wrapper of the imporant JSON structures to add to a stage
    */
   public ExecuteCommandJson getCommandJson(ActionExecutionContext actionExecContext,
-      Cluster cluster) throws AmbariException {
+      Cluster cluster, StackId stackId) throws AmbariException {
 
     Map<String, String> commandParamsStage = StageUtils.getCommandParamsStage(actionExecContext);
     Map<String, String> hostParamsStage = new HashMap<String, String>();
@@ -1038,8 +1039,8 @@ public class AmbariCustomCommandExecutionHelper {
     if (null != cluster) {
       clusterHostInfo = StageUtils.getClusterHostInfo(
           cluster);
-      hostParamsStage = createDefaultHostParams(cluster);
-      StackId stackId = cluster.getDesiredStackVersion();
+      // Important, because this runs during Stack Uprade, it needs to use the effective Stack Id.
+      hostParamsStage = createDefaultHostParams(cluster, stackId);
       String componentName = null;
       String serviceName = null;
       if (actionExecContext.getOperationLevel() != null) {
@@ -1070,6 +1071,10 @@ public class AmbariCustomCommandExecutionHelper {
 
   Map<String, String> createDefaultHostParams(Cluster cluster) {
     StackId stackId = cluster.getDesiredStackVersion();
+    return createDefaultHostParams(cluster, stackId);
+  }
+
+  Map<String, String> createDefaultHostParams(Cluster cluster, StackId stackId) {
     TreeMap<String, String> hostLevelParams = new TreeMap<String, String>();
     hostLevelParams.put(JDK_LOCATION, managementController.getJdkResourceUrl());
     hostLevelParams.put(JAVA_HOME, managementController.getJavaHome());

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
index aa51d4e..d2203fc 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
@@ -3336,7 +3336,11 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
         actionManager,
         actionRequest);
 
-    ExecuteCommandJson jsons = customCommandExecutionHelper.getCommandJson(actionExecContext, cluster);
+    StackId stackId = null;
+    if (null != cluster) {
+      stackId = cluster.getDesiredStackVersion();
+    }
+    ExecuteCommandJson jsons = customCommandExecutionHelper.getCommandJson(actionExecContext, cluster, stackId);
     String commandParamsForStage = jsons.getCommandParamsForStage();
 
     // Ensure that the specified requestContext (if any) is set as the request context

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/controller/PrereqCheckRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/PrereqCheckRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/PrereqCheckRequest.java
index f8c5316..b8dda3a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/PrereqCheckRequest.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/PrereqCheckRequest.java
@@ -23,6 +23,7 @@ import java.util.Map;
 import org.apache.ambari.server.checks.CheckDescription;
 import org.apache.ambari.server.state.StackId;
 import org.apache.ambari.server.state.stack.PrereqCheckStatus;
+import org.apache.ambari.server.state.stack.upgrade.UpgradeType;
 
 /**
  * Represents a prerequisite check request.
@@ -33,17 +34,34 @@ public class PrereqCheckRequest {
   private StackId m_sourceStackId;
   private StackId m_targetStackId;
 
+  private UpgradeType m_upgradeType;
+
   private Map<CheckDescription, PrereqCheckStatus> m_results =
       new HashMap<CheckDescription, PrereqCheckStatus>();
 
-  public PrereqCheckRequest(String clusterName) {
+
+  public PrereqCheckRequest(String clusterName, UpgradeType upgradeType) {
     m_clusterName = clusterName;
+    m_upgradeType = upgradeType;
+  }
+
+  /**
+   * Construct a request to performs checks before an Upgrade.
+   * The default type is Rolling.
+   * @param clusterName
+   */
+  public PrereqCheckRequest(String clusterName) {
+    this(clusterName, UpgradeType.ROLLING);
   }
 
   public String getClusterName() {
     return m_clusterName;
   }
 
+  public UpgradeType getUpgradeType() {
+    return m_upgradeType;
+  }
+
   public String getRepositoryVersion() {
     return m_repositoryVersion;
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
index 7030d23..e8a089d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
@@ -620,10 +620,10 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
       }
     } catch (AmbariException e) {
       e.printStackTrace();
-      throw new SystemException("Can not perform request. " + e.getMessage(), e);
+      throw new SystemException("Cannot perform request. " + e.getMessage(), e);
     } catch (InterruptedException e) {
       e.printStackTrace();
-      throw new SystemException("Can not perform request. " + e.getMessage(), e);
+      throw new SystemException("Cannot perform request. " + e.getMessage(), e);
     }
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/CompatibleRepositoryVersionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/CompatibleRepositoryVersionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/CompatibleRepositoryVersionResourceProvider.java
index 6344aa2..2a1092b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/CompatibleRepositoryVersionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/CompatibleRepositoryVersionResourceProvider.java
@@ -61,7 +61,6 @@ public class CompatibleRepositoryVersionResourceProvider extends ReadOnlyResourc
   public static final String REPOSITORY_VERSION_STACK_VERSION_PROPERTY_ID      = "CompatibleRepositoryVersions/stack_version";
   public static final String REPOSITORY_VERSION_REPOSITORY_VERSION_PROPERTY_ID = "CompatibleRepositoryVersions/repository_version";
   public static final String REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID       = "CompatibleRepositoryVersions/display_name";
-  public static final String REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID       = "CompatibleRepositoryVersions/upgrade_pack";
   public static final String SUBRESOURCE_OPERATING_SYSTEMS_PROPERTY_ID         = new OperatingSystemResourceDefinition().getPluralName();
   public static final String SUBRESOURCE_REPOSITORIES_PROPERTY_ID              = new RepositoryResourceDefinition().getPluralName();
 
@@ -73,7 +72,6 @@ public class CompatibleRepositoryVersionResourceProvider extends ReadOnlyResourc
       REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID,
       REPOSITORY_VERSION_STACK_NAME_PROPERTY_ID,
       REPOSITORY_VERSION_STACK_VERSION_PROPERTY_ID,
-      REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID,
       SUBRESOURCE_OPERATING_SYSTEMS_PROPERTY_ID);
 
   static Map<Type, String> keyPropertyIds = new HashMap<Type, String>() {
@@ -151,7 +149,6 @@ public class CompatibleRepositoryVersionResourceProvider extends ReadOnlyResourc
       setResourceProperty(resource, REPOSITORY_VERSION_STACK_NAME_PROPERTY_ID, entity.getStackName(), requestedIds);
       setResourceProperty(resource, REPOSITORY_VERSION_STACK_VERSION_PROPERTY_ID, entity.getStackVersion(), requestedIds);
       setResourceProperty(resource, REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID, entity.getDisplayName(), requestedIds);
-      setResourceProperty(resource, REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID, entity.getUpgradePackage(), requestedIds);
       setResourceProperty(resource, REPOSITORY_VERSION_REPOSITORY_VERSION_PROPERTY_ID, entity.getVersion(), requestedIds);
 
       resources.add(resource);

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PreUpgradeCheckResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PreUpgradeCheckResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PreUpgradeCheckResourceProvider.java
index ce58e1e..93093d2 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PreUpgradeCheckResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PreUpgradeCheckResourceProvider.java
@@ -20,30 +20,40 @@ package org.apache.ambari.server.controller.internal;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.StaticallyInject;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.checks.AbstractCheckDescriptor;
 import org.apache.ambari.server.checks.UpgradeCheckRegistry;
 import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.controller.PrereqCheckRequest;
+import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
 import org.apache.ambari.server.controller.spi.NoSuchResourceException;
 import org.apache.ambari.server.controller.spi.Predicate;
 import org.apache.ambari.server.controller.spi.Request;
 import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.controller.spi.Resource.Type;
+import org.apache.ambari.server.controller.spi.SystemException;
+import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
 import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 import org.apache.ambari.server.state.CheckHelper;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.UpgradeHelper;
 import org.apache.ambari.server.state.stack.PrerequisiteCheck;
 
 import com.google.common.collect.Sets;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
+import org.apache.ambari.server.state.stack.UpgradePack;
+import org.apache.ambari.server.state.stack.upgrade.Direction;
+import org.apache.ambari.server.state.stack.upgrade.UpgradeType;
 
 /**
  * Resource provider for pre-upgrade checks.
@@ -61,6 +71,7 @@ public class PreUpgradeCheckResourceProvider extends ReadOnlyResourceProvider {
   public static final String UPGRADE_CHECK_FAILED_DETAIL_PROPERTY_ID      = PropertyHelper.getPropertyId("UpgradeChecks", "failed_detail");
   public static final String UPGRADE_CHECK_CHECK_TYPE_PROPERTY_ID         = PropertyHelper.getPropertyId("UpgradeChecks", "check_type");
   public static final String UPGRADE_CHECK_CLUSTER_NAME_PROPERTY_ID       = PropertyHelper.getPropertyId("UpgradeChecks", "cluster_name");
+  public static final String UPGRADE_CHECK_UPGRADE_TYPE_PROPERTY_ID       = PropertyHelper.getPropertyId("UpgradeChecks", "upgrade_type");
   public static final String UPGRADE_CHECK_REPOSITORY_VERSION_PROPERTY_ID = PropertyHelper.getPropertyId("UpgradeChecks", "repository_version");
 
   @Inject
@@ -72,6 +83,9 @@ public class PreUpgradeCheckResourceProvider extends ReadOnlyResourceProvider {
   @Inject
   private static UpgradeCheckRegistry upgradeCheckRegistry;
 
+  @Inject
+  private static Provider<UpgradeHelper> upgradeHelper;
+
   private static Set<String> pkPropertyIds = Collections.singleton(UPGRADE_CHECK_ID_PROPERTY_ID);
 
   public static Set<String> propertyIds = Sets.newHashSet(
@@ -83,6 +97,7 @@ public class PreUpgradeCheckResourceProvider extends ReadOnlyResourceProvider {
       UPGRADE_CHECK_FAILED_DETAIL_PROPERTY_ID,
       UPGRADE_CHECK_CHECK_TYPE_PROPERTY_ID,
       UPGRADE_CHECK_CLUSTER_NAME_PROPERTY_ID,
+      UPGRADE_CHECK_UPGRADE_TYPE_PROPERTY_ID,
       UPGRADE_CHECK_REPOSITORY_VERSION_PROPERTY_ID);
 
 
@@ -107,7 +122,8 @@ public class PreUpgradeCheckResourceProvider extends ReadOnlyResourceProvider {
   }
 
   @Override
-  public Set<Resource> getResources(Request request, Predicate predicate) throws NoSuchResourceException {
+  public Set<Resource> getResources(Request request, Predicate predicate) throws SystemException, UnsupportedPropertyException,
+    NoSuchResourceException, NoSuchParentResourceException {
 
     final Set<Resource> resources = new HashSet<Resource>();
     final Set<String> requestedIds = getRequestPropertyIds(request, predicate);
@@ -115,6 +131,9 @@ public class PreUpgradeCheckResourceProvider extends ReadOnlyResourceProvider {
 
     for (Map<String, Object> propertyMap: propertyMaps) {
       final String clusterName = propertyMap.get(UPGRADE_CHECK_CLUSTER_NAME_PROPERTY_ID).toString();
+      // TODO AMBARI-12698, uncomment once the UI starts passing the property.
+      // final UpgradeType upgradeType = (UpgradeType) propertyMap.get(UPGRADE_CHECK_UPGRADE_TYPE_PROPERTY_ID);
+      final UpgradeType upgradeType = UpgradeType.NON_ROLLING;
       final Cluster cluster;
 
       try {
@@ -124,20 +143,40 @@ public class PreUpgradeCheckResourceProvider extends ReadOnlyResourceProvider {
       }
 
       String stackName = cluster.getCurrentStackVersion().getStackName();
+      String sourceStackVersion = cluster.getCurrentStackVersion().getStackVersion();
 
-      final PrereqCheckRequest upgradeCheckRequest = new PrereqCheckRequest(clusterName);
+      final PrereqCheckRequest upgradeCheckRequest = new PrereqCheckRequest(clusterName, upgradeType);
       upgradeCheckRequest.setSourceStackId(cluster.getCurrentStackVersion());
 
       if (propertyMap.containsKey(UPGRADE_CHECK_REPOSITORY_VERSION_PROPERTY_ID)) {
         String repositoryVersionId = propertyMap.get(UPGRADE_CHECK_REPOSITORY_VERSION_PROPERTY_ID).toString();
         RepositoryVersionEntity repositoryVersionEntity = repositoryVersionDAO.findByStackNameAndVersion(stackName, repositoryVersionId);
-
         // set some required properties on the check request
         upgradeCheckRequest.setRepositoryVersion(repositoryVersionId);
         upgradeCheckRequest.setTargetStackId(repositoryVersionEntity.getStackId());
       }
 
-      for (PrerequisiteCheck prerequisiteCheck : checkHelper.performChecks(upgradeCheckRequest, upgradeCheckRegistry.getUpgradeChecks())) {
+      //ambariMetaInfo.getStack(stackName, cluster.getCurrentStackVersion().getStackVersion()).getUpgradePacks()
+      // TODO AMBARI-12698, filter the upgrade checks to run based on the stack and upgrade type, or the upgrade pack.
+      UpgradePack upgradePack = null;
+      try{
+        // Hint: PreChecks currently executing only before UPGRADE direction
+        upgradePack = upgradeHelper.get().suggestUpgradePack(clusterName, sourceStackVersion,
+            upgradeCheckRequest.getRepositoryVersion(), Direction.UPGRADE, upgradeType);
+      } catch (AmbariException e) {
+        throw new SystemException(e.getMessage(), e);
+      }
+
+      if (upgradePack == null) {
+        throw new SystemException(String.format("Upgrade pack not found for the target repository version %s",
+          upgradeCheckRequest.getRepositoryVersion()));
+      }
+
+      // ToDo: properly handle exceptions, i.e. create fake check with error description
+
+      List<AbstractCheckDescriptor> upgradeChecksToRun = upgradeCheckRegistry.getFilteredUpgradeChecks(upgradePack);
+
+      for (PrerequisiteCheck prerequisiteCheck : checkHelper.performChecks(upgradeCheckRequest, upgradeChecksToRun)) {
         final Resource resource = new ResourceImpl(Resource.Type.PreUpgradeCheck);
         setResourceProperty(resource, UPGRADE_CHECK_ID_PROPERTY_ID, prerequisiteCheck.getId(), requestedIds);
         setResourceProperty(resource, UPGRADE_CHECK_CHECK_PROPERTY_ID, prerequisiteCheck.getDescription(), requestedIds);
@@ -147,6 +186,7 @@ public class PreUpgradeCheckResourceProvider extends ReadOnlyResourceProvider {
         setResourceProperty(resource, UPGRADE_CHECK_FAILED_DETAIL_PROPERTY_ID,prerequisiteCheck.getFailedDetail(), requestedIds);
         setResourceProperty(resource, UPGRADE_CHECK_CHECK_TYPE_PROPERTY_ID, prerequisiteCheck.getType(), requestedIds);
         setResourceProperty(resource, UPGRADE_CHECK_CLUSTER_NAME_PROPERTY_ID, prerequisiteCheck.getClusterName(), requestedIds);
+        setResourceProperty(resource, UPGRADE_CHECK_UPGRADE_TYPE_PROPERTY_ID, upgradeType, requestedIds);
         if (upgradeCheckRequest.getRepositoryVersion() != null) {
           setResourceProperty(resource, UPGRADE_CHECK_REPOSITORY_VERSION_PROPERTY_ID, upgradeCheckRequest.getRepositoryVersion(), requestedIds);
         }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ff8a56af/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProvider.java
index f1fa3bf..60210c3 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProvider.java
@@ -19,12 +19,14 @@ package org.apache.ambari.server.controller.internal;
 
 import java.text.MessageFormat;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import com.google.inject.Provider;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.ObjectNotFoundException;
 import org.apache.ambari.server.api.resources.OperatingSystemResourceDefinition;
@@ -49,10 +51,13 @@ import org.apache.ambari.server.orm.entities.OperatingSystemEntity;
 import org.apache.ambari.server.orm.entities.RepositoryEntity;
 import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 import org.apache.ambari.server.orm.entities.StackEntity;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.OperatingSystemInfo;
 import org.apache.ambari.server.state.RepositoryVersionState;
 import org.apache.ambari.server.state.StackId;
 import org.apache.ambari.server.state.StackInfo;
+import org.apache.ambari.server.state.stack.UpgradePack;
 import org.apache.ambari.server.state.stack.upgrade.RepositoryVersionHelper;
 import org.apache.commons.lang.ObjectUtils;
 import org.apache.commons.lang.StringUtils;
@@ -73,7 +78,6 @@ public class RepositoryVersionResourceProvider extends AbstractResourceProvider
   public static final String REPOSITORY_VERSION_STACK_VERSION_PROPERTY_ID      = PropertyHelper.getPropertyId("RepositoryVersions", "stack_version");
   public static final String REPOSITORY_VERSION_REPOSITORY_VERSION_PROPERTY_ID = PropertyHelper.getPropertyId("RepositoryVersions", "repository_version");
   public static final String REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID       = PropertyHelper.getPropertyId("RepositoryVersions", "display_name");
-  public static final String REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID       = PropertyHelper.getPropertyId("RepositoryVersions", "upgrade_pack");
   public static final String SUBRESOURCE_OPERATING_SYSTEMS_PROPERTY_ID         = new OperatingSystemResourceDefinition().getPluralName();
   public static final String SUBRESOURCE_REPOSITORIES_PROPERTY_ID              = new RepositoryResourceDefinition().getPluralName();
 
@@ -92,7 +96,6 @@ public class RepositoryVersionResourceProvider extends AbstractResourceProvider
       add(REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID);
       add(REPOSITORY_VERSION_STACK_NAME_PROPERTY_ID);
       add(REPOSITORY_VERSION_STACK_VERSION_PROPERTY_ID);
-      add(REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID);
       add(SUBRESOURCE_OPERATING_SYSTEMS_PROPERTY_ID);
     }
   };
@@ -121,6 +124,9 @@ public class RepositoryVersionResourceProvider extends AbstractResourceProvider
   @Inject
   private RepositoryVersionHelper repositoryVersionHelper;
 
+  @Inject
+  private Provider<Clusters> clusters;
+
   /**
    * Data access object used for lookup up stacks.
    */
@@ -148,13 +154,13 @@ public class RepositoryVersionResourceProvider extends AbstractResourceProvider
         @Override
         public Void invoke() throws AmbariException {
           final String[] requiredProperties = {
-              REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID,
-              SUBRESOURCE_OPERATING_SYSTEMS_PROPERTY_ID,
-              REPOSITORY_VERSION_STACK_NAME_PROPERTY_ID,
-              REPOSITORY_VERSION_STACK_VERSION_PROPERTY_ID,
-              REPOSITORY_VERSION_REPOSITORY_VERSION_PROPERTY_ID
+            REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID,
+            SUBRESOURCE_OPERATING_SYSTEMS_PROPERTY_ID,
+            REPOSITORY_VERSION_STACK_NAME_PROPERTY_ID,
+            REPOSITORY_VERSION_STACK_VERSION_PROPERTY_ID,
+            REPOSITORY_VERSION_REPOSITORY_VERSION_PROPERTY_ID
           };
-          for (String propertyName: requiredProperties) {
+          for (String propertyName : requiredProperties) {
             if (properties.get(propertyName) == null) {
               throw new AmbariException("Property " + propertyName + " should be provided");
             }
@@ -214,7 +220,6 @@ public class RepositoryVersionResourceProvider extends AbstractResourceProvider
       setResourceProperty(resource, REPOSITORY_VERSION_STACK_NAME_PROPERTY_ID, entity.getStackName(), requestedIds);
       setResourceProperty(resource, REPOSITORY_VERSION_STACK_VERSION_PROPERTY_ID, entity.getStackVersion(), requestedIds);
       setResourceProperty(resource, REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID, entity.getDisplayName(), requestedIds);
-      setResourceProperty(resource, REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID, entity.getUpgradePackage(), requestedIds);
       setResourceProperty(resource, REPOSITORY_VERSION_REPOSITORY_VERSION_PROPERTY_ID, entity.getVersion(), requestedIds);
 
       resources.add(resource);
@@ -243,22 +248,18 @@ public class RepositoryVersionResourceProvider extends AbstractResourceProvider
             throw new ObjectNotFoundException("There is no repository version with id " + id);
           }
 
-          if (StringUtils.isNotBlank(ObjectUtils.toString(propertyMap.get(REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID)))) {
-            StackEntity stackEntity = entity.getStack();
-            String stackName = stackEntity.getStackName();
-            String stackVersion = stackEntity.getStackVersion();
+          // Prevent changing repo version if there's already a cluster version that has performed some meaningful action on it.
+          StackEntity stackEntity = entity.getStack();
+          String stackName = stackEntity.getStackName();
+          String stackVersion = stackEntity.getStackVersion();
 
-            final List<ClusterVersionEntity> clusterVersionEntities = clusterVersionDAO.findByStackAndVersion(
-                stackName, stackVersion, entity.getVersion());
+          final List<ClusterVersionEntity> clusterVersionEntities = clusterVersionDAO.findByStackAndVersion(
+              stackName, stackVersion, entity.getVersion());
 
-            if (!clusterVersionEntities.isEmpty()) {
-              final ClusterVersionEntity firstClusterVersion = clusterVersionEntities.get(0);
-              throw new AmbariException("Upgrade pack can't be changed for repository version which is " +
-                firstClusterVersion.getState().name() + " on cluster " + firstClusterVersion.getClusterEntity().getClusterName());
-            }
-
-            final String upgradePackage = propertyMap.get(REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID).toString();
-            entity.setUpgradePackage(upgradePackage);
+          if (!clusterVersionEntities.isEmpty()) {
+            final ClusterVersionEntity firstClusterVersion = clusterVersionEntities.get(0);
+            throw new AmbariException("Upgrade pack can't be changed for repository version which has a state of " +
+              firstClusterVersion.getState().name() + " on cluster " + firstClusterVersion.getClusterEntity().getClusterName());
           }
 
           if (StringUtils.isNotBlank(ObjectUtils.toString(propertyMap.get(SUBRESOURCE_OPERATING_SYSTEMS_PROPERTY_ID)))) {
@@ -348,14 +349,13 @@ public class RepositoryVersionResourceProvider extends AbstractResourceProvider
    */
   protected void validateRepositoryVersion(RepositoryVersionEntity repositoryVersion) throws AmbariException {
     final StackId requiredStack = new StackId(repositoryVersion.getStack());
-    final String stackName = requiredStack.getStackName();
-    final String stackMajorVersion = requiredStack.getStackVersion();
-    final String stackFullName = requiredStack.getStackId();
-
-    // check that stack exists
-    final StackInfo stackInfo = ambariMetaInfo.getStack(stackName, stackMajorVersion);
-    if (stackInfo.getUpgradePacks() == null) {
-      throw new AmbariException("Stack " + stackFullName + " doesn't have upgrade packages");
+
+    final String requiredStackName = requiredStack.getStackName();
+    final String requiredStackVersion = requiredStack.getStackVersion();
+    final String requiredStackId = requiredStack.getStackId();
+
+    if (!upgradePackExists(repositoryVersion.getVersion())) {
+      throw new AmbariException("Stack " + requiredStackId + " doesn't have upgrade packages");
     }
 
     // List of all repo urls that are already added at stack
@@ -374,7 +374,7 @@ public class RepositoryVersionResourceProvider extends AbstractResourceProvider
 
     // check that repositories contain only supported operating systems
     final Set<String> osSupported = new HashSet<String>();
-    for (OperatingSystemInfo osInfo: ambariMetaInfo.getOperatingSystems(stackName, stackMajorVersion)) {
+    for (OperatingSystemInfo osInfo: ambariMetaInfo.getOperatingSystems(requiredStackName, requiredStackVersion)) {
       osSupported.add(osInfo.getOsType());
     }
     final Set<String> osRepositoryVersion = new HashSet<String>();
@@ -394,7 +394,7 @@ public class RepositoryVersionResourceProvider extends AbstractResourceProvider
     }
     for (String os: osRepositoryVersion) {
       if (!osSupported.contains(os)) {
-        throw new AmbariException("Operating system type " + os + " is not supported by stack " + stackFullName);
+        throw new AmbariException("Operating system type " + os + " is not supported by stack " + requiredStackId);
       }
     }
 
@@ -405,6 +405,35 @@ public class RepositoryVersionResourceProvider extends AbstractResourceProvider
   }
 
   /**
+   * Check for required upgrade pack across all stack definitions
+   * @param checkVersion version to check (e.g. 2.2.3.0-1111)
+   * @return existence flag
+   */
+  private boolean upgradePackExists(String checkVersion) throws AmbariException{
+    Collection<StackInfo> stacks = new ArrayList<StackInfo>();
+
+    // Search results only in the installed stacks
+    for (Cluster cluster:clusters.get().getClusters().values()){
+      stacks.add(ambariMetaInfo.getStack(cluster.getCurrentStackVersion().getStackName(),
+                                          cluster.getCurrentStackVersion().getStackVersion()));
+    }
+
+    for (StackInfo si: stacks){
+      Map<String, UpgradePack> upgradePacks = si.getUpgradePacks();
+      if (upgradePacks!=null) {
+        for (UpgradePack upgradePack: upgradePacks.values()){
+          if (upgradePack.canBeApplied(checkVersion)) {
+            // If we found at least one match, the rest could be skipped
+            return true;
+          }
+        }
+      }
+    }
+   return false;
+  }
+
+
+  /**
    * Transforms map of json properties to repository version entity.
    *
    * @param properties json map
@@ -430,7 +459,6 @@ public class RepositoryVersionResourceProvider extends AbstractResourceProvider
       throw new AmbariException("Json structure for operating systems is incorrect", ex);
     }
     entity.setOperatingSystems(operatingSystemsJson);
-    entity.setUpgradePackage(repositoryVersionHelper.getUpgradePackageName(stackName, stackVersion, entity.getVersion()));
     return entity;
   }