You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by jo...@apache.org on 2017/06/27 23:38:20 UTC

[3/3] ambari git commit: AMBARI-21358 - Upgrades Must Track To/From Repository Versions Instead of Strings (jonathanhurley)

AMBARI-21358 - Upgrades Must Track To/From Repository Versions Instead of Strings (jonathanhurley)


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

Branch: refs/heads/branch-feature-AMBARI-21348
Commit: 7ad307c2c36e6170cd3053e707b313edebbdaa1a
Parents: 7b8f0ea
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Tue Jun 27 13:58:43 2017 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Tue Jun 27 19:37:57 2017 -0400

----------------------------------------------------------------------
 .../actionmanager/ExecutionCommandWrapper.java  |   7 +
 .../alerts/ComponentVersionAlertRunnable.java   |   4 +-
 .../server/checks/PreviousUpgradeCompleted.java |  11 +-
 .../AmbariCustomCommandExecutionHelper.java     |   6 -
 .../internal/UpgradeResourceProvider.java       | 132 ++++++-----
 .../server/orm/entities/UpgradeEntity.java      |  46 ++--
 .../upgrades/ComponentVersionCheckAction.java   |  20 +-
 .../upgrades/FinalizeUpgradeAction.java         | 137 ++++++------
 .../upgrades/UpdateDesiredStackAction.java      | 106 ++++-----
 .../org/apache/ambari/server/state/Cluster.java |   4 +
 .../ambari/server/state/UpgradeContext.java     | 211 +++++-------------
 .../server/state/UpgradeContextFactory.java     |  14 +-
 .../ambari/server/state/UpgradeHelper.java      |  27 ++-
 .../server/state/cluster/ClusterImpl.java       |  32 ++-
 .../services/RetryUpgradeActionService.java     |   4 +-
 .../state/stack/upgrade/HostOrderGrouping.java  |   3 +-
 .../server/upgrade/UpgradeCatalog220.java       |  10 +-
 .../server/upgrade/UpgradeCatalog252.java       |  33 +++
 .../main/resources/Ambari-DDL-Derby-CREATE.sql  |   8 +-
 .../main/resources/Ambari-DDL-MySQL-CREATE.sql  |   8 +-
 .../main/resources/Ambari-DDL-Oracle-CREATE.sql |   8 +-
 .../resources/Ambari-DDL-Postgres-CREATE.sql    |   8 +-
 .../resources/Ambari-DDL-SQLAnywhere-CREATE.sql |   8 +-
 .../resources/Ambari-DDL-SQLServer-CREATE.sql   |   8 +-
 .../ComponentVersionAlertRunnableTest.java      |   5 +-
 .../creator/UpgradeEventCreatorTest.java        |   4 +-
 .../checks/PreviousUpgradeCompletedTest.java    |  13 +-
 .../StackUpgradeConfigurationMergeTest.java     |  35 ++-
 .../internal/UpgradeResourceProviderTest.java   |  71 +++---
 .../UpgradeSummaryResourceProviderTest.java     |  14 +-
 .../ambari/server/orm/dao/UpgradeDAOTest.java   |  32 ++-
 .../upgrades/UpgradeActionTest.java             |  56 +++--
 .../server/state/ServiceComponentTest.java      |  31 +--
 .../ambari/server/state/UpgradeHelperTest.java  | 219 +++++++++++--------
 .../cluster/ClusterEffectiveVersionTest.java    |  31 ++-
 .../services/RetryUpgradeActionServiceTest.java |  30 +--
 .../stack/upgrade/StageWrapperBuilderTest.java  |  32 ++-
 37 files changed, 742 insertions(+), 686 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/7ad307c2/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ExecutionCommandWrapper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ExecutionCommandWrapper.java b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ExecutionCommandWrapper.java
index 26c39fc..81bc80f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ExecutionCommandWrapper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ExecutionCommandWrapper.java
@@ -26,7 +26,9 @@ import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.ClusterNotFoundException;
 import org.apache.ambari.server.agent.AgentCommand.AgentCommandType;
 import org.apache.ambari.server.agent.ExecutionCommand;
+import org.apache.ambari.server.agent.ExecutionCommand.KeyNames;
 import org.apache.ambari.server.orm.dao.HostRoleCommandDAO;
+import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.ConfigHelper;
@@ -179,6 +181,11 @@ public class ExecutionCommandWrapper {
             }
         }
       }
+
+      ClusterVersionEntity effectiveClusterVersion = cluster.getEffectiveClusterVersion();
+      executionCommand.getCommandParams().put(KeyNames.VERSION,
+          effectiveClusterVersion.getRepositoryVersion().getVersion());
+
     } catch (ClusterNotFoundException cnfe) {
       // it's possible that there are commands without clusters; in such cases,
       // just return the de-serialized command and don't try to read configs

http://git-wip-us.apache.org/repos/asf/ambari/blob/7ad307c2/ambari-server/src/main/java/org/apache/ambari/server/alerts/ComponentVersionAlertRunnable.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/alerts/ComponentVersionAlertRunnable.java b/ambari-server/src/main/java/org/apache/ambari/server/alerts/ComponentVersionAlertRunnable.java
index 7dfbe47..9dc10ea 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/alerts/ComponentVersionAlertRunnable.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/alerts/ComponentVersionAlertRunnable.java
@@ -106,7 +106,9 @@ public class ComponentVersionAlertRunnable extends AlertRunnable {
     // if there is an upgrade in progress, then skip running this alert
     UpgradeEntity upgrade = cluster.getUpgradeInProgress();
     if (null != upgrade) {
-      String message = MessageFormat.format(UPGRADE_IN_PROGRESS_MSG, upgrade.getToVersion());
+      RepositoryVersionEntity repositoryVersion = upgrade.getToRepositoryVersion();
+      String message = MessageFormat.format(UPGRADE_IN_PROGRESS_MSG,
+          repositoryVersion.getVersion());
 
       return Collections.singletonList(
           buildAlert(cluster, myDefinition, AlertState.SKIPPED, message));

http://git-wip-us.apache.org/repos/asf/ambari/blob/7ad307c2/ambari-server/src/main/java/org/apache/ambari/server/checks/PreviousUpgradeCompleted.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/PreviousUpgradeCompleted.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/PreviousUpgradeCompleted.java
index fe57ae4..833ee73 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/PreviousUpgradeCompleted.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/PreviousUpgradeCompleted.java
@@ -22,6 +22,7 @@ import java.util.LinkedHashSet;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.controller.PrereqCheckRequest;
+import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 import org.apache.ambari.server.orm.entities.UpgradeEntity;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.stack.PrereqCheckStatus;
@@ -46,7 +47,7 @@ public class PreviousUpgradeCompleted extends AbstractCheckDescriptor {
   /**
    * The message displayed as part of this pre-upgrade check.
    */
-  public static final String ERROR_MESSAGE = "There is an existing {0} from {1} to {2} which has not completed. This {3} must be completed before a new upgrade or downgrade can begin.";
+  public static final String ERROR_MESSAGE = "There is an existing {0} from {1}-{2} to {3}-{4} which has not completed. This {5} must be completed before a new upgrade or downgrade can begin.";
 
   /**
    * Constructor.
@@ -66,12 +67,16 @@ public class PreviousUpgradeCompleted extends AbstractCheckDescriptor {
       Direction direction = upgradeInProgress.getDirection();
       String directionText = direction.getText(false);
 
+      RepositoryVersionEntity fromRepositoryVersion = upgradeInProgress.getFromRepositoryVersion();
+      RepositoryVersionEntity toRepositoryVersion = upgradeInProgress.getToRepositoryVersion();
+
       errorMessage = MessageFormat.format(ERROR_MESSAGE, directionText,
-          upgradeInProgress.getFromVersion(), upgradeInProgress.getToVersion(), directionText);
+          fromRepositoryVersion.getStackName(), fromRepositoryVersion.getVersion(),
+          toRepositoryVersion.getStackName(), toRepositoryVersion.getVersion(), directionText);
     }
 
     if (null != errorMessage) {
-      LinkedHashSet<String> failedOn = new LinkedHashSet<String>();
+      LinkedHashSet<String> failedOn = new LinkedHashSet<>();
       failedOn.add(cluster.getClusterName());
       prerequisiteCheck.setFailedOn(failedOn);
       prerequisiteCheck.setStatus(PrereqCheckStatus.FAIL);

http://git-wip-us.apache.org/repos/asf/ambari/blob/7ad307c2/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 6e75ab6..3a672b6 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
@@ -332,8 +332,6 @@ public class AmbariCustomCommandExecutionHelper {
     StackInfo stackInfo = ambariMetaInfo.getStack
        (stackId.getStackName(), stackId.getStackVersion());
 
-    ClusterVersionEntity effectiveClusterVersion = cluster.getEffectiveClusterVersion();
-
     CustomCommandDefinition customCommandDefinition = null;
     ComponentInfo ci = serviceInfo.getComponentByName(componentName);
     if(ci != null){
@@ -479,10 +477,6 @@ public class AmbariCustomCommandExecutionHelper {
       commandParams.put(SERVICE_PACKAGE_FOLDER, serviceInfo.getServicePackageFolder());
       commandParams.put(HOOKS_FOLDER, stackInfo.getStackHooksFolder());
 
-      if (effectiveClusterVersion != null) {
-       commandParams.put(KeyNames.VERSION, effectiveClusterVersion.getRepositoryVersion().getVersion());
-      }
-
       Map<String, String> roleParams = execCmd.getRoleParams();
       if (roleParams == null) {
         roleParams = new TreeMap<>();

http://git-wip-us.apache.org/repos/asf/ambari/blob/7ad307c2/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 71c0b80..da716b3 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
@@ -114,7 +114,6 @@ 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.UpgradeScope;
 import org.apache.ambari.server.state.stack.upgrade.UpgradeType;
 import org.apache.ambari.server.state.svccomphost.ServiceComponentHostServerActionEvent;
@@ -379,26 +378,49 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
         final Long repositoryId = (Long) requestMap.get(UPGRADE_REPO_ID);
         final String repositoryName = (String) requestMap.get(UPGRADE_REPO_NAME);
         final String repositoryVersion = (String) requestMap.get(UPGRADE_REPO_VERSION);
-        RepositoryVersionEntity repositoryVersionEntity = null;
+
+        RepositoryVersionEntity toRepositoryVersion = null;
 
         if (null != repositoryId) {
-          repositoryVersionEntity = s_repoVersionDAO.findByPK(repositoryId);
+          toRepositoryVersion = s_repoVersionDAO.findByPK(repositoryId);
         } else {
           if (StringUtils.isNotBlank(repositoryName)) {
-            repositoryVersionEntity = s_repoVersionDAO.findByStackNameAndVersion(repositoryName,
+            toRepositoryVersion = s_repoVersionDAO.findByStackNameAndVersion(repositoryName,
                 repositoryVersion);
           } else {
-            repositoryVersionEntity = s_repoVersionDAO.findByVersion(repositoryVersion);
+            toRepositoryVersion = s_repoVersionDAO.findByVersion(repositoryVersion);
           }
         }
 
-        if (null == repositoryVersionEntity) {
+        if (null == toRepositoryVersion) {
           throw new AmbariException(
               "Unable to find repository by any combination of id, name, or version");
         }
 
+        // determine the correct "from" repo version which is based on upgrade
+        // direction
+        RepositoryVersionEntity fromRepositoryVersion = cluster.getCurrentClusterVersion().getRepositoryVersion();
+
+        if (direction.isDowngrade()) {
+          String downgradeFromVersion = (String) requestMap.get(UPGRADE_FROM_VERSION);
+
+          UpgradeEntity lastUpgradeItemForCluster = s_upgradeDAO.findLastUpgradeForCluster(
+              cluster.getClusterId(), Direction.UPGRADE);
+
+          RepositoryVersionEntity lastUpgradeTargetVersion = lastUpgradeItemForCluster.getToRepositoryVersion();
+          String lastUpgradeVersion = lastUpgradeTargetVersion.getVersion();
+          if (null != downgradeFromVersion
+              && !StringUtils.equals(downgradeFromVersion, lastUpgradeVersion)) {
+            throw new AmbariException(
+                "Unable to perform downgrade to " + toRepositoryVersion.getVersion()
+                    + " since there is no prior failed upgrade to " + downgradeFromVersion);
+          }
+
+          fromRepositoryVersion = lastUpgradeTargetVersion;
+        }
+
         final UpgradeContext upgradeContext = s_upgradeContextFactory.create(cluster, upgradeType,
-            direction, repositoryVersionEntity.getVersion(), requestMap);
+            direction, fromRepositoryVersion, toRepositoryVersion, requestMap);
 
         UpgradePack upgradePack = validateRequest(upgradeContext);
         upgradeContext.setUpgradePack(upgradePack);
@@ -619,8 +641,8 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     setResourceProperty(resource, UPGRADE_TYPE, entity.getUpgradeType(), 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);
+    setResourceProperty(resource, UPGRADE_FROM_VERSION, entity.getFromRepositoryVersion().getVersion(), requestedIds);
+    setResourceProperty(resource, UPGRADE_TO_VERSION, entity.getToRepositoryVersion().getVersion(), requestedIds);
     setResourceProperty(resource, UPGRADE_DIRECTION, entity.getDirection(), requestedIds);
     setResourceProperty(resource, UPGRADE_SUSPENDED, entity.isSuspended(), requestedIds);
     setResourceProperty(resource, UPGRADE_DOWNGRADE_ALLOWED, entity.isDowngradeAllowed(), requestedIds);
@@ -721,19 +743,17 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     Cluster cluster = upgradeContext.getCluster();
     Direction direction = upgradeContext.getDirection();
     Map<String, Object> requestMap = upgradeContext.getUpgradeRequest();
-    UpgradeType upgradeType = upgradeContext.getType();
-
     ConfigHelper configHelper = getManagementController().getConfigHelper();
-    String userName = getManagementController().getAuthName();
 
-    // the version being upgraded or downgraded to (ie 2.2.1.0-1234)
-    final String version = upgradeContext.getVersion();
+    // the version being upgraded to or downgraded from (ie 2.2.1.0-1234)
+    final RepositoryVersionEntity repositoryVersion = upgradeContext.getTargetRepositoryVersion();
 
     MasterHostResolver resolver = null;
     if (direction.isUpgrade()) {
       resolver = new MasterHostResolver(configHelper, cluster);
     } else {
-      resolver = new MasterHostResolver(configHelper, cluster, version);
+      resolver = new MasterHostResolver(configHelper, cluster,
+          upgradeContext.getTargetRepositoryVersion().getVersion());
     }
 
     Set<String> supportedServices = new HashSet<>();
@@ -744,13 +764,16 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     upgradeContext.setScope(scope);
 
     if (direction.isDowngrade()) {
-      if (requestMap.containsKey(UPGRADE_FROM_VERSION)) {
-        upgradeContext.setDowngradeFromVersion((String) requestMap.get(UPGRADE_FROM_VERSION));
-      } else {
-        UpgradeEntity lastUpgradeItemForCluster = s_upgradeDAO.findLastUpgradeForCluster(
-            cluster.getClusterId(), Direction.UPGRADE);
+      String downgradeFromVersion = (String) requestMap.get(UPGRADE_FROM_VERSION);
+
+      UpgradeEntity lastUpgradeItemForCluster = s_upgradeDAO.findLastUpgradeForCluster(
+          cluster.getClusterId(), Direction.UPGRADE);
 
-        upgradeContext.setDowngradeFromVersion(lastUpgradeItemForCluster.getToVersion());
+      String lastUpgradeVersion = lastUpgradeItemForCluster.getToRepositoryVersion().getVersion();
+      if (null != downgradeFromVersion
+          && !StringUtils.equals(downgradeFromVersion, lastUpgradeVersion)) {
+        throw new AmbariException("Unable to perform downgrade to " + repositoryVersion.getVersion()
+            + " since there is no prior failed upgrade to " + downgradeFromVersion);
       }
     }
 
@@ -804,11 +827,8 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     }
 
     List<UpgradeGroupEntity> groupEntities = new ArrayList<>();
-    RequestStageContainer req = createRequest(cluster, direction, version);
-
-    // the upgrade context calculated these for us based on direction
-    StackId sourceStackId = upgradeContext.getOriginalStackId();
-    StackId targetStackId = upgradeContext.getTargetStackId();
+    RequestStageContainer req = createRequest(cluster, direction,
+        upgradeContext.getTargetRepositoryVersion().getStackId());
 
     /**
     During a Rolling Upgrade, change the desired Stack Id if jumping across
@@ -823,7 +843,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     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, userName);
+      applyStackAndProcessConfigurations(upgradeContext);
     }
 
     // resolve or build a proper config upgrade pack - always start out with the config pack
@@ -831,7 +851,8 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     //
     // HDP 2.2 to 2.3 should start with the config-upgrade.xml from HDP 2.2
     // HDP 2.2 to 2.4 should start with HDP 2.2 and merge in HDP 2.3's config-upgrade.xml
-    ConfigUpgradePack configUpgradePack = ConfigurationPackBuilder.build(pack, sourceStackId);
+    ConfigUpgradePack configUpgradePack = ConfigurationPackBuilder.build(pack,
+        upgradeContext.getOriginalStackId());
 
     // TODO: for now, all service components are transitioned to upgrading state
     // TODO: When performing patch upgrade, we should only target supported services/components
@@ -848,7 +869,9 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     // !!! determine which stack to check for component isAdvertised
     StackId componentStack = upgradeContext.getDirection() == Direction.UPGRADE ?
         upgradeContext.getTargetStackId() : upgradeContext.getOriginalStackId();
-    s_upgradeHelper.putComponentsToUpgradingState(version, targetComponents, componentStack);
+
+    s_upgradeHelper.putComponentsToUpgradingState(repositoryVersion.getStackId(),
+        repositoryVersion.getVersion(), targetComponents, componentStack);
 
     for (UpgradeGroupHolder group : groups) {
       boolean skippable = group.skippable;
@@ -875,17 +898,6 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
               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.
-              if (upgradeType == UpgradeType.NON_ROLLING && UpdateStackGrouping.class.equals(group.groupClass)) {
-                if (direction.isUpgrade()) {
-                  upgradeContext.setEffectiveStackId(upgradeContext.getTargetStackId());
-                } else {
-                  upgradeContext.setEffectiveStackId(upgradeContext.getOriginalStackId());
-                }
-              } else if (UpdateStackGrouping.class.equals(group.groupClass)) {
-                upgradeContext.setEffectiveStackId(upgradeContext.getTargetStackId());
-              }
-
               injectVariables(configHelper, cluster, itemEntity);
               makeServerSideStage(upgradeContext, req, itemEntity, (ServerSideActionTask) task,
                   skippable, supportsAutoSkipOnFailure, allowRetry, pack, configUpgradePack);
@@ -916,8 +928,8 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     }
 
     UpgradeEntity entity = new UpgradeEntity();
-    entity.setFromVersion(cluster.getCurrentClusterVersion().getRepositoryVersion().getVersion());
-    entity.setToVersion(version);
+    entity.setFromRepositoryVersion(upgradeContext.getSourceRepositoryVersion());
+    entity.setToRepositoryVersion(upgradeContext.getTargetRepositoryVersion());
     entity.setUpgradeGroups(groupEntities);
     entity.setClusterId(cluster.getClusterId());
     entity.setDirection(direction);
@@ -987,31 +999,16 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
    * </ul>
    *
    *
-   * @param stackName Stack name such as HDP, HDPWIN, BIGTOP
-   * @param cluster
-   *          the cluster
-   * @param version
-   *          the version
-   * @param direction
-   *          upgrade or downgrade
-   * @param upgradePack
-   *          upgrade pack used for upgrade or downgrade. This is needed to determine
-   *          which services are effected.
-   * @param userName
-   *          username performing the action
+   * @param context
+   *          the upgrade context (not {@code null}).
    * @throws AmbariException
    */
-  public void applyStackAndProcessConfigurations(String stackName, Cluster cluster, String version, Direction direction, UpgradePack upgradePack, String userName)
-    throws AmbariException {
-    RepositoryVersionEntity targetRve = s_repoVersionDAO.findByStackNameAndVersion(stackName, version);
-    if (null == targetRve) {
-      LOG.info("Could not find version entity for {}; not setting new configs", version);
-      return;
-    }
-
-    if (null == userName) {
-      userName = getManagementController().getAuthName();
-    }
+  public void applyStackAndProcessConfigurations(UpgradeContext context) throws AmbariException {
+    Cluster cluster = context.getCluster();
+    Direction direction = context.getDirection();
+    UpgradePack upgradePack = context.getUpgradePack();
+    RepositoryVersionEntity targetRve = context.getTargetRepositoryVersion();
+    String userName = getManagementController().getAuthName();
 
     // if the current and target stacks are the same (ie HDP 2.2.0.0 -> 2.2.1.0)
     // then we should never do anything with configs on either upgrade or
@@ -1235,12 +1232,13 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     }
   }
 
-  private RequestStageContainer createRequest(Cluster cluster, Direction direction, String version) throws AmbariException {
+  private RequestStageContainer createRequest(Cluster cluster, Direction direction, StackId stackId)
+      throws AmbariException {
     ActionManager actionManager = getManagementController().getActionManager();
 
     RequestStageContainer requestStages = new RequestStageContainer(
         actionManager.getNextRequestId(), null, s_requestFactory.get(), actionManager);
-    requestStages.setRequestContext(String.format("%s to %s", direction.getVerb(true), version));
+    requestStages.setRequestContext(String.format("%s to %s", direction.getVerb(true), stackId));
 
     Map<String, Set<String>> clusterHostInfo = StageUtils.getClusterHostInfo(cluster);
     String clusterHostInfoJson = StageUtils.getGson().toJson(clusterHostInfo);

http://git-wip-us.apache.org/repos/asf/ambari/blob/7ad307c2/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 152fde1..8c37b51 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
@@ -60,7 +60,7 @@ import org.apache.ambari.server.state.stack.upgrade.UpgradeType;
   @NamedQuery(name = "UpgradeEntity.findUpgrade",
       query = "SELECT u FROM UpgradeEntity u WHERE u.upgradeId = :upgradeId"),
   @NamedQuery(name = "UpgradeEntity.findUpgradeByRequestId",
-      query = "SELECT u FROM UpgradeEntity u WHERE u.requestId = :requestId"),  
+      query = "SELECT u FROM UpgradeEntity u WHERE u.requestId = :requestId"),
   @NamedQuery(name = "UpgradeEntity.findLatestForClusterInDirection",
       query = "SELECT u FROM UpgradeEntity u JOIN RequestEntity r ON u.requestId = r.requestId WHERE u.clusterId = :clusterId AND u.direction = :direction ORDER BY r.startTime DESC, u.upgradeId DESC"),
   @NamedQuery(name = "UpgradeEntity.findLatestForCluster",
@@ -91,11 +91,17 @@ public class UpgradeEntity {
   @JoinColumn(name = "request_id", nullable = false, insertable = true, updatable = false)
   private RequestEntity requestEntity = null;
 
-  @Column(name="from_version", nullable = false)
-  private String fromVersion = null;
+  @JoinColumn(
+      name = "from_repo_version_id",
+      referencedColumnName = "repo_version_id",
+      nullable = false)
+  private RepositoryVersionEntity fromRepositoryVersion;
 
-  @Column(name="to_version", nullable = false)
-  private String toVersion = null;
+  @JoinColumn(
+      name = "to_repo_version_id",
+      referencedColumnName = "repo_version_id",
+      nullable = false)
+  private RepositoryVersionEntity toRepositoryVersion;
 
   @Column(name="direction", nullable = false)
   @Enumerated(value = EnumType.STRING)
@@ -189,29 +195,31 @@ public class UpgradeEntity {
   /**
    * @return the "from" version
    */
-  public String getFromVersion() {
-    return fromVersion;
+  public RepositoryVersionEntity getFromRepositoryVersion() {
+    return fromRepositoryVersion;
   }
 
   /**
-   * @param version the "from" version
+   * @param repositoryVersion
+   *          the "from" version
    */
-  public void setFromVersion(String version) {
-    fromVersion = version;
+  public void setFromRepositoryVersion(RepositoryVersionEntity repositoryVersion) {
+    fromRepositoryVersion = repositoryVersion;
   }
 
   /**
    * @return the "to" version
    */
-  public String getToVersion() {
-    return toVersion;
+  public RepositoryVersionEntity getToRepositoryVersion() {
+    return toRepositoryVersion;
   }
 
   /**
-   * @param version the "to" version
+   * @param repositoryVersion
+   *          the "to" version
    */
-  public void setToVersion(String version) {
-    toVersion = version;
+  public void setToRepositoryVersion(RepositoryVersionEntity repositoryVersion) {
+    toRepositoryVersion = repositoryVersion;
   }
 
   /**
@@ -356,10 +364,10 @@ public class UpgradeEntity {
     if (requestId != null ? !requestId.equals(that.requestId) : that.requestId != null) {
       return false;
     }
-    if (fromVersion != null ? !fromVersion.equals(that.fromVersion) : that.fromVersion != null) {
+    if (fromRepositoryVersion != null ? !fromRepositoryVersion.equals(that.fromRepositoryVersion) : that.fromRepositoryVersion != null) {
       return false;
     }
-    if (toVersion != null ? !toVersion.equals(that.toVersion) : that.toVersion != null) {
+    if (toRepositoryVersion != null ? !toRepositoryVersion.equals(that.toRepositoryVersion) : that.toRepositoryVersion != null) {
       return false;
     }
     if (direction != null ? !direction.equals(that.direction) : that.direction != null) {
@@ -383,8 +391,8 @@ public class UpgradeEntity {
     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 + (fromRepositoryVersion != null ? fromRepositoryVersion.hashCode() : 0);
+    result = 31 * result + (toRepositoryVersion != null ? toRepositoryVersion.hashCode() : 0);
     result = 31 * result + (direction != null ? direction.hashCode() : 0);
     result = 31 * result + (suspended != null ? suspended.hashCode() : 0);
     result = 31 * result + (upgradeType != null ? upgradeType.hashCode() : 0);

http://git-wip-us.apache.org/repos/asf/ambari/blob/7ad307c2/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/ComponentVersionCheckAction.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/ComponentVersionCheckAction.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/ComponentVersionCheckAction.java
index 7705c7d..9ae9844 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/ComponentVersionCheckAction.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/ComponentVersionCheckAction.java
@@ -28,13 +28,16 @@ import java.util.concurrent.ConcurrentMap;
 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.orm.entities.RepositoryVersionEntity;
 import org.apache.ambari.server.state.Cluster;
-import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.UpgradeContext;
+import org.apache.ambari.server.state.UpgradeContextFactory;
 import org.apache.commons.lang.StringUtils;
 
 import com.google.gson.JsonArray;
 import com.google.gson.JsonObject;
 import com.google.gson.JsonPrimitive;
+import com.google.inject.Inject;
 
 /**
  * Action that checks component versions to ensure {@link FinalizeUpgradeAction} will
@@ -42,20 +45,23 @@ import com.google.gson.JsonPrimitive;
  */
 public class ComponentVersionCheckAction extends FinalizeUpgradeAction {
 
+  /**
+   * Used for building {@link UpgradeContext} instances.
+   */
+  @Inject
+  private UpgradeContextFactory upgradeContextFactory;
 
   @Override
   public CommandReport execute(ConcurrentMap<String, Object> requestSharedDataContext)
       throws AmbariException, InterruptedException {
 
-    Map<String, String> commandParams = getExecutionCommand().getCommandParams();
-
-    String version = commandParams.get(VERSION_KEY);
-    StackId targetStackId = new StackId(commandParams.get(TARGET_STACK_KEY));
     String clusterName = getExecutionCommand().getClusterName();
-
     Cluster cluster = clusters.getCluster(clusterName);
+    UpgradeContext context = upgradeContextFactory.create(cluster, cluster.getUpgradeInProgress());
+    RepositoryVersionEntity targetRepositoryVersion = context.getTargetRepositoryVersion();
 
-    List<InfoTuple> errors = checkHostComponentVersions(cluster, version, targetStackId);
+    List<InfoTuple> errors = checkHostComponentVersions(cluster,
+        targetRepositoryVersion.getVersion(), context.getTargetStackId());
 
     StringBuilder outSB = new StringBuilder();
     StringBuilder errSB = new StringBuilder();

http://git-wip-us.apache.org/repos/asf/ambari/blob/7ad307c2/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/FinalizeUpgradeAction.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/FinalizeUpgradeAction.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/FinalizeUpgradeAction.java
index e73651e..2fc492b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/FinalizeUpgradeAction.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/FinalizeUpgradeAction.java
@@ -24,7 +24,6 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentMap;
 
@@ -32,7 +31,6 @@ 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.events.HostComponentVersionAdvertisedEvent;
 import org.apache.ambari.server.events.StackUpgradeFinishEvent;
 import org.apache.ambari.server.events.publishers.VersionEventPublisher;
 import org.apache.ambari.server.orm.dao.ClusterVersionDAO;
@@ -40,7 +38,6 @@ import org.apache.ambari.server.orm.dao.HostComponentStateDAO;
 import org.apache.ambari.server.orm.dao.HostVersionDAO;
 import org.apache.ambari.server.orm.dao.ServiceComponentDesiredStateDAO;
 import org.apache.ambari.server.orm.dao.StackDAO;
-import org.apache.ambari.server.orm.dao.UpgradeDAO;
 import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
 import org.apache.ambari.server.orm.entities.HostComponentStateEntity;
 import org.apache.ambari.server.orm.entities.HostEntity;
@@ -59,6 +56,8 @@ import org.apache.ambari.server.state.Service;
 import org.apache.ambari.server.state.ServiceComponent;
 import org.apache.ambari.server.state.ServiceComponentHost;
 import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.UpgradeContext;
+import org.apache.ambari.server.state.UpgradeContextFactory;
 import org.apache.ambari.server.state.UpgradeState;
 import org.apache.ambari.server.state.stack.upgrade.Direction;
 import org.apache.ambari.server.state.svccomphost.ServiceComponentHostSummary;
@@ -120,57 +119,56 @@ public class FinalizeUpgradeAction extends AbstractServerAction {
   @Inject
   private ServiceComponentDesiredStateDAO serviceComponentDesiredStateDAO;
 
-  /**
-   * Gets {@link UpgradeEntity} instances.
-   */
-  @Inject
-  private UpgradeDAO upgradeDAO;
-
   @Inject
   private AmbariMetaInfo ambariMetaInfo;
 
   @Inject
   VersionEventPublisher versionEventPublisher;
 
+  /**
+   * Used for building {@link UpgradeContext} instances.
+   */
+  @Inject
+  private UpgradeContextFactory upgradeContextFactory;
+
   @Override
   public CommandReport execute(ConcurrentMap<String, Object> requestSharedDataContext)
       throws AmbariException, InterruptedException {
 
-    Map<String, String> commandParams = getExecutionCommand().getCommandParams();
-
-    boolean isDowngrade = commandParams.containsKey(UPGRADE_DIRECTION_KEY) &&
-        "downgrade".equals(commandParams.get(UPGRADE_DIRECTION_KEY).toLowerCase());
-
-    String version = commandParams.get(VERSION_KEY);
-    StackId originalStackId = new StackId(commandParams.get(ORIGINAL_STACK_KEY));
-    StackId targetStackId = new StackId(commandParams.get(TARGET_STACK_KEY));
-
     String clusterName = getExecutionCommand().getClusterName();
+    Cluster cluster = clusters.getCluster(clusterName);
+    UpgradeContext context = upgradeContextFactory.create(cluster, cluster.getUpgradeInProgress());
 
-    if (isDowngrade) {
-      return finalizeDowngrade(clusterName, originalStackId, targetStackId, version);
+    if (context.getDirection() == Direction.DOWNGRADE) {
+      return finalizeDowngrade(context);
     } else {
-      return finalizeUpgrade(clusterName, version, commandParams);
+      return finalizeUpgrade(context);
     }
   }
 
   /**
    * Execution path for upgrade.
-   * @param clusterName the name of the cluster the upgrade is for
-   * @param version     the target version of the upgrade
+   *
+   * @param context
+   *          the upgrade context (not {@code null}).
    * @return the command report
    */
-  private CommandReport finalizeUpgrade(String clusterName, String version,
-      Map<String, String> commandParams)
+  private CommandReport finalizeUpgrade(UpgradeContext context)
     throws AmbariException, InterruptedException {
 
     StringBuilder outSB = new StringBuilder();
     StringBuilder errSB = new StringBuilder();
 
     try {
-      outSB.append(MessageFormat.format("Begin finalizing the upgrade of cluster {0} to version {1}\n", clusterName, version));
+      Cluster cluster = context.getCluster();
+      String clusterName = cluster.getClusterName();
+      RepositoryVersionEntity targetRepositoryVersion = context.getTargetRepositoryVersion();
+      String version = targetRepositoryVersion.getVersion();
+
+      outSB.append(MessageFormat.format(
+          "Begin finalizing the upgrade of cluster {0} to version {1}\n", clusterName,
+          targetRepositoryVersion.getVersion()));
 
-      Cluster cluster = clusters.getCluster(clusterName);
       StackId clusterDesiredStackId = cluster.getDesiredStackVersion();
       StackId clusterCurrentStackId = cluster.getCurrentStackVersion();
 
@@ -188,9 +186,9 @@ public class FinalizeUpgradeAction extends AbstractServerAction {
           clusterName, clusterDesiredStackId, version);
 
       // Will include hosts whose state is INSTALLED
-      Set<HostVersionEntity> hostVersionsAllowed = new HashSet<HostVersionEntity>();
-      Set<String> hostsWithoutCorrectVersionState = new HashSet<String>();
-      Set<String> hostsToUpdate = new HashSet<String>();
+      Set<HostVersionEntity> hostVersionsAllowed = new HashSet<>();
+      Set<String> hostsWithoutCorrectVersionState = new HashSet<>();
+      Set<String> hostsToUpdate = new HashSet<>();
 
       // It is important to only iterate over the hosts with a version, as
       // opposed to all hosts, since some hosts may only have components that do
@@ -307,8 +305,6 @@ public class FinalizeUpgradeAction extends AbstractServerAction {
       cluster.mapHostVersions(hostsToUpdate, upgradingClusterVersion, RepositoryVersionState.CURRENT);
 
       versionEventPublisher.publish(new StackUpgradeFinishEvent(cluster));
-      // Reset upgrade state
-      cluster.setUpgradeEntity(null);
 
       // transitioning the cluster into CURRENT will update the current/desired
       // stack values
@@ -316,24 +312,15 @@ public class FinalizeUpgradeAction extends AbstractServerAction {
       cluster.transitionClusterVersion(clusterDesiredStackId, version,
           RepositoryVersionState.CURRENT);
 
-      if (commandParams.containsKey(REQUEST_ID)) {
-        String requestId = commandParams.get(REQUEST_ID);
-        UpgradeEntity upgradeEntity = upgradeDAO.findUpgradeByRequestId(Long.valueOf(requestId));
+      UpgradeEntity upgradeEntity = cluster.getUpgradeInProgress();
+      outSB.append("Creating upgrade history.\n");
+      writeComponentHistory(cluster, upgradeEntity, clusterCurrentStackId, clusterDesiredStackId);
 
-        if (null != upgradeEntity) {
-          outSB.append("Creating upgrade history.\n");
-          writeComponentHistory(cluster, upgradeEntity, clusterCurrentStackId,
-              clusterDesiredStackId);
-        } else {
-          String warning = String.format(
-              "Unable to create upgrade history because no upgrade could be found for request with ID %s\n",
-              requestId);
-
-          outSB.append(warning);
-        }
-      }
+      // Reset upgrade state
+      cluster.setUpgradeEntity(null);
 
       outSB.append("Upgrade was successful!\n");
+
       return createCommandReport(0, HostRoleStatus.COMPLETED, "{}", outSB.toString(), errSB.toString());
     } catch (Exception e) {
       errSB.append(e.getMessage());
@@ -344,24 +331,24 @@ public class FinalizeUpgradeAction extends AbstractServerAction {
   /**
    * Execution path for downgrade.
    *
-   * @param clusterName
-   *          the name of the cluster the downgrade is for
-   * @paran originalStackId the stack ID of the cluster before the upgrade.
-   * @paran targetStackId the stack ID that was desired for this upgrade.
-   * @param version
-   *          the target version of the downgrade
+   * @param context
+   *          the upgrade context (not {@code null}).
    * @return the command report
    */
-  private CommandReport finalizeDowngrade(String clusterName,
-      StackId originalStackId, StackId targetStackId, String version)
+  private CommandReport finalizeDowngrade(UpgradeContext context)
       throws AmbariException, InterruptedException {
 
     StringBuilder out = new StringBuilder();
     StringBuilder err = new StringBuilder();
 
     try {
-      Cluster cluster = clusters.getCluster(clusterName);
+      Cluster cluster = context.getCluster();
+      String clusterName = cluster.getClusterName();
+
       StackId currentClusterStackId = cluster.getCurrentStackVersion();
+      StackId originalStackId = context.getOriginalStackId();
+      StackId targetStackId = context.getTargetStackId();
+      RepositoryVersionEntity targetRepositoryVersion = context.getTargetRepositoryVersion();
 
       // Safety check that the cluster's stack (from clusterstate's current_stack_id) is equivalent to the
       // cluster's CURRENT repo version's stack. This is to avoid deleting configs from the target stack if the customer
@@ -370,8 +357,8 @@ public class FinalizeUpgradeAction extends AbstractServerAction {
       RepositoryVersionEntity currentRepoVersion = currentClusterVersion.getRepositoryVersion();
       StackId currentRepoStackId = currentRepoVersion.getStackId();
       if (!currentRepoStackId.equals(originalStackId)) {
-        String msg = String.format("The stack of Cluster %s's CURRENT repo version is %s, yet the original stack id from " +
-            "the Stack Upgrade has a different value of %s. %s",
+        String msg = String.format(
+            "The stack of cluster %s's CURRENT repo version is %s, yet the original stack id from the Stack Upgrade has a different value of %s. %s",
             clusterName, currentRepoStackId.getStackId(), originalStackId.getStackId(), PREVIOUS_UPGRADE_NOT_COMPLETED_MSG);
         out.append(msg);
         err.append(msg);
@@ -394,20 +381,32 @@ public class FinalizeUpgradeAction extends AbstractServerAction {
         throw new AmbariException("Could not find current cluster version");
       }
 
-      out.append(String.format("Comparing downgrade version %s to current cluster version %s\n",
-          version,
+
+      out.append(String.format(
+          "Comparing downgrade version %s %s to current cluster version %s %s\n", targetStackId,
+          targetRepositoryVersion.getVersion(), clusterVersion.getRepositoryVersion().getStackId(),
           clusterVersion.getRepositoryVersion().getVersion()));
 
-      if (!version.equals(clusterVersion.getRepositoryVersion().getVersion())) {
+      if (!targetStackId.equals(clusterVersion.getRepositoryVersion().getStackId())) {
+        throw new AmbariException(
+            String.format("Downgrade stack %s is not the current cluster stack of %s",
+                targetStackId, clusterVersion.getRepositoryVersion().getStackId()));
+      }
+
+      if (!StringUtils.equals(targetRepositoryVersion.getVersion(),
+          clusterVersion.getRepositoryVersion().getVersion())) {
         throw new AmbariException(
             String.format("Downgrade version %s is not the current cluster version of %s",
-                version, clusterVersion.getRepositoryVersion().getVersion()));
+                targetRepositoryVersion.getVersion(),
+                clusterVersion.getRepositoryVersion().getVersion()));
       } else {
-        out.append(String.format("Downgrade version is the same as current.  Searching " +
-          "for cluster versions that do not match %s\n", version));
+        out.append(String.format(
+            "Downgrade version is the same as current. Searching "
+                + "for cluster versions that do not match %s\n",
+            targetRepositoryVersion.getVersion()));
       }
 
-      Set<String> badVersions = new HashSet<String>();
+      Set<String> badVersions = new HashSet<>();
 
       // update the cluster version
       for (ClusterVersionEntity cve : clusterVersionDAO.findByCluster(clusterName)) {
@@ -428,7 +427,7 @@ public class FinalizeUpgradeAction extends AbstractServerAction {
       out.append(String.format("Found %d other version(s) not matching downgrade: %s\n",
           badVersions.size(), StringUtils.join(badVersions, ", ")));
 
-      Set<String> badHosts = new HashSet<String>();
+      Set<String> badHosts = new HashSet<>();
       for (String badVersion : badVersions) {
         List<HostVersionEntity> hostVersions = hostVersionDAO.findByClusterStackAndVersion(
             clusterName, targetStackId, badVersion);
@@ -440,8 +439,8 @@ public class FinalizeUpgradeAction extends AbstractServerAction {
         }
       }
 
-      out.append(String.format("Found %d hosts not matching downgrade version: %s\n",
-          badHosts.size(), version));
+      out.append(String.format("Found %d hosts not matching downgrade version: %s %s\n",
+          badHosts.size(), targetStackId, targetRepositoryVersion.getVersion()));
 
       for (String badHost : badHosts) {
         List<HostComponentStateEntity> hostComponentStates = hostComponentStateDAO.findByHost(badHost);
@@ -483,7 +482,7 @@ public class FinalizeUpgradeAction extends AbstractServerAction {
   protected List<InfoTuple> checkHostComponentVersions(Cluster cluster, String desiredVersion, StackId targetStackId)
           throws AmbariException {
 
-    ArrayList<InfoTuple> errors = new ArrayList<InfoTuple>();
+    ArrayList<InfoTuple> errors = new ArrayList<>();
 
     for (Service service : cluster.getServices().values()) {
       for (ServiceComponent serviceComponent : service.getServiceComponents().values()) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/7ad307c2/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
index 5b592c7..e3f9824 100644
--- 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
@@ -20,29 +20,29 @@ import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.VERSION;
 
 import java.io.PrintWriter;
 import java.io.StringWriter;
-import java.util.Map;
 import java.util.concurrent.ConcurrentMap;
 
 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.configuration.Configuration;
 import org.apache.ambari.server.controller.AmbariServer;
 import org.apache.ambari.server.controller.internal.UpgradeResourceProvider;
+import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 import org.apache.ambari.server.serveraction.AbstractServerAction;
-import org.apache.ambari.server.serveraction.ServerAction;
 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 org.apache.ambari.server.state.UpgradeContext;
+import org.apache.ambari.server.state.UpgradeContextFactory;
 import org.apache.ambari.server.state.stack.UpgradePack;
 import org.apache.ambari.server.state.stack.upgrade.Direction;
-
-import com.google.inject.Inject;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.inject.Inject;
+
 /**
  * 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
@@ -57,25 +57,9 @@ public class UpdateDesiredStackAction extends AbstractServerAction {
   private static final Logger LOG = LoggerFactory.getLogger(UpdateDesiredStackAction.class);
 
   public static final String COMMAND_PARAM_VERSION = VERSION;
-  public static final String COMMAND_DOWNGRADE_FROM_VERSION = "downgrade_from_version";
-  public static final String COMMAND_PARAM_DIRECTION = "upgrade_direction";
   public static final String COMMAND_PARAM_UPGRADE_PACK = "upgrade_pack";
 
   /**
-   * The original "current" stack of the cluster before the upgrade started.
-   * This is the same regardless of whether the current direction is
-   * {@link Direction#UPGRADE} or {@link Direction#DOWNGRADE}.
-   */
-  public static final String COMMAND_PARAM_ORIGINAL_STACK = "original_stack";
-
-  /**
-   * 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}.
-   */
-  public static final String COMMAND_PARAM_TARGET_STACK = "target_stack";
-
-  /**
    * The Cluster that this ServerAction implementation is executing on.
    */
   @Inject
@@ -85,89 +69,75 @@ public class UpdateDesiredStackAction extends AbstractServerAction {
   private AmbariMetaInfo ambariMetaInfo;
 
   /**
-   * The Ambari configuration.
+   * Used for building {@link UpgradeContext} instances.
    */
   @Inject
-  private Configuration m_configuration;
+  UpgradeContextFactory m_upgradeContextFactory;
 
   @Override
   public CommandReport execute(ConcurrentMap<String, Object> requestSharedDataContext)
       throws AmbariException, InterruptedException {
-    Map<String, String> commandParams = getExecutionCommand().getCommandParams();
-
-    StackId originalStackId = new StackId(commandParams.get(COMMAND_PARAM_ORIGINAL_STACK));
-    StackId targetStackId = new StackId(commandParams.get(COMMAND_PARAM_TARGET_STACK));
-    Direction direction = Direction.UPGRADE;
-    if(commandParams.containsKey(COMMAND_PARAM_DIRECTION)
-        && "downgrade".equals(commandParams.get(COMMAND_PARAM_DIRECTION).toLowerCase())) {
-      direction = Direction.DOWNGRADE;
-    }
-    String version = commandParams.get(COMMAND_PARAM_VERSION);
-    String upgradePackName = commandParams.get(COMMAND_PARAM_UPGRADE_PACK);
     String clusterName = getExecutionCommand().getClusterName();
-    UpgradePack upgradePack = ambariMetaInfo.getUpgradePacks(originalStackId.getStackName(), originalStackId.getStackVersion()).get(upgradePackName);
-
-    Map<String, String> roleParams = getExecutionCommand().getRoleParams();
+    Cluster cluster = clusters.getCluster(clusterName);
+    UpgradeContext context = m_upgradeContextFactory.create(cluster,
+        cluster.getUpgradeInProgress());
 
-    // Make a best attempt at setting the username
-    String userName;
-    if (roleParams != null && roleParams.containsKey(ServerAction.ACTION_USER_NAME)) {
-      userName = roleParams.get(ServerAction.ACTION_USER_NAME);
-    } else {
-      userName = m_configuration.getAnonymousAuditName();
-      LOG.warn(String.format("Did not receive role parameter %s, will save configs using anonymous username %s", ServerAction.ACTION_USER_NAME, userName));
-    }
 
     // invalidate any cached effective ID
-    Cluster cluster = clusters.getCluster(clusterName);
     cluster.invalidateUpgradeEffectiveVersion();
 
-    return updateDesiredStack(cluster, originalStackId, targetStackId, version, direction,
-        upgradePack, userName);
+    return updateDesiredStack(cluster, context);
   }
 
   /**
    * Set the cluster's Desired Stack Id during an upgrade.
    *
-   * @param cluster the cluster
-   * @param originalStackId the stack Id of the cluster before the upgrade.
-   * @param targetStackId the stack Id that was desired for this upgrade.
-   * @param direction direction, either upgrade or downgrade
-   * @param upgradePack Upgrade Pack to use
-   * @param userName username performing the action
+   * @param context
+   *          the upgrade context (not {@code null}).
    * @return the command report to return
    */
-  private CommandReport updateDesiredStack(
-      Cluster cluster, StackId originalStackId, StackId targetStackId,
-      String version, Direction direction, UpgradePack upgradePack, String userName)
+  private CommandReport updateDesiredStack(Cluster cluster, UpgradeContext context)
       throws AmbariException, InterruptedException {
 
+    UpgradePack upgradePack = context.getUpgradePack();
+    Direction direction = context.getDirection();
+    RepositoryVersionEntity fromRepositoryVersion = context.getSourceRepositoryVersion();
+    RepositoryVersionEntity toRepositoryVersion = context.getTargetRepositoryVersion();
+
     String clusterName = cluster.getClusterName();
     StringBuilder out = new StringBuilder();
     StringBuilder err = new StringBuilder();
 
     try {
       StackId currentClusterStackId = cluster.getCurrentStackVersion();
-      out.append(String.format("Params: %s %s %s %s %s %s\n",
-          clusterName, originalStackId.getStackId(), targetStackId.getStackId(), version, direction.getText(false), upgradePack.getName()));
+      out.append(String.format("%s %s from %s-%s to %s-%s using %s\n",
+          direction.getVerb(true), clusterName,
+          fromRepositoryVersion.getStackId().getStackName(),
+          fromRepositoryVersion.getVersion(),
+          toRepositoryVersion.getStackId().getStackName(),
+          toRepositoryVersion.getVersion(), upgradePack.getName()));
 
-      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()));
+      out.append(String.format(
+          "Checking if can update the desired stack to %s. The cluster's current stack is %s\n",
+          toRepositoryVersion.getStackId(), currentClusterStackId.getStackId()));
 
       // Ensure that the target stack id exist
+      StackId targetStackId = toRepositoryVersion.getStackId();
       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",
-            COMMAND_PARAM_TARGET_STACK, targetStackId.getStackId());
+        String message = String.format("Invalid target stack of \n", 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.
+      StackId originalStackId = context.getOriginalStackId();
       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", COMMAND_PARAM_ORIGINAL_STACK, originalStackId.getStackId(), currentClusterStackId.getStackId());
+        String message = String.format(
+            "The current cluster stack of %s doesn't match the original upgrade stack of %s",
+            currentClusterStackId, originalStackId);
+
         err.append(message);
         out.append(message);
         return createCommandReport(-1, HostRoleStatus.FAILED, "{}", out.toString(), err.toString());
@@ -175,7 +145,7 @@ public class UpdateDesiredStackAction extends AbstractServerAction {
 
       // 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());
+        String message = String.format("Success! The cluster's desired stack was already set to %s\n", targetStackId.getStackId());
         out.append(message);
         return createCommandReport(0, HostRoleStatus.COMPLETED, "{}", out.toString(), err.toString());
       }
@@ -183,8 +153,8 @@ public class UpdateDesiredStackAction extends AbstractServerAction {
       // Create Create new configurations that are a merge between the current stack and the desired stack
       // Also updates the desired stack version.
       UpgradeResourceProvider upgradeResourceProvider = new UpgradeResourceProvider(AmbariServer.getController());
-      upgradeResourceProvider.applyStackAndProcessConfigurations(targetStackId.getStackName(), cluster, version, direction, upgradePack, userName);
-      String message = String.format("Success! Set cluster's %s Desired Stack Id to %s.\n", clusterName, targetStackId.getStackId());
+      upgradeResourceProvider.applyStackAndProcessConfigurations(context);
+      String message = String.format("Success! Set cluster's %s desired stack to %s.\n", clusterName, targetStackId.getStackId());
       out.append(message);
 
       return createCommandReport(0, HostRoleStatus.COMPLETED, "{}", out.toString(), err.toString());

http://git-wip-us.apache.org/repos/asf/ambari/blob/7ad307c2/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java b/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java
index 56c2b36..b365818 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java
@@ -173,7 +173,11 @@ public interface Cluster {
    *
    * @return the effective cluster stack version given the current upgrading
    *         conditions of the cluster.
+   * 
+   * @deprecated to be removed once the cluster tracks the desired repo instead
+   *             of desired stack id
    */
+  @Deprecated
   ClusterVersionEntity getEffectiveClusterVersion() throws AmbariException;
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/7ad307c2/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 4042089..1bb3d77 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
@@ -32,7 +32,6 @@ import org.apache.ambari.annotations.ExperimentalFeature;
 import org.apache.ambari.server.actionmanager.HostRoleCommandFactory;
 import org.apache.ambari.server.agent.ExecutionCommand.KeyNames;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
-import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
 import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 import org.apache.ambari.server.orm.entities.UpgradeEntity;
 import org.apache.ambari.server.stack.MasterHostResolver;
@@ -105,38 +104,21 @@ public class UpgradeContext {
   private UpgradePack m_upgradePack;
 
   /**
-   * The version being upgrade to or downgraded to.
+   * The source of the upgrade/downgrade.
    */
-  private final String m_version;
+  private final RepositoryVersionEntity m_fromRepositoryVersion;
 
   /**
-   * The original "current" stack of the cluster before the upgrade started.
-   * This is the same regardless of whether the current direction is
-   * {@link Direction#UPGRADE} or {@link Direction#DOWNGRADE}.
-   */
-  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.
+   * The target of the upgrade/downgrade.
    */
-  private StackId m_effectiveStackId;
+  private final RepositoryVersionEntity m_toRepositoryVersion;
 
-  /**
-   * 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}.
-   */
-  private StackId m_targetStackId;
 
   private MasterHostResolver m_resolver;
   private AmbariMetaInfo m_metaInfo;
   private List<ServiceComponentHost> m_unhealthy = new ArrayList<>();
   private Map<String, String> m_serviceNames = new HashMap<>();
   private Map<String, String> m_componentNames = new HashMap<>();
-  private String m_downgradeFromVersion = null;
 
   /**
    * {@code true} if slave/client component failures should be automatically
@@ -176,11 +158,6 @@ public class UpgradeContext {
   private RoleGraphFactory m_roleGraphFactory;
 
   /**
-   * Used to lookup the reposotory version given a stack name and version.
-   */
-  final private RepositoryVersionDAO m_repoVersionDAO;
-
-  /**
    * Used for serializing the upgrade type.
    */
   @Inject
@@ -197,24 +174,19 @@ public class UpgradeContext {
    *          the direction for the upgrade
    * @param upgradeRequestMap
    *          the original map of paramters used to create the upgrade
-   *
-   * @param repoVersionDAO
-   *          the repository version DAO.
    */
   @AssistedInject
   public UpgradeContext(@Assisted Cluster cluster, @Assisted UpgradeType type,
-      @Assisted Direction direction, @Assisted String version,
-      @Assisted Map<String, Object> upgradeRequestMap,
-      RepositoryVersionDAO repoVersionDAO) {
-    m_repoVersionDAO = repoVersionDAO;
+      @Assisted Direction direction,
+      @Assisted("fromRepositoryVersion") RepositoryVersionEntity fromRepositoryVersion,
+      @Assisted("toRepositoryVersion") RepositoryVersionEntity toRepositoryVersion,
+      @Assisted Map<String, Object> upgradeRequestMap) {
     m_cluster = cluster;
     m_type = type;
     m_direction = direction;
-    m_version = version;
+    m_fromRepositoryVersion = fromRepositoryVersion;
+    m_toRepositoryVersion = toRepositoryVersion;
     m_upgradeRequestMap = upgradeRequestMap;
-
-    // sets the original/target stacks - requires direction and cluster
-    setSourceAndTargetStacks();
   }
 
   /**
@@ -224,26 +196,23 @@ public class UpgradeContext {
    *          the cluster that the upgrade is for
    * @param upgradeEntity
    *          the upgrade entity
-   * @param repoVersionDAO
-   *          the repository version DAO.
    */
   @AssistedInject
   public UpgradeContext(@Assisted Cluster cluster, @Assisted UpgradeEntity upgradeEntity,
-      RepositoryVersionDAO repoVersionDAO) {
-    m_repoVersionDAO = repoVersionDAO;
+      AmbariMetaInfo ambariMetaInfo) {
 
+    m_metaInfo = ambariMetaInfo;
     m_cluster = cluster;
     m_type = upgradeEntity.getUpgradeType();
     m_direction = upgradeEntity.getDirection();
 
-    m_version = upgradeEntity.getToVersion();
+    m_fromRepositoryVersion = upgradeEntity.getFromRepositoryVersion();
+    m_toRepositoryVersion = upgradeEntity.getToRepositoryVersion();
 
-    // sets the original/target stacks - requires direction and cluster
-    setSourceAndTargetStacks();
-
-    if (m_direction == Direction.DOWNGRADE) {
-      m_downgradeFromVersion = upgradeEntity.getFromVersion();
-    }
+    String upgradePackage = upgradeEntity.getUpgradePackage();
+    StackId stackId = getOriginalStackId();
+    Map<String, UpgradePack> packs = m_metaInfo.getUpgradePacks(stackId.getStackName(), stackId.getStackVersion());
+    m_upgradePack = packs.get(upgradePackage);
 
     // since this constructor is initialized from an entity, then this map is
     // not present
@@ -251,61 +220,6 @@ public class UpgradeContext {
   }
 
   /**
-   * Sets the source and target stack IDs. This will also set the effective
-   * stack ID based on the already-set {@link UpgradeType} and
-   * {@link Direction}.
-   *
-   * @see #getEffectiveStackId()
-   */
-  private void setSourceAndTargetStacks() {
-    StackId sourceStackId = null;
-
-    // taret stack will not always be what it is today - tagging as experimental
-    @Experimental(feature = ExperimentalFeature.PATCH_UPGRADES)
-    StackId targetStackId = null;
-
-    switch (m_direction) {
-      case UPGRADE:
-        sourceStackId = m_cluster.getCurrentStackVersion();
-
-        RepositoryVersionEntity targetRepositoryVersion = m_repoVersionDAO.findByStackNameAndVersion(
-            sourceStackId.getStackName(), m_version);
-
-        // !!! temporary workaround to get upgrades across stacks to start
-        if (null == targetRepositoryVersion) {
-          targetRepositoryVersion = m_repoVersionDAO.findByVersion(m_version);
-        }
-
-        // !!! TODO check the repo_version for patch-ness and restrict the
-        // context to those services that require it. Consult the version
-        // definition and add the service names to supportedServices
-        targetStackId = targetRepositoryVersion.getStackId();
-        break;
-      case DOWNGRADE:
-        sourceStackId = m_cluster.getCurrentStackVersion();
-        targetStackId = m_cluster.getDesiredStackVersion();
-        break;
-    }
-
-    m_originalStackId = sourceStackId;
-
-    switch (m_type) {
-      case ROLLING:
-      case HOST_ORDERED:
-        m_effectiveStackId = targetStackId;
-        break;
-      case NON_ROLLING:
-        m_effectiveStackId = (m_direction.isUpgrade()) ? sourceStackId : targetStackId;
-        break;
-      default:
-        m_effectiveStackId = targetStackId;
-        break;
-    }
-
-    m_targetStackId = targetStackId;
-  }
-
-  /**
    * Gets the original mapping of key/value pairs from the request which created
    * the upgrade.
    *
@@ -347,8 +261,15 @@ public class UpgradeContext {
   /**
    * @return the target version for the upgrade
    */
-  public String getVersion() {
-    return m_version;
+  public RepositoryVersionEntity getTargetRepositoryVersion() {
+    return m_toRepositoryVersion;
+  }
+
+  /**
+   * @return the source version for the upgrade
+   */
+  public RepositoryVersionEntity getSourceRepositoryVersion() {
+    return m_fromRepositoryVersion;
   }
 
   /**
@@ -404,48 +325,44 @@ public class UpgradeContext {
   }
 
   /**
-   * @return the originalStackId
-   */
-  public StackId getOriginalStackId() {
-    return m_originalStackId;
-  }
-
-  /**
-   * @param originalStackId
-   *          the originalStackId to set
+   * Gets the target stack of the upgrade based on the target repository which
+   * finalization will set.
+   *
+   * @return the target stack (never {@code null}).
    */
-  public void setOriginalStackId(StackId originalStackId) {
-    m_originalStackId = originalStackId;
+  public StackId getTargetStackId() {
+    return m_toRepositoryVersion.getStackId();
   }
 
   /**
-   * @return the effectiveStackId that is currently in use.
+   * Gets the current stack of the components participating in the upgrade.
+   *
+   * @return the source stack (never {@code null}).
    */
-  public StackId getEffectiveStackId() {
-    return m_effectiveStackId;
+  public StackId getSourceStackId() {
+    return m_fromRepositoryVersion.getStackId();
   }
 
   /**
-   * @param effectiveStackId the effectiveStackId to set
+   * @return the originalStackId
    */
-  public void setEffectiveStackId(StackId effectiveStackId) {
-    m_effectiveStackId = effectiveStackId;
+  public StackId getOriginalStackId() {
+    if (m_direction == Direction.UPGRADE) {
+      return m_fromRepositoryVersion.getStackId();
+    } else {
+      return m_toRepositoryVersion.getStackId();
+    }
   }
 
-
   /**
-   * @return the targetStackId
+   * @return the effectiveStackId that is currently in use.
    */
-  public StackId getTargetStackId() {
-    return m_targetStackId;
-  }
+  public StackId getEffectiveStackId() {
+    if (m_type == UpgradeType.NON_ROLLING && m_direction == Direction.UPGRADE) {
+      return m_fromRepositoryVersion.getStackId();
+    }
 
-  /**
-   * @param targetStackId
-   *          the targetStackId to set
-   */
-  public void setTargetStackId(StackId targetStackId) {
-    m_targetStackId = targetStackId;
+    return m_toRepositoryVersion.getStackId();
   }
 
   /**
@@ -490,24 +407,6 @@ public class UpgradeContext {
   }
 
   /**
-   * This method returns the non-finalized version we are downgrading from.
-   *
-   * @return version cluster is downgrading from
-   */
-  public String getDowngradeFromVersion() {
-    return m_downgradeFromVersion;
-  }
-
-  /**
-   * Set the HDP stack version we are downgrading from.
-   *
-   * @param downgradeFromVersion
-   */
-  public void setDowngradeFromVersion(String downgradeFromVersion) {
-    m_downgradeFromVersion = downgradeFromVersion;
-  }
-
-  /**
    * Gets whether skippable components that failed are automatically skipped.
    *
    * @return the skipComponentFailures
@@ -627,11 +526,7 @@ public class UpgradeContext {
    * following properties are already set:
    * <ul>
    * <li>{@link #COMMAND_PARAM_CLUSTER_NAME}
-   * <li>{@link #COMMAND_PARAM_VERSION}
    * <li>{@link #COMMAND_PARAM_DIRECTION}
-   * <li>{@link #COMMAND_PARAM_ORIGINAL_STACK}
-   * <li>{@link #COMMAND_PARAM_TARGET_STACK}
-   * <li>{@link #COMMAND_DOWNGRADE_FROM_VERSION}
    * <li>{@link #COMMAND_PARAM_UPGRADE_TYPE}
    * <li>{@link KeyNames#REFRESH_CONFIG_TAGS_BEFORE_EXECUTION} - necessary in
    * order to have the commands contain the correct configurations. Otherwise,
@@ -647,11 +542,7 @@ public class UpgradeContext {
     Map<String, String> parameters = new HashMap<>();
 
     parameters.put(COMMAND_PARAM_CLUSTER_NAME, m_cluster.getClusterName());
-    parameters.put(COMMAND_PARAM_VERSION, getVersion());
     parameters.put(COMMAND_PARAM_DIRECTION, getDirection().name().toLowerCase());
-    parameters.put(COMMAND_PARAM_ORIGINAL_STACK, getOriginalStackId().getStackId());
-    parameters.put(COMMAND_PARAM_TARGET_STACK, getTargetStackId().getStackId());
-    parameters.put(COMMAND_DOWNGRADE_FROM_VERSION, getDowngradeFromVersion());
 
     if (null != getType()) {
       // use the serialized attributes of the enum to convert it to a string,

http://git-wip-us.apache.org/repos/asf/ambari/blob/7ad307c2/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeContextFactory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeContextFactory.java b/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeContextFactory.java
index 4f15ee2..d482b8a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeContextFactory.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeContextFactory.java
@@ -19,10 +19,13 @@ package org.apache.ambari.server.state;
 
 import java.util.Map;
 
+import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 import org.apache.ambari.server.orm.entities.UpgradeEntity;
 import org.apache.ambari.server.state.stack.upgrade.Direction;
 import org.apache.ambari.server.state.stack.upgrade.UpgradeType;
 
+import com.google.inject.assistedinject.Assisted;
+
 /**
  * The {@link UpgradeContextFactory} is used to create dependency-injected
  * instances of {@link UpgradeContext}s.
@@ -39,9 +42,12 @@ public interface UpgradeContextFactory {
    *          {@code null}).
    * @param direction
    *          the direction for the upgrade
-   * @param version
-   *          the version being upgrade-to or downgraded-from (not
+   * @param fromRepositoryVersion
+   *          the repository where any existing services are coming from
    *          {@code null}).
+   * @param toRepositoryVersion
+   *          the repository which is the target of the finalized
+   *          upgrade/downgrade {@code null}).
    * @param upgradeRequestMap
    *          the original map of parameters used to create the upgrade (not
    *          {@code null}).
@@ -49,7 +55,9 @@ public interface UpgradeContextFactory {
    * @return an initialized {@link UpgradeContext}.
    */
   UpgradeContext create(Cluster cluster, UpgradeType type, Direction direction,
-      String version, Map<String, Object> upgradeRequestMap);
+      @Assisted("fromRepositoryVersion") RepositoryVersionEntity fromRepositoryVersion,
+      @Assisted("toRepositoryVersion") RepositoryVersionEntity toRepositoryVersion,
+      Map<String, Object> upgradeRequestMap);
 
   /**
    * Creates an {@link UpgradeContext} which is injected with dependencies.

http://git-wip-us.apache.org/repos/asf/ambari/blob/7ad307c2/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 4cdccdd..69663fb 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
@@ -211,6 +211,9 @@ public class UpgradeHelper {
     }
 
     RepositoryVersionEntity versionEntity = s_repoVersionDAO.get().findByStackNameAndVersion(stack.getStackName(), repoVersion);
+    if (null == versionEntity) {
+      versionEntity = s_repoVersionDAO.get().findByVersion(repoVersion);
+    }
 
     if (versionEntity == null) {
       throw new AmbariException(String.format("Repository version %s was not found", repoVersion));
@@ -406,7 +409,7 @@ public class UpgradeHelper {
               case ROLLING:
                 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);
@@ -428,17 +431,17 @@ public class UpgradeHelper {
                   // So need to make 2 stages, and add different parameters to each one.
 
                   HostsType ht1 = new HostsType();
-                  LinkedHashSet<String> h1Hosts = new LinkedHashSet<String>();
+                  LinkedHashSet<String> h1Hosts = new LinkedHashSet<>();
                   h1Hosts.add(hostsType.master);
                   ht1.hosts = h1Hosts;
-                  Map<String, String> h1Params = new HashMap<String, String>();
+                  Map<String, String> h1Params = new HashMap<>();
                   h1Params.put("desired_namenode_role", "active");
 
                   HostsType ht2 = new HostsType();
-                  LinkedHashSet<String> h2Hosts = new LinkedHashSet<String>();
+                  LinkedHashSet<String> h2Hosts = new LinkedHashSet<>();
                   h2Hosts.add(hostsType.secondary);
                   ht2.hosts = h2Hosts;
-                  Map<String, String> h2Params = new HashMap<String, String>();
+                  Map<String, String> h2Params = new HashMap<>();
                   h2Params.put("desired_namenode_role", "standby");
 
 
@@ -538,7 +541,7 @@ public class UpgradeHelper {
   private String tokenReplace(UpgradeContext ctx, String source, String service, String component) {
     Cluster cluster = ctx.getCluster();
     MasterHostResolver mhr = ctx.getResolver();
-    String version = ctx.getVersion();
+    String version = ctx.getTargetRepositoryVersion().getVersion();
 
     String result = source;
 
@@ -722,17 +725,19 @@ public class UpgradeHelper {
    * the upgrade state individually, we wrap this method inside of a transaction
    * to prevent 1000's of transactions from being opened and committed.
    *
+   * @param stackId
+   *          the desired stack ID for the upgrade
    * @param version
    *          desired version (like 2.2.1.0-1234) for upgrade
    * @param targetServices
    *          targets for upgrade
    * @param targetStack
-   *          the target stack for the components.  Express and Rolling upgrades determine
-   *          the "correct" stack differently, so the component's desired stack id is not
-   *          a reliable indicator.
+   *          the target stack for the components. Express and Rolling upgrades
+   *          determine the "correct" stack differently, so the component's
+   *          desired stack id is not a reliable indicator.
    */
   @Transactional
-  public void putComponentsToUpgradingState(String version,
+  public void putComponentsToUpgradingState(StackId stackId, String version,
       Map<Service, Set<ServiceComponent>> targetServices, StackId targetStack) throws AmbariException {
 
     for (Map.Entry<Service, Set<ServiceComponent>> entry: targetServices.entrySet()) {
@@ -768,6 +773,8 @@ public class UpgradeHelper {
             serviceComponentHost.setVersion(StackVersionListener.UNKNOWN_VERSION);
           }
         }
+
+        serviceComponent.setDesiredStackVersion(stackId);
         serviceComponent.setDesiredVersion(desiredVersion);
 
       }

http://git-wip-us.apache.org/repos/asf/ambari/blob/7ad307c2/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
index a9e33f0..c4f28b2 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
@@ -145,6 +145,7 @@ import org.apache.ambari.server.state.fsm.InvalidStateTransitionException;
 import org.apache.ambari.server.state.scheduler.RequestExecution;
 import org.apache.ambari.server.state.scheduler.RequestExecutionFactory;
 import org.apache.ambari.server.state.stack.upgrade.Direction;
+import org.apache.ambari.server.state.stack.upgrade.UpgradeType;
 import org.apache.ambari.server.state.svccomphost.ServiceComponentHostSummary;
 import org.apache.ambari.server.topology.TopologyRequest;
 import org.apache.commons.collections.CollectionUtils;
@@ -1038,23 +1039,17 @@ public class ClusterImpl implements Cluster {
     Long upgradeId = upgradeEntity.getId();
     String effectiveVersion = upgradeEffectiveVersionCache.get(upgradeId);
     if (null == effectiveVersion) {
-      switch (upgradeEntity.getUpgradeType()) {
-        case NON_ROLLING:
-          if (upgradeEntity.getDirection() == Direction.UPGRADE) {
-            boolean pastChangingStack = isNonRollingUpgradePastUpgradingStack(upgradeEntity);
-            effectiveVersion = pastChangingStack ? upgradeEntity.getToVersion()
-                : upgradeEntity.getFromVersion();
-          } else {
-            // Should be the lower value during a Downgrade.
-            effectiveVersion = upgradeEntity.getToVersion();
-          }
-          break;
-        case ROLLING:
-        default:
-          // Version will be higher on upgrade and lower on downgrade
-          // directions.
-          effectiveVersion = upgradeEntity.getToVersion();
-          break;
+      if(upgradeEntity.getUpgradeType() != UpgradeType.ROLLING){
+        effectiveVersion = upgradeEntity.getToRepositoryVersion().getVersion();
+      } else {
+        if (upgradeEntity.getDirection() == Direction.UPGRADE) {
+          boolean pastChangingStack = isNonRollingUpgradePastUpgradingStack(upgradeEntity);
+          effectiveVersion = pastChangingStack ? upgradeEntity.getToRepositoryVersion().getVersion()
+              : upgradeEntity.getFromRepositoryVersion().getVersion();
+        } else {
+          // Should be the lower value during a Downgrade.
+          effectiveVersion = upgradeEntity.getToRepositoryVersion().getVersion();
+        }
       }
 
       // cache for later use
@@ -1062,7 +1057,8 @@ public class ClusterImpl implements Cluster {
     }
 
     if (effectiveVersion == null) {
-      throw new AmbariException("Unable to determine which version to use during Stack Upgrade, effectiveVersion is null.");
+      throw new AmbariException(
+          "Unable to determine which version to use during Stack Upgrade, effectiveVersion is null.");
     }
 
     // Find the first cluster version whose repo matches the expected version.

http://git-wip-us.apache.org/repos/asf/ambari/blob/7ad307c2/ambari-server/src/main/java/org/apache/ambari/server/state/services/RetryUpgradeActionService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/services/RetryUpgradeActionService.java b/ambari-server/src/main/java/org/apache/ambari/server/state/services/RetryUpgradeActionService.java
index 584ce98..91898dc 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/services/RetryUpgradeActionService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/services/RetryUpgradeActionService.java
@@ -178,9 +178,11 @@ public class RetryUpgradeActionService extends AbstractScheduledService {
       LOG.debug("There is no active stack upgrade in progress. Skip retrying failed tasks.");
       return null;
     }
+
     LOG.debug("Found an active stack upgrade with id: {}, direction: {}, type: {}, from version: {}, to version: {}",
         currentUpgrade.getId(), currentUpgrade.getDirection(), currentUpgrade.getUpgradeType(),
-        currentUpgrade.getFromVersion(), currentUpgrade.getToVersion());
+        currentUpgrade.getFromRepositoryVersion().getVersion(),
+        currentUpgrade.getToRepositoryVersion().getVersion());
 
     return currentUpgrade.getRequestId();
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/7ad307c2/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/HostOrderGrouping.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/HostOrderGrouping.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/HostOrderGrouping.java
index 97864a6..9ca0d4e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/HostOrderGrouping.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/HostOrderGrouping.java
@@ -175,7 +175,8 @@ public class HostOrderGrouping extends Grouping {
           if (null != hostsType && !hostsType.hosts.contains(hostName)) {
             LOG.warn("Host {} could not be orchestrated. Either there are no components for {}/{} " +
                 "or the target version {} is already current.",
-                hostName, sch.getServiceName(), sch.getServiceComponentName(), upgradeContext.getVersion());
+                hostName, sch.getServiceName(), sch.getServiceComponentName(),
+                upgradeContext.getTargetRepositoryVersion().getVersion());
             continue;
           }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/7ad307c2/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog220.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog220.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog220.java
index d806dde..8ee7943 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog220.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog220.java
@@ -244,7 +244,7 @@ public class UpgradeCatalog220 extends AbstractUpgradeCatalog {
   }
 
   private void addKerberosDescriptorTable() throws SQLException {
-    List<DBAccessor.DBColumnInfo> columns = new ArrayList<DBAccessor.DBColumnInfo>();
+    List<DBAccessor.DBColumnInfo> columns = new ArrayList<>();
     columns.add(new DBAccessor.DBColumnInfo(KERBEROS_DESCRIPTOR_NAME_COLUMN, String.class, 255, null, false));
     columns.add(new DBAccessor.DBColumnInfo(KERBEROS_DESCRIPTOR_COLUMN, char[].class, null, null, false));
 
@@ -315,8 +315,8 @@ public class UpgradeCatalog220 extends AbstractUpgradeCatalog {
       upgradeDAO.merge(upgrade);
 
       LOG.info(String.format("Updated upgrade id %s, upgrade pack %s from version %s to %s",
-        upgrade.getId(), upgrade.getUpgradePackage(), upgrade.getFromVersion(),
-        upgrade.getToVersion()));
+        upgrade.getId(), upgrade.getUpgradePackage(), upgrade.getFromRepositoryVersion().getVersion(),
+          upgrade.getToRepositoryVersion().getVersion()));
     }
 
     // make the columns nullable now that they have defaults
@@ -1026,7 +1026,7 @@ public class UpgradeCatalog220 extends AbstractUpgradeCatalog {
 
       Config hiveEnvConfig = cluster.getDesiredConfigByType(HIVE_ENV_CONFIG);
       if (hiveEnvConfig != null) {
-        Map<String, String> hiveEnvProps = new HashMap<String, String>();
+        Map<String, String> hiveEnvProps = new HashMap<>();
         String content = hiveEnvConfig.getProperties().get(CONTENT_PROPERTY);
         // For HDP-2.3 we need to add hive heap size management to content,
         // for others we need to update content
@@ -1396,7 +1396,7 @@ public class UpgradeCatalog220 extends AbstractUpgradeCatalog {
         if (clientProps != null) {
           Map<String, String> properties = clientProps.getProperties();
           if (properties == null) {
-            properties = new HashMap<String, String>();
+            properties = new HashMap<>();
           }
           // <2.2.0 did not account for a custom service principal.
           // Need to ensure that the client knows the server's principal (the primary) to properly authenticate.