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/05/23 19:39:24 UTC

[6/6] ambari git commit: AMBARI-21059. Reduce Dependency on Cluster Desired Stack ID (ncole)

AMBARI-21059. Reduce Dependency on Cluster Desired Stack ID (ncole)


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

Branch: refs/heads/branch-feature-AMBARI-12556
Commit: a45f5427b08fc354e8b54481e7da3d6083112345
Parents: a436eb2
Author: Nate Cole <nc...@hortonworks.com>
Authored: Thu May 18 08:57:45 2017 -0400
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Tue May 23 15:38:59 2017 -0400

----------------------------------------------------------------------
 .../ambari/annotations/ExperimentalFeature.java |   7 +-
 .../ambari/server/actionmanager/Stage.java      |   4 +-
 .../ambari/server/agent/HeartBeatHandler.java   |  40 +--
 .../ambari/server/agent/HeartbeatMonitor.java   |   4 +-
 .../ambari/server/agent/HeartbeatProcessor.java |   4 +-
 .../server/api/services/AmbariMetaInfo.java     |  56 +++-
 .../server/checks/AbstractCheckDescriptor.java  |  28 +-
 .../checks/ComponentsInstallationCheck.java     |   3 -
 .../checks/HostsMasterMaintenanceCheck.java     |   2 +-
 .../checks/HostsRepositoryVersionCheck.java     |   4 +-
 .../server/checks/RangerPasswordCheck.java      |   8 +-
 .../checks/ServiceCheckValidityCheck.java       |   2 +-
 .../ambari/server/checks/ServicesUpCheck.java   |   3 +-
 .../YarnTimelineServerStatePreservingCheck.java |   4 +-
 .../controller/AmbariActionExecutionHelper.java |  34 ++-
 .../AmbariCustomCommandExecutionHelper.java     |  51 +++-
 .../controller/AmbariManagementController.java  |   3 +-
 .../AmbariManagementControllerImpl.java         | 263 +++++++++++--------
 .../server/controller/KerberosHelperImpl.java   |  93 ++++---
 .../server/controller/ServiceRequest.java       |  17 +-
 .../internal/ClientConfigResourceProvider.java  |   8 +-
 .../ClusterStackVersionResourceProvider.java    |  20 +-
 .../internal/ComponentResourceProvider.java     |  16 +-
 .../internal/ServiceResourceProvider.java       |  64 +++--
 .../internal/StackDefinedPropertyProvider.java  |  18 +-
 .../internal/UpgradeResourceProvider.java       |   2 +-
 .../logging/LoggingSearchPropertyProvider.java  |  12 +-
 .../metrics/timeline/AMSPropertyProvider.java   |   9 +-
 .../state/DefaultServiceCalculatedState.java    |   5 +-
 .../state/HBaseServiceCalculatedState.java      |   4 +-
 .../state/HDFSServiceCalculatedState.java       |   4 +-
 .../state/HiveServiceCalculatedState.java       |   5 +-
 .../state/OozieServiceCalculatedState.java      |   5 +-
 .../state/YARNServiceCalculatedState.java       |   5 +-
 .../server/metadata/RoleCommandOrder.java       |  34 ++-
 .../ambari/server/orm/dao/ClusterDAO.java       |   2 +-
 .../server/orm/dao/RepositoryVersionDAO.java    |  14 +
 .../orm/entities/RepositoryVersionEntity.java   |   2 +
 .../upgrades/AutoSkipFailedSummaryAction.java   |  10 +-
 .../org/apache/ambari/server/state/Cluster.java |  36 +--
 .../apache/ambari/server/state/Clusters.java    |   9 -
 .../ambari/server/state/ConfigFactory.java      |  18 ++
 .../ambari/server/state/ConfigHelper.java       | 175 ++++--------
 .../apache/ambari/server/state/ConfigImpl.java  |  13 +-
 .../server/state/ServiceComponentHost.java      |   7 +
 .../server/state/ServiceComponentImpl.java      |  14 +-
 .../apache/ambari/server/state/ServiceImpl.java |  25 +-
 .../server/state/cluster/ClusterImpl.java       |  19 +-
 .../server/state/cluster/ClustersImpl.java      |  45 +---
 .../state/configgroup/ConfigGroupImpl.java      |   2 +-
 .../stack/upgrade/ServiceCheckGrouping.java     |   3 +-
 .../svccomphost/ServiceComponentHostImpl.java   |   9 +
 .../server/upgrade/AbstractUpgradeCatalog.java  |  27 +-
 .../server/upgrade/FinalUpgradeCatalog.java     |  28 +-
 .../server/upgrade/UpgradeCatalog200.java       |  11 +-
 .../server/upgrade/UpgradeCatalog210.java       |  20 +-
 .../server/upgrade/UpgradeCatalog212.java       |  10 +-
 .../server/upgrade/UpgradeCatalog2121.java      |  64 +++--
 .../server/upgrade/UpgradeCatalog220.java       | 174 ++++++------
 .../server/upgrade/UpgradeCatalog221.java       |  11 +-
 .../server/upgrade/UpgradeCatalog222.java       | 146 ++++++----
 .../server/upgrade/UpgradeCatalog240.java       |  42 ++-
 .../apache/ambari/server/view/ViewRegistry.java |  27 +-
 .../ExecutionCommandWrapperTest.java            |  11 +-
 .../server/agent/TestHeartbeatHandler.java      |  34 +--
 .../checks/HostsMasterMaintenanceCheckTest.java |   8 +-
 .../server/checks/RangerPasswordCheckTest.java  |  15 +-
 .../checks/ServiceCheckValidityCheckTest.java   |   3 +-
 .../server/checks/ServicesUpCheckTest.java      |   5 +
 .../AmbariManagementControllerImplTest.java     | 156 +++++------
 .../AmbariManagementControllerTest.java         |  58 ++--
 .../server/controller/KerberosHelperTest.java   | 226 +++-------------
 .../ClientConfigResourceProviderTest.java       |  10 +-
 .../internal/ComponentResourceProviderTest.java |  14 +-
 .../internal/HostResourceProviderTest.java      |   5 +
 .../internal/ServiceResourceProviderTest.java   |   3 +
 .../StackDefinedPropertyProviderTest.java       |  21 +-
 .../LoggingSearchPropertyProviderTest.java      |  27 +-
 .../RestMetricsPropertyProviderTest.java        |  14 +
 .../timeline/AMSPropertyProviderTest.java       |  36 ++-
 .../apache/ambari/server/events/EventsTest.java |   1 +
 .../HostVersionOutOfSyncListenerTest.java       |   3 +
 .../server/metadata/RoleCommandOrderTest.java   |  64 +++--
 .../ambari/server/metadata/RoleGraphTest.java   |  23 ++
 .../apache/ambari/server/orm/OrmTestHelper.java |  25 +-
 .../AutoSkipFailedSummaryActionTest.java        |  24 ++
 .../ComponentVersionCheckActionTest.java        |   5 +
 .../server/stageplanner/TestStagePlanner.java   |  58 +++-
 .../ambari/server/state/ConfigGroupTest.java    |   7 +-
 .../ambari/server/state/ConfigHelperTest.java   |  27 +-
 .../server/state/ServiceComponentTest.java      |   3 +
 .../state/alerts/AlertEventPublisherTest.java   |   5 +-
 .../state/cluster/ClusterDeadlockTest.java      |   3 +
 .../server/state/cluster/ClusterImplTest.java   |  16 +-
 .../state/cluster/ClustersDeadlockTest.java     |   2 +
 .../server/state/cluster/ClustersTest.java      |  69 +----
 .../ConcurrentServiceConfigVersionTest.java     |   3 +-
 ...omponentHostConcurrentWriteDeadlockTest.java |   4 +
 .../services/RetryUpgradeActionServiceTest.java |  10 +-
 .../svccomphost/ServiceComponentHostTest.java   |   1 +
 .../upgrade/AbstractUpgradeCatalogTest.java     |   8 +-
 .../server/upgrade/UpgradeCatalog200Test.java   |  20 +-
 .../server/upgrade/UpgradeCatalog210Test.java   |  17 +-
 .../server/upgrade/UpgradeCatalog211Test.java   |   3 +-
 .../server/upgrade/UpgradeCatalog212Test.java   |  13 +-
 .../server/upgrade/UpgradeCatalog220Test.java   |  16 +-
 .../server/upgrade/UpgradeCatalog221Test.java   |   4 +-
 .../server/upgrade/UpgradeCatalog222Test.java   |  84 ++++--
 .../server/upgrade/UpgradeCatalog240Test.java   | 116 +++++---
 .../server/upgrade/UpgradeCatalog250Test.java   |  36 +--
 .../server/upgrade/UpgradeCatalog300Test.java   |  17 +-
 .../server/upgrade/UpgradeCatalogHelper.java    |   5 +-
 .../ambari/server/view/ViewRegistryTest.java    |  13 +-
 .../app/controllers/wizard/step8_controller.js  |  13 +-
 114 files changed, 1811 insertions(+), 1357 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/a45f5427/ambari-server/src/main/java/org/apache/ambari/annotations/ExperimentalFeature.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/annotations/ExperimentalFeature.java b/ambari-server/src/main/java/org/apache/ambari/annotations/ExperimentalFeature.java
index 1d5ba0e..7532452 100644
--- a/ambari-server/src/main/java/org/apache/ambari/annotations/ExperimentalFeature.java
+++ b/ambari-server/src/main/java/org/apache/ambari/annotations/ExperimentalFeature.java
@@ -40,5 +40,10 @@ public enum ExperimentalFeature {
   /**
    * Used for code that is targeted for patch upgrades
    */
-  PATCH_UPGRADES
+  PATCH_UPGRADES,
+
+  /**
+   * For code that is for multi-service
+   */
+  MULTI_SERVICE
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/a45f5427/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/Stage.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/Stage.java b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/Stage.java
index 574afa1..562024b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/Stage.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/Stage.java
@@ -199,7 +199,9 @@ public class Stage {
     stageEntity.setRoleSuccessCriterias(new ArrayList<RoleSuccessCriteriaEntity>());
     stageEntity.setClusterHostInfo(clusterHostInfo);
     stageEntity.setCommandParamsStage(commandParamsStage);
-    stageEntity.setHostParamsStage(hostParamsStage);
+    if (null != hostParamsStage) {
+      stageEntity.setHostParamsStage(hostParamsStage);
+    }
     stageEntity.setCommandExecutionType(commandExecutionType);
     stageEntity.setStatus(status);
     stageEntity.setDisplayStatus(displayStatus);

http://git-wip-us.apache.org/repos/asf/ambari/blob/a45f5427/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
index 3601528..0175b44 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
@@ -44,10 +44,9 @@ import org.apache.ambari.server.state.ComponentInfo;
 import org.apache.ambari.server.state.ConfigHelper;
 import org.apache.ambari.server.state.Host;
 import org.apache.ambari.server.state.HostState;
+import org.apache.ambari.server.state.ServiceComponent;
 import org.apache.ambari.server.state.ServiceComponentHost;
-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.alert.AlertDefinition;
 import org.apache.ambari.server.state.alert.AlertDefinitionHash;
 import org.apache.ambari.server.state.fsm.InvalidStateTransitionException;
@@ -87,9 +86,6 @@ public class HeartBeatHandler {
   private HeartbeatProcessor heartbeatProcessor;
 
   @Inject
-  private Injector injector;
-
-  @Inject
   private Configuration config;
 
   @Inject
@@ -506,36 +502,26 @@ public class HeartBeatHandler {
     ComponentsResponse response = new ComponentsResponse();
 
     Cluster cluster = clusterFsm.getCluster(clusterName);
-    StackId stackId = cluster.getCurrentStackVersion();
-    if (stackId == null) {
-      throw new AmbariException("Cannot provide stack components map. " +
-        "Stack hasn't been selected yet.");
-    }
-    StackInfo stack = ambariMetaInfo.getStack(stackId.getStackName(),
-        stackId.getStackVersion());
 
-    response.setClusterName(clusterName);
-    response.setStackName(stackId.getStackName());
-    response.setStackVersion(stackId.getStackVersion());
-    response.setComponents(getComponentsMap(stack));
+    Map<String, Map<String, String>> componentsMap = new HashMap<>();
 
-    return response;
-  }
+    for (org.apache.ambari.server.state.Service service : cluster.getServices().values()) {
+      componentsMap.put(service.getName(), new HashMap<String, String>());
 
-  private Map<String, Map<String, String>> getComponentsMap(StackInfo stack) {
-    Map<String, Map<String, String>> result = new HashMap<>();
+      for (ServiceComponent component : service.getServiceComponents().values()) {
+        StackId stackId = component.getDesiredStackId();
 
-    for (ServiceInfo service : stack.getServices()) {
-      Map<String, String> components = new HashMap<>();
+        ComponentInfo componentInfo = ambariMetaInfo.getComponent(
+            stackId.getStackName(), stackId.getStackVersion(), service.getName(), component.getName());
 
-      for (ComponentInfo component : service.getComponents()) {
-        components.put(component.getName(), component.getCategory());
+        componentsMap.get(service.getName()).put(component.getName(), componentInfo.getCategory());
       }
-
-      result.put(service.getName(), components);
     }
 
-    return result;
+    response.setClusterName(clusterName);
+    response.setComponents(componentsMap);
+
+    return response;
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/a45f5427/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatMonitor.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatMonitor.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatMonitor.java
index a77ed75..76111f5 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatMonitor.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatMonitor.java
@@ -240,7 +240,9 @@ public class HeartbeatMonitor implements Runnable {
       ServiceComponentHost sch, Map<String, DesiredConfig> desiredConfigs) throws AmbariException {
     String serviceName = sch.getServiceName();
     String componentName = sch.getServiceComponentName();
-    StackId stackId = cluster.getDesiredStackVersion();
+
+    StackId stackId = sch.getDesiredStackId();
+
     ServiceInfo serviceInfo = ambariMetaInfo.getService(stackId.getStackName(),
         stackId.getStackVersion(), serviceName);
     ComponentInfo componentInfo = ambariMetaInfo.getComponent(

http://git-wip-us.apache.org/repos/asf/ambari/blob/a45f5427/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 17e1f9c..6e9371c 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(),

http://git-wip-us.apache.org/repos/asf/ambari/blob/a45f5427/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 c655c62..9d787fc 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
@@ -380,6 +380,13 @@ 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);
@@ -538,6 +545,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);
 
@@ -632,6 +651,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);
 
@@ -1139,22 +1169,12 @@ 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();
+//      Collection<ServiceInfo> stackServices = new ArrayList<>();
       Map<String, ServiceInfo> stackServiceMap = new HashMap<>();
       Map<String, ComponentInfo> stackComponentMap = new HashMap<>();
-      for (ServiceInfo stackService : stackServices) {
-        stackServiceMap.put(stackService.getName(), stackService);
 
-        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();
@@ -1162,12 +1182,20 @@ public class AmbariMetaInfo {
       // for every service installed in that cluster, get the service metainfo
       // and off of that the alert definitions
       List<AlertDefinition> stackDefinitions = new ArrayList<>(50);
-      for (String clusterServiceName : clusterServiceNames) {
-        ServiceInfo stackService = stackServiceMap.get(clusterServiceName);
+
+      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);
@@ -1270,6 +1298,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/a45f5427/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 2fc1787..a0affd0 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
@@ -37,6 +37,7 @@ 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.RepositoryType;
+import org.apache.ambari.server.state.Service;
 import org.apache.ambari.server.state.ServiceInfo;
 import org.apache.ambari.server.state.stack.PrereqCheckType;
 import org.apache.ambari.server.state.stack.PrerequisiteCheck;
@@ -232,6 +233,15 @@ public abstract class AbstractCheckDescriptor {
     return properties.get(propertyName);
   }
 
+  protected Cluster getCluster(PrereqCheckRequest request) throws AmbariException {
+    String clusterName = request.getClusterName();
+    if (null != clusterName) {
+      return clustersProvider.get().getCluster(clusterName);
+    }
+
+    return null;
+  }
+
   /**
    * Gets the fail reason
    * @param key               the failure text key
@@ -257,19 +267,21 @@ public abstract class AbstractCheckDescriptor {
 
         try {
           Cluster c = clusters.getCluster(request.getClusterName());
-          Map<String, ServiceInfo> services = metaInfo.getServices(
-              c.getDesiredStackVersion().getStackName(),
-              c.getDesiredStackVersion().getStackVersion());
 
           LinkedHashSet<String> displays = new LinkedHashSet<>();
-          for (String name : names) {
-            if (services.containsKey(name)) {
-              displays.add(services.get(name).getDisplayName());
-            } else {
-              displays.add(name);
+
+          for (Service service : c.getServices().values()) {
+            if (names.contains(service.getName())) {
+              try {
+                ServiceInfo serviceInfo = metaInfo.getService(service);
+                displays.add(serviceInfo.getDisplayName());
+              } catch (Exception e) {
+                displays.add(service.getName());
+              }
             }
           }
           names = displays;
+
         } catch (Exception e) {
           LOG.warn("Could not load service info map");
         }

http://git-wip-us.apache.org/repos/asf/ambari/blob/a45f5427/ambari-server/src/main/java/org/apache/ambari/server/checks/ComponentsInstallationCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/ComponentsInstallationCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/ComponentsInstallationCheck.java
index 70a061c..988fc78 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/ComponentsInstallationCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/ComponentsInstallationCheck.java
@@ -32,7 +32,6 @@ import org.apache.ambari.server.state.Host;
 import org.apache.ambari.server.state.MaintenanceState;
 import org.apache.ambari.server.state.Service;
 import org.apache.ambari.server.state.ServiceComponent;
-import org.apache.ambari.server.state.StackId;
 import org.apache.ambari.server.state.State;
 import org.apache.ambari.server.state.stack.PrereqCheckStatus;
 import org.apache.ambari.server.state.stack.PrerequisiteCheck;
@@ -64,8 +63,6 @@ public class ComponentsInstallationCheck extends AbstractCheckDescriptor {
     final Cluster cluster = clustersProvider.get().getCluster(clusterName);
     Set<String> failedServiceNames = new HashSet<>();
 
-    StackId stackId = cluster.getCurrentStackVersion();
-
     // Preq-req check should fail if any service component is in INSTALL_FAILED state
     Set<String> installFailedHostComponents = new HashSet<>();
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/a45f5427/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsMasterMaintenanceCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsMasterMaintenanceCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsMasterMaintenanceCheck.java
index 1e87319..e5082c9 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsMasterMaintenanceCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsMasterMaintenanceCheck.java
@@ -66,7 +66,7 @@ public class HostsMasterMaintenanceCheck extends AbstractCheckDescriptor {
   public void perform(PrerequisiteCheck prerequisiteCheck, PrereqCheckRequest request) throws AmbariException {
     final String clusterName = request.getClusterName();
     final Cluster cluster = clustersProvider.get().getCluster(clusterName);
-    final StackId stackId = cluster.getDesiredStackVersion();
+    final StackId stackId = request.getSourceStackId();
     final Set<String> hostsWithMasterComponent = new HashSet<>();
 
     // TODO AMBARI-12698, need to pass the upgrade pack to use in the request, or at least the type.

http://git-wip-us.apache.org/repos/asf/ambari/blob/a45f5427/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsRepositoryVersionCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsRepositoryVersionCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsRepositoryVersionCheck.java
index a4cea31..a66db3c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsRepositoryVersionCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/HostsRepositoryVersionCheck.java
@@ -67,7 +67,9 @@ public class HostsRepositoryVersionCheck extends AbstractCheckDescriptor {
     final String clusterName = request.getClusterName();
     final Cluster cluster = clustersProvider.get().getCluster(clusterName);
     final Map<String, Host> clusterHosts = clustersProvider.get().getHostsForCluster(clusterName);
-    final StackId stackId = cluster.getDesiredStackVersion();
+    final StackId stackId = request.getSourceStackId();
+
+
 
     for (Host host : clusterHosts.values()) {
       // hosts in MM will produce a warning if they do not have the repo version

http://git-wip-us.apache.org/repos/asf/ambari/blob/a45f5427/ambari-server/src/main/java/org/apache/ambari/server/checks/RangerPasswordCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/RangerPasswordCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/RangerPasswordCheck.java
index a55a148..4a36be0 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/RangerPasswordCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/RangerPasswordCheck.java
@@ -32,7 +32,7 @@ import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.configuration.ComponentSSLConfiguration;
 import org.apache.ambari.server.controller.PrereqCheckRequest;
 import org.apache.ambari.server.controller.internal.URLStreamProvider;
-import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Service;
 import org.apache.ambari.server.state.StackId;
 import org.apache.ambari.server.state.stack.PrereqCheckStatus;
 import org.apache.ambari.server.state.stack.PrerequisiteCheck;
@@ -83,10 +83,10 @@ public class RangerPasswordCheck extends AbstractCheckDescriptor {
       return false;
     }
 
-    final Cluster cluster = clustersProvider.get().getCluster(request.getClusterName());
+    Service service = getCluster(request).getService("RANGER");
 
-    StackId clusterStackId = cluster.getCurrentStackVersion();
-    if (clusterStackId.getStackName().equals("HDP")) {
+    StackId stackId = service.getDesiredStackId();
+    if (stackId.getStackName().equals("HDP")) {
       String sourceVersion = request.getSourceStackId().getStackVersion();
 
       return VersionUtils.compareVersions(sourceVersion, "2.3.0.0") >= 0;

http://git-wip-us.apache.org/repos/asf/ambari/blob/a45f5427/ambari-server/src/main/java/org/apache/ambari/server/checks/ServiceCheckValidityCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServiceCheckValidityCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServiceCheckValidityCheck.java
index 4ccdc0a..750b25e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServiceCheckValidityCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServiceCheckValidityCheck.java
@@ -116,7 +116,7 @@ public class ServiceCheckValidityCheck extends AbstractCheckDescriptor {
       if (service.getMaintenanceState() != MaintenanceState.OFF || !hasAtLeastOneComponentVersionAdvertised(service)) {
         continue;
       }
-      StackId stackId = cluster.getCurrentStackVersion();
+      StackId stackId = service.getDesiredStackId();
       boolean isServiceWitNoConfigs = ambariMetaInfo.get().isServiceWithNoConfigs(stackId.getStackName(), stackId.getStackVersion(), service.getName());
       if (isServiceWitNoConfigs){
         LOG.info(String.format("%s in %s version %s does not have customizable configurations. Skip checking service configuration history.", service.getName(), stackId.getStackName(), stackId.getStackVersion()));

http://git-wip-us.apache.org/repos/asf/ambari/blob/a45f5427/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesUpCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesUpCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesUpCheck.java
index 273bdaa..6b03249 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesUpCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesUpCheck.java
@@ -91,10 +91,9 @@ public class ServicesUpCheck extends AbstractCheckDescriptor {
     List<String> errorMessages = new ArrayList<>();
     Set<String> failedServiceNames = new HashSet<>();
 
-    StackId stackId = cluster.getCurrentStackVersion();
-
     for (Map.Entry<String, Service> serviceEntry : cluster.getServices().entrySet()) {
       final Service service = serviceEntry.getValue();
+      StackId stackId = service.getDesiredStackId();
 
       // Ignore services like Tez that are clientOnly.
       if (service.isClientOnlyService()) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/a45f5427/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 d8dba96..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,9 +82,9 @@ 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)) {
-          Service yarnService = cluster.getService("YARN");
           String currentRepositoryVersion = yarnService.getDesiredRepositoryVersion().getVersion();
           return VersionUtils.compareVersions(currentRepositoryVersion, minStackVersion) >= 0;
         }

http://git-wip-us.apache.org/repos/asf/ambari/blob/a45f5427/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariActionExecutionHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariActionExecutionHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariActionExecutionHelper.java
index 9fb77e8..9977210 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariActionExecutionHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariActionExecutionHelper.java
@@ -54,6 +54,7 @@ import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.ComponentInfo;
 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.ServiceInfo;
 import org.apache.ambari.server.state.StackId;
@@ -146,8 +147,6 @@ public class AmbariActionExecutionHelper {
           actionRequest.getClusterName());
       }
 
-      StackId stackId = cluster.getCurrentStackVersion();
-
       String expectedService = actionDef.getTargetService() == null ? "" : actionDef.getTargetService();
 
       String actualService = resourceFilter == null || resourceFilter.getServiceName() == null ? "" : resourceFilter.getServiceName();
@@ -157,11 +156,14 @@ public class AmbariActionExecutionHelper {
       }
 
       targetService = expectedService;
-      if (targetService == null || targetService.isEmpty()) {
+      if (StringUtils.isBlank(targetService)) {
         targetService = actualService;
       }
 
-      if (targetService != null && !targetService.isEmpty()) {
+      if (StringUtils.isNotBlank(targetService)) {
+        Service service = cluster.getService(targetService);
+        StackId stackId = service.getDesiredStackId();
+
         ServiceInfo serviceInfo;
         try {
           serviceInfo = ambariMetaInfo.getService(stackId.getStackName(), stackId.getStackVersion(),
@@ -184,16 +186,20 @@ public class AmbariActionExecutionHelper {
       }
 
       targetComponent = expectedComponent;
-      if (targetComponent == null || targetComponent.isEmpty()) {
+      if (StringUtils.isBlank(targetComponent)) {
         targetComponent = actualComponent;
       }
 
-      if (!targetComponent.isEmpty() && targetService.isEmpty()) {
+      if (StringUtils.isNotBlank(targetComponent) && StringUtils.isBlank(targetService)) {
         throw new AmbariException("Action " + actionRequest.getActionName() + " targets component " + targetComponent +
           " without specifying the target service.");
       }
 
-      if (targetComponent != null && !targetComponent.isEmpty()) {
+      if (StringUtils.isNotBlank(targetComponent)) {
+        Service service = cluster.getService(targetService);
+        ServiceComponent component = service.getServiceComponent(targetComponent);
+        StackId stackId = component.getDesiredStackId();
+
         ComponentInfo compInfo;
         try {
           compInfo = ambariMetaInfo.getComponent(stackId.getStackName(), stackId.getStackVersion(),
@@ -281,13 +287,16 @@ public class AmbariActionExecutionHelper {
     }
 
     if (null != cluster) {
-      StackId stackId = cluster.getCurrentStackVersion();
+//      StackId stackId = cluster.getCurrentStackVersion();
       if (serviceName != null && !serviceName.isEmpty()) {
         if (componentName != null && !componentName.isEmpty()) {
-          Map<String, ServiceComponentHost> componentHosts =
-            cluster.getService(serviceName)
-              .getServiceComponent(componentName).getServiceComponentHosts();
+          Service service = cluster.getService(serviceName);
+          ServiceComponent component = service.getServiceComponent(componentName);
+          StackId stackId = component.getDesiredStackId();
+
+          Map<String, ServiceComponentHost> componentHosts = component.getServiceComponentHosts();
           candidateHosts.addAll(componentHosts.keySet());
+
           try {
             componentInfo = ambariMetaInfo.getComponent(stackId.getStackName(),
                 stackId.getStackVersion(), serviceName, componentName);
@@ -297,8 +306,7 @@ public class AmbariActionExecutionHelper {
           }
         } else {
           for (String component : cluster.getService(serviceName).getServiceComponents().keySet()) {
-            Map<String, ServiceComponentHost> componentHosts =
-              cluster.getService(serviceName)
+            Map<String, ServiceComponentHost> componentHosts = cluster.getService(serviceName)
                 .getServiceComponent(component).getServiceComponentHosts();
             candidateHosts.addAll(componentHosts.keySet());
           }

http://git-wip-us.apache.org/repos/asf/ambari/blob/a45f5427/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 397c1c2..31a34fe 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
@@ -195,12 +195,15 @@ public class AmbariCustomCommandExecutionHelper {
       String serviceName, String componentName, String commandName)
       throws AmbariException {
 
-    Cluster cluster = clusters.getCluster(clusterName);
-    StackId stackId = cluster.getDesiredStackVersion();
-
     if (componentName == null) {
       return false;
     }
+
+    Cluster cluster = clusters.getCluster(clusterName);
+    Service service = cluster.getService(serviceName);
+    ServiceComponent component = service.getServiceComponent(componentName);
+    StackId stackId = component.getDesiredStackId();
+
     ComponentInfo componentInfo = ambariMetaInfo.getComponent(
         stackId.getStackName(), stackId.getStackVersion(),
         serviceName, componentName);
@@ -320,12 +323,12 @@ public class AmbariCustomCommandExecutionHelper {
       throw new AmbariException(message);
     }
 
-    StackId stackId = cluster.getDesiredStackVersion();
+    Service service = cluster.getService(serviceName);
+    StackId stackId = service.getDesiredStackId();
+
     AmbariMetaInfo ambariMetaInfo = managementController.getAmbariMetaInfo();
-    ServiceInfo serviceInfo = ambariMetaInfo.getService(
-        stackId.getStackName(), stackId.getStackVersion(), serviceName);
-    StackInfo stackInfo = ambariMetaInfo.getStack
-       (stackId.getStackName(), stackId.getStackVersion());
+    ServiceInfo serviceInfo = ambariMetaInfo.getService(service);
+    StackInfo stackInfo = ambariMetaInfo.getStack(stackId);
 
     CustomCommandDefinition customCommandDefinition = null;
     ComponentInfo ci = serviceInfo.getComponentByName(componentName);
@@ -691,7 +694,13 @@ public class AmbariCustomCommandExecutionHelper {
 
     String clusterName = stage.getClusterName();
     Cluster cluster = clusters.getCluster(clusterName);
-    StackId stackId = cluster.getDesiredStackVersion();
+    Service service = cluster.getService(serviceName);
+    ServiceComponent component = null;
+    if (null != componentName) {
+      component = service.getServiceComponent(componentName);
+    }
+    StackId stackId = (null != component) ? component.getDesiredStackId() : service.getDesiredStackId();
+
     AmbariMetaInfo ambariMetaInfo = managementController.getAmbariMetaInfo();
     ServiceInfo serviceInfo = ambariMetaInfo.getService(stackId.getStackName(),
         stackId.getStackVersion(), serviceName);
@@ -1252,7 +1261,7 @@ public class AmbariCustomCommandExecutionHelper {
     }
 
     final CommandRepository command = new CommandRepository();
-    StackId stackId = cluster.getDesiredStackVersion();
+    StackId stackId = component.getDesiredStackId();
     command.setRepositories(repoInfos);
     command.setStackName(stackId.getStackName());
 
@@ -1310,7 +1319,7 @@ public class AmbariCustomCommandExecutionHelper {
     String hostOsFamily = host.getOsFamily();
     String hostName = host.getHostName();
 
-    StackId stackId = cluster.getDesiredStackVersion();
+    StackId stackId = component.getDesiredStackId();
 
     Map<String, List<RepositoryInfo>> repos = ambariMetaInfo.getRepository(
             stackId.getStackName(), stackId.getStackVersion());
@@ -1409,6 +1418,10 @@ public class AmbariCustomCommandExecutionHelper {
       }
 
       if (serviceName != null && componentName != null && null != stackId) {
+        Service service = cluster.getService(serviceName);
+        ServiceComponent component = service.getServiceComponent(componentName);
+        stackId = component.getDesiredStackId();
+
         ComponentInfo componentInfo = ambariMetaInfo.getComponent(
                 stackId.getStackName(), stackId.getStackVersion(),
                 serviceName, componentName);
@@ -1448,8 +1461,8 @@ public class AmbariCustomCommandExecutionHelper {
   }
 
   Map<String, String> createDefaultHostParams(Cluster cluster, RepositoryVersionEntity repositoryVersion) throws AmbariException {
-    StackId stackId = cluster.getDesiredStackVersion();
-    if (null == stackId && null != repositoryVersion) {
+    StackId stackId = null;
+    if (null != repositoryVersion) {
       stackId = repositoryVersion.getStackId();
     }
 
@@ -1482,6 +1495,7 @@ public class AmbariCustomCommandExecutionHelper {
     for (Map.Entry<String, String> dbConnectorName : configs.getDatabaseConnectorNames().entrySet()) {
       hostLevelParams.put(dbConnectorName.getKey(), dbConnectorName.getValue());
     }
+
     for (Map.Entry<String, String> previousDBConnectorName : configs.getPreviousDatabaseConnectorNames().entrySet()) {
       hostLevelParams.put(previousDBConnectorName.getKey(), previousDBConnectorName.getValue());
     }
@@ -1501,9 +1515,18 @@ public class AmbariCustomCommandExecutionHelper {
    */
   public boolean isTopologyRefreshRequired(String actionName, String clusterName, String serviceName)
       throws AmbariException {
+
     if (actionName.equals(START_COMMAND_NAME) || actionName.equals(RESTART_COMMAND_NAME)) {
       Cluster cluster = clusters.getCluster(clusterName);
-      StackId stackId = cluster.getDesiredStackVersion();
+      StackId stackId = null;
+      try {
+        Service service = cluster.getService(serviceName);
+        stackId = service.getDesiredStackId();
+      } catch (AmbariException e) {
+        LOG.debug("Could not load service {}, skipping topology check", serviceName);
+        stackId = cluster.getDesiredStackVersion();
+      }
+
 
       AmbariMetaInfo ambariMetaInfo = managementController.getAmbariMetaInfo();
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/a45f5427/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
index 96bab85..fe01a0d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
@@ -57,6 +57,7 @@ import org.apache.ambari.server.state.ServiceComponentFactory;
 import org.apache.ambari.server.state.ServiceComponentHost;
 import org.apache.ambari.server.state.ServiceInfo;
 import org.apache.ambari.server.state.ServiceOsSpecific;
+import org.apache.ambari.server.state.StackId;
 import org.apache.ambari.server.state.State;
 import org.apache.ambari.server.state.configgroup.ConfigGroupFactory;
 import org.apache.ambari.server.state.quicklinksprofile.QuickLinkVisibilityController;
@@ -114,7 +115,7 @@ public interface AmbariManagementController {
    * TODO move this method to Cluster? doesn't seem to be on its place
    * @return config created
    */
-  Config createConfig(Cluster cluster, String type, Map<String, String> properties,
+  Config createConfig(StackId stackId, Cluster cluster, String type, Map<String, String> properties,
                       String versionTag, Map<String, Map<String, String>> propertiesAttributes);
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/a45f5427/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 e373f81..faa9c54 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
@@ -199,6 +199,7 @@ import org.apache.ambari.server.utils.SecretReference;
 import org.apache.ambari.server.utils.StageUtils;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.BooleanUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.math.NumberUtils;
 import org.apache.http.client.utils.URIBuilder;
@@ -696,27 +697,25 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
     for (ServiceComponentHostRequest request : requests) {
       Cluster cluster = clusters.getCluster(request.getClusterName());
 
-      StackId stackId = cluster.getCurrentStackVersion();
-      Collection<String> monitoringServices = ambariMetaInfo.getMonitoringServiceNames(
-        stackId.getStackName(), stackId.getStackVersion());
+      for (Service service : cluster.getServices().values()) {
+        ServiceInfo serviceInfo = ambariMetaInfo.getService(service);
 
-      for (String serviceName : monitoringServices) {
-        if (cluster.getServices().containsKey(serviceName)) {
-          Service service = cluster.getService(serviceName);
-
-          for (ServiceComponent sc : service.getServiceComponents().values()) {
-            if (sc.isMasterComponent()) {
-              for (ServiceComponentHost sch : sc.getServiceComponentHosts().values()) {
-                sch.setRestartRequired(true);
-              }
-              continue;
-            }
+        if (!BooleanUtils.toBoolean(serviceInfo.isMonitoringService())) {
+          continue;
+        }
 
-            String hostname = request.getHostname();
-            if (sc.getServiceComponentHosts().containsKey(hostname)) {
-              ServiceComponentHost sch = sc.getServiceComponentHost(hostname);
+        for (ServiceComponent sc : service.getServiceComponents().values()) {
+          if (sc.isMasterComponent()) {
+            for (ServiceComponentHost sch : sc.getServiceComponentHosts().values()) {
               sch.setRestartRequired(true);
             }
+            continue;
+          }
+
+          String hostname = request.getHostname();
+          if (sc.getServiceComponentHosts().containsKey(hostname)) {
+            ServiceComponentHost sch = sc.getServiceComponentHost(hostname);
+            sch.setRestartRequired(true);
           }
         }
       }
@@ -725,8 +724,8 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
 
   private void setRestartRequiredServices(
           Service service, String componentName) throws AmbariException {
-    Cluster cluster = service.getCluster();
-    StackId stackId = cluster.getCurrentStackVersion();
+
+    StackId stackId = service.getDesiredStackId();
     if (service.getServiceComponent(componentName).isClientComponent()) {
       return;
     }
@@ -751,22 +750,21 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
   @Override
   public void registerRackChange(String clusterName) throws AmbariException {
     Cluster cluster = clusters.getCluster(clusterName);
-    StackId stackId = cluster.getCurrentStackVersion();
 
-    Set<String> rackSensitiveServices =
-        ambariMetaInfo.getRackSensitiveServicesNames(stackId.getStackName(), stackId.getStackVersion());
+    for (Service service : cluster.getServices().values()) {
+      ServiceInfo serviceInfo = ambariMetaInfo.getService(service);
 
-    Map<String, Service> services = cluster.getServices();
+      if (!BooleanUtils.toBoolean(serviceInfo.isRestartRequiredAfterRackChange())) {
+        continue;
+      }
 
-    for (Service service : services.values()) {
-      if(rackSensitiveServices.contains(service.getName())) {
-        Map<String, ServiceComponent> serviceComponents = service.getServiceComponents();
-        for (ServiceComponent serviceComponent : serviceComponents.values()) {
-          Map<String, ServiceComponentHost> schMap = serviceComponent.getServiceComponentHosts();
-          for (Entry<String, ServiceComponentHost> sch : schMap.entrySet()) {
-            ServiceComponentHost serviceComponentHost = sch.getValue();
-            serviceComponentHost.setRestartRequired(true);
-          }
+      Map<String, ServiceComponent> serviceComponents = service.getServiceComponents();
+
+      for (ServiceComponent serviceComponent : serviceComponents.values()) {
+        Map<String, ServiceComponentHost> schMap = serviceComponent.getServiceComponentHosts();
+        for (Entry<String, ServiceComponentHost> sch : schMap.entrySet()) {
+          ServiceComponentHost serviceComponentHost = sch.getValue();
+          serviceComponentHost.setRestartRequired(true);
         }
       }
     }
@@ -895,13 +893,24 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
 
     Map<String, Map<String, String>> propertiesAttributes = new HashMap<>();
 
-    StackId currentStackId = cluster.getCurrentStackVersion();
-    StackInfo currentStackInfo = ambariMetaInfo.getStack(currentStackId.getStackName(), currentStackId.getStackVersion());
-    Map<String, Map<String, String>> defaultConfigAttributes = currentStackInfo.getDefaultConfigAttributesForConfigType(configType);
+    Set<StackId> visitedStacks = new HashSet<>();
+
+    for (Service clusterService : cluster.getServices().values()) {
+      StackId stackId = clusterService.getDesiredStackId();
+      StackInfo stackInfo = ambariMetaInfo.getStack(clusterService.getDesiredStackId());
 
-    if(defaultConfigAttributes != null){
-      ConfigHelper.mergeConfigAttributes(propertiesAttributes, defaultConfigAttributes);
+      if (visitedStacks.contains(stackId)) {
+        continue;
+      }
+
+      Map<String, Map<String, String>> defaultConfigAttributes = stackInfo.getDefaultConfigAttributesForConfigType(configType);
+      if (null != defaultConfigAttributes) {
+        ConfigHelper.mergeConfigAttributes(propertiesAttributes, defaultConfigAttributes);
+      }
+
+      visitedStacks.add(stackId);
     }
+
     // overwrite default attributes with request attributes
     if(requestPropertiesAttributes != null){
       ConfigHelper.mergeConfigAttributes(propertiesAttributes, requestPropertiesAttributes);
@@ -913,7 +922,15 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
           request.getType()));
     }
 
-    Config config = createConfig(cluster, request.getType(), requestProperties,
+    StackId stackId = null;
+    if (null != service) {
+      Service svc = cluster.getService(service);
+      stackId = svc.getDesiredStackId();
+    } else {
+      stackId = cluster.getDesiredStackVersion();
+    }
+
+    Config config = createConfig(stackId, cluster, request.getType(), requestProperties,
       request.getVersionTag(), propertiesAttributes);
 
     LOG.info(MessageFormat.format("Creating configuration with tag ''{0}'' to cluster ''{1}''  for configuration type {2}",
@@ -925,10 +942,10 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
   }
 
   @Override
-  public Config createConfig(Cluster cluster, String type, Map<String, String> properties,
+  public Config createConfig(StackId stackId, Cluster cluster, String type, Map<String, String> properties,
                              String versionTag, Map<String, Map<String, String>> propertiesAttributes) {
 
-    Config config = configFactory.createNew(cluster, type, versionTag, properties,
+    Config config = configFactory.createNew(stackId, cluster, type, versionTag, properties,
         propertiesAttributes);
 
     cluster.addConfig(config);
@@ -1091,13 +1108,6 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
 
     Map<String, Cluster> allClusters = clusters.getClusters();
     for (Cluster c : allClusters.values()) {
-      if (request.getStackVersion() != null) {
-        if (!request.getStackVersion().equals(
-            c.getDesiredStackVersion().getStackId())) {
-          // skip non matching stack versions
-          continue;
-        }
-      }
 
 // TODO: Uncomment this when the UI doesn't require view access for View-only users.
 //       If the user is authorized to view information about this cluster, add it to the response
@@ -1154,20 +1164,13 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
     }
 
     if (request.getComponentName() != null) {
-      if (request.getServiceName() == null
-          || request.getServiceName().isEmpty()) {
-        StackId stackId = cluster.getDesiredStackVersion();
-        String serviceName =
-            ambariMetaInfo.getComponentToService(stackId.getStackName(),
-                stackId.getStackVersion(), request.getComponentName());
-        if (LOG.isDebugEnabled()) {
-          LOG.debug("Looking up service name for component"
-              + ", componentName=" + request.getComponentName()
-              + ", serviceName=" + serviceName
-              + ", stackInfo=" + stackId.getStackId());
-        }
-        if (serviceName == null
-            || serviceName.isEmpty()) {
+      if (StringUtils.isBlank(request.getServiceName())) {
+
+        // !!! FIXME the assumption that a component is unique across all stacks is a ticking
+        // time bomb.  Blueprints are making this assumption.
+        String serviceName = findServiceName(cluster, request.getComponentName());
+
+        if (StringUtils.isBlank(serviceName)) {
           LOG.error("Unable to find service for component {}", request.getComponentName());
           throw new ServiceComponentHostNotFoundException(
               cluster.getClusterName(), null, request.getComponentName(), request.getHostname());
@@ -2194,7 +2197,9 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
     HostEntity hostEntity = host.getHostEntity();
     Map<String, String> hostAttributes = gson.fromJson(hostEntity.getHostAttributes(), hostAttributesType);
     String osFamily = host.getOSFamilyFromHostAttributes(hostAttributes);
-    StackId stackId = cluster.getDesiredStackVersion();
+
+    StackId stackId = scHost.getServiceComponent().getDesiredStackId();
+
     ServiceInfo serviceInfo = ambariMetaInfo.getService(stackId.getStackName(),
         stackId.getStackVersion(), serviceName);
     ComponentInfo componentInfo = ambariMetaInfo.getComponent(
@@ -2593,12 +2598,10 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
       Map<String, Set<String>> clusterHostInfo = StageUtils.getClusterHostInfo(cluster);
 
       String clusterHostInfoJson = StageUtils.getGson().toJson(clusterHostInfo);
-      String hostParamsJson = StageUtils.getGson().toJson(
-          customCommandExecutionHelper.createDefaultHostParams(cluster, null));
 
       Stage stage = createNewStage(requestStages.getLastStageId(), cluster,
           requestStages.getId(), requestProperties.get(REQUEST_CONTEXT_PROPERTY),
-          clusterHostInfoJson, "{}", hostParamsJson);
+          clusterHostInfoJson, "{}", null);
       boolean skipFailure = false;
       if (requestProperties.containsKey(Setting.SETTING_NAME_SKIP_FAILURE) && requestProperties.get(Setting.SETTING_NAME_SKIP_FAILURE).equalsIgnoreCase("true")) {
         skipFailure = true;
@@ -2711,6 +2714,13 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
             Service service = cluster.getService(scHost.getServiceName());
             ServiceComponent serviceComponent = service.getServiceComponent(compName);
 
+            if (StringUtils.isBlank(stage.getHostParamsStage())) {
+              RepositoryVersionEntity repositoryVersion = serviceComponent.getDesiredRepositoryVersion();
+              stage.setHostParamsStage(StageUtils.getGson().toJson(
+                  customCommandExecutionHelper.createDefaultHostParams(cluster, repositoryVersion)));
+            }
+
+
             // Do not create role command for hosts that are not responding
             if (scHost.getHostState().equals(HostState.HEARTBEAT_LOST)) {
               LOG.info("Command is not created for servicecomponenthost "
@@ -3290,24 +3300,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
 
   @Override
   public String findServiceName(Cluster cluster, String componentName) throws AmbariException {
-    StackId stackId = cluster.getDesiredStackVersion();
-    String serviceName =
-        ambariMetaInfo.getComponentToService(stackId.getStackName(),
-            stackId.getStackVersion(), componentName);
-    if (LOG.isDebugEnabled()) {
-      LOG.debug("Looking up service name for component"
-          + ", componentName=" + componentName
-          + ", serviceName=" + serviceName);
-    }
-
-    if (serviceName == null
-        || serviceName.isEmpty()) {
-      throw new AmbariException("Could not find service for component"
-          + ", componentName=" + componentName
-          + ", clusterName=" + cluster.getClusterName()
-          + ", stackInfo=" + stackId.getStackId());
-    }
-    return serviceName;
+    return cluster.getServiceByComponentName(componentName).getName();
   }
 
   /**
@@ -3991,13 +3984,51 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
     RepositoryVersionEntity desiredRepositoryVersion = null;
 
     RequestOperationLevel operationLevel = actionExecContext.getOperationLevel();
-    if (null != operationLevel && null != operationLevel.getServiceName()) {
+    if (null != operationLevel && StringUtils.isNotBlank(operationLevel.getServiceName())) {
       Service service = cluster.getService(operationLevel.getServiceName());
       if (null != service) {
         desiredRepositoryVersion = service.getDesiredRepositoryVersion();
       }
     }
 
+    if (null == desiredRepositoryVersion && CollectionUtils.isNotEmpty(actionExecContext.getResourceFilters())) {
+      Set<RepositoryVersionEntity> versions = new HashSet<>();
+
+      for (RequestResourceFilter filter : actionExecContext.getResourceFilters()) {
+        RepositoryVersionEntity repoVersion = null;
+
+        if (StringUtils.isNotBlank(filter.getServiceName())) {
+          Service service = cluster.getService(filter.getServiceName());
+
+          if (StringUtils.isNotBlank(filter.getComponentName())) {
+            ServiceComponent serviceComponent = service.getServiceComponent(filter.getComponentName());
+
+            repoVersion = serviceComponent.getDesiredRepositoryVersion();
+          }
+
+          if (null == repoVersion) {
+            repoVersion = service.getDesiredRepositoryVersion();
+          }
+        }
+
+        if (null != repoVersion) {
+          versions.add(repoVersion);
+        }
+      }
+
+      if (1 == versions.size()) {
+        desiredRepositoryVersion = versions.iterator().next();
+      } else if (versions.size() > 1) {
+        Set<String> errors = new HashSet<>();
+        for (RepositoryVersionEntity version : versions) {
+          errors.add(String.format("%s/%s", version.getStackId(), version.getVersion()));
+        }
+        throw new IllegalArgumentException(String.format("More than one repository is resolved with this Action: %s",
+            StringUtils.join(errors, ';')));
+      }
+    }
+
+
     ExecuteCommandJson jsons = customCommandExecutionHelper.getCommandJson(actionExecContext,
         cluster, desiredRepositoryVersion);
 
@@ -5013,52 +5044,52 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
   @SuppressWarnings("unchecked")
   @Override
   public void initializeWidgetsAndLayouts(Cluster cluster, Service service) throws AmbariException {
-    StackId stackId = cluster.getDesiredStackVersion();
     Type widgetLayoutType = new TypeToken<Map<String, List<WidgetLayout>>>(){}.getType();
 
-    try {
-      Map<String, Object> widgetDescriptor = null;
-      StackInfo stackInfo = ambariMetaInfo.getStack(stackId.getStackName(), stackId.getStackVersion());
-      if (service != null) {
-        // Service widgets
-        ServiceInfo serviceInfo = stackInfo.getService(service.getName());
-        File widgetDescriptorFile = serviceInfo.getWidgetsDescriptorFile();
-        if (widgetDescriptorFile != null && widgetDescriptorFile.exists()) {
-          try {
-            widgetDescriptor = gson.fromJson(new FileReader(widgetDescriptorFile), widgetLayoutType);
-          } catch (Exception ex) {
-            String msg = "Error loading widgets from file: " + widgetDescriptorFile;
-            LOG.error(msg, ex);
-            throw new AmbariException(msg);
-          }
-        }
-      } else {
-        // Cluster level widgets
+    Set<File> widgetDescriptorFiles = new HashSet<>();
+
+    if (null != service) {
+      ServiceInfo serviceInfo = ambariMetaInfo.getService(service);
+      File widgetDescriptorFile = serviceInfo.getWidgetsDescriptorFile();
+      if (widgetDescriptorFile != null && widgetDescriptorFile.exists()) {
+        widgetDescriptorFiles.add(widgetDescriptorFile);
+      }
+    } else {
+      Set<StackId> stackIds = new HashSet<>();
+
+      for (Service svc : cluster.getServices().values()) {
+        stackIds.add(svc.getDesiredStackId());
+      }
+
+      for (StackId stackId : stackIds) {
+        StackInfo stackInfo = ambariMetaInfo.getStack(stackId);
+
         String widgetDescriptorFileLocation = stackInfo.getWidgetsDescriptorFileLocation();
         if (widgetDescriptorFileLocation != null) {
           File widgetDescriptorFile = new File(widgetDescriptorFileLocation);
           if (widgetDescriptorFile.exists()) {
-            try {
-              widgetDescriptor = gson.fromJson(new FileReader(widgetDescriptorFile), widgetLayoutType);
-            } catch (Exception ex) {
-              String msg = "Error loading widgets from file: " + widgetDescriptorFile;
-              LOG.error(msg, ex);
-              throw new AmbariException(msg);
-            }
+            widgetDescriptorFiles.add(widgetDescriptorFile);
           }
         }
       }
-      if (widgetDescriptor != null) {
-        LOG.debug("Loaded widget descriptor: " + widgetDescriptor);
+    }
+
+    for (File widgetDescriptorFile : widgetDescriptorFiles) {
+      Map<String, Object> widgetDescriptor = null;
+
+      try {
+        widgetDescriptor = gson.fromJson(new FileReader(widgetDescriptorFile), widgetLayoutType);
+
         for (Object artifact : widgetDescriptor.values()) {
           List<WidgetLayout> widgetLayouts = (List<WidgetLayout>) artifact;
           createWidgetsAndLayouts(cluster, widgetLayouts);
         }
+
+      } catch (Exception ex) {
+        String msg = "Error loading widgets from file: " + widgetDescriptorFile;
+        LOG.error(msg, ex);
+        throw new AmbariException(msg);
       }
-    } catch (Exception e) {
-      throw new AmbariException("Error creating stack widget artifacts. " +
-        (service != null ? "Service: " + service.getName() + ", " : "") +
-        "Cluster: " + cluster.getClusterName(), e);
     }
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/a45f5427/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java
index 8a5731b..55b5811 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java
@@ -426,8 +426,6 @@ public class KerberosHelperImpl implements KerberosHelper {
                                                                    Map<String, Set<String>> propertiesToRemove,
                                                                    boolean kerberosEnabled) throws AmbariException {
 
-    StackId stackVersion = cluster.getCurrentStackVersion();
-
     List<String> hostNames = new ArrayList<>();
     Collection<Host> hosts = cluster.getHosts();
 
@@ -488,44 +486,58 @@ public class KerberosHelperImpl implements KerberosHelper {
         }
       }
 
-      StackAdvisorRequest request = StackAdvisorRequest.StackAdvisorRequestBuilder
-          .forStack(stackVersion.getStackName(), stackVersion.getStackVersion())
-          .forServices(new ArrayList<>(services))
-          .forHosts(hostNames)
-          .withComponentHostsMap(cluster.getServiceComponentHostMap(null, services))
-          .withConfigurations(requestConfigurations)
-          .ofType(StackAdvisorRequest.StackAdvisorRequestType.CONFIGURATIONS)
-          .build();
+      Set<StackId> visitedStacks = new HashSet<>();
 
-      try {
-        RecommendationResponse response = stackAdvisorHelper.recommend(request);
-
-        RecommendationResponse.Recommendation recommendation = (response == null) ? null : response.getRecommendations();
-        RecommendationResponse.Blueprint blueprint = (recommendation == null) ? null : recommendation.getBlueprint();
-        Map<String, RecommendationResponse.BlueprintConfigurations> configurations = (blueprint == null) ? null : blueprint.getConfigurations();
-
-        if (configurations != null) {
-          for (Map.Entry<String, RecommendationResponse.BlueprintConfigurations> configuration : configurations.entrySet()) {
-            String configType = configuration.getKey();
-            Map<String, String> recommendedConfigProperties = configuration.getValue().getProperties();
-            Map<String, ValueAttributesInfo> recommendedConfigPropertyAttributes = configuration.getValue().getPropertyAttributes();
-            Map<String, String> existingConfigProperties = (existingConfigurations == null) ? null : existingConfigurations.get(configType);
-            Map<String, String> kerberosConfigProperties = kerberosConfigurations.get(configType);
-            Set<String> ignoreProperties = (propertiesToIgnore == null) ? null : propertiesToIgnore.get(configType);
-
-            addRecommendedPropertiesForConfigType(kerberosConfigurations, configType, recommendedConfigProperties,
-                existingConfigProperties, kerberosConfigProperties, ignoreProperties);
-
-            if (recommendedConfigPropertyAttributes != null) {
-              removeRecommendedPropertiesForConfigType(configType, recommendedConfigPropertyAttributes,
-                  existingConfigProperties, kerberosConfigurations, ignoreProperties, propertiesToRemove);
+      for (String serviceName : services) {
+        Service service = cluster.getService(serviceName);
+        StackId stackId = service.getDesiredStackId();
+
+        if (visitedStacks.contains(stackId)) {
+          continue;
+        }
+
+        StackAdvisorRequest request = StackAdvisorRequest.StackAdvisorRequestBuilder
+            .forStack(stackId.getStackName(), stackId.getStackVersion())
+            .forServices(new ArrayList<>(services))
+            .forHosts(hostNames)
+            .withComponentHostsMap(cluster.getServiceComponentHostMap(null, services))
+            .withConfigurations(requestConfigurations)
+            .ofType(StackAdvisorRequest.StackAdvisorRequestType.CONFIGURATIONS)
+            .build();
+
+        try {
+          RecommendationResponse response = stackAdvisorHelper.recommend(request);
+
+          RecommendationResponse.Recommendation recommendation = (response == null) ? null : response.getRecommendations();
+          RecommendationResponse.Blueprint blueprint = (recommendation == null) ? null : recommendation.getBlueprint();
+          Map<String, RecommendationResponse.BlueprintConfigurations> configurations = (blueprint == null) ? null : blueprint.getConfigurations();
+
+          if (configurations != null) {
+            for (Map.Entry<String, RecommendationResponse.BlueprintConfigurations> configuration : configurations.entrySet()) {
+              String configType = configuration.getKey();
+              Map<String, String> recommendedConfigProperties = configuration.getValue().getProperties();
+              Map<String, ValueAttributesInfo> recommendedConfigPropertyAttributes = configuration.getValue().getPropertyAttributes();
+              Map<String, String> existingConfigProperties = (existingConfigurations == null) ? null : existingConfigurations.get(configType);
+              Map<String, String> kerberosConfigProperties = kerberosConfigurations.get(configType);
+              Set<String> ignoreProperties = (propertiesToIgnore == null) ? null : propertiesToIgnore.get(configType);
+
+              addRecommendedPropertiesForConfigType(kerberosConfigurations, configType, recommendedConfigProperties,
+                  existingConfigProperties, kerberosConfigProperties, ignoreProperties);
+
+              if (recommendedConfigPropertyAttributes != null) {
+                removeRecommendedPropertiesForConfigType(configType, recommendedConfigPropertyAttributes,
+                    existingConfigProperties, kerberosConfigurations, ignoreProperties, propertiesToRemove);
+              }
             }
           }
+
+        } catch (Exception e) {
+          throw new AmbariException(e.getMessage(), e);
         }
 
-      } catch (Exception e) {
-        throw new AmbariException(e.getMessage(), e);
+        visitedStacks.add(stackId);
       }
+
     }
 
     return kerberosConfigurations;
@@ -2559,7 +2571,18 @@ public class KerberosHelperImpl implements KerberosHelper {
    * @throws AmbariException if an error occurs while retrieving the Kerberos descriptor
    */
   private KerberosDescriptor getKerberosDescriptorFromStack(Cluster cluster) throws AmbariException {
-    StackId stackId = cluster.getCurrentStackVersion();
+    // !!! FIXME in a per-service view, what does this become?
+    Set<StackId> stackIds = new HashSet<>();
+
+    for (Service service : cluster.getServices().values()) {
+      stackIds.add(service.getDesiredStackId());
+    }
+
+    if (1 != stackIds.size()) {
+      throw new AmbariException("Services are deployed from multiple stacks and cannot determine a unique one.");
+    }
+
+    StackId stackId = stackIds.iterator().next();
 
     // -------------------------------
     // Get the default Kerberos descriptor from the stack, which is the same as the value from

http://git-wip-us.apache.org/repos/asf/ambari/blob/a45f5427/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceRequest.java
index 66c1a93..7a5abbb 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceRequest.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceRequest.java
@@ -17,7 +17,7 @@
  */
 package org.apache.ambari.server.controller;
 
-
+import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 
 public class ServiceRequest {
 
@@ -30,6 +30,10 @@ public class ServiceRequest {
 
   private String desiredStack;
   private String desiredRepositoryVersion;
+  /**
+   * Short-lived object that gets set while validating a request
+   */
+  private RepositoryVersionEntity resolvedRepository;
 
   public ServiceRequest(String clusterName, String serviceName, String desiredStack,
       String desiredRepositoryVersion, String desiredState) {
@@ -154,4 +158,15 @@ public class ServiceRequest {
       .append(", credentialStoreSupported=").append(credentialStoreSupported);
     return sb.toString();
   }
+
+  /**
+   * @param repositoryVersion
+   */
+  public void setResolvedRepository(RepositoryVersionEntity repositoryVersion) {
+    resolvedRepository = repositoryVersion;
+  }
+
+  public RepositoryVersionEntity getResolvedRepository() {
+    return resolvedRepository;
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/a45f5427/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java
index 4ad01a5..846ce09 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java
@@ -89,6 +89,8 @@ 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.PropertyInfo.PropertyType;
+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.ServiceOsSpecific;
 import org.apache.ambari.server.state.StackId;
@@ -224,15 +226,19 @@ public class ClientConfigResourceProvider extends AbstractControllerResourceProv
       try {
         cluster = clusters.getCluster(response.getClusterName());
 
-        StackId stackId = cluster.getCurrentStackVersion();
         String serviceName = response.getServiceName();
         String componentName = response.getComponentName();
         String hostName = response.getHostname();
         ComponentInfo componentInfo = null;
         String packageFolder = null;
 
+        Service service = cluster.getService(serviceName);
+        ServiceComponent component = service.getServiceComponent(componentName);
+        StackId stackId = component.getDesiredStackId();
+
         componentInfo = managementController.getAmbariMetaInfo().
           getComponent(stackId.getStackName(), stackId.getStackVersion(), serviceName, componentName);
+
         packageFolder = managementController.getAmbariMetaInfo().
           getService(stackId.getStackName(), stackId.getStackVersion(), serviceName).getServicePackageFolder();
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/a45f5427/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
index 6447888..14c9501 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
@@ -70,6 +70,7 @@ import org.apache.ambari.server.state.ComponentInfo;
 import org.apache.ambari.server.state.Host;
 import org.apache.ambari.server.state.RepositoryType;
 import org.apache.ambari.server.state.RepositoryVersionState;
+import org.apache.ambari.server.state.Service;
 import org.apache.ambari.server.state.ServiceComponentHost;
 import org.apache.ambari.server.state.StackId;
 import org.apache.ambari.server.state.repository.VersionDefinitionXml;
@@ -217,7 +218,6 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
       Long id = Long.parseLong(propertyMap.get(CLUSTER_STACK_VERSION_ID_PROPERTY_ID).toString());
       requestedEntities.add(id);
     } else {
-      cluster.getCurrentStackVersion();
       List<RepositoryVersionEntity> entities = repositoryVersionDAO.findAll();
 
       for (RepositoryVersionEntity entity : entities) {
@@ -327,21 +327,31 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
           cluster.getClusterName(), entity.getDirection().getText(false)));
     }
 
-    final StackId stackId;
+    Set<StackId> stackIds = new HashSet<>();
     if (propertyMap.containsKey(CLUSTER_STACK_VERSION_STACK_PROPERTY_ID) &&
             propertyMap.containsKey(CLUSTER_STACK_VERSION_VERSION_PROPERTY_ID)) {
       stackName = (String) propertyMap.get(CLUSTER_STACK_VERSION_STACK_PROPERTY_ID);
       stackVersion = (String) propertyMap.get(CLUSTER_STACK_VERSION_VERSION_PROPERTY_ID);
-      stackId = new StackId(stackName, stackVersion);
+      StackId stackId = new StackId(stackName, stackVersion);
       if (! ami.isSupportedStack(stackName, stackVersion)) {
         throw new NoSuchParentResourceException(String.format("Stack %s is not supported",
                 stackId));
       }
+      stackIds.add(stackId);
     } else { // Using stack that is current for cluster
-      StackId currentStackVersion = cluster.getCurrentStackVersion();
-      stackId = currentStackVersion;
+      for (Service service : cluster.getServices().values()) {
+        stackIds.add(service.getDesiredStackId());
+      }
+    }
+
+    if (stackIds.size() > 1) {
+      throw new SystemException("Could not determine stack to add out of " + StringUtils.join(stackIds, ','));
     }
 
+    StackId stackId = stackIds.iterator().next();
+    stackName = stackId.getStackName();
+    stackVersion = stackId.getStackVersion();
+
     RepositoryVersionEntity repoVersionEntity = repositoryVersionDAO.findByStackAndVersion(
         stackId, desiredRepoVersion);
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/a45f5427/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ComponentResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ComponentResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ComponentResourceProvider.java
index 24ef41a..026ccb9 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ComponentResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ComponentResourceProvider.java
@@ -333,6 +333,7 @@ public class ComponentResourceProvider extends AbstractControllerResourceProvide
       if (!componentNames.containsKey(request.getClusterName())) {
         componentNames.put(request.getClusterName(), new HashMap<String, Set<String>>());
       }
+
       Map<String, Set<String>> serviceComponents = componentNames.get(request.getClusterName());
       if (!serviceComponents.containsKey(request.getServiceName())) {
         serviceComponents.put(request.getServiceName(), new HashSet<String>());
@@ -449,7 +450,6 @@ public class ComponentResourceProvider extends AbstractControllerResourceProvide
     Set<ServiceComponentResponse> response = new HashSet<>();
     String category = null;
 
-    StackId stackId = cluster.getDesiredStackVersion();
 
     if (request.getComponentName() != null) {
       setServiceNameIfAbsent(request, cluster, ambariMetaInfo);
@@ -458,6 +458,8 @@ public class ComponentResourceProvider extends AbstractControllerResourceProvide
       ServiceComponent sc = s.getServiceComponent(request.getComponentName());
       ServiceComponentResponse serviceComponentResponse = sc.convertToResponse();
 
+      StackId stackId = sc.getDesiredStackId();
+
       try {
         ComponentInfo componentInfo = ambariMetaInfo.getComponent(stackId.getStackName(),
             stackId.getStackVersion(), s.getName(), request.getComponentName());
@@ -489,6 +491,8 @@ public class ComponentResourceProvider extends AbstractControllerResourceProvide
           continue;
         }
 
+        StackId stackId = sc.getDesiredStackId();
+
         ServiceComponentResponse serviceComponentResponse = sc.convertToResponse();
         try {
           ComponentInfo componentInfo = ambariMetaInfo.getComponent(stackId.getStackName(),
@@ -826,17 +830,17 @@ public class ComponentResourceProvider extends AbstractControllerResourceProvide
                                       final Cluster cluster,
                                       final AmbariMetaInfo ambariMetaInfo) throws AmbariException {
     if (StringUtils.isEmpty(request.getServiceName())) {
-      StackId stackId = cluster.getDesiredStackVersion();
+
       String componentName = request.getComponentName();
-      String serviceName = ambariMetaInfo.getComponentToService(stackId.getStackName(),
-              stackId.getStackVersion(), componentName);
+
+      String serviceName = getManagementController().findServiceName(cluster, componentName);
+
       debug("Looking up service name for component, componentName={}, serviceName={}", componentName, serviceName);
 
       if (StringUtils.isEmpty(serviceName)) {
         throw new AmbariException("Could not find service for component"
                 + ", componentName=" + request.getComponentName()
-                + ", clusterName=" + cluster.getClusterName()
-                + ", stackInfo=" + stackId.getStackId());
+                + ", clusterName=" + cluster.getClusterName());
       }
       request.setServiceName(serviceName);
     }