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/05/16 16:45:28 UTC

[5/5] ambari git commit: AMBARI-21022 - Upgrades Should Be Associated With Repositories Instead of String Versions (jonathanhurley)

AMBARI-21022 - Upgrades Should Be Associated With Repositories Instead of String Versions (jonathanhurley)


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

Branch: refs/heads/branch-feature-AMBARI-12556
Commit: 522039ebd3f259c2a54db5102108209b94d5d004
Parents: 87e8bdf
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Mon May 15 13:32:05 2017 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Tue May 16 12:45:14 2017 -0400

----------------------------------------------------------------------
 .../actionmanager/ExecutionCommandWrapper.java  |  32 +
 .../ambari/server/agent/ExecutionCommand.java   |  21 +-
 .../alerts/ComponentVersionAlertRunnable.java   |   6 +-
 .../request/AddUpgradeRequestAuditEvent.java    |  10 +-
 .../eventcreator/UpgradeEventCreator.java       |   2 +-
 .../server/checks/PreviousUpgradeCompleted.java |   7 +-
 .../AmbariCustomCommandExecutionHelper.java     |  49 +-
 .../AmbariManagementControllerImpl.java         |  15 +-
 .../AbstractControllerResourceProvider.java     |   2 +-
 .../internal/UpgradeResourceProvider.java       | 708 +++-----------
 .../dao/ServiceComponentDesiredStateDAO.java    |  52 -
 .../ServiceComponentDesiredStateEntity.java     |  36 -
 .../entities/ServiceComponentHistoryEntity.java | 181 ----
 .../server/orm/entities/UpgradeEntity.java      | 165 ++--
 .../orm/entities/UpgradeHistoryEntity.java      | 232 +++++
 .../upgrades/AbstractUpgradeServerAction.java   |  41 -
 .../upgrades/ComponentVersionCheckAction.java   |  14 +-
 .../upgrades/FinalizeUpgradeAction.java         | 292 +++---
 .../upgrades/UpdateDesiredStackAction.java      |  91 +-
 .../ambari/server/stack/MasterHostResolver.java |  56 +-
 .../ambari/server/state/UpgradeContext.java     | 956 +++++++++++++------
 .../server/state/UpgradeContextFactory.java     |  15 +-
 .../ambari/server/state/UpgradeHelper.java      |  37 +-
 .../services/RetryUpgradeActionService.java     |  15 +-
 .../server/state/stack/upgrade/Direction.java   |   9 +
 .../state/stack/upgrade/HostOrderGrouping.java  |  15 +-
 .../server/upgrade/UpgradeCatalog220.java       |   4 +-
 .../main/resources/Ambari-DDL-Derby-CREATE.sql  |  27 +-
 .../main/resources/Ambari-DDL-MySQL-CREATE.sql  |  25 +-
 .../main/resources/Ambari-DDL-Oracle-CREATE.sql |  31 +-
 .../resources/Ambari-DDL-Postgres-CREATE.sql    |  27 +-
 .../resources/Ambari-DDL-SQLAnywhere-CREATE.sql |  31 +-
 .../resources/Ambari-DDL-SQLServer-CREATE.sql   |  27 +-
 .../src/main/resources/META-INF/persistence.xml |   2 +-
 .../ComponentVersionAlertRunnableTest.java      |   3 +-
 .../creator/UpgradeEventCreatorTest.java        |   4 +-
 .../checks/PreviousUpgradeCompletedTest.java    |   8 +-
 .../StackUpgradeConfigurationMergeTest.java     |  13 +-
 .../internal/UpgradeResourceProviderTest.java   |  73 +-
 .../UpgradeSummaryResourceProviderTest.java     |  14 +-
 .../ambari/server/orm/dao/UpgradeDAOTest.java   |  26 +-
 .../ComponentVersionCheckActionTest.java        |  21 +-
 .../upgrades/UpgradeActionTest.java             | 123 +--
 .../server/state/ServiceComponentTest.java      | 175 ----
 .../ambari/server/state/UpgradeHelperTest.java  | 446 ++++++---
 .../services/RetryUpgradeActionServiceTest.java |   3 +-
 .../stack/upgrade/StageWrapperBuilderTest.java  |  30 +-
 47 files changed, 2012 insertions(+), 2160 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/522039eb/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 fe6707e..f680c09 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
@@ -25,11 +25,16 @@ 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.RepositoryVersionEntity;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.ConfigHelper;
 import org.apache.ambari.server.state.DesiredConfig;
+import org.apache.ambari.server.state.Service;
+import org.apache.ambari.server.state.ServiceComponent;
+import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -176,6 +181,33 @@ public class ExecutionCommandWrapper {
                 executionCommand.getConfigurationAttributes().get(type));
             }
         }
+
+        // set the repository version for the component this command is for -
+        // always use the current desired version
+        RepositoryVersionEntity repositoryVersion = null;
+        String serviceName = executionCommand.getServiceName();
+        if (!StringUtils.isEmpty(serviceName)) {
+          Service service = cluster.getService(serviceName);
+          if (null != service) {
+            repositoryVersion = service.getDesiredRepositoryVersion();
+          }
+
+          String componentName = executionCommand.getComponentName();
+          if (!StringUtils.isEmpty(componentName)) {
+            ServiceComponent serviceComponent = service.getServiceComponent(
+                executionCommand.getComponentName());
+
+            if (null != serviceComponent) {
+              repositoryVersion = serviceComponent.getDesiredRepositoryVersion();
+            }
+          }
+        }
+
+        if (null != repositoryVersion) {
+          executionCommand.getCommandParams().put(KeyNames.VERSION, repositoryVersion.getVersion());
+          executionCommand.getHostLevelParams().put(KeyNames.CURRENT_VERSION, repositoryVersion.getVersion());
+        }
+
       }
     } catch (ClusterNotFoundException cnfe) {
       // it's possible that there are commands without clusters; in such cases,

http://git-wip-us.apache.org/repos/asf/ambari/blob/522039eb/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
index 4ab50ea..d8a4b1e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
@@ -158,7 +158,7 @@ public class ExecutionCommand extends AgentCommand {
   }
 
   public Map<String, Map<String, String>> getConfigurationCredentials() {
-    return this.configurationCredentials;
+    return configurationCredentials;
   }
 
   public String getCommandId() {
@@ -462,7 +462,6 @@ public class ExecutionCommand extends AgentCommand {
     String GROUP_LIST = "group_list";
     String USER_GROUPS = "user_groups";
     String NOT_MANAGED_HDFS_PATH_LIST = "not_managed_hdfs_path_list";
-    String VERSION = "version";
     String REFRESH_TOPOLOGY = "refresh_topology";
     String HOST_SYS_PREPPED = "host_sys_prepped";
     String MAX_DURATION_OF_RETRIES = "max_duration_for_retries";
@@ -504,8 +503,24 @@ public class ExecutionCommand extends AgentCommand {
     String REPO_VERSION_ID = "repository_version_id";
 
     /**
-     * Put on hostLevelParams to indicate the version that the component should be.
+     * The version of the component to send down with the command. Normally,
+     * this is simply the repository version of the component. However, during
+     * ugprades, this value may change depending on the progress of the upgrade
+     * and the type/direction.
+     */
+    @Experimental(
+        feature = ExperimentalFeature.PATCH_UPGRADES,
+        comment = "Change this to reflect the component version")
+    String VERSION = "version";
+
+    /**
+     * Put on hostLevelParams to indicate the version that the component should
+     * be.
      */
+    @Deprecated
+    @Experimental(
+        feature = ExperimentalFeature.PATCH_UPGRADES,
+        comment = "This should be replaced by a map of all service component versions")
     String CURRENT_VERSION = "current_version";
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/522039eb/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 ec5c85e..6bdcf0c 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
@@ -39,6 +39,7 @@ 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.stack.upgrade.Direction;
 import org.apache.commons.lang.StringUtils;
 
 import com.google.inject.Inject;
@@ -63,7 +64,7 @@ public class ComponentVersionAlertRunnable extends AlertRunnable {
   /**
    * The message for the alert when there is an upgrade in progress.
    */
-  private static final String UPGRADE_IN_PROGRESS_MSG = "This alert will be suspended while the upgrade to {0} is in progress.";
+  private static final String UPGRADE_IN_PROGRESS_MSG = "This alert will be suspended while the {0} is in progress.";
 
   /**
    * The unknown component error message.
@@ -95,7 +96,8 @@ 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());
+      Direction direction = upgrade.getDirection();
+      String message = MessageFormat.format(UPGRADE_IN_PROGRESS_MSG, direction.getText(false));
 
       return Collections.singletonList(
           buildAlert(cluster, myDefinition, AlertState.SKIPPED, message));

http://git-wip-us.apache.org/repos/asf/ambari/blob/522039eb/ambari-server/src/main/java/org/apache/ambari/server/audit/event/request/AddUpgradeRequestAuditEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/audit/event/request/AddUpgradeRequestAuditEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/audit/event/request/AddUpgradeRequestAuditEvent.java
index 2c6df7b..215c232 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/audit/event/request/AddUpgradeRequestAuditEvent.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/audit/event/request/AddUpgradeRequestAuditEvent.java
@@ -33,7 +33,7 @@ public class AddUpgradeRequestAuditEvent extends RequestAuditEvent {
     /**
      * Repository version
      */
-    private String repositoryVersion;
+    private String repositoryVersionId;
 
     /**
      * Upgrade type (rolling, non-rolling)
@@ -65,8 +65,8 @@ public class AddUpgradeRequestAuditEvent extends RequestAuditEvent {
     protected void buildAuditMessage(StringBuilder builder) {
       super.buildAuditMessage(builder);
 
-      builder.append(", Repository version(")
-        .append(repositoryVersion)
+      builder.append(", Repository version ID(")
+        .append(repositoryVersionId)
         .append("), Upgrade type(")
         .append(upgradeType)
         .append("), Cluster name(")
@@ -74,8 +74,8 @@ public class AddUpgradeRequestAuditEvent extends RequestAuditEvent {
         .append(")");
     }
 
-    public AddUpgradeRequestAuditEventBuilder withRepositoryVersion(String repositoryVersion) {
-      this.repositoryVersion = repositoryVersion;
+    public AddUpgradeRequestAuditEventBuilder withRepositoryVersionId(String repositoryVersionId) {
+      this.repositoryVersionId = repositoryVersionId;
       return this;
     }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/522039eb/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/UpgradeEventCreator.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/UpgradeEventCreator.java b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/UpgradeEventCreator.java
index 456aa00..db4549f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/UpgradeEventCreator.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/UpgradeEventCreator.java
@@ -83,7 +83,7 @@ public class UpgradeEventCreator implements RequestAuditEventCreator {
       .withResultStatus(result.getStatus())
       .withUrl(request.getURI())
       .withRemoteIp(request.getRemoteAddress())
-      .withRepositoryVersion(RequestAuditEventCreatorHelper.getProperty(request, UpgradeResourceProvider.UPGRADE_VERSION))
+      .withRepositoryVersionId(RequestAuditEventCreatorHelper.getProperty(request, UpgradeResourceProvider.UPGRADE_REPO_VERSION_ID))
       .withUpgradeType(RequestAuditEventCreatorHelper.getProperty(request, UpgradeResourceProvider.UPGRADE_TYPE))
       .withClusterName(RequestAuditEventCreatorHelper.getProperty(request, UpgradeResourceProvider.UPGRADE_CLUSTER_NAME))
       .build();

http://git-wip-us.apache.org/repos/asf/ambari/blob/522039eb/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 ef165a5..0292b72 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
@@ -46,7 +46,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} {1} {2} which has not completed. This {3} must be completed before a new upgrade or downgrade can begin.";
 
   /**
    * Constructor.
@@ -65,9 +65,10 @@ public class PreviousUpgradeCompleted extends AbstractCheckDescriptor {
     if (null != upgradeInProgress) {
       Direction direction = upgradeInProgress.getDirection();
       String directionText = direction.getText(false);
+      String prepositionText = direction.getPreposition();
 
-      errorMessage = MessageFormat.format(ERROR_MESSAGE, directionText,
-          upgradeInProgress.getFromVersion(), upgradeInProgress.getToVersion(), directionText);
+      errorMessage = MessageFormat.format(ERROR_MESSAGE, directionText, prepositionText,
+          upgradeInProgress.getRepositoryVersion().getVersion(), directionText);
     }
 
     if (null != errorMessage) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/522039eb/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 617d7c0..397c1c2 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
@@ -480,19 +480,6 @@ public class AmbariCustomCommandExecutionHelper {
       commandParams.put(SERVICE_PACKAGE_FOLDER, serviceInfo.getServicePackageFolder());
       commandParams.put(HOOKS_FOLDER, stackInfo.getStackHooksFolder());
 
-      RepositoryVersionEntity repoVersion = null;
-      if (null != component) {
-        repoVersion = component.getDesiredRepositoryVersion();
-      }
-
-      if (null == repoVersion && null != clusterService) {
-        repoVersion = clusterService.getDesiredRepositoryVersion();
-      }
-
-      if (repoVersion != null) {
-       commandParams.put(KeyNames.VERSION, repoVersion.getVersion());
-      }
-
       Map<String, String> roleParams = execCmd.getRoleParams();
       if (roleParams == null) {
         roleParams = new TreeMap<>();
@@ -1396,18 +1383,23 @@ public class AmbariCustomCommandExecutionHelper {
    * @return a wrapper of the imporant JSON structures to add to a stage
    */
   public ExecuteCommandJson getCommandJson(ActionExecutionContext actionExecContext,
-      Cluster cluster, StackId stackId) throws AmbariException {
+      Cluster cluster, RepositoryVersionEntity repositoryVersion) throws AmbariException {
 
     Map<String, String> commandParamsStage = StageUtils.getCommandParamsStage(actionExecContext);
     Map<String, String> hostParamsStage = new HashMap<>();
     Map<String, Set<String>> clusterHostInfo;
     String clusterHostInfoJson = "{}";
 
+    StackId stackId = null;
+    if (null != repositoryVersion) {
+      stackId = repositoryVersion.getStackId();
+    }
+
     if (null != cluster) {
       clusterHostInfo = StageUtils.getClusterHostInfo(cluster);
 
       // Important, because this runs during Stack Uprade, it needs to use the effective Stack Id.
-      hostParamsStage = createDefaultHostParams(cluster, null);
+      hostParamsStage = createDefaultHostParams(cluster, repositoryVersion);
 
       String componentName = null;
       String serviceName = null;
@@ -1416,7 +1408,7 @@ public class AmbariCustomCommandExecutionHelper {
         serviceName = actionExecContext.getOperationLevel().getServiceName();
       }
 
-      if (serviceName != null && componentName != null) {
+      if (serviceName != null && componentName != null && null != stackId) {
         ComponentInfo componentInfo = ambariMetaInfo.getComponent(
                 stackId.getStackName(), stackId.getStackVersion(),
                 serviceName, componentName);
@@ -1428,17 +1420,22 @@ public class AmbariCustomCommandExecutionHelper {
         String clientsToUpdateConfigs = gson.toJson(clientsToUpdateConfigsList);
         hostParamsStage.put(CLIENTS_TO_UPDATE_CONFIGS, clientsToUpdateConfigs);
       }
+
       clusterHostInfoJson = StageUtils.getGson().toJson(clusterHostInfo);
 
       //Propogate HCFS service type info to command params
-      Map<String, ServiceInfo> serviceInfos = ambariMetaInfo.getServices(stackId.getStackName(), stackId.getStackVersion());
-      for (ServiceInfo serviceInfoInstance : serviceInfos.values()) {
-        if (serviceInfoInstance.getServiceType() != null) {
-          LOG.debug("Adding {} to command parameters for {}", serviceInfoInstance.getServiceType(),
-              serviceInfoInstance.getName());
-
-          commandParamsStage.put("dfs_type", serviceInfoInstance.getServiceType());
-          break;
+      if (null != stackId) {
+        Map<String, ServiceInfo> serviceInfos = ambariMetaInfo.getServices(stackId.getStackName(),
+            stackId.getStackVersion());
+
+        for (ServiceInfo serviceInfoInstance : serviceInfos.values()) {
+          if (serviceInfoInstance.getServiceType() != null) {
+            LOG.debug("Adding {} to command parameters for {}",
+                serviceInfoInstance.getServiceType(), serviceInfoInstance.getName());
+
+            commandParamsStage.put("dfs_type", serviceInfoInstance.getServiceType());
+            break;
+          }
         }
       }
     }
@@ -1482,10 +1479,6 @@ public class AmbariCustomCommandExecutionHelper {
     String notManagedHdfsPathList = gson.toJson(notManagedHdfsPathSet);
     hostLevelParams.put(NOT_MANAGED_HDFS_PATH_LIST, notManagedHdfsPathList);
 
-    if (null != repositoryVersion) {
-      hostLevelParams.put(KeyNames.CURRENT_VERSION, repositoryVersion.getVersion());
-    }
-
     for (Map.Entry<String, String> dbConnectorName : configs.getDatabaseConnectorNames().entrySet()) {
       hostLevelParams.put(dbConnectorName.getKey(), dbConnectorName.getValue());
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/522039eb/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 882f583..a4f59a5 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
@@ -3988,12 +3988,19 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
         actionManager,
         actionRequest);
 
-    StackId stackId = null;
-    if (null != cluster) {
-      stackId = cluster.getDesiredStackVersion();
+    RepositoryVersionEntity desiredRepositoryVersion = null;
+
+    RequestOperationLevel operationLevel = actionExecContext.getOperationLevel();
+    if (null != operationLevel) {
+      Service service = cluster.getService(operationLevel.getServiceName());
+      if (null != service) {
+        desiredRepositoryVersion = service.getDesiredRepositoryVersion();
+      }
     }
 
-    ExecuteCommandJson jsons = customCommandExecutionHelper.getCommandJson(actionExecContext, cluster, stackId);
+    ExecuteCommandJson jsons = customCommandExecutionHelper.getCommandJson(actionExecContext,
+        cluster, desiredRepositoryVersion);
+
     String commandParamsForStage = jsons.getCommandParamsForStage();
 
     Map<String, String> commandParamsStage = gson.fromJson(commandParamsForStage, new TypeToken<Map<String, String>>()

http://git-wip-us.apache.org/repos/asf/ambari/blob/522039eb/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
index a762e2b..77e6250 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
@@ -266,7 +266,7 @@ public abstract class AbstractControllerResourceProvider extends AbstractAuthori
    *
    * @return resource provider for the specified type
    */
-  ResourceProvider getResourceProvider(Resource.Type type) {
+  public static ResourceProvider getResourceProvider(Resource.Type type) {
     return ((ClusterControllerImpl) ClusterControllerHelper.getClusterController()).
         ensureResourceProvider(type);
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/522039eb/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 7ca6164..c3691bf 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
@@ -23,13 +23,11 @@ import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SERVICE_P
 import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -65,8 +63,6 @@ import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
 import org.apache.ambari.server.controller.spi.SystemException;
 import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
-import org.apache.ambari.server.controller.utilities.PredicateBuilder;
-import org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.apache.ambari.server.orm.dao.HostRoleCommandDAO;
 import org.apache.ambari.server.orm.dao.HostRoleCommandStatusSummaryDTO;
 import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
@@ -78,20 +74,20 @@ import org.apache.ambari.server.orm.entities.RequestEntity;
 import org.apache.ambari.server.orm.entities.StackEntity;
 import org.apache.ambari.server.orm.entities.UpgradeEntity;
 import org.apache.ambari.server.orm.entities.UpgradeGroupEntity;
+import org.apache.ambari.server.orm.entities.UpgradeHistoryEntity;
 import org.apache.ambari.server.orm.entities.UpgradeItemEntity;
 import org.apache.ambari.server.security.authorization.AuthorizationException;
 import org.apache.ambari.server.security.authorization.AuthorizationHelper;
 import org.apache.ambari.server.security.authorization.ResourceType;
 import org.apache.ambari.server.security.authorization.RoleAuthorization;
 import org.apache.ambari.server.serveraction.upgrades.UpdateDesiredStackAction;
-import org.apache.ambari.server.stack.MasterHostResolver;
 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.DesiredConfig;
-import org.apache.ambari.server.state.Host;
-import org.apache.ambari.server.state.RepositoryType;
+import org.apache.ambari.server.state.Service;
+import org.apache.ambari.server.state.ServiceComponent;
 import org.apache.ambari.server.state.ServiceInfo;
 import org.apache.ambari.server.state.StackId;
 import org.apache.ambari.server.state.StackInfo;
@@ -99,33 +95,26 @@ import org.apache.ambari.server.state.UpgradeContext;
 import org.apache.ambari.server.state.UpgradeContextFactory;
 import org.apache.ambari.server.state.UpgradeHelper;
 import org.apache.ambari.server.state.UpgradeHelper.UpgradeGroupHolder;
-import org.apache.ambari.server.state.repository.VersionDefinitionXml;
 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;
 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.HostOrderGrouping;
-import org.apache.ambari.server.state.stack.upgrade.HostOrderItem;
-import org.apache.ambari.server.state.stack.upgrade.HostOrderItem.HostOrderActionType;
 import org.apache.ambari.server.state.stack.upgrade.ManualTask;
 import org.apache.ambari.server.state.stack.upgrade.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;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang.StringUtils;
+import org.codehaus.jackson.annotate.JsonProperty;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
-import com.google.gson.Gson;
 import com.google.gson.JsonArray;
 import com.google.gson.JsonObject;
 import com.google.inject.Inject;
@@ -140,12 +129,12 @@ import com.google.inject.persist.Transactional;
 public class UpgradeResourceProvider extends AbstractControllerResourceProvider {
 
   public static final String UPGRADE_CLUSTER_NAME = "Upgrade/cluster_name";
-  public static final String UPGRADE_VERSION = "Upgrade/repository_version";
+  public static final String UPGRADE_REPO_VERSION_ID = "Upgrade/repository_version_id";
   public static final String UPGRADE_TYPE = "Upgrade/upgrade_type";
   public static final String UPGRADE_PACK = "Upgrade/pack";
   public static final String UPGRADE_REQUEST_ID = "Upgrade/request_id";
-  public static final String UPGRADE_FROM_VERSION = "Upgrade/from_version";
-  public static final String UPGRADE_TO_VERSION = "Upgrade/to_version";
+  public static final String UPGRADE_ASSOCIATED_VERSION = "Upgrade/associated_version";
+  public static final String UPGRADE_VERSIONS = "Upgrade/versions";
   public static final String UPGRADE_DIRECTION = "Upgrade/direction";
   public static final String UPGRADE_DOWNGRADE_ALLOWED = "Upgrade/downgrade_allowed";
   public static final String UPGRADE_REQUEST_STATUS = "Upgrade/request_status";
@@ -154,7 +143,6 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
   public static final String UPGRADE_SKIP_PREREQUISITE_CHECKS = "Upgrade/skip_prerequisite_checks";
   public static final String UPGRADE_FAIL_ON_CHECK_WARNINGS = "Upgrade/fail_on_check_warnings";
 
-
   /**
    * Names that appear in the Upgrade Packs that are used by
    * {@link org.apache.ambari.server.state.cluster.ClusterImpl#isNonRollingUpgradePastUpgradingStack}
@@ -169,17 +157,17 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
   /**
    * Skip slave/client component failures if the tasks are skippable.
    */
-  protected static final String UPGRADE_SKIP_FAILURES = "Upgrade/skip_failures";
+  public static final String UPGRADE_SKIP_FAILURES = "Upgrade/skip_failures";
 
   /**
    * Skip service check failures if the tasks are skippable.
    */
-  protected static final String UPGRADE_SKIP_SC_FAILURES = "Upgrade/skip_service_check_failures";
+  public static final String UPGRADE_SKIP_SC_FAILURES = "Upgrade/skip_service_check_failures";
 
   /**
    * Skip manual verification tasks for hands-free upgrade/downgrade experience.
    */
-  protected static final String UPGRADE_SKIP_MANUAL_VERIFICATION = "Upgrade/skip_manual_verification";
+  public static final String UPGRADE_SKIP_MANUAL_VERIFICATION = "Upgrade/skip_manual_verification";
 
   /**
    * When creating an upgrade of type {@link UpgradeType#HOST_ORDERED}, this
@@ -200,7 +188,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
    * </pre>
    *
    */
-  protected static final String UPGRADE_HOST_ORDERED_HOSTS = "Upgrade/host_order";
+  public static final String UPGRADE_HOST_ORDERED_HOSTS = "Upgrade/host_order";
 
   /*
    * Lifted from RequestResourceProvider
@@ -217,6 +205,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
 
   private static final Set<String> PK_PROPERTY_IDS = new HashSet<>(
       Arrays.asList(UPGRADE_REQUEST_ID, UPGRADE_CLUSTER_NAME));
+
   private static final Set<String> PROPERTY_IDS = new HashSet<>();
 
   /**
@@ -267,9 +256,6 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
   @Inject
   private static Configuration s_configuration;
 
-  @Inject
-  private static Gson s_gson;
-
   /**
    * Used to create instances of {@link UpgradeContext} with injected
    * dependencies.
@@ -280,12 +266,12 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
   static {
     // properties
     PROPERTY_IDS.add(UPGRADE_CLUSTER_NAME);
-    PROPERTY_IDS.add(UPGRADE_VERSION);
+    PROPERTY_IDS.add(UPGRADE_REPO_VERSION_ID);
     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);
+    PROPERTY_IDS.add(UPGRADE_ASSOCIATED_VERSION);
+    PROPERTY_IDS.add(UPGRADE_VERSIONS);
     PROPERTY_IDS.add(UPGRADE_DIRECTION);
     PROPERTY_IDS.add(UPGRADE_DOWNGRADE_ALLOWED);
     PROPERTY_IDS.add(UPGRADE_SUSPENDED);
@@ -305,6 +291,9 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     PROPERTY_IDS.add(REQUEST_STATUS_PROPERTY_ID);
     PROPERTY_IDS.add(REQUEST_TYPE_ID);
 
+    PROPERTY_IDS.add("Upgrade/from_version");
+    PROPERTY_IDS.add("Upgrade/to_version");
+
     // keys
     KEY_PROPERTY_IDS.put(Resource.Type.Upgrade, UPGRADE_REQUEST_ID);
     KEY_PROPERTY_IDS.put(Resource.Type.Cluster, UPGRADE_CLUSTER_NAME);
@@ -355,32 +344,8 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
       @Override
       public UpgradeEntity invoke() throws AmbariException, AuthorizationException {
 
-        final String directionProperty = (String) requestMap.get(UPGRADE_DIRECTION);
-        if (StringUtils.isEmpty(directionProperty)) {
-          throw new AmbariException(String.format("%s is required", UPGRADE_DIRECTION));
-        }
-
-        final Direction direction = Direction.valueOf(directionProperty);
-
-        // Default to ROLLING upgrade, but attempt to read from properties.
-        UpgradeType upgradeType = UpgradeType.ROLLING;
-        if (requestMap.containsKey(UPGRADE_TYPE)) {
-          try {
-            upgradeType = UpgradeType.valueOf(requestMap.get(UPGRADE_TYPE).toString());
-          } catch (Exception e) {
-            throw new AmbariException(String.format("Property %s has an incorrect value of %s.",
-                UPGRADE_TYPE, requestMap.get(UPGRADE_TYPE)));
-          }
-        }
-
-        // the version being upgraded or downgraded to (ie 2.2.1.0-1234)
-        final String version = (String) requestMap.get(UPGRADE_VERSION);
-
-        final UpgradeContext upgradeContext = s_upgradeContextFactory.create(cluster, upgradeType,
-            direction, version, requestMap);
-
-        UpgradePack upgradePack = validateRequest(upgradeContext);
-        upgradeContext.setUpgradePack(upgradePack);
+        // create the context, validating the properties in the process
+        final UpgradeContext upgradeContext = s_upgradeContextFactory.create(cluster, requestMap);
 
         try {
           return createUpgrade(upgradeContext);
@@ -598,47 +563,33 @@ 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_DIRECTION, entity.getDirection(), requestedIds);
     setResourceProperty(resource, UPGRADE_SUSPENDED, entity.isSuspended(), requestedIds);
     setResourceProperty(resource, UPGRADE_DOWNGRADE_ALLOWED, entity.isDowngradeAllowed(), requestedIds);
     setResourceProperty(resource, UPGRADE_SKIP_FAILURES, entity.isComponentFailureAutoSkipped(), requestedIds);
     setResourceProperty(resource, UPGRADE_SKIP_SC_FAILURES, entity.isServiceCheckFailureAutoSkipped(), requestedIds);
 
-    return resource;
-  }
-
-  /**
-   * Validates a singular API request.
-   *
-   * @param upgradeContext the map of properties
-   * @return the validated upgrade pack
-   * @throws AmbariException
-   */
-  private UpgradePack validateRequest(UpgradeContext upgradeContext) throws AmbariException {
-    Cluster cluster = upgradeContext.getCluster();
-    Direction direction = upgradeContext.getDirection();
-    Map<String, Object> requestMap = upgradeContext.getUpgradeRequest();
-    UpgradeType upgradeType = upgradeContext.getType();
+    // set the assocaited to/from version (to/from is dictated by direction)
+    RepositoryVersionEntity repositoryVersion = entity.getRepositoryVersion();
+    setResourceProperty(resource, UPGRADE_ASSOCIATED_VERSION, repositoryVersion.getVersion(), requestedIds);
 
-    /**
-     * 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);
+    // now set the target verison for all services in the upgrade
+    Map<String, RepositoryVersions> repositoryVersions = new HashMap<>();
+    for( UpgradeHistoryEntity history : entity.getHistory() ){
+      RepositoryVersions serviceVersions = repositoryVersions.get(history.getServiceName());
+      if (null != serviceVersions) {
+        continue;
+      }
 
-    String version = (String) requestMap.get(UPGRADE_VERSION);
-    String versionForUpgradePack = (String) requestMap.get(UPGRADE_FROM_VERSION);
+      serviceVersions = new RepositoryVersions(history.getFromReposistoryVersion(),
+          history.getTargetRepositoryVersion());
 
-    UpgradePack pack = s_upgradeHelper.suggestUpgradePack(cluster.getClusterName(),
-        versionForUpgradePack, version, direction, upgradeType, preferredUpgradePackName);
+      repositoryVersions.put(history.getServiceName(), serviceVersions);
+    }
 
-    // the validator will throw an exception if the upgrade request is not valid
-    UpgradeRequestValidator upgradeRequestValidator = buildValidator(upgradeType);
-    upgradeRequestValidator.validate(upgradeContext, pack);
+    setResourceProperty(resource, UPGRADE_VERSIONS, repositoryVersions, requestedIds);
 
-    return pack;
+    return resource;
   }
 
   /**
@@ -698,112 +649,9 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     UpgradePack pack = upgradeContext.getUpgradePack();
     Cluster cluster = upgradeContext.getCluster();
     Direction direction = upgradeContext.getDirection();
-    Map<String, Object> requestMap = upgradeContext.getUpgradeRequest();
-    UpgradeType upgradeType = upgradeContext.getType();
 
     ConfigHelper configHelper = getManagementController().getConfigHelper();
 
-    // the upgrade context calculated these for us based on direction
-    StackId sourceStackId = upgradeContext.getOriginalStackId();
-
-    // the version being upgraded or downgraded to (ie 2.2.1.0-1234)
-    final String version = upgradeContext.getVersion();
-
-    MasterHostResolver resolver = null;
-    if (direction.isUpgrade()) {
-      resolver = new MasterHostResolver(configHelper, cluster);
-    } else {
-      resolver = new MasterHostResolver(configHelper, cluster, version);
-    }
-
-    Set<String> supportedServices = new HashSet<>();
-    UpgradeScope scope = UpgradeScope.COMPLETE;
-
-    switch (direction) {
-      case UPGRADE:
-        RepositoryVersionEntity targetRepositoryVersion = upgradeContext.getTargetRepositoryVersion();
-        RepositoryType repositoryType = targetRepositoryVersion.getType();
-
-        // !!! Consult the version definition and add the service names to supportedServices
-        if (repositoryType != RepositoryType.STANDARD) {
-          scope = UpgradeScope.PARTIAL;
-
-          try {
-            VersionDefinitionXml vdf = targetRepositoryVersion.getRepositoryXml();
-            supportedServices.addAll(vdf.getAvailableServiceNames());
-
-            // if this is every true, then just stop the upgrade attempt and
-            // throw an exception
-            if (supportedServices.isEmpty()) {
-              String message = String.format(
-                  "When using a VDF of type %s, the available services must be defined in the VDF",
-                  targetRepositoryVersion.getType());
-              throw new AmbariException(message);
-            }
-
-          } catch (Exception e) {
-            String msg = String.format("Could not parse version definition for %s.  Upgrade will not proceed.", version);
-            LOG.error(msg, e);
-            throw new AmbariException(msg);
-          }
-        }
-
-        break;
-      case DOWNGRADE:
-        break;
-    }
-
-    upgradeContext.setResolver(resolver);
-    upgradeContext.setSupportedServices(supportedServices);
-    upgradeContext.setScope(scope);
-
-    @Experimental(feature = ExperimentalFeature.PATCH_UPGRADES,
-        comment = "Check for any other way downgrade to get set, if required")
-    String downgradeFromVersion = null;
-
-    if (direction.isDowngrade()) {
-      if (requestMap.containsKey(UPGRADE_FROM_VERSION)) {
-        downgradeFromVersion = (String) requestMap.get(UPGRADE_FROM_VERSION);
-      } else {
-        UpgradeEntity lastUpgradeItemForCluster = s_upgradeDAO.findLastUpgradeForCluster(
-            cluster.getClusterId(), Direction.UPGRADE);
-
-        downgradeFromVersion = lastUpgradeItemForCluster.getToVersion();
-      }
-
-      if (null == downgradeFromVersion) {
-        throw new AmbariException("When downgrading, the downgrade version must be specified");
-      }
-
-      upgradeContext.setDowngradeFromVersion(downgradeFromVersion);
-    }
-
-    // optionally skip failures - this can be supplied on either the request or
-    // in the upgrade pack explicitely, however the request will always override
-    // the upgrade pack if explicitely specified
-    boolean skipComponentFailures = pack.isComponentFailureAutoSkipped();
-    boolean skipServiceCheckFailures = pack.isServiceCheckFailureAutoSkipped();
-
-    // only override the upgrade pack if set on the request
-    if (requestMap.containsKey(UPGRADE_SKIP_FAILURES)) {
-      skipComponentFailures = Boolean.parseBoolean((String) requestMap.get(UPGRADE_SKIP_FAILURES));
-    }
-
-    // only override the upgrade pack if set on the request
-    if (requestMap.containsKey(UPGRADE_SKIP_SC_FAILURES)) {
-      skipServiceCheckFailures = Boolean.parseBoolean(
-          (String) requestMap.get(UPGRADE_SKIP_SC_FAILURES));
-    }
-
-    boolean skipManualVerification = false;
-    if(requestMap.containsKey(UPGRADE_SKIP_MANUAL_VERIFICATION)) {
-      skipManualVerification = Boolean.parseBoolean((String) requestMap.get(UPGRADE_SKIP_MANUAL_VERIFICATION));
-    }
-
-    upgradeContext.setAutoSkipComponentFailures(skipComponentFailures);
-    upgradeContext.setAutoSkipServiceCheckFailures(skipServiceCheckFailures);
-    upgradeContext.setAutoSkipManualVerification(skipManualVerification);
-
     List<UpgradeGroupHolder> groups = s_upgradeHelper.createSequence(pack, upgradeContext);
 
     if (groups.isEmpty()) {
@@ -828,7 +676,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     }
 
     List<UpgradeGroupEntity> groupEntities = new ArrayList<>();
-    RequestStageContainer req = createRequest(direction, version);
+    RequestStageContainer req = createRequest(upgradeContext);
 
     /**
     During a Rolling Upgrade, change the desired Stack Id if jumping across
@@ -849,21 +697,24 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
       s_upgradeHelper.putComponentsToUpgradingState(upgradeContext);
     }
 
+    @Experimental(feature = ExperimentalFeature.PATCH_UPGRADES, comment = "This is wrong")
+    StackId configurationPackSourceStackId = upgradeContext.getRepositoryVersion().getStackId();
+
     // resolve or build a proper config upgrade pack - always start out with the config pack
     // for the current stack and merge into that
     //
     // 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,
+        configurationPackSourceStackId);
 
     // create the upgrade and request
     for (UpgradeGroupHolder group : groups) {
-      boolean skippable = group.skippable;
-      boolean supportsAutoSkipOnFailure = group.supportsAutoSkipOnFailure;
-      boolean allowRetry = group.allowRetry;
-
       List<UpgradeItemEntity> itemEntities = new ArrayList<>();
+
       for (StageWrapper wrapper : group.items) {
+        RepositoryVersionEntity effectiveRepositoryVersion = upgradeContext.getRepositoryVersion();
+
         if (wrapper.getType() == StageWrapper.Type.SERVER_SIDE_ACTION) {
           // !!! each stage is guaranteed to be of one type. but because there
           // is a bug that prevents one stage with multiple tasks assigned for
@@ -882,20 +733,9 @@ 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);
+              makeServerSideStage(group, upgradeContext, effectiveRepositoryVersion, req,
+                  itemEntity, (ServerSideActionTask) task, configUpgradePack);
             }
           }
         } else {
@@ -908,8 +748,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
           injectVariables(configHelper, cluster, itemEntity);
 
           // upgrade items match a stage
-          createStage(upgradeContext, req, itemEntity, wrapper, skippable,
-              supportsAutoSkipOnFailure, allowRetry);
+          createStage(group, upgradeContext, effectiveRepositoryVersion, req, itemEntity, wrapper);
         }
       }
 
@@ -923,21 +762,14 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     }
 
     UpgradeEntity entity = new UpgradeEntity();
-
-    if (null != downgradeFromVersion) {
-      entity.setFromVersion(downgradeFromVersion);
-    } else {
-      entity.setFromVersion("");
-    }
-
-    entity.setToVersion(version);
+    entity.setRepositoryVersion(upgradeContext.getRepositoryVersion());
     entity.setUpgradeGroups(groupEntities);
     entity.setClusterId(cluster.getClusterId());
     entity.setDirection(direction);
     entity.setUpgradePackage(pack.getName());
     entity.setUpgradeType(pack.getType());
-    entity.setAutoSkipComponentFailures(skipComponentFailures);
-    entity.setAutoSkipServiceCheckFailures(skipServiceCheckFailures);
+    entity.setAutoSkipComponentFailures(upgradeContext.isComponentFailureAutoSkipped());
+    entity.setAutoSkipServiceCheckFailures(upgradeContext.isServiceCheckFailureAutoSkipped());
 
     if (upgradeContext.getDirection().isDowngrade()) {
       // !!! You can't downgrade a Downgrade, no matter what the upgrade pack says.
@@ -946,6 +778,37 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
       entity.setDowngradeAllowed(pack.isDowngradeAllowed());
     }
 
+    // set upgrade history for every component in the upgrade
+    Set<String> services = upgradeContext.getSupportedServices();
+    for (String serviceName : services) {
+      Service service = cluster.getService(serviceName);
+      Map<String, ServiceComponent> componentMap = service.getServiceComponents();
+      for (ServiceComponent component : componentMap.values()) {
+        UpgradeHistoryEntity history = new UpgradeHistoryEntity();
+        history.setUpgrade(entity);
+        history.setServiceName(serviceName);
+        history.setComponentName(component.getName());
+
+        // depending on whether this is an upgrade or a downgrade, the history
+        // will be different
+        if (upgradeContext.getDirection() == Direction.UPGRADE) {
+          history.setFromRepositoryVersion(component.getDesiredRepositoryVersion());
+          history.setTargetRepositoryVersion(upgradeContext.getRepositoryVersion());
+        } else {
+          // the target version on a downgrade is the original version that the
+          // service was on in the failed upgrade
+          RepositoryVersionEntity targetRepositoryVersion =
+              upgradeContext.getTargetRepositoryVersion(serviceName);
+
+          history.setFromRepositoryVersion(upgradeContext.getRepositoryVersion());
+          history.setTargetRepositoryVersion(targetRepositoryVersion);
+        }
+
+        // add the history
+        entity.addHistory(history);
+      }
+    }
+
     req.getRequestStatusResponse();
     return createUpgradeInsideTransaction(cluster, req, entity);
   }
@@ -1014,8 +877,8 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     Cluster cluster = upgradeContext.getCluster();
     Direction direction = upgradeContext.getDirection();
     UpgradePack upgradePack = upgradeContext.getUpgradePack();
-    String stackName = upgradeContext.getTargetStackId().getStackName();
-    String version = upgradeContext.getVersion();
+    String stackName = upgradeContext.getRepositoryVersion().getStackId().getStackName();
+    String version = upgradeContext.getRepositoryVersion().getStackId().getStackVersion();
     String userName = getManagementController().getAuthName();
 
     RepositoryVersionEntity targetRve = s_repoVersionDAO.findByStackNameAndVersion(stackName, version);
@@ -1250,36 +1113,45 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     }
   }
 
-  private RequestStageContainer createRequest(Direction direction, String version) {
+  private RequestStageContainer createRequest(UpgradeContext upgradeContext) {
     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));
+
+    Direction direction = upgradeContext.getDirection();
+    RepositoryVersionEntity repositoryVersion = upgradeContext.getRepositoryVersion();
+
+    requestStages.setRequestContext(String.format("%s %s %s", direction.getVerb(true),
+        direction.getPreposition(), repositoryVersion.getVersion()));
 
     return requestStages;
   }
 
-  private void createStage(UpgradeContext context, RequestStageContainer request,
-      UpgradeItemEntity entity, StageWrapper wrapper, boolean skippable,
-      boolean supportsAutoSkipOnFailure, boolean allowRetry)
+  private void createStage(UpgradeGroupHolder group, UpgradeContext context,
+      RepositoryVersionEntity effectiveRepositoryVersion,
+      RequestStageContainer request, UpgradeItemEntity entity, StageWrapper wrapper)
           throws AmbariException {
 
+    boolean skippable = group.skippable;
+    boolean supportsAutoSkipOnFailure = group.supportsAutoSkipOnFailure;
+    boolean allowRetry = group.allowRetry;
+
     switch (wrapper.getType()) {
       case CONFIGURE:
       case START:
       case STOP:
       case RESTART:
-        makeCommandStage(context, request, entity, wrapper, skippable, supportsAutoSkipOnFailure,
-            allowRetry);
+        makeCommandStage(context, request, effectiveRepositoryVersion, entity, wrapper, skippable,
+            supportsAutoSkipOnFailure, allowRetry);
         break;
       case RU_TASKS:
-        makeActionStage(context, request, entity, wrapper, skippable, supportsAutoSkipOnFailure,
-            allowRetry);
+        makeActionStage(context, request, effectiveRepositoryVersion, entity, wrapper, skippable,
+            supportsAutoSkipOnFailure, allowRetry);
         break;
       case SERVICE_CHECK:
-        makeServiceCheckStage(context, request, entity, wrapper, skippable,
-            supportsAutoSkipOnFailure, allowRetry);
+        makeServiceCheckStage(context, request, effectiveRepositoryVersion, entity, wrapper,
+            skippable, supportsAutoSkipOnFailure, allowRetry);
         break;
       default:
         break;
@@ -1302,9 +1174,9 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
   }
 
   private void makeActionStage(UpgradeContext context, RequestStageContainer request,
-      UpgradeItemEntity entity, StageWrapper wrapper, boolean skippable,
-      boolean supportsAutoSkipOnFailure, boolean allowRetry)
-          throws AmbariException {
+      RepositoryVersionEntity effectiveRepositoryVersion, UpgradeItemEntity entity,
+      StageWrapper wrapper, boolean skippable, boolean supportsAutoSkipOnFailure,
+      boolean allowRetry) throws AmbariException {
 
     if (0 == wrapper.getHosts().size()) {
       throw new AmbariException(
@@ -1328,7 +1200,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 = context.getEffectiveStackId();
+    StackId stackId = effectiveRepositoryVersion.getStackId();
 
     StackInfo stackInfo = ambariMetaInfo.getStack(stackId.getStackName(),
         stackId.getStackVersion());
@@ -1354,7 +1226,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     actionContext.setAutoSkipFailures(context.isComponentFailureAutoSkipped());
 
     ExecuteCommandJson jsons = s_commandExecutionHelper.get().getCommandJson(actionContext,
-        cluster, context.getEffectiveStackId());
+        cluster, effectiveRepositoryVersion);
 
     Stage stage = s_stageFactory.get().createNew(request.getId().longValue(), "/tmp/ambari",
         cluster.getClusterName(), cluster.getClusterId(), entity.getText(),
@@ -1395,9 +1267,9 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
    * @throws AmbariException
    */
   private void makeCommandStage(UpgradeContext context, RequestStageContainer request,
-      UpgradeItemEntity entity, StageWrapper wrapper, boolean skippable,
-      boolean supportsAutoSkipOnFailure, boolean allowRetry)
-          throws AmbariException {
+      RepositoryVersionEntity effectiveRepositoryVersion, UpgradeItemEntity entity,
+      StageWrapper wrapper, boolean skippable, boolean supportsAutoSkipOnFailure,
+      boolean allowRetry) throws AmbariException {
 
     Cluster cluster = context.getCluster();
 
@@ -1437,7 +1309,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     actionContext.setMaintenanceModeHostExcluded(true);
 
     ExecuteCommandJson jsons = s_commandExecutionHelper.get().getCommandJson(actionContext,
-        cluster, context.getEffectiveStackId());
+        cluster, effectiveRepositoryVersion);
 
     Stage stage = s_stageFactory.get().createNew(request.getId().longValue(), "/tmp/ambari",
         cluster.getClusterName(), cluster.getClusterId(), entity.getText(),
@@ -1470,9 +1342,9 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
   }
 
   private void makeServiceCheckStage(UpgradeContext context, RequestStageContainer request,
-      UpgradeItemEntity entity, StageWrapper wrapper, boolean skippable,
-      boolean supportsAutoSkipOnFailure, boolean allowRetry)
-          throws AmbariException {
+      RepositoryVersionEntity effectiveRepositoryVersion, UpgradeItemEntity entity,
+      StageWrapper wrapper, boolean skippable, boolean supportsAutoSkipOnFailure,
+      boolean allowRetry) throws AmbariException {
 
     List<RequestResourceFilter> filters = new ArrayList<>();
 
@@ -1499,7 +1371,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     actionContext.setMaintenanceModeHostExcluded(true);
 
     ExecuteCommandJson jsons = s_commandExecutionHelper.get().getCommandJson(actionContext,
-        cluster, context.getEffectiveStackId());
+        cluster, effectiveRepositoryVersion);
 
     Stage stage = s_stageFactory.get().createNew(request.getId().longValue(), "/tmp/ambari",
         cluster.getClusterName(), cluster.getClusterId(), entity.getText(),
@@ -1536,13 +1408,13 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
    * upgrade
    * @throws AmbariException
    */
-  private void makeServerSideStage(UpgradeContext context, RequestStageContainer request,
-      UpgradeItemEntity entity, ServerSideActionTask task, boolean skippable,
-      boolean supportsAutoSkipOnFailure, boolean allowRetry,
-      UpgradePack upgradePack, ConfigUpgradePack configUpgradePack)
-          throws AmbariException {
+  private void makeServerSideStage(UpgradeGroupHolder group, UpgradeContext context,
+      RepositoryVersionEntity effectiveRepositoryVersion, RequestStageContainer request,
+      UpgradeItemEntity entity, ServerSideActionTask task, ConfigUpgradePack configUpgradePack)
+      throws AmbariException {
 
     Cluster cluster = context.getCluster();
+    UpgradePack upgradePack = context.getUpgradePack();
 
     Map<String, String> commandParams = getNewParameterMap(request, context);
     commandParams.put(UpgradeContext.COMMAND_PARAM_UPGRADE_PACK, upgradePack.getName());
@@ -1624,21 +1496,21 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
         commandParams);
 
     actionContext.setTimeout(Short.valueOf((short) -1));
-    actionContext.setRetryAllowed(allowRetry);
+    actionContext.setRetryAllowed(group.allowRetry);
     actionContext.setAutoSkipFailures(context.isComponentFailureAutoSkipped());
 
     // hosts in maintenance mode are excluded from the upgrade
     actionContext.setMaintenanceModeHostExcluded(true);
 
     ExecuteCommandJson jsons = s_commandExecutionHelper.get().getCommandJson(actionContext,
-        cluster, context.getEffectiveStackId());
+        cluster, null);
 
     Stage stage = s_stageFactory.get().createNew(request.getId().longValue(), "/tmp/ambari",
         cluster.getClusterName(), cluster.getClusterId(), stageText, jsons.getClusterHostInfo(),
         jsons.getCommandParamsForStage(), jsons.getHostParamsForStage());
 
-    stage.setSkippable(skippable);
-    stage.setAutoSkipFailureSupported(supportsAutoSkipOnFailure);
+    stage.setSkippable(group.skippable);
+    stage.setAutoSkipFailureSupported(group.supportsAutoSkipOnFailure);
 
     long stageId = request.getLastStageId() + 1;
     if (0L == stageId) {
@@ -1652,7 +1524,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
         getManagementController().getAuthName(), Role.AMBARI_SERVER_ACTION, RoleCommand.EXECUTE,
         cluster.getClusterName(),
         new ServiceComponentHostServerActionEvent(null, System.currentTimeMillis()), commandParams,
-        itemDetail, null, s_configuration.getDefaultServerTaskTimeout(), allowRetry,
+        itemDetail, null, s_configuration.getDefaultServerTaskTimeout(), group.allowRetry,
         context.isComponentFailureAutoSkipped());
 
     request.addStages(Collections.singletonList(stage));
@@ -1663,11 +1535,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
    * following properties are already set:
    * <ul>
    * <li>{@link UpgradeContext#COMMAND_PARAM_CLUSTER_NAME}
-   * <li>{@link UpgradeContext#COMMAND_PARAM_VERSION}
    * <li>{@link UpgradeContext#COMMAND_PARAM_DIRECTION}
-   * <li>{@link UpgradeContext#COMMAND_PARAM_ORIGINAL_STACK}
-   * <li>{@link UpgradeContext#COMMAND_PARAM_TARGET_STACK}
-   * <li>{@link UpgradeContext#COMMAND_DOWNGRADE_FROM_VERSION}
    * <li>{@link UpgradeContext#COMMAND_PARAM_UPGRADE_TYPE}
    * <li>{@link KeyNames#REFRESH_CONFIG_TAGS_BEFORE_EXECUTION} - necessary in
    * order to have the commands contain the correct configurations. Otherwise,
@@ -1778,57 +1646,6 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
   }
 
   /**
-   * Builds the list of {@link HostOrderItem}s from the upgrade request. If the
-   * upgrade request does not contain the hosts
-   *
-   * @param requestMap
-   *          the map of properties from the request (not {@code null}).
-   * @return the ordered list of actions to orchestrate for the
-   *         {@link UpgradeType#HOST_ORDERED} upgrade.
-   * @throws AmbariException
-   *           if the request properties are not valid.
-   */
-  @SuppressWarnings("unchecked")
-  private List<HostOrderItem> extractHostOrderItemsFromRequest(Map<String, Object> requestMap)
-      throws AmbariException {
-    // ewwww
-    Set<Map<String, List<String>>> hostsOrder = (Set<Map<String, List<String>>>) requestMap.get(
-        UPGRADE_HOST_ORDERED_HOSTS);
-
-    if (CollectionUtils.isEmpty(hostsOrder)) {
-      throw new AmbariException(
-          String.format("The %s property must be specified when using a %s upgrade type.",
-              UPGRADE_HOST_ORDERED_HOSTS, UpgradeType.HOST_ORDERED));
-    }
-
-    List<HostOrderItem> hostOrderItems = new ArrayList<>();
-
-    // extract all of the hosts so that we can ensure they are all accounted for
-    Iterator<Map<String, List<String>>> iterator = hostsOrder.iterator();
-    while (iterator.hasNext()) {
-      Map<String, List<String>> grouping = iterator.next();
-      List<String> hosts = grouping.get("hosts");
-      List<String> serviceChecks = grouping.get("service_checks");
-
-      if (CollectionUtils.isEmpty(hosts) && CollectionUtils.isEmpty(serviceChecks)) {
-        throw new AmbariException(String.format(
-            "The %s property must contain at least one object with either a %s or %s key",
-            UPGRADE_HOST_ORDERED_HOSTS, "hosts", "service_checks"));
-      }
-
-      if (CollectionUtils.isNotEmpty(hosts)) {
-        hostOrderItems.add(new HostOrderItem(HostOrderActionType.HOST_UPGRADE, hosts));
-      }
-
-      if (CollectionUtils.isNotEmpty(serviceChecks)) {
-        hostOrderItems.add(new HostOrderItem(HostOrderActionType.SERVICE_CHECK, serviceChecks));
-      }
-    }
-
-    return hostOrderItems;
-  }
-
-  /**
    * Builds the correct {@link ConfigUpgradePack} based on the upgrade and
    * source stack.
    * <ul>
@@ -1887,267 +1704,34 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
   }
 
   /**
-   * Builds a chain of {@link UpgradeRequestValidator}s to ensure that the
-   * incoming request to create a new upgrade is valid.
-   *
-   * @param upgradeType
-   *          the type of upgrade to build the validator for.
-   * @return the validator which can check to ensure that the properties are
-   *         valid.
-   */
-  private UpgradeRequestValidator buildValidator(UpgradeType upgradeType){
-    UpgradeRequestValidator validator = new BasicUpgradePropertiesValidator();
-    UpgradeRequestValidator preReqValidator = new PreReqCheckValidator();
-    validator.setNextValidator(preReqValidator);
-
-    final UpgradeRequestValidator upgradeTypeValidator;
-    switch( upgradeType ){
-      case HOST_ORDERED:
-        upgradeTypeValidator = new HostOrderedUpgradeValidator();
-        break;
-      case NON_ROLLING:
-      case ROLLING:
-      default:
-        upgradeTypeValidator = null;
-        break;
-    }
-
-    preReqValidator.setNextValidator(upgradeTypeValidator);
-    return validator;
-  }
-
-  /**
-   * The {@link UpgradeRequestValidator} contains the logic to check for correct
-   * upgrade request properties and then pass the responsibility onto the next
-   * validator in the chain.
+   * The {@link RepositoryVersions} class is used to represent to/from versions
+   * of a service during an upgrade or downgrade.
    */
-  private abstract class UpgradeRequestValidator {
-    /**
-     * The next validator.
-     */
-    UpgradeRequestValidator m_nextValidator;
+  final static class RepositoryVersions {
+    @JsonProperty("from_repository_id")
+    final long fromRepositoryId;
 
-    /**
-     * Sets the next validator in the chain.
-     *
-     * @param nextValidator
-     *          the next validator to run, or {@code null} for none.
-     */
-    void setNextValidator(UpgradeRequestValidator nextValidator) {
-      m_nextValidator = nextValidator;
-    }
+    @JsonProperty("from_repository_version")
+    final String fromRepositoryVersion;
 
-    /**
-     * Validates the upgrade request from this point in the chain.
-     *
-     * @param upgradeContext
-     * @param upgradePack
-     * @throws AmbariException
-     */
-    final void validate(UpgradeContext upgradeContext, UpgradePack upgradePack)
-        throws AmbariException {
+    @JsonProperty("to_repository_id")
+    final long toRepositoryId;
 
-      // run this instance's check
-      check(upgradeContext, upgradePack);
-
-      // pass along to the next
-      if( null != m_nextValidator ) {
-        m_nextValidator.validate(upgradeContext, upgradePack);
-      }
-    }
+    @JsonProperty("to_repository_version")
+    final String toRepositoryVersion;
 
     /**
-     * Checks to ensure that upgrade request is valid given the specific
-     * arguments.
+     * Constructor.
      *
-     * @param upgradeContext
-     * @param upgradePack
-     *
-     * @throws AmbariException
-     */
-    abstract void check(UpgradeContext upgradeContext, UpgradePack upgradePack)
-        throws AmbariException;
-  }
-
-  /**
-   * The {@link BasicUpgradePropertiesValidator} ensures that the basic required
-   * properties are present on the upgrade request.
-   */
-  private final class BasicUpgradePropertiesValidator extends UpgradeRequestValidator {
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void check(UpgradeContext upgradeContext, UpgradePack upgradePack)
-        throws AmbariException {
-      Map<String, Object> requestMap = upgradeContext.getUpgradeRequest();
-
-      String clusterName = (String) requestMap.get(UPGRADE_CLUSTER_NAME);
-      String version = (String) requestMap.get(UPGRADE_VERSION);
-      String direction = (String) requestMap.get(UPGRADE_DIRECTION);
-
-      if (StringUtils.isBlank(clusterName)) {
-        throw new AmbariException(String.format("%s is required", UPGRADE_CLUSTER_NAME));
-      }
-
-      if (StringUtils.isBlank(version)) {
-        throw new AmbariException(String.format("%s is required", UPGRADE_VERSION));
-      }
-
-      if (StringUtils.isBlank(direction)) {
-        throw new AmbariException(String.format("%s is required", UPGRADE_DIRECTION));
-      }
-    }
-  }
-
-  /**
-   * The {@link PreReqCheckValidator} ensures that the upgrade pre-requisite
-   * checks have passed.
-   */
-  private final class PreReqCheckValidator extends UpgradeRequestValidator {
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    void check(UpgradeContext upgradeContext, UpgradePack upgradePack) throws AmbariException {
-      Cluster cluster = upgradeContext.getCluster();
-      Direction direction = upgradeContext.getDirection();
-      Map<String, Object> requestMap = upgradeContext.getUpgradeRequest();
-      UpgradeType upgradeType = upgradeContext.getType();
-
-      String version = (String) requestMap.get(UPGRADE_VERSION);
-      boolean skipPrereqChecks = Boolean.parseBoolean((String) requestMap.get(UPGRADE_SKIP_PREREQUISITE_CHECKS));
-      boolean failOnCheckWarnings = Boolean.parseBoolean((String) requestMap.get(UPGRADE_FAIL_ON_CHECK_WARNINGS));
-      String preferredUpgradePack = requestMap.containsKey(UPGRADE_PACK) ? (String) requestMap.get(UPGRADE_PACK) : null;
-
-      // verify that there is not an upgrade or downgrade that is in progress or suspended
-      UpgradeEntity existingUpgrade = cluster.getUpgradeInProgress();
-      if( null != existingUpgrade ){
-        throw new AmbariException(
-            String.format("Unable to perform %s as another %s (request ID %s) is in progress.",
-                direction.getText(false), existingUpgrade.getDirection().getText(false),
-                existingUpgrade.getRequestId()));
-      }
-
-      // skip this check if it's a downgrade or we are instructed to skip it
-      if( direction.isDowngrade() || skipPrereqChecks ){
-        return;
-      }
-
-      // Validate pre-req checks pass
-      PreUpgradeCheckResourceProvider preUpgradeCheckResourceProvider = (PreUpgradeCheckResourceProvider)
-          getResourceProvider(Resource.Type.PreUpgradeCheck);
-
-      Predicate preUpgradeCheckPredicate = new PredicateBuilder().property(
-          PreUpgradeCheckResourceProvider.UPGRADE_CHECK_CLUSTER_NAME_PROPERTY_ID).equals(cluster.getClusterName()).and().property(
-          PreUpgradeCheckResourceProvider.UPGRADE_CHECK_REPOSITORY_VERSION_PROPERTY_ID).equals(version).and().property(
-          PreUpgradeCheckResourceProvider.UPGRADE_CHECK_UPGRADE_TYPE_PROPERTY_ID).equals(upgradeType).and().property(
-          PreUpgradeCheckResourceProvider.UPGRADE_CHECK_UPGRADE_PACK_PROPERTY_ID).equals(preferredUpgradePack).toPredicate();
-
-      Request preUpgradeCheckRequest = PropertyHelper.getReadRequest();
-
-      Set<Resource> preUpgradeCheckResources;
-      try {
-        preUpgradeCheckResources = preUpgradeCheckResourceProvider.getResources(
-            preUpgradeCheckRequest, preUpgradeCheckPredicate);
-      } catch (NoSuchResourceException|SystemException|UnsupportedPropertyException|NoSuchParentResourceException e) {
-        throw new AmbariException(
-            String.format("Unable to perform %s. Prerequisite checks could not be run",
-                direction.getText(false), e));
-      }
-
-      List<Resource> failedResources = new LinkedList<>();
-      if (preUpgradeCheckResources != null) {
-        for (Resource res : preUpgradeCheckResources) {
-          PrereqCheckStatus prereqCheckStatus = (PrereqCheckStatus) res.getPropertyValue(
-              PreUpgradeCheckResourceProvider.UPGRADE_CHECK_STATUS_PROPERTY_ID);
-
-          if (prereqCheckStatus == PrereqCheckStatus.FAIL
-              || (failOnCheckWarnings && prereqCheckStatus == PrereqCheckStatus.WARNING)) {
-            failedResources.add(res);
-          }
-        }
-      }
-
-      if (!failedResources.isEmpty()) {
-        throw new AmbariException(
-            String.format("Unable to perform %s. Prerequisite checks failed %s",
-                direction.getText(false), s_gson.toJson(failedResources)));
-      }
-    }
-  }
-
-  /**
-   * Ensures that for {@link UpgradeType#HOST_ORDERED}, the properties supplied
-   * are valid.
-   */
-  @SuppressWarnings("unchecked")
-  private final class HostOrderedUpgradeValidator extends UpgradeRequestValidator {
-
-    /**
-     * {@inheritDoc}
+     * @param from
+     * @param target
      */
-    @Override
-    void check(UpgradeContext upgradeContext, UpgradePack upgradePack) throws AmbariException {
-      Cluster cluster = upgradeContext.getCluster();
-      Direction direction = upgradeContext.getDirection();
-      Map<String, Object> requestMap = upgradeContext.getUpgradeRequest();
-
-      String skipFailuresRequestProperty = (String) requestMap.get(UPGRADE_SKIP_FAILURES);
-      if (Boolean.parseBoolean(skipFailuresRequestProperty)) {
-        throw new AmbariException(
-            String.format("The %s property is not valid when creating a %s upgrade.",
-                UPGRADE_SKIP_FAILURES, UpgradeType.HOST_ORDERED));
-      }
-
-      String skipManualVerification = (String) requestMap.get(UPGRADE_SKIP_MANUAL_VERIFICATION);
-      if (Boolean.parseBoolean(skipManualVerification)) {
-        throw new AmbariException(
-            String.format("The %s property is not valid when creating a %s upgrade.",
-                UPGRADE_SKIP_MANUAL_VERIFICATION, UpgradeType.HOST_ORDERED));
-      }
+    public RepositoryVersions(RepositoryVersionEntity from, RepositoryVersionEntity to) {
+      fromRepositoryId = from.getId();
+      fromRepositoryVersion = from.getVersion();
 
-      if (!requestMap.containsKey(UPGRADE_HOST_ORDERED_HOSTS)) {
-        throw new AmbariException(
-            String.format("The %s property is required when creating a %s upgrade.",
-                UPGRADE_HOST_ORDERED_HOSTS, UpgradeType.HOST_ORDERED));
-      }
-
-      List<HostOrderItem> hostOrderItems = extractHostOrderItemsFromRequest(requestMap);
-      List<String> hostsFromRequest = new ArrayList<>(hostOrderItems.size());
-      for (HostOrderItem hostOrderItem : hostOrderItems) {
-        if (hostOrderItem.getType() == HostOrderActionType.HOST_UPGRADE) {
-          hostsFromRequest.addAll(hostOrderItem.getActionItems());
-        }
-      }
-
-      // ensure that all hosts for this cluster are accounted for
-      Collection<Host> hosts = cluster.getHosts();
-      Set<String> clusterHostNames = new HashSet<>(hosts.size());
-      for (Host host : hosts) {
-        clusterHostNames.add(host.getHostName());
-      }
-
-      Collection<String> disjunction = CollectionUtils.disjunction(hostsFromRequest,
-          clusterHostNames);
-
-      if (CollectionUtils.isNotEmpty(disjunction)) {
-        throw new AmbariException(String.format(
-            "The supplied list of hosts must match the cluster hosts in an upgrade of type %s. The following hosts are either missing or invalid: %s",
-            UpgradeType.HOST_ORDERED, StringUtils.join(disjunction, ", ")));
-      }
-
-      // verify that the upgradepack has the required grouping and set the
-      // action items on it
-      HostOrderGrouping hostOrderGrouping = null;
-      List<Grouping> groupings = upgradePack.getGroups(direction);
-      for (Grouping grouping : groupings) {
-        if (grouping instanceof HostOrderGrouping) {
-          hostOrderGrouping = (HostOrderGrouping) grouping;
-          hostOrderGrouping.setHostOrderItems(hostOrderItems);
-        }
-      }
+      toRepositoryId = to.getId();
+      toRepositoryVersion = to.getVersion();
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/522039eb/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ServiceComponentDesiredStateDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ServiceComponentDesiredStateDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ServiceComponentDesiredStateDAO.java
index 92f1d09..a65a94a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ServiceComponentDesiredStateDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ServiceComponentDesiredStateDAO.java
@@ -20,14 +20,12 @@ package org.apache.ambari.server.orm.dao;
 
 import java.util.List;
 
-import javax.persistence.CascadeType;
 import javax.persistence.EntityManager;
 import javax.persistence.NoResultException;
 import javax.persistence.TypedQuery;
 
 import org.apache.ambari.server.orm.RequiresSession;
 import org.apache.ambari.server.orm.entities.ServiceComponentDesiredStateEntity;
-import org.apache.ambari.server.orm.entities.ServiceComponentHistoryEntity;
 import org.apache.ambari.server.orm.entities.ServiceComponentVersionEntity;
 
 import com.google.inject.Inject;
@@ -130,56 +128,6 @@ public class ServiceComponentDesiredStateDAO {
   }
 
   /**
-   * Creates a service component upgrade/downgrade historical event.
-   *
-   * @param serviceComponentHistoryEntity
-   */
-  @Transactional
-  public void create(ServiceComponentHistoryEntity serviceComponentHistoryEntity) {
-    entityManagerProvider.get().persist(serviceComponentHistoryEntity);
-  }
-
-  /**
-   * Merges a service component upgrade/downgrade historical event, creating it
-   * in the process if it does not already exist. The associated
-   * {@link ServiceComponentDesiredStateEntity} is automatically merged via its
-   * {@link CascadeType}.
-   *
-   * @param serviceComponentHistoryEntity
-   * @return
-   */
-  @Transactional
-  public ServiceComponentHistoryEntity merge(
-      ServiceComponentHistoryEntity serviceComponentHistoryEntity) {
-    return entityManagerProvider.get().merge(serviceComponentHistoryEntity);
-  }
-
-  /**
-   * Gets the history for a component.
-   *
-   * @param clusterId
-   *          the component's cluster.
-   * @param serviceName
-   *          the component's service (not {@code null}).
-   * @param componentName
-   *          the component's name (not {@code null}).
-   * @return
-   */
-  @RequiresSession
-  public List<ServiceComponentHistoryEntity> findHistory(long clusterId, String serviceName,
-      String componentName) {
-    EntityManager entityManager = entityManagerProvider.get();
-    TypedQuery<ServiceComponentHistoryEntity> query = entityManager.createNamedQuery(
-        "ServiceComponentHistoryEntity.findByComponent", ServiceComponentHistoryEntity.class);
-
-    query.setParameter("clusterId", clusterId);
-    query.setParameter("serviceName", serviceName);
-    query.setParameter("componentName", componentName);
-
-    return daoUtils.selectList(query);
-  }
-
-  /**
    * @param clusterId     the cluster id
    * @param serviceName   the service name
    * @param componentName the component name

http://git-wip-us.apache.org/repos/asf/ambari/blob/522039eb/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentDesiredStateEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentDesiredStateEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentDesiredStateEntity.java
index 7576e00..baba85e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentDesiredStateEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentDesiredStateEntity.java
@@ -113,15 +113,6 @@ public class ServiceComponentDesiredStateEntity {
   @OneToMany(mappedBy = "serviceComponentDesiredStateEntity")
   private Collection<HostComponentDesiredStateEntity> hostComponentDesiredStateEntities;
 
-  /**
-   * All of the upgrades and downgrades which have occurred for this component.
-   * Can be {@code null} for none.
-   */
-  @OneToMany(
-      mappedBy = "m_serviceComponentDesiredStateEntity",
-      cascade = { CascadeType.ALL })
-  private Collection<ServiceComponentHistoryEntity> serviceComponentHistory;
-
   @OneToMany(mappedBy = "m_serviceComponentDesiredStateEntity", cascade = { CascadeType.ALL })
   private Collection<ServiceComponentVersionEntity> serviceComponentVersions;
 
@@ -178,33 +169,6 @@ public class ServiceComponentDesiredStateEntity {
   }
 
   /**
-   * Adds a historical entry for the version of this service component. New
-   * entries are automatically created when this entity is merged via a
-   * {@link CascadeType#MERGE}.
-   *
-   * @param historicalEntry
-   *          the entry to add.
-   */
-  public void addHistory(ServiceComponentHistoryEntity historicalEntry) {
-    if (null == serviceComponentHistory) {
-      serviceComponentHistory = new ArrayList<>();
-    }
-
-    serviceComponentHistory.add(historicalEntry);
-    historicalEntry.setServiceComponentDesiredState(this);
-  }
-
-  /**
-   * Gets the history of this component's upgrades and downgrades.
-   *
-   * @return the component history, or {@code null} if none.
-   */
-  public Collection<ServiceComponentHistoryEntity> getHistory() {
-    return serviceComponentHistory;
-  }
-
-
-  /**
    * @param versionEntity the version to add
    */
   public void addVersion(ServiceComponentVersionEntity versionEntity) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/522039eb/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentHistoryEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentHistoryEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentHistoryEntity.java
deleted file mode 100644
index 1521468..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentHistoryEntity.java
+++ /dev/null
@@ -1,181 +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.orm.entities;
-
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.JoinColumn;
-import javax.persistence.ManyToOne;
-import javax.persistence.NamedQueries;
-import javax.persistence.NamedQuery;
-import javax.persistence.Table;
-import javax.persistence.TableGenerator;
-
-import org.apache.commons.lang.builder.HashCodeBuilder;
-
-import com.google.common.base.Objects;
-
-/**
- * The {@link ServiceComponentHistoryEntity} class is used to represent an
- * upgrade or downgrade which was performed on an individual service component.
- */
-@Entity
-@Table(name = "servicecomponent_history")
-@TableGenerator(
-    name = "servicecomponent_history_id_generator",
-    table = "ambari_sequences",
-    pkColumnName = "sequence_name",
-    valueColumnName = "sequence_value",
-    pkColumnValue = "servicecomponent_history_id_seq",
-    initialValue = 0)
-@NamedQueries({ @NamedQuery(
-    name = "ServiceComponentHistoryEntity.findByComponent",
-    query = "SELECT history FROM ServiceComponentHistoryEntity history WHERE history.m_serviceComponentDesiredStateEntity.clusterId = :clusterId AND history.m_serviceComponentDesiredStateEntity.serviceName = :serviceName AND history.m_serviceComponentDesiredStateEntity.componentName = :componentName") })
-public class ServiceComponentHistoryEntity {
-
-  @Id
-  @GeneratedValue(
-      strategy = GenerationType.TABLE,
-      generator = "servicecomponent_history_id_generator")
-  @Column(name = "id", nullable = false, updatable = false)
-  private long m_id;
-
-  @ManyToOne(optional = false, cascade = { CascadeType.MERGE })
-  @JoinColumn(name = "component_id", referencedColumnName = "id", nullable = false)
-  private ServiceComponentDesiredStateEntity m_serviceComponentDesiredStateEntity;
-
-  @ManyToOne(optional = false)
-  @JoinColumn(name = "from_stack_id", referencedColumnName = "stack_id", nullable = false)
-  private StackEntity m_fromStack;
-
-  @ManyToOne(optional = false)
-  @JoinColumn(name = "to_stack_id", referencedColumnName = "stack_id", nullable = false)
-  private StackEntity m_toStack;
-
-  @ManyToOne(optional = false)
-  @JoinColumn(name = "upgrade_id", referencedColumnName = "upgrade_id", nullable = false)
-  private UpgradeEntity m_upgradeEntity;
-
-  public ServiceComponentDesiredStateEntity getServiceComponentDesiredState() {
-    return m_serviceComponentDesiredStateEntity;
-  }
-
-  /**
-   * Sets the component associated with this historical entry.
-   *
-   * @param serviceComponentDesiredStateEntity
-   *          the component to associate with this historical entry (not
-   *          {@code null}).
-   */
-  public void setServiceComponentDesiredState(ServiceComponentDesiredStateEntity serviceComponentDesiredStateEntity) {
-    m_serviceComponentDesiredStateEntity = serviceComponentDesiredStateEntity;
-  }
-
-  /**
-   * @return the id
-   */
-  public long getId() {
-    return m_id;
-  }
-
-  /**
-   * @return the fromStack
-   */
-  public StackEntity getFromStack() {
-    return m_fromStack;
-  }
-
-  /**
-   * @param fromStack
-   *          the fromStack to set
-   */
-  public void setFromStack(StackEntity fromStack) {
-    m_fromStack = fromStack;
-  }
-
-  /**
-   * @return the toStack
-   */
-  public StackEntity getToStack() {
-    return m_toStack;
-  }
-
-  /**
-   * @param toStack
-   *          the toStack to set
-   */
-  public void setToStack(StackEntity toStack) {
-    m_toStack = toStack;
-  }
-
-  /**
-   * @return the upgradeEntity
-   */
-  public UpgradeEntity getUpgrade() {
-    return m_upgradeEntity;
-  }
-
-  /**
-   * @param upgradeEntity
-   *          the upgradeEntity to set
-   */
-  public void setUpgrade(UpgradeEntity upgradeEntity) {
-    m_upgradeEntity = upgradeEntity;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public int hashCode() {
-    HashCodeBuilder hashCodeBuilder = new HashCodeBuilder();
-    hashCodeBuilder.append(m_fromStack);
-    hashCodeBuilder.append(m_toStack);
-    hashCodeBuilder.append(m_upgradeEntity);
-    hashCodeBuilder.append(m_serviceComponentDesiredStateEntity);
-    return hashCodeBuilder.toHashCode();
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public boolean equals(Object obj) {
-    if (this == obj) {
-      return true;
-    }
-
-    if (obj == null) {
-      return false;
-    }
-
-    if (getClass() != obj.getClass()) {
-      return false;
-    }
-
-    final ServiceComponentHistoryEntity other = (ServiceComponentHistoryEntity) obj;
-    return Objects.equal(m_fromStack, other.m_fromStack)
-        && Objects.equal(m_toStack, other.m_toStack)
-        && Objects.equal(m_upgradeEntity, other.m_upgradeEntity) 
-        && Objects.equal(m_serviceComponentDesiredStateEntity, other.m_serviceComponentDesiredStateEntity);
-  }
-}