You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by nc...@apache.org on 2017/07/13 19:14:55 UTC

[37/37] ambari git commit: AMBARI-21450. Initial cherry-picking for feature branch (ncole)

AMBARI-21450. Initial cherry-picking for feature branch (ncole)


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

Branch: refs/heads/branch-feature-AMBARI-21450
Commit: 48f7fb22ae2ea61d7b05fa24703ccff2941bf8ff
Parents: 88d93b9
Author: Nate Cole <nc...@hortonworks.com>
Authored: Thu Jul 13 15:13:50 2017 -0400
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Thu Jul 13 15:13:50 2017 -0400

----------------------------------------------------------------------
 .../apache/ambari/annotations/Experimental.java |    2 +-
 .../ambari/server/StateRecoveryManager.java     |   39 +-
 .../actionmanager/ExecutionCommandWrapper.java  |   78 +-
 .../ExecutionCommandWrapperFactory.java         |    2 +-
 .../ambari/server/agent/CommandRepository.java  |  184 ++
 .../ambari/server/agent/ExecutionCommand.java   |  135 +-
 .../ambari/server/agent/HeartbeatProcessor.java |   14 +-
 .../alerts/ComponentVersionAlertRunnable.java   |   57 +-
 .../server/api/services/AmbariMetaInfo.java     |  166 +-
 .../request/AddUpgradeRequestAuditEvent.java    |   10 +-
 .../eventcreator/UpgradeEventCreator.java       |    2 +-
 .../server/checks/AbstractCheckDescriptor.java  |    9 +-
 .../checks/DatabaseConsistencyCheckHelper.java  |    2 -
 .../HardcodedStackVersionPropertiesCheck.java   |   79 +-
 .../server/checks/InstallPackagesCheck.java     |   20 +-
 .../server/checks/PreviousUpgradeCompleted.java |   12 +-
 .../YarnTimelineServerStatePreservingCheck.java |    7 +-
 .../controller/ActionExecutionContext.java      |   53 +-
 .../controller/AmbariActionExecutionHelper.java |  108 +-
 .../AmbariCustomCommandExecutionHelper.java     |  422 ++-
 .../AmbariManagementControllerImpl.java         |  165 +-
 .../ambari/server/controller/HostRequest.java   |   67 +-
 .../ambari/server/controller/HostResponse.java  |  267 +-
 .../server/controller/KerberosHelperImpl.java   |  124 +-
 .../server/controller/PrereqCheckRequest.java   |   27 +-
 .../RootServiceComponentResponse.java           |   51 +-
 .../RootServiceHostComponentResponse.java       |   62 +-
 .../controller/RootServiceResponseFactory.java  |   95 +-
 .../ServiceComponentHostResponse.java           |   41 +-
 .../controller/ServiceComponentResponse.java    |   74 +-
 .../server/controller/ServiceRequest.java       |   46 +-
 .../server/controller/ServiceResponse.java      |   78 +-
 .../AbstractControllerResourceProvider.java     |    2 +-
 .../ClusterStackVersionResourceProvider.java    |  710 +---
 .../internal/ComponentResourceProvider.java     |    9 +-
 .../internal/HostComponentResourceProvider.java |   81 +-
 .../internal/HostResourceProvider.java          |  253 +-
 .../HostStackVersionResourceProvider.java       |   78 +-
 .../controller/internal/HostStatusHelper.java   |    9 +-
 .../PreUpgradeCheckResourceProvider.java        |   27 +-
 .../RepositoryVersionResourceProvider.java      |  100 +-
 ...ootServiceHostComponentResourceProvider.java |   36 +-
 .../internal/ScaleClusterRequest.java           |    8 +-
 .../internal/ServiceResourceProvider.java       |  256 +-
 .../internal/UpgradeResourceProvider.java       | 1198 ++-----
 .../controller/utilities/PropertyHelper.java    |   29 +-
 .../DistributeRepositoriesActionListener.java   |   21 +-
 .../upgrade/HostVersionOutOfSyncListener.java   |  101 +-
 .../listeners/upgrade/StackVersionListener.java |  101 +-
 .../ambari/server/orm/dao/ClusterDAO.java       |  173 +-
 .../server/orm/dao/ClusterVersionDAO.java       |  233 --
 .../server/orm/dao/HostComponentStateDAO.java   |   39 +-
 .../ambari/server/orm/dao/HostVersionDAO.java   |  189 +-
 .../ambari/server/orm/dao/ServiceConfigDAO.java |   19 +-
 .../server/orm/dao/ServiceDesiredStateDAO.java  |   20 +-
 .../apache/ambari/server/orm/dao/StackDAO.java  |   16 +-
 .../orm/entities/ClusterConfigEntity.java       |  129 +-
 .../server/orm/entities/ClusterEntity.java      |   17 -
 .../orm/entities/ClusterVersionEntity.java      |  217 --
 .../server/orm/entities/RepositoryEntity.java   |   11 +-
 .../orm/entities/RepositoryVersionEntity.java   |   11 -
 .../ServiceComponentDesiredStateEntity.java     |  152 +-
 .../entities/ServiceComponentVersionEntity.java |   28 +-
 .../orm/entities/ServiceDesiredStateEntity.java |   87 +-
 .../entities/ServiceDesiredStateEntityPK.java   |    5 +-
 .../server/orm/entities/UpgradeEntity.java      |  199 +-
 .../orm/entities/UpgradeHistoryEntity.java      |  233 ++
 .../PrepareDisableKerberosServerAction.java     |   12 +-
 .../UpdateKerberosConfigsServerAction.java      |   31 +-
 .../upgrades/AbstractUpgradeServerAction.java   |   59 +
 .../upgrades/ComponentVersionCheckAction.java   |   34 +-
 .../serveraction/upgrades/ConfigureAction.java  |    2 +-
 .../upgrades/FinalizeUpgradeAction.java         |  614 ++--
 .../upgrades/UpdateDesiredStackAction.java      |  163 +-
 .../ambari/server/stack/MasterHostResolver.java |   85 +-
 .../apache/ambari/server/stack/RepoUtil.java    |   11 +-
 .../stack/UpdateActiveRepoVersionOnStartup.java |   50 +-
 .../org/apache/ambari/server/state/Cluster.java |  210 +-
 .../ambari/server/state/ConfigHelper.java       |  284 +-
 .../server/state/RepositoryVersionState.java    |   85 +-
 .../org/apache/ambari/server/state/Service.java |   23 +-
 .../ambari/server/state/ServiceComponent.java   |   29 +-
 .../server/state/ServiceComponentHost.java      |   40 +-
 .../server/state/ServiceComponentImpl.java      |  270 +-
 .../ambari/server/state/ServiceFactory.java     |   27 +-
 .../apache/ambari/server/state/ServiceImpl.java |  195 +-
 .../ambari/server/state/UpgradeContext.java     | 1011 ++++--
 .../server/state/UpgradeContextFactory.java     |   25 +-
 .../ambari/server/state/UpgradeHelper.java      |  381 ++-
 .../server/state/cluster/ClusterImpl.java       | 1369 ++------
 .../server/state/cluster/ClustersImpl.java      |   34 +-
 .../ambari/server/state/host/HostImpl.java      |   16 +-
 .../state/repository/VersionDefinitionXml.java  |   26 +-
 .../services/RetryUpgradeActionService.java     |   24 +-
 .../state/stack/upgrade/ClusterGrouping.java    |   12 +-
 .../server/state/stack/upgrade/Direction.java   |   11 +-
 .../server/state/stack/upgrade/ExecuteTask.java |    2 +-
 .../server/state/stack/upgrade/Grouping.java    |   18 +-
 .../state/stack/upgrade/HostOrderGrouping.java  |   19 +-
 .../stack/upgrade/RepositoryVersionHelper.java  |  140 +-
 .../state/stack/upgrade/StageWrapper.java       |    8 +-
 .../stack/upgrade/StageWrapperBuilder.java      |    2 +-
 .../ambari/server/state/stack/upgrade/Task.java |    2 +-
 .../server/state/stack/upgrade/TaskWrapper.java |   10 +-
 .../state/stack/upgrade/TaskWrapperBuilder.java |    8 +-
 .../svccomphost/ServiceComponentHostImpl.java   |  216 +-
 .../ServiceComponentHostSummary.java            |  112 +-
 .../server/upgrade/AbstractUpgradeCatalog.java  |   30 +-
 .../server/upgrade/SchemaUpgradeHelper.java     |   15 +-
 .../server/upgrade/StackUpgradeHelper.java      |  172 -
 .../ambari/server/upgrade/StackUpgradeUtil.java |  197 --
 .../server/upgrade/UpgradeCatalog200.java       |  611 ----
 .../server/upgrade/UpgradeCatalog210.java       | 1761 ----------
 .../server/upgrade/UpgradeCatalog211.java       |  295 --
 .../server/upgrade/UpgradeCatalog212.java       |  404 ---
 .../server/upgrade/UpgradeCatalog2121.java      |  194 --
 .../server/upgrade/UpgradeCatalog220.java       | 1409 --------
 .../server/upgrade/UpgradeCatalog221.java       |  448 ---
 .../server/upgrade/UpgradeCatalog222.java       |  751 -----
 .../server/upgrade/UpgradeCatalog230.java       |  402 ---
 .../server/upgrade/UpgradeCatalog240.java       | 3020 ------------------
 .../server/upgrade/UpgradeCatalog2402.java      |  207 --
 .../server/upgrade/UpgradeCatalog242.java       |  272 --
 .../server/upgrade/UpgradeCatalog250.java       | 1344 --------
 .../apache/ambari/server/utils/StageUtils.java  |   64 +-
 .../main/python/ambari_server/serverUpgrade.py  |  140 -
 .../src/main/resources/META-INF/persistence.xml |    1 -
 .../ambari/server/StateRecoveryManagerTest.java |  134 +-
 .../ExecutionCommandWrapperTest.java            |   39 +-
 .../ComponentVersionAlertRunnableTest.java      |   36 +-
 .../creator/UpgradeEventCreatorTest.java        |    4 +-
 ...ardcodedStackVersionPropertiesCheckTest.java |   10 +-
 .../server/checks/InstallPackagesCheckTest.java |   32 +-
 .../checks/PreviousUpgradeCompletedTest.java    |   15 +-
 ...nTimelineServerStatePreservingCheckTest.java |   23 +-
 .../AmbariCustomCommandExecutionHelperTest.java |  174 +-
 .../RootServiceResponseFactoryTest.java         |   11 +-
 ...ClusterStackVersionResourceProviderTest.java |  548 +---
 .../internal/HostResourceProviderTest.java      |  184 +-
 .../HostStackVersionResourceProviderTest.java   |   14 +-
 .../PreUpgradeCheckResourceProviderTest.java    |   22 +-
 .../RepositoryVersionResourceProviderTest.java  |  100 +-
 .../internal/ServiceResourceProviderTest.java   |  157 +-
 .../internal/UpgradeResourceProviderTest.java   |  532 +--
 .../HostVersionOutOfSyncListenerTest.java       |  178 +-
 .../upgrade/StackVersionListenerTest.java       |  129 +-
 .../orm/dao/HostComponentStateDAOTest.java      |    4 +-
 .../server/orm/dao/HostVersionDAOTest.java      |   38 +-
 .../server/orm/dao/ServiceConfigDAOTest.java    |  419 +--
 .../ComponentVersionCheckActionTest.java        |  223 +-
 .../ambari/server/stack/RepoUtilTest.java       |   10 +-
 .../UpdateActiveRepoVersionOnStartupTest.java   |   88 +-
 .../ambari/server/state/UpgradeHelperTest.java  |  648 ++--
 .../state/repository/VersionDefinitionTest.java |    2 +-
 .../services/RetryUpgradeActionServiceTest.java |   46 +-
 .../upgrade/RepositoryVersionHelperTest.java    |   31 +-
 .../stack/upgrade/StageWrapperBuilderTest.java  |   12 +-
 .../server/upgrade/StackUpgradeUtilTest.java    |  145 -
 .../server/upgrade/UpgradeCatalog200Test.java   |  922 ------
 .../server/upgrade/UpgradeCatalog210Test.java   | 1345 --------
 .../server/upgrade/UpgradeCatalog211Test.java   |  444 ---
 .../server/upgrade/UpgradeCatalog2121Test.java  |  164 -
 .../server/upgrade/UpgradeCatalog212Test.java   |  545 ----
 .../server/upgrade/UpgradeCatalog220Test.java   | 1633 ----------
 .../server/upgrade/UpgradeCatalog221Test.java   |  614 ----
 .../server/upgrade/UpgradeCatalog222Test.java   | 1125 -------
 .../server/upgrade/UpgradeCatalog230Test.java   |  313 --
 .../server/upgrade/UpgradeCatalog240Test.java   | 2586 ---------------
 .../server/upgrade/UpgradeCatalog242Test.java   |  448 ---
 .../server/upgrade/UpgradeCatalog250Test.java   | 2131 ------------
 170 files changed, 7859 insertions(+), 33121 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/48f7fb22/ambari-server/src/main/java/org/apache/ambari/annotations/Experimental.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/annotations/Experimental.java b/ambari-server/src/main/java/org/apache/ambari/annotations/Experimental.java
index 8282095..5495933 100644
--- a/ambari-server/src/main/java/org/apache/ambari/annotations/Experimental.java
+++ b/ambari-server/src/main/java/org/apache/ambari/annotations/Experimental.java
@@ -1,4 +1,4 @@
-/**
+/*
  * 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

http://git-wip-us.apache.org/repos/asf/ambari/blob/48f7fb22/ambari-server/src/main/java/org/apache/ambari/server/StateRecoveryManager.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/StateRecoveryManager.java b/ambari-server/src/main/java/org/apache/ambari/server/StateRecoveryManager.java
index aa6f053..03990a2 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/StateRecoveryManager.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/StateRecoveryManager.java
@@ -1,4 +1,4 @@
-/**
+/*
  * 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
@@ -18,16 +18,17 @@
 
 package org.apache.ambari.server;
 
-import com.google.inject.Inject;
-import org.apache.ambari.server.orm.dao.ClusterVersionDAO;
+import java.util.List;
+
 import org.apache.ambari.server.orm.dao.HostVersionDAO;
-import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
+import org.apache.ambari.server.orm.dao.ServiceComponentDesiredStateDAO;
 import org.apache.ambari.server.orm.entities.HostVersionEntity;
+import org.apache.ambari.server.orm.entities.ServiceComponentDesiredStateEntity;
 import org.apache.ambari.server.state.RepositoryVersionState;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.List;
+import com.google.inject.Inject;
 
 /**
  * Is executed on server start.
@@ -35,20 +36,18 @@ import java.util.List;
  */
 public class StateRecoveryManager {
 
-  private static Logger LOG = LoggerFactory.getLogger(StateRecoveryManager.class);
+  private static final Logger LOG = LoggerFactory.getLogger(StateRecoveryManager.class);
 
   @Inject
   private HostVersionDAO hostVersionDAO;
 
   @Inject
-  private ClusterVersionDAO clusterVersionDAO;
-
+  private ServiceComponentDesiredStateDAO serviceComponentDAO;
 
   public void doWork() {
     checkHostAndClusterVersions();
   }
 
-
   void checkHostAndClusterVersions() {
     List<HostVersionEntity> hostVersions = hostVersionDAO.findAll();
     for (HostVersionEntity hostVersion : hostVersions) {
@@ -65,18 +64,20 @@ public class StateRecoveryManager {
       }
     }
 
-    List<ClusterVersionEntity> clusterVersions = clusterVersionDAO.findAll();
-    for (ClusterVersionEntity clusterVersion : clusterVersions) {
-      if (clusterVersion.getState().equals(RepositoryVersionState.INSTALLING)) {
-        clusterVersion.setState(RepositoryVersionState.INSTALL_FAILED);
+    List<ServiceComponentDesiredStateEntity> components = serviceComponentDAO.findAll();
+    for (ServiceComponentDesiredStateEntity component : components) {
+      if (RepositoryVersionState.INSTALLING == component.getRepositoryState()) {
+        component.setRepositoryState(RepositoryVersionState.INSTALL_FAILED);
+        serviceComponentDAO.merge(component);
         String msg = String.format(
-                "Recovered state of cluster version %s for cluster %s from %s to %s",
-                clusterVersion.getRepositoryVersion().getDisplayName(),
-                clusterVersion.getClusterEntity().getClusterName(),
-                RepositoryVersionState.INSTALLING,
-                RepositoryVersionState.INSTALL_FAILED);
+            "Recovered state of cluster %s of component %s/%s for version %s from %s to %s",
+            component.getClusterId(),
+            component.getServiceName(),
+            component.getComponentName(),
+            component.getDesiredRepositoryVersion().getDisplayName(),
+            RepositoryVersionState.INSTALLING,
+            RepositoryVersionState.INSTALL_FAILED);
         LOG.warn(msg);
-        clusterVersionDAO.merge(clusterVersion);
       }
     }
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/48f7fb22/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 28946e7..efd609a 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
@@ -17,29 +17,25 @@
  */
 package org.apache.ambari.server.actionmanager;
 
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.HOOKS_FOLDER;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SERVICE_PACKAGE_FOLDER;
-
 import java.util.HashMap;
 import java.util.Map;
-import java.util.Set;
 import java.util.TreeMap;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.ClusterNotFoundException;
+import org.apache.ambari.server.ServiceNotFoundException;
 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.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.orm.dao.HostRoleCommandDAO;
-import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
+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.ServiceInfo;
-import org.apache.ambari.server.state.StackId;
-import org.apache.ambari.server.state.StackInfo;
+import org.apache.ambari.server.state.Service;
+import org.apache.ambari.server.state.ServiceComponent;
+import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -67,12 +63,6 @@ public class ExecutionCommandWrapper {
   @Inject
   private Gson gson;
 
-  /**
-   * Used for injecting hooks and common-services into the command.
-   */
-  @Inject
-  private AmbariMetaInfo ambariMetaInfo;
-
   @AssistedInject
   public ExecutionCommandWrapper(@Assisted String jsonExecutionCommand) {
     this.jsonExecutionCommand = jsonExecutionCommand;
@@ -95,7 +85,6 @@ public class ExecutionCommandWrapper {
    * long as it has been instructed to set updated ones at execution time.
    *
    * @return
-   * @see ExecutionCommand#setForceRefreshConfigTagsBeforeExecution(Set)
    */
   public ExecutionCommand getExecutionCommand() {
     if (executionCommand != null) {
@@ -155,7 +144,8 @@ public class ExecutionCommandWrapper {
       // now that the tags have been updated (if necessary), fetch the
       // configurations
       Map<String, Map<String, String>> configurationTags = executionCommand.getConfigurationTags();
-      if (null != configurationTags && !configurationTags.isEmpty()) {
+
+      if (MapUtils.isNotEmpty(configurationTags)) {
         Map<String, Map<String, String>> configProperties = configHelper
             .getEffectiveConfigProperties(cluster, configurationTags);
 
@@ -196,34 +186,44 @@ public class ExecutionCommandWrapper {
         }
       }
 
-      Map<String,String> commandParams = executionCommand.getCommandParams();
+      // set the repository version for the component this command is for -
+      // always use the current desired version
+      try {
+        RepositoryVersionEntity repositoryVersion = null;
+        String serviceName = executionCommand.getServiceName();
+        if (!StringUtils.isEmpty(serviceName)) {
+          Service service = cluster.getService(serviceName);
+          if (null != service) {
+            repositoryVersion = service.getDesiredRepositoryVersion();
+          }
 
-      ClusterVersionEntity effectiveClusterVersion = cluster.getEffectiveClusterVersion();
-      if (null != effectiveClusterVersion) {
-        commandParams.put(KeyNames.VERSION,
-            effectiveClusterVersion.getRepositoryVersion().getVersion());
-      }
+          String componentName = executionCommand.getComponentName();
+          if (!StringUtils.isEmpty(componentName)) {
+            ServiceComponent serviceComponent = service.getServiceComponent(
+                executionCommand.getComponentName());
 
-      // add the stack and common-services folders to the command, but only if
-      // they don't exist - they may have been put on here with specific values
-      // ahead of time
-      StackId stackId = cluster.getDesiredStackVersion();
-      StackInfo stackInfo = ambariMetaInfo.getStack(stackId.getStackName(),
-          stackId.getStackVersion());
+            if (null != serviceComponent) {
+              repositoryVersion = serviceComponent.getDesiredRepositoryVersion();
+            }
+          }
+        }
 
-      if (!commandParams.containsKey(HOOKS_FOLDER)) {
-        commandParams.put(HOOKS_FOLDER, stackInfo.getStackHooksFolder());
+        if (null != repositoryVersion) {
+          executionCommand.getCommandParams().put(KeyNames.VERSION, repositoryVersion.getVersion());
+          executionCommand.getHostLevelParams().put(KeyNames.CURRENT_VERSION, repositoryVersion.getVersion());
+        }
+      } catch (ServiceNotFoundException serviceNotFoundException) {
+        // it's possible that there are commands specified for a service where
+        // the service doesn't exist yet
+        LOG.warn(
+            "The service {} is not installed in the cluster. No repository version will be sent for this command.",
+            executionCommand.getServiceName());
       }
 
-      if (!commandParams.containsKey(SERVICE_PACKAGE_FOLDER)) {
-        String serviceName = executionCommand.getServiceName();
-        if (!StringUtils.isEmpty(serviceName)) {
-          ServiceInfo serviceInfo = ambariMetaInfo.getService(stackId.getStackName(),
-              stackId.getStackVersion(), serviceName);
+      // set the desired versions of versionable components.  This is safe even during an upgrade because
+      // we are "loading-late": components that have not yet upgraded in an EU will have the correct versions.
+      executionCommand.setComponentVersions(cluster);
 
-          commandParams.put(SERVICE_PACKAGE_FOLDER, serviceInfo.getServicePackageFolder());
-        }
-      }
     } 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/48f7fb22/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ExecutionCommandWrapperFactory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ExecutionCommandWrapperFactory.java b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ExecutionCommandWrapperFactory.java
index 29ee709..02d1b23 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ExecutionCommandWrapperFactory.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ExecutionCommandWrapperFactory.java
@@ -1,4 +1,4 @@
-/**
+/*
  * 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

http://git-wip-us.apache.org/repos/asf/ambari/blob/48f7fb22/ambari-server/src/main/java/org/apache/ambari/server/agent/CommandRepository.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/CommandRepository.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/CommandRepository.java
new file mode 100644
index 0000000..3d96122
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/CommandRepository.java
@@ -0,0 +1,184 @@
+/**
+ * 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.agent;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.ambari.server.orm.entities.RepositoryEntity;
+import org.apache.ambari.server.state.RepositoryInfo;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * Wraps the information required to create repositories from a command.  This was added
+ * as a top level command object.
+ */
+public class CommandRepository {
+
+  @SerializedName("repositories")
+  private List<Repository> m_repositories = new ArrayList<>();
+
+  @SerializedName("repoVersion")
+  private String m_repoVersion;
+
+  @SerializedName("repoVersionId")
+  private long m_repoVersionId;
+
+  @SerializedName("stackName")
+  private String m_stackName;
+
+  /**
+   * @param version the repo version
+   */
+  public void setRepositoryVersion(String version) {
+    m_repoVersion = version;
+  }
+
+  /**
+   * @param id the repository id
+   */
+  public void setRepositoryVersionId(long id) {
+    m_repoVersionId = id;
+  }
+
+  /**
+   * @param name the stack name
+   */
+  public void setStackName(String name) {
+    m_stackName = name;
+  }
+
+  /**
+   * @param repositories the repositories if sourced from the stack instead of the repo_version.
+   */
+  public void setRepositories(Collection<RepositoryInfo> repositories) {
+    m_repositories = new ArrayList<>();
+
+    for (RepositoryInfo info : repositories) {
+      m_repositories.add(new Repository(info));
+    }
+  }
+
+  /**
+   * @param osType        the OS type for the repositories
+   * @param repositories  the repository entities that should be processed into a file
+   */
+  public void setRepositories(String osType, Collection<RepositoryEntity> repositories) {
+    m_repositories = new ArrayList<>();
+
+    for (RepositoryEntity entity : repositories) {
+      m_repositories.add(new Repository(osType, entity));
+    }
+  }
+
+  /**
+   * @return the repositories that the command should process into a file.
+   */
+  public Collection<Repository> getRepositories() {
+    return m_repositories;
+  }
+
+  /**
+   * Sets a uniqueness on the repo ids.
+   *
+   * @param suffix  the repo id suffix
+   */
+  public void setUniqueSuffix(String suffix) {
+    for (Repository repo : m_repositories) {
+      repo.m_repoId = repo.m_repoId + suffix;
+    }
+  }
+
+  /**
+   * Minimal information required to generate repo files on the agent.  These are copies
+   * of the repository objects from repo versions that can be changed for URL overrides, etc.
+   */
+  public static class Repository {
+
+    @SerializedName("baseUrl")
+    private String m_baseUrl;
+
+    @SerializedName("repoId")
+    private String m_repoId;
+
+    /**
+     * The name should not change.  Ubuntu requires that it match exactly as the repo was built.
+     */
+    @SerializedName("repoName")
+    private final String m_repoName;
+
+    @SerializedName("mirrorsList")
+    private String m_mirrorsList;
+
+    private transient String m_osType;
+
+    private Repository(RepositoryInfo info) {
+      m_baseUrl = info.getBaseUrl();
+      m_osType = info.getOsType();
+      m_repoId = info.getRepoId();
+      m_repoName = info.getRepoName();
+      m_mirrorsList = info.getMirrorsList();
+    }
+
+    private Repository(String osType, RepositoryEntity entity) {
+      m_baseUrl = entity.getBaseUrl();
+      m_repoId = entity.getRepositoryId();
+      m_repoName = entity.getName();
+      m_mirrorsList = entity.getMirrorsList();
+      m_osType = osType;
+    }
+
+    public void setBaseUrl(String url) {
+      m_baseUrl = url;
+    }
+
+    public String getOsType() {
+      return m_osType;
+    }
+
+    public String getRepoId() {
+      return m_repoId;
+    }
+
+    public String getRepoName() {
+      return m_repoName;
+    }
+
+
+    public String getBaseUrl() {
+      return m_baseUrl;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String toString() {
+      return new ToStringBuilder(null)
+          .append("os", m_osType)
+          .append("name", m_repoName)
+          .append("id", m_repoId)
+          .append("baseUrl", m_baseUrl)
+          .toString();
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/48f7fb22/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 32fb37b..441c047 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
@@ -1,4 +1,4 @@
-/**
+/*
  * 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
@@ -24,11 +24,16 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.ambari.annotations.Experimental;
+import org.apache.ambari.annotations.ExperimentalFeature;
+import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.RoleCommand;
-import org.apache.ambari.server.state.ServiceInfo;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Service;
+import org.apache.ambari.server.state.ServiceComponent;
 import org.apache.ambari.server.utils.StageUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.gson.annotations.SerializedName;
 
@@ -39,7 +44,7 @@ import com.google.gson.annotations.SerializedName;
  */
 public class ExecutionCommand extends AgentCommand {
 
-  private static Log LOG = LogFactory.getLog(ExecutionCommand.class);
+  private static final Logger LOG = LoggerFactory.getLogger(ExecutionCommand.class);
 
   public ExecutionCommand() {
     super(AgentCommandType.EXECUTION_COMMAND);
@@ -67,7 +72,7 @@ public class ExecutionCommand extends AgentCommand {
   private String role;
 
   @SerializedName("hostLevelParams")
-  private Map<String, String> hostLevelParams = new HashMap<String, String>();
+  private Map<String, String> hostLevelParams = new HashMap<>();
 
   @SerializedName("roleParams")
   private Map<String, String> roleParams = null;
@@ -76,8 +81,7 @@ public class ExecutionCommand extends AgentCommand {
   private RoleCommand roleCommand;
 
   @SerializedName("clusterHostInfo")
-  private Map<String, Set<String>> clusterHostInfo =
-      new HashMap<String, Set<String>>();
+  private Map<String, Set<String>> clusterHostInfo = new HashMap<>();
 
   @SerializedName("configurations")
   private Map<String, Map<String, String>> configurations;
@@ -92,7 +96,7 @@ public class ExecutionCommand extends AgentCommand {
   private boolean forceRefreshConfigTagsBeforeExecution = false;
 
   @SerializedName("commandParams")
-  private Map<String, String> commandParams = new HashMap<String, String>();
+  private Map<String, String> commandParams = new HashMap<>();
 
   @SerializedName("serviceName")
   private String serviceName;
@@ -104,13 +108,10 @@ public class ExecutionCommand extends AgentCommand {
   private String componentName;
 
   @SerializedName("kerberosCommandParams")
-  private List<Map<String, String>> kerberosCommandParams = new ArrayList<Map<String, String>>();
+  private List<Map<String, String>> kerberosCommandParams = new ArrayList<>();
 
   @SerializedName("localComponents")
-  private Set<String> localComponents = new HashSet<String>();
-
-  @SerializedName("availableServices")
-  private Map<String, String> availableServices = new HashMap<>();
+  private Set<String> localComponents = new HashSet<>();
 
   /**
    * "true" or "false" indicating whether this
@@ -144,12 +145,23 @@ public class ExecutionCommand extends AgentCommand {
   @SerializedName("configuration_credentials")
   private Map<String, Map<String, String>> configurationCredentials;
 
+
+  /**
+   * Provides information regarding the content of repositories.  This structure replaces
+   * the deprecated use of {@link KeyNames#REPO_INFO}
+   */
+  @SerializedName("repositoryFile")
+  private CommandRepository commandRepository;
+
+  @SerializedName("componentVersionMap")
+  private Map<String, Map<String, String>> componentVersionMap = new HashMap<>();
+
   public void setConfigurationCredentials(Map<String, Map<String, String>> configurationCredentials) {
     this.configurationCredentials = configurationCredentials;
   }
 
   public Map<String, Map<String, String>> getConfigurationCredentials() {
-    return this.configurationCredentials;
+    return configurationCredentials;
   }
 
   public String getCommandId() {
@@ -291,18 +303,6 @@ public class ExecutionCommand extends AgentCommand {
     this.localComponents = localComponents;
   }
 
-  public Map<String, String> getAvailableServices() {
-    return availableServices;
-  }
-
-  public void setAvailableServicesFromServiceInfoMap(Map<String, ServiceInfo> serviceInfoMap) {
-    Map<String, String> serviceVersionMap = new HashMap<>();
-    for (Map.Entry<String, ServiceInfo> entry : serviceInfoMap.entrySet()) {
-      serviceVersionMap.put(entry.getKey(), entry.getValue().getVersion());
-    }
-    availableServices = serviceVersionMap;
-  }
-
   public Map<String, Map<String, Map<String, String>>> getConfigurationAttributes() {
     return configurationAttributes;
   }
@@ -395,10 +395,24 @@ public class ExecutionCommand extends AgentCommand {
   }
 
   /**
+   * @return the repository file that is to be written.
+   */
+  public CommandRepository getRepositoryFile() {
+    return commandRepository;
+  }
+
+  /**
+   * @param repository  the command repository instance.
+   */
+  public void setRepositoryFile(CommandRepository repository) {
+    commandRepository = repository;
+  }
+
+  /**
    * Contains key name strings. These strings are used inside maps
    * incapsulated inside command.
    */
-  public static interface KeyNames {
+  public interface KeyNames {
     String COMMAND_TIMEOUT = "command_timeout";
     String SCRIPT = "script";
     String SCRIPT_TYPE = "script_type";
@@ -421,6 +435,11 @@ public class ExecutionCommand extends AgentCommand {
     String ORACLE_JDBC_URL = "oracle_jdbc_url";
     String DB_DRIVER_FILENAME = "db_driver_filename";
     String CLIENTS_TO_UPDATE_CONFIGS = "clientsToUpdateConfigs";
+    /**
+     * Keep for backward compatibility.
+     */
+    @Deprecated
+    @Experimental(feature=ExperimentalFeature.PATCH_UPGRADES)
     String REPO_INFO = "repo_info";
     String DB_NAME = "db_name";
     String GLOBAL = "global";
@@ -433,7 +452,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";
@@ -454,6 +472,8 @@ public class ExecutionCommand extends AgentCommand {
     /**
      * The key indicating that the package_version string is available
      */
+    @Deprecated
+    @Experimental(feature=ExperimentalFeature.PATCH_UPGRADES)
     String PACKAGE_VERSION = "package_version";
 
     /**
@@ -468,6 +488,63 @@ public class ExecutionCommand extends AgentCommand {
      * The agent will return this value back in its response so the repository
      * can be looked up and possibly have its version updated.
      */
+    @Deprecated
+    @Experimental(feature=ExperimentalFeature.PATCH_UPGRADES)
     String REPO_VERSION_ID = "repository_version_id";
+
+    /**
+     * 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";
+  }
+
+  /**
+   * @return
+   */
+  public Map<String, Map<String, String>> getComponentVersionMap() {
+    return componentVersionMap;
+  }
+
+  /**
+   * Used to set a map of {service -> { component -> version}}.  This is necessary when performing
+   * an upgrade to correct build paths of required binaries.
+   * @param cluster the cluster from which to build the map
+   */
+  public void setComponentVersions(Cluster cluster) throws AmbariException {
+    Map<String, Map<String, String>> componentVersionMap = new HashMap<>();
+
+    for (Service service : cluster.getServices().values()) {
+      Map<String, String> componentMap = new HashMap<>();
+
+      boolean shouldSet = false;
+      for (ServiceComponent component : service.getServiceComponents().values()) {
+        if (component.isVersionAdvertised()) {
+          shouldSet = true;
+          componentMap.put(component.getName(), component.getDesiredVersion());
+        }
+      }
+
+      if (shouldSet) {
+        componentVersionMap.put(service.getName(), componentMap);
+      }
+    }
+
+    this.componentVersionMap = componentVersionMap;
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/48f7fb22/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatProcessor.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatProcessor.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatProcessor.java
index 222f201..6fc3bdd 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatProcessor.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatProcessor.java
@@ -293,13 +293,13 @@ public class HeartbeatProcessor extends AbstractService{
         int slaveCount = 0;
         int slavesRunning = 0;
 
-        StackId stackId;
         Cluster cluster = clusterFsm.getCluster(clusterName);
-        stackId = cluster.getDesiredStackVersion();
 
 
         List<ServiceComponentHost> scHosts = cluster.getServiceComponentHosts(heartbeat.getHostname());
         for (ServiceComponentHost scHost : scHosts) {
+          StackId stackId = scHost.getDesiredStackId();
+
           ComponentInfo componentInfo =
               ambariMetaInfo.getComponent(stackId.getStackName(),
                   stackId.getStackVersion(), scHost.getServiceName(),
@@ -356,7 +356,7 @@ public class HeartbeatProcessor extends AbstractService{
     List<CommandReport> reports = heartbeat.getReports();
 
     // Cache HostRoleCommand entities because we will need them few times
-    List<Long> taskIds = new ArrayList<Long>();
+    List<Long> taskIds = new ArrayList<>();
     for (CommandReport report : reports) {
       taskIds.add(report.getTaskId());
     }
@@ -491,9 +491,7 @@ public class HeartbeatProcessor extends AbstractService{
             }
 
             // Updating stack version, if needed (this is not actually for express/rolling upgrades!)
-            if (scHost.getState().equals(org.apache.ambari.server.state.State.UPGRADING)) {
-              scHost.setStackVersion(scHost.getDesiredStackVersion());
-            } else if ((report.getRoleCommand().equals(RoleCommand.START.toString()) ||
+            if ((report.getRoleCommand().equals(RoleCommand.START.toString()) ||
                 (report.getRoleCommand().equals(RoleCommand.CUSTOM_COMMAND.toString()) &&
                     ("START".equals(report.getCustomCommand()) ||
                         "RESTART".equals(report.getCustomCommand()))))
@@ -615,10 +613,6 @@ public class HeartbeatProcessor extends AbstractService{
                 }
               }
 
-              if (null != status.getStackVersion() && !status.getStackVersion().isEmpty()) {
-                scHost.setStackVersion(gson.fromJson(status.getStackVersion(), StackId.class));
-              }
-
               if (null != status.getConfigTags()) {
                 scHost.updateActualConfigs(status.getConfigTags());
               }

http://git-wip-us.apache.org/repos/asf/ambari/blob/48f7fb22/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 9dc10ea..45cc973 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
@@ -1,4 +1,4 @@
-/**
+/*
  * 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
@@ -28,7 +28,6 @@ import java.util.TreeMap;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
-import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
 import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 import org.apache.ambari.server.orm.entities.UpgradeEntity;
 import org.apache.ambari.server.state.Alert;
@@ -36,9 +35,11 @@ import org.apache.ambari.server.state.AlertState;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.ComponentInfo;
 import org.apache.ambari.server.state.Host;
+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.State;
+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.
@@ -75,17 +76,6 @@ public class ComponentVersionAlertRunnable extends AlertRunnable {
    */
   private static final String MISMATCHED_VERSIONS_MSG = "The following components are reporting unexpected versions: ";
 
-  /**
-   * The message when there is no CURRENT cluster version, but the cluster is
-   * still being setup.
-   */
-  private static final String CLUSTER_PROVISIONING_MSG = "The cluster is currently being provisioned. This alert will be skipped.";
-
-  /**
-   * The message when there is no CURRENT cluster version.
-   */
-  private static final String CLUSTER_OUT_OF_SYNC_MSG = "The cluster's CURRENT version could not be determined.";
-
   @Inject
   private AmbariMetaInfo m_metaInfo;
 
@@ -102,13 +92,12 @@ public class ComponentVersionAlertRunnable extends AlertRunnable {
    * {@inheritDoc}
    */
   @Override
-  List<Alert> execute(Cluster cluster, AlertDefinitionEntity myDefinition) {
+  List<Alert> execute(Cluster cluster, AlertDefinitionEntity myDefinition) throws AmbariException {
     // if there is an upgrade in progress, then skip running this alert
     UpgradeEntity upgrade = cluster.getUpgradeInProgress();
     if (null != upgrade) {
-      RepositoryVersionEntity repositoryVersion = upgrade.getToRepositoryVersion();
-      String message = MessageFormat.format(UPGRADE_IN_PROGRESS_MSG,
-          repositoryVersion.getVersion());
+      Direction direction = upgrade.getDirection();
+      String message = MessageFormat.format(UPGRADE_IN_PROGRESS_MSG, direction.getText(false));
 
       return Collections.singletonList(
           buildAlert(cluster, myDefinition, AlertState.SKIPPED, message));
@@ -117,27 +106,15 @@ public class ComponentVersionAlertRunnable extends AlertRunnable {
     TreeMap<Host, Set<ServiceComponentHost>> versionMismatches = new TreeMap<>();
     Collection<Host> hosts = cluster.getHosts();
 
-    // no cluster version is very bad ...
-    ClusterVersionEntity clusterVersionEntity = cluster.getCurrentClusterVersion();
-    if (null == clusterVersionEntity) {
-      if (cluster.getProvisioningState() == State.INIT
-          || cluster.getAllClusterVersions().size() == 1) {
-        return Collections.singletonList(
-            buildAlert(cluster, myDefinition, AlertState.SKIPPED, CLUSTER_PROVISIONING_MSG));
-      } else {
-        return Collections.singletonList(
-            buildAlert(cluster, myDefinition, AlertState.CRITICAL, CLUSTER_OUT_OF_SYNC_MSG));
-      }
-    }
-
-    RepositoryVersionEntity repositoryVersionEntity = clusterVersionEntity.getRepositoryVersion();
-    String clusterVersion = repositoryVersionEntity.getVersion();
-
     for (Host host : hosts) {
-      List<ServiceComponentHost> hostComponents = cluster.getServiceComponentHosts(
-          host.getHostName());
+      List<ServiceComponentHost> hostComponents = cluster.getServiceComponentHosts(host.getHostName());
       for (ServiceComponentHost hostComponent : hostComponents) {
-        StackId desiredStackId = hostComponent.getDesiredStackVersion();
+        Service service = cluster.getService(hostComponent.getServiceName());
+        ServiceComponent serviceComponent = service.getServiceComponent(hostComponent.getServiceComponentName());
+
+        RepositoryVersionEntity desiredRepositoryVersion = service.getDesiredRepositoryVersion();
+        StackId desiredStackId = serviceComponent.getDesiredStackId();
+        String desiredVersion = desiredRepositoryVersion.getVersion();
 
         final ComponentInfo componentInfo;
         try {
@@ -159,7 +136,7 @@ public class ComponentVersionAlertRunnable extends AlertRunnable {
         }
 
         String version = hostComponent.getVersion();
-        if (!StringUtils.equals(version, clusterVersion)) {
+        if (!StringUtils.equals(version, desiredVersion)) {
           Set<ServiceComponentHost> mismatchedComponents = versionMismatches.get(host);
           if (null == mismatchedComponents) {
             mismatchedComponents = new HashSet<>();
@@ -194,4 +171,4 @@ public class ComponentVersionAlertRunnable extends AlertRunnable {
 
     return Collections.singletonList(buildAlert(cluster, myDefinition, alertState, alertText));
   }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/48f7fb22/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
index 2d13cba..4ca35a9 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
@@ -1,4 +1,4 @@
-/**
+/*
  * 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
@@ -140,8 +140,17 @@ public class AmbariMetaInfo {
     }
   };
   private final static Logger LOG = LoggerFactory.getLogger(AmbariMetaInfo.class);
+
+  /**
+   * Repository XML base url property name
+   */
   public static final String REPOSITORY_XML_PROPERTY_BASEURL = "baseurl";
 
+  /**
+   * Repository XML mirrors list property name
+   */
+  public static final String REPOSITORY_XML_PROPERTY_MIRRORSLIST = "mirrorslist";
+
   // all the supported OS'es
   @Inject
   private OsFamily osFamily;
@@ -258,7 +267,7 @@ public class AmbariMetaInfo {
   @Inject
   public void init() throws Exception {
     // Need to be initialized before all actions
-    ALL_SUPPORTED_OS = new ArrayList<String>(osFamily.os_list());
+    ALL_SUPPORTED_OS = new ArrayList<>(osFamily.os_list());
 
     readServerVersion();
 
@@ -371,12 +380,19 @@ public class AmbariMetaInfo {
     return foundDependency;
   }
 
+  /**
+   * Gets repositories that are keyed by operating system type.
+   * @param stackName the stack name
+   * @param version   the stack version
+   * @return
+   * @throws AmbariException
+   */
   public Map<String, List<RepositoryInfo>> getRepository(String stackName,
                                                          String version) throws AmbariException {
     StackInfo stack = getStack(stackName, version);
     List<RepositoryInfo> repository = stack.getRepositories();
 
-    Map<String, List<RepositoryInfo>> reposResult = new HashMap<String, List<RepositoryInfo>>();
+    Map<String, List<RepositoryInfo>> reposResult = new HashMap<>();
     for (RepositoryInfo repo : repository) {
       if (!reposResult.containsKey(repo.getOsType())) {
         reposResult.put(repo.getOsType(),
@@ -393,7 +409,7 @@ public class AmbariMetaInfo {
     StackInfo stack = getStack(stackName, version);
     List<RepositoryInfo> repositories = stack.getRepositories();
 
-    List<RepositoryInfo> repositoriesResult = new ArrayList<RepositoryInfo>();
+    List<RepositoryInfo> repositoriesResult = new ArrayList<>();
     for (RepositoryInfo repository : repositories) {
       if (repository.getOsType().equals(osType)) {
         repositoriesResult.add(repository);
@@ -480,10 +496,7 @@ public class AmbariMetaInfo {
   public String getComponentToService(String stackName, String version,
                                       String componentName) throws AmbariException {
     if (LOG.isDebugEnabled()) {
-      LOG.debug("Looking for service for component"
-          + ", stackName=" + stackName
-          + ", stackVersion=" + version
-          + ", componentName=" + componentName);
+      LOG.debug("Looking for service for component, stackName={}, stackVersion={}, componentName={}", stackName, version, componentName);
     }
     Map<String, ServiceInfo> services = getServices(stackName, version);
     String retService = null;
@@ -510,7 +523,7 @@ public class AmbariMetaInfo {
    */
   public Map<String, ServiceInfo> getServices(String stackName, String version) throws AmbariException {
 
-    Map<String, ServiceInfo> servicesInfoResult = new HashMap<String, ServiceInfo>();
+    Map<String, ServiceInfo> servicesInfoResult = new HashMap<>();
 
     Collection<ServiceInfo> services;
     StackInfo stack;
@@ -529,6 +542,18 @@ public class AmbariMetaInfo {
     return servicesInfoResult;
   }
 
+  /**
+   * Convenience method to use stack id instead of separate name and version.
+   * @param service
+   *            the service business object
+   * @return  the service info instance defined from the stack for the business object
+   * @throws AmbariException
+   */
+  public ServiceInfo getService(Service service) throws AmbariException {
+    StackId stackId = service.getDesiredStackId();
+    return getService(stackId.getStackName(), stackId.getStackVersion(), service.getName());
+  }
+
   public ServiceInfo getService(String stackName, String version, String serviceName) throws AmbariException {
     ServiceInfo service = getStack(stackName, version).getService(serviceName);
 
@@ -546,10 +571,11 @@ public class AmbariMetaInfo {
     return removedServices.contains(serviceName);
   }
 
+
   public Collection<String> getMonitoringServiceNames(String stackName, String version)
     throws AmbariException{
 
-    List<String> monitoringServices = new ArrayList<String>();
+    List<String> monitoringServices = new ArrayList<>();
     for (ServiceInfo service : getServices(stackName, version).values()) {
       if ((service.isMonitoringService() != null) && service.isMonitoringService()) {
         monitoringServices.add(service.getName());
@@ -561,7 +587,7 @@ public class AmbariMetaInfo {
   public Set<String> getRestartRequiredServicesNames(String stackName, String version)
     throws AmbariException{
 
-    HashSet<String> needRestartServices = new HashSet<String>();
+    HashSet<String> needRestartServices = new HashSet<>();
     Collection<ServiceInfo> serviceInfos = getServices(stackName, version).values();
 
     for (ServiceInfo service : serviceInfos) {
@@ -588,7 +614,7 @@ public class AmbariMetaInfo {
   public Set<String> getRackSensitiveServicesNames(String stackName, String version)
       throws AmbariException {
 
-    HashSet<String> needRestartServices = new HashSet<String>();
+    HashSet<String> needRestartServices = new HashSet<>();
 
     Collection<ServiceInfo> serviceInfos = getServices(stackName, version).values();
 
@@ -617,6 +643,17 @@ public class AmbariMetaInfo {
     return stacks;
   }
 
+  /**
+   * Convenience method to get stack info from a stack id
+   * @param stackId
+   *            the stack id
+   * @return  the stack info
+   * @throws AmbariException
+   */
+  public StackInfo getStack(StackId stackId) throws AmbariException {
+    return getStack(stackId.getStackName(), stackId.getStackVersion());
+  }
+
   public StackInfo getStack(String stackName, String version) throws AmbariException {
     StackInfo stackInfoResult = stackManager.getStack(stackName, version);
 
@@ -628,7 +665,7 @@ public class AmbariMetaInfo {
   }
 
   public List<String> getStackParentVersions(String stackName, String version) {
-    List<String> parents = new ArrayList<String>();
+    List<String> parents = new ArrayList<>();
     try {
       StackInfo stackInfo = getStack(stackName, version);
       String parentVersion = stackInfo.getParentStackVersion();
@@ -669,13 +706,13 @@ public class AmbariMetaInfo {
   public Set<PropertyInfo> getServiceProperties(String stackName, String version, String serviceName)
       throws AmbariException {
 
-    return new HashSet<PropertyInfo>(getService(stackName, version, serviceName).getProperties());
+    return new HashSet<>(getService(stackName, version, serviceName).getProperties());
   }
 
   public Set<PropertyInfo> getStackProperties(String stackName, String version)
       throws AmbariException {
 
-    return new HashSet<PropertyInfo>(getStack(stackName, version).getProperties());
+    return new HashSet<>(getStack(stackName, version).getProperties());
   }
 
   public Set<PropertyInfo> getPropertiesByName(String stackName, String version, String serviceName, String propertyName)
@@ -692,7 +729,7 @@ public class AmbariMetaInfo {
           + ", propertyName=" + propertyName);
     }
 
-    Set<PropertyInfo> propertyResult = new HashSet<PropertyInfo>();
+    Set<PropertyInfo> propertyResult = new HashSet<>();
 
     for (PropertyInfo property : properties) {
       if (property.getName().equals(propertyName)) {
@@ -720,7 +757,7 @@ public class AmbariMetaInfo {
           + ", propertyName=" + propertyName);
     }
 
-    Set<PropertyInfo> propertyResult = new HashSet<PropertyInfo>();
+    Set<PropertyInfo> propertyResult = new HashSet<>();
 
     for (PropertyInfo property : properties) {
       if (property.getName().equals(propertyName)) {
@@ -743,7 +780,7 @@ public class AmbariMetaInfo {
   public Set<OperatingSystemInfo> getOperatingSystems(String stackName, String version)
       throws AmbariException {
 
-    Set<OperatingSystemInfo> operatingSystems = new HashSet<OperatingSystemInfo>();
+    Set<OperatingSystemInfo> operatingSystems = new HashSet<>();
     StackInfo stack = getStack(stackName, version);
     List<RepositoryInfo> repositories = stack.getRepositories();
     for (RepositoryInfo repository : repositories) {
@@ -794,13 +831,12 @@ public class AmbariMetaInfo {
 
   private void getCustomActionDefinitions(File customActionDefinitionRoot) throws JAXBException, AmbariException {
     if (customActionDefinitionRoot != null) {
-      LOG.debug("Loading custom action definitions from "
-          + customActionDefinitionRoot.getAbsolutePath());
+      LOG.debug("Loading custom action definitions from {}", customActionDefinitionRoot.getAbsolutePath());
 
       if (customActionDefinitionRoot.exists() && customActionDefinitionRoot.isDirectory()) {
         adManager.readCustomActionDefinitions(customActionDefinitionRoot);
       } else {
-        LOG.debug("No action definitions found at " + customActionDefinitionRoot.getAbsolutePath());
+        LOG.debug("No action definitions found at {}", customActionDefinitionRoot.getAbsolutePath());
       }
     }
   }
@@ -857,43 +893,27 @@ public class AmbariMetaInfo {
     return sb.toString();
   }
 
-  /**
-   * @param stackName the stack name
-   * @param stackVersion the stack version
-   * @param osType the os
-   * @param repoId the repo id
-   * @param newBaseUrl the new base url
-   */
-  public void updateRepoBaseURL(String stackName,
-      String stackVersion, String osType, String repoId, String newBaseUrl) throws AmbariException {
-
-    // validate existing
-    RepositoryInfo ri = getRepository(stackName, stackVersion, osType, repoId);
-
+  public void createRepo(String stackName, String stackVersion, String osType, String repoId, String baseUrl, String mirrorsList) throws AmbariException {
     if (!stackRoot.exists()) {
-      throw new StackAccessException("Stack root does not exist.");
+      throw new StackAccessException("Create repo - Stack root does not exist.");
     }
 
-    ri.setBaseUrl(newBaseUrl);
-
-    if (null != metaInfoDAO) {
-      String metaKey = generateRepoMetaKey(stackName, stackVersion, osType,
-          repoId, REPOSITORY_XML_PROPERTY_BASEURL);
-
-      MetainfoEntity entity = new MetainfoEntity();
-      entity.setMetainfoName(metaKey);
-      entity.setMetainfoValue(newBaseUrl);
-
-      // !!! need a way to remove
-      if (newBaseUrl.equals("")) {
-        metaInfoDAO.remove(entity);
-      } else {
-        metaInfoDAO.merge(entity);
-        ri.setBaseUrlFromSaved(true);
-      }
+    if (null != baseUrl) {
+      createRepoInMetaInfo(stackName, stackVersion, osType, repoId, baseUrl, REPOSITORY_XML_PROPERTY_BASEURL);
+    } else if (null != mirrorsList) {
+      createRepoInMetaInfo(stackName, stackVersion, osType, repoId, mirrorsList, REPOSITORY_XML_PROPERTY_MIRRORSLIST);
     }
   }
 
+  private void createRepoInMetaInfo(String stackName, String stackVersion, String osType, String repoId, String value, String repositoryXmlProperty) {
+    String metaKey = generateRepoMetaKey(stackName, stackVersion, osType,
+        repoId, repositoryXmlProperty);
+    MetainfoEntity entity = new MetainfoEntity();
+    entity.setMetainfoName(metaKey);
+    entity.setMetainfoValue(value);
+    metaInfoDAO.create(entity);
+  }
+
   public File getStackRoot() {
     return stackRoot;
   }
@@ -911,7 +931,7 @@ public class AmbariMetaInfo {
     ServiceInfo svc = getService(stackName, stackVersion, serviceName);
 
     if (null == svc.getMetricsFile() || !svc.getMetricsFile().exists()) {
-      LOG.debug("Metrics file for " + stackName + "/" + stackVersion + "/" + serviceName + " not found.");
+      LOG.debug("Metrics file for {}/{}/{} not found.", stackName, stackVersion, serviceName);
       return null;
     }
 
@@ -993,7 +1013,7 @@ public class AmbariMetaInfo {
   }
 
   private Map<String, Metric> getAggregateFunctionMetrics(String metricName, Metric currentMetric) {
-    Map<String, Metric> newMetrics = new HashMap<String, Metric>();
+    Map<String, Metric> newMetrics = new HashMap<>();
     if (!PropertyHelper.hasAggregateFunctionSuffix(currentMetric.getName())) {
       // For every function id
       for (String identifierToAdd : AGGREGATE_FUNCTION_IDENTIFIERS) {
@@ -1099,46 +1119,44 @@ public class AmbariMetaInfo {
     // for every cluster
     for (Cluster cluster : clusterMap.values()) {
       long clusterId = cluster.getClusterId();
-      StackId stackId = cluster.getDesiredStackVersion();
-      StackInfo stackInfo = getStack(stackId.getStackName(),
-          stackId.getStackVersion());
 
       // creating a mapping between names and service/component for fast lookups
-      Collection<ServiceInfo> stackServices = stackInfo.getServices();
-      Map<String, ServiceInfo> stackServiceMap = new HashMap<String, ServiceInfo>();
-      Map<String, ComponentInfo> stackComponentMap = new HashMap<String, ComponentInfo>();
-      for (ServiceInfo stackService : stackServices) {
-        stackServiceMap.put(stackService.getName(), stackService);
+//      Collection<ServiceInfo> stackServices = new ArrayList<>();
+      Map<String, ServiceInfo> stackServiceMap = new HashMap<>();
+      Map<String, ComponentInfo> stackComponentMap = new HashMap<>();
 
-        List<ComponentInfo> components = stackService.getComponents();
-        for (ComponentInfo component : components) {
-          stackComponentMap.put(component.getName(), component);
-        }
-      }
 
       Map<String, Service> clusterServiceMap = cluster.getServices();
       Set<String> clusterServiceNames = clusterServiceMap.keySet();
 
       // for every service installed in that cluster, get the service metainfo
       // and off of that the alert definitions
-      List<AlertDefinition> stackDefinitions = new ArrayList<AlertDefinition>(50);
-      for (String clusterServiceName : clusterServiceNames) {
-        ServiceInfo stackService = stackServiceMap.get(clusterServiceName);
+      List<AlertDefinition> stackDefinitions = new ArrayList<>(50);
+
+      for (Service service : cluster.getServices().values()) {
+        ServiceInfo stackService = getService(service.getDesiredStackId().getStackName(),
+            service.getDesiredStackId().getStackVersion(), service.getName());
+
         if (null == stackService) {
           continue;
         }
 
+        stackServiceMap.put(stackService.getName(), stackService);
+        List<ComponentInfo> components = stackService.getComponents();
+        for (ComponentInfo component : components) {
+          stackComponentMap.put(component.getName(), component);
+        }
 
         // get all alerts defined on the stack for each cluster service
         Set<AlertDefinition> serviceDefinitions = getAlertDefinitions(stackService);
         stackDefinitions.addAll(serviceDefinitions);
       }
 
-      List<AlertDefinitionEntity> persist = new ArrayList<AlertDefinitionEntity>();
+      List<AlertDefinitionEntity> persist = new ArrayList<>();
       List<AlertDefinitionEntity> entities = alertDefinitionDao.findAll(clusterId);
 
       // create a map of the entities for fast extraction
-      Map<String, AlertDefinitionEntity> mappedEntities = new HashMap<String, AlertDefinitionEntity>(100);
+      Map<String, AlertDefinitionEntity> mappedEntities = new HashMap<>(100);
       for (AlertDefinitionEntity entity : entities) {
         mappedEntities.put(entity.getDefinitionName(), entity);
       }
@@ -1219,7 +1237,7 @@ public class AmbariMetaInfo {
       // stack but still exists in the database - we disable the alert to
       // preserve historical references
       List<AlertDefinitionEntity> definitions = alertDefinitionDao.findAllEnabled(clusterId);
-      List<AlertDefinitionEntity> definitionsToDisable = new ArrayList<AlertDefinitionEntity>();
+      List<AlertDefinitionEntity> definitionsToDisable = new ArrayList<>();
 
       for (AlertDefinitionEntity definition : definitions) {
         String serviceName = definition.getServiceName();
@@ -1230,6 +1248,8 @@ public class AmbariMetaInfo {
           continue;
         }
 
+        StackId stackId = cluster.getService(serviceName).getDesiredStackId();
+
         if (!stackServiceMap.containsKey(serviceName)) {
           LOG.info(
               "The {} service has been marked as deleted for stack {}, disabling alert {}",

http://git-wip-us.apache.org/repos/asf/ambari/blob/48f7fb22/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 69b4536..59115e3 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)
@@ -64,8 +64,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(")
@@ -73,8 +73,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/48f7fb22/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 e64e94c..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_REPO_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/48f7fb22/ambari-server/src/main/java/org/apache/ambari/server/checks/AbstractCheckDescriptor.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/AbstractCheckDescriptor.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/AbstractCheckDescriptor.java
index d9d8b42..fe28471 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/AbstractCheckDescriptor.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/AbstractCheckDescriptor.java
@@ -24,9 +24,8 @@ import java.util.Set;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
-import org.apache.ambari.server.controller.PrereqCheckRequest;
 import org.apache.ambari.server.configuration.Configuration;
-import org.apache.ambari.server.orm.dao.ClusterVersionDAO;
+import org.apache.ambari.server.controller.PrereqCheckRequest;
 import org.apache.ambari.server.orm.dao.HostVersionDAO;
 import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
 import org.apache.ambari.server.orm.dao.UpgradeDAO;
@@ -35,7 +34,6 @@ import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.Config;
 import org.apache.ambari.server.state.DesiredConfig;
 import org.apache.ambari.server.state.ServiceInfo;
-import org.apache.ambari.server.state.StackId;
 import org.apache.ambari.server.state.stack.PrereqCheckType;
 import org.apache.ambari.server.state.stack.PrerequisiteCheck;
 import org.apache.ambari.server.state.stack.UpgradePack;
@@ -61,9 +59,6 @@ public abstract class AbstractCheckDescriptor {
   Provider<Clusters> clustersProvider;
 
   @Inject
-  Provider<ClusterVersionDAO> clusterVersionDAOProvider;
-
-  @Inject
   Provider<HostVersionDAO> hostVersionDaoProvider;
 
   @Inject
@@ -241,7 +236,7 @@ public abstract class AbstractCheckDescriptor {
               c.getDesiredStackVersion().getStackName(),
               c.getDesiredStackVersion().getStackVersion());
 
-          LinkedHashSet<String> displays = new LinkedHashSet<String>();
+          LinkedHashSet<String> displays = new LinkedHashSet<>();
           for (String name : names) {
             if (services.containsKey(name)) {
               displays.add(services.get(name).getDisplayName());

http://git-wip-us.apache.org/repos/asf/ambari/blob/48f7fb22/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelper.java
index c6239d8..256e7b0 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelper.java
@@ -655,8 +655,6 @@ public class DatabaseConsistencyCheckHelper {
       if (!clusterConfigEntity.isServiceDeleted()){
         continue; // skip clusterConfigs that did not leave after service deletion
       }
-      LOG.info("Removing cluster config mapping of clusterConfigEntity {} that is not mapped to any service", clusterConfigEntity);
-      clusterDAO.removeClusterConfigMappingEntityByConfig(clusterConfigEntity);
       LOG.info("Removing config that is not mapped to any service {}", clusterConfigEntity);
       clusterDAO.removeConfig(clusterConfigEntity);
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/48f7fb22/ambari-server/src/main/java/org/apache/ambari/server/checks/HardcodedStackVersionPropertiesCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/HardcodedStackVersionPropertiesCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/HardcodedStackVersionPropertiesCheck.java
index f5e2b10..b103bca 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/HardcodedStackVersionPropertiesCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/HardcodedStackVersionPropertiesCheck.java
@@ -1,4 +1,4 @@
-/**
+/*
  * 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
@@ -17,33 +17,25 @@
  */
 package org.apache.ambari.server.checks;
 
-import com.google.inject.Inject;
-import com.google.inject.Provider;
-import com.google.inject.Singleton;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 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.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.ConfigMergeHelper;
-import org.apache.ambari.server.state.ConfigMergeHelper.ThreeWayValue;
 import org.apache.ambari.server.state.DesiredConfig;
 import org.apache.ambari.server.state.stack.PrereqCheckStatus;
 import org.apache.ambari.server.state.stack.PrerequisiteCheck;
 import org.apache.ambari.server.state.stack.upgrade.UpgradeType;
+import org.apache.commons.lang.StringUtils;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import com.google.inject.Singleton;
 
 /**
  * Checks for properties that contain hardcoded CURRENT hdp version string.
@@ -57,12 +49,6 @@ import java.util.regex.Pattern;
     required = { UpgradeType.ROLLING, UpgradeType.NON_ROLLING, UpgradeType.HOST_ORDERED })
 public class HardcodedStackVersionPropertiesCheck extends AbstractCheckDescriptor {
 
-  @Inject
-  private Provider<Clusters> m_clusters;
-
-  @Inject
-  private Provider<ConfigHelper> m_config_helper_provider;
-
   public HardcodedStackVersionPropertiesCheck() {
     super(CheckDescription.HARDCODED_STACK_VERSION_PROPERTIES_CHECK);
   }
@@ -71,18 +57,13 @@ public class HardcodedStackVersionPropertiesCheck extends AbstractCheckDescripto
   public void perform(PrerequisiteCheck prerequisiteCheck, PrereqCheckRequest request)
       throws AmbariException {
 
-    String stackName = request.getTargetStackId().getStackName();
-    RepositoryVersionEntity rve = repositoryVersionDaoProvider.get().
-      findByStackNameAndVersion(stackName, request.getRepositoryVersion());
-
-    Cluster cluster = m_clusters.get().getCluster(request.getClusterName());
+    Cluster cluster = clustersProvider.get().getCluster(request.getClusterName());
 
-    String currentHdpVersion = cluster.getCurrentClusterVersion().getRepositoryVersion().getVersion();
-
-    Map<String, DesiredConfig> desiredConfigs = cluster.getDesiredConfigs();
+    Set<String> versions = new HashSet<>();
     Set<String> failures = new HashSet<>();
+    Set<String> failedVersions = new HashSet<>();
 
-    Pattern searchPattern = getHardcodeSearchPattern(currentHdpVersion);
+    Map<String, DesiredConfig> desiredConfigs = cluster.getDesiredConfigs();
     for (Entry<String, DesiredConfig> configEntry : desiredConfigs.entrySet()) {
       String configType = configEntry.getKey();
       DesiredConfig desiredConfig = configEntry.getValue();
@@ -90,23 +71,31 @@ public class HardcodedStackVersionPropertiesCheck extends AbstractCheckDescripto
 
       Map<String, String> properties = config.getProperties();
       for (Entry<String, String> property : properties.entrySet()) {
-        if (stringContainsVersionHardcode(property.getValue(), searchPattern)) {
-          failures.add(String.format(" %s/%s",
-            configType, property.getKey()));
+
+        // !!! this code is already iterating every config property, so an extra loop for the small-ish
+        // numbers of repository versions won't add that much more overhead
+        for (String version : versions) {
+          Pattern searchPattern = getHardcodeSearchPattern(version);
+          if (stringContainsVersionHardcode(property.getValue(), searchPattern)) {
+            failedVersions.add(version);
+            failures.add(String.format("%s/%s found a hardcoded value %s",
+              configType, property.getKey(), version));
+          }
         }
       }
+    }
 
-      if (failures.size() > 0) {
-        prerequisiteCheck.setStatus(PrereqCheckStatus.WARNING);
-        String failReason = getFailReason(prerequisiteCheck, request);
+    if (failures.size() > 0) {
+      prerequisiteCheck.setStatus(PrereqCheckStatus.WARNING);
+      String failReason = getFailReason(prerequisiteCheck, request);
 
-        prerequisiteCheck.setFailReason(String.format(failReason, currentHdpVersion));
-        prerequisiteCheck.setFailedOn(new LinkedHashSet<>(failures));
+      prerequisiteCheck.setFailReason(String.format(failReason, StringUtils.join(failedVersions, ',')));
+      prerequisiteCheck.setFailedOn(new LinkedHashSet<>(failures));
 
-      } else {
-        prerequisiteCheck.setStatus(PrereqCheckStatus.PASS);
-      }
+    } else {
+      prerequisiteCheck.setStatus(PrereqCheckStatus.PASS);
     }
+
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/48f7fb22/ambari-server/src/main/java/org/apache/ambari/server/checks/InstallPackagesCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/InstallPackagesCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/InstallPackagesCheck.java
index 38bdda2..ac2116f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/InstallPackagesCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/InstallPackagesCheck.java
@@ -24,7 +24,6 @@ import java.util.Set;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.controller.PrereqCheckRequest;
-import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
 import org.apache.ambari.server.orm.entities.HostVersionEntity;
 import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 import org.apache.ambari.server.state.Cluster;
@@ -75,9 +74,7 @@ public class InstallPackagesCheck extends AbstractCheckDescriptor {
       return;
     }
 
-    final ClusterVersionEntity clusterVersion = clusterVersionDAOProvider.get().findByClusterAndStackAndVersion(
-        clusterName, targetStackId, repoVersion);
-    final Set<String> failedHosts = new HashSet<String>();
+    final Set<String> failedHosts = new HashSet<>();
 
     for (Host host : cluster.getHosts()) {
       if (host.getMaintenanceState(cluster.getClusterId()) != MaintenanceState.ON) {
@@ -95,19 +92,12 @@ public class InstallPackagesCheck extends AbstractCheckDescriptor {
               "Install Packages had failed. Please re-run Install Packages, if necessary place following hosts " +
               "in Maintenance mode: {4}", cluster.getClusterName(), targetStackId.getStackName(),
           targetStackId.getStackVersion(), repoVersion, StringUtils.join(failedHosts, ", "));
-      prerequisiteCheck.setFailedOn(new LinkedHashSet<String>(failedHosts));
-      prerequisiteCheck.setStatus(PrereqCheckStatus.FAIL);
-      prerequisiteCheck.setFailReason(message);
-    } else if (clusterVersion.getState() == RepositoryVersionState.INSTALL_FAILED) {
-      String message = MessageFormat.format("Cluster [{0},{1},{2},{3}] is in INSTALL_FAILED state because " +
-              "Install Packages failed. Please re-run Install Packages even if you placed the failed hosts " +
-              "in Maintenance mode.", cluster.getClusterName(), targetStackId.getStackName(),
-          targetStackId.getStackVersion(), repoVersion);
-      LinkedHashSet<String> failedOn = new LinkedHashSet<String>();
-      failedOn.add(cluster.getClusterName());
-      prerequisiteCheck.setFailedOn(failedOn);
+      prerequisiteCheck.setFailedOn(new LinkedHashSet<>(failedHosts));
       prerequisiteCheck.setStatus(PrereqCheckStatus.FAIL);
       prerequisiteCheck.setFailReason(message);
+      return;
     }
+
+    prerequisiteCheck.setStatus(PrereqCheckStatus.PASS);
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/48f7fb22/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 833ee73..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
@@ -22,7 +22,6 @@ 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;
@@ -47,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}-{2} to {3}-{4} which has not completed. This {5} 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.
@@ -66,13 +65,10 @@ public class PreviousUpgradeCompleted extends AbstractCheckDescriptor {
     if (null != upgradeInProgress) {
       Direction direction = upgradeInProgress.getDirection();
       String directionText = direction.getText(false);
+      String prepositionText = direction.getPreposition();
 
-      RepositoryVersionEntity fromRepositoryVersion = upgradeInProgress.getFromRepositoryVersion();
-      RepositoryVersionEntity toRepositoryVersion = upgradeInProgress.getToRepositoryVersion();
-
-      errorMessage = MessageFormat.format(ERROR_MESSAGE, directionText,
-          fromRepositoryVersion.getStackName(), fromRepositoryVersion.getVersion(),
-          toRepositoryVersion.getStackName(), toRepositoryVersion.getVersion(), 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/48f7fb22/ambari-server/src/main/java/org/apache/ambari/server/checks/YarnTimelineServerStatePreservingCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/YarnTimelineServerStatePreservingCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/YarnTimelineServerStatePreservingCheck.java
index 8cb8020..ba4b61e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/YarnTimelineServerStatePreservingCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/YarnTimelineServerStatePreservingCheck.java
@@ -82,10 +82,11 @@ public class YarnTimelineServerStatePreservingCheck extends AbstractCheckDescrip
       if(minStack.length == 2) {
         String minStackName = minStack[0];
         String minStackVersion = minStack[1];
-        String stackName = cluster.getCurrentStackVersion().getStackName();
+        Service yarnService = cluster.getService("YARN");
+        String stackName = yarnService.getDesiredStackId().getStackName();
         if (minStackName.equals(stackName)) {
-          String currentClusterRepositoryVersion = cluster.getCurrentClusterVersion().getRepositoryVersion().getVersion();
-          return VersionUtils.compareVersions(currentClusterRepositoryVersion, minStackVersion) >= 0;
+          String currentRepositoryVersion = yarnService.getDesiredRepositoryVersion().getVersion();
+          return VersionUtils.compareVersions(currentRepositoryVersion, minStackVersion) >= 0;
         }
       }
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/48f7fb22/ambari-server/src/main/java/org/apache/ambari/server/controller/ActionExecutionContext.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ActionExecutionContext.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ActionExecutionContext.java
index c361094..42a95c0 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ActionExecutionContext.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ActionExecutionContext.java
@@ -1,4 +1,4 @@
-/**
+/*
  * 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
@@ -19,13 +19,14 @@
 
 package org.apache.ambari.server.controller;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
 import org.apache.ambari.server.actionmanager.TargetHostType;
+import org.apache.ambari.server.agent.ExecutionCommand;
 import org.apache.ambari.server.controller.internal.RequestOperationLevel;
 import org.apache.ambari.server.controller.internal.RequestResourceFilter;
-import org.apache.ambari.server.state.StackId;
 
 /**
  * The context required to create tasks and stages for a custom action
@@ -42,7 +43,8 @@ public class ActionExecutionContext {
   private String expectedComponentName;
   private boolean hostsInMaintenanceModeExcluded = true;
   private boolean allowRetry = false;
-  private StackId stackId;
+
+  private List<ExecutionCommandVisitor> m_visitors = new ArrayList<>();
 
   /**
    * {@code true} if slave/client component failures should be automatically
@@ -171,27 +173,13 @@ public class ActionExecutionContext {
   }
 
   /**
-   * Gets the stack to use for generating stack-associated values for a command.
-   * In some cases the cluster's stack is not the correct one to use, such as
-   * when distributing a repository.
+   * Adds a command visitor that will be invoked after a command is created.  Provides access
+   * to the command.
    *
-   * @return the stackId the stack to use when generating stack-specific content
-   *         for the command.
+   * @param visitor the visitor
    */
-  public StackId getStackId() {
-    return stackId;
-  }
-
-  /**
-   * Sets the stack to use for generating stack-associated values for a command.
-   * In some cases the cluster's stack is not the correct one to use, such as
-   * when distributing a repository.
-   *
-   * @param stackId
-   *          the stackId to use for stack-based properties on the command.
-   */
-  public void setStackId(StackId stackId) {
-    this.stackId = stackId;
+  public void addVisitor(ExecutionCommandVisitor visitor) {
+    m_visitors.add(visitor);
   }
 
   @Override
@@ -233,4 +221,25 @@ public class ActionExecutionContext {
     hostsInMaintenanceModeExcluded = excluded;
   }
 
+  /**
+   * Called as a way to post-process the command after it has been created and various objects
+   * have been set.
+   *
+   * @param command the command
+   */
+  public void visitAll(ExecutionCommand command) {
+    for (ExecutionCommandVisitor visitor : m_visitors) {
+      visitor.visit(command);
+    }
+  }
+
+  /**
+   * Interface that allows a final attempt to setting values on an {@link ExecutionCommand}
+   * @author ncole
+   *
+   */
+  public static interface ExecutionCommandVisitor {
+    public void visit(ExecutionCommand command);
+  }
+
 }
\ No newline at end of file