You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by jo...@apache.org on 2015/04/16 16:37:31 UTC

[8/8] ambari git commit: AMBARI-10511 - Use Stack Table For Entity Relationships (jonathanhurley)

AMBARI-10511 - Use Stack Table For Entity Relationships (jonathanhurley)


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

Branch: refs/heads/trunk
Commit: 746df034c630081df187dd442fb460596568113f
Parents: e6a02ee
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Wed Apr 15 20:08:34 2015 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Thu Apr 16 10:37:14 2015 -0400

----------------------------------------------------------------------
 .../checks/HostsRepositoryVersionCheck.java     |  15 +-
 .../AmbariManagementControllerImpl.java         | 104 +--
 .../ambari/server/controller/AmbariServer.java  |   3 -
 .../internal/BaseBlueprintProcessor.java        |  39 +-
 .../internal/BlueprintResourceProvider.java     |  65 +-
 .../ClusterStackVersionResourceProvider.java    |  48 +-
 ...atibleRepositoryVersionResourceProvider.java |   9 +-
 .../HostStackVersionResourceProvider.java       |  22 +-
 .../RepositoryVersionResourceProvider.java      |  34 +-
 .../server/controller/internal/Stack.java       |  17 +
 .../internal/UpgradeResourceProvider.java       |   2 +-
 .../controller/utilities/DatabaseChecker.java   |  13 +-
 .../DistributeRepositoriesActionListener.java   |   9 +-
 .../server/orm/dao/ClusterVersionDAO.java       |  38 +-
 .../ambari/server/orm/dao/HostVersionDAO.java   |  59 +-
 .../server/orm/dao/RepositoryVersionDAO.java    |  71 ++-
 .../server/orm/entities/BlueprintEntity.java    |  77 +--
 .../orm/entities/ClusterConfigEntity.java       |  74 ++-
 .../server/orm/entities/ClusterEntity.java      |  23 +-
 .../server/orm/entities/ClusterStateEntity.java |  43 +-
 .../orm/entities/ClusterVersionEntity.java      |  23 +-
 .../HostComponentDesiredStateEntity.java        |  68 +-
 .../orm/entities/HostComponentStateEntity.java  |  80 ++-
 .../ambari/server/orm/entities/HostEntity.java  |  31 +-
 .../server/orm/entities/HostVersionEntity.java  |  58 +-
 .../orm/entities/RepositoryVersionEntity.java   |  74 ++-
 .../ServiceComponentDesiredStateEntity.java     |  65 +-
 .../orm/entities/ServiceConfigEntity.java       |  35 +-
 .../orm/entities/ServiceDesiredStateEntity.java |  71 ++-
 .../upgrades/FinalizeUpgradeAction.java         |  18 +-
 .../org/apache/ambari/server/state/Cluster.java |  36 +-
 .../apache/ambari/server/state/Clusters.java    |   9 +-
 .../apache/ambari/server/state/ConfigImpl.java  |  38 +-
 .../server/state/ServiceComponentImpl.java      |  32 +-
 .../apache/ambari/server/state/ServiceImpl.java |  27 +-
 .../org/apache/ambari/server/state/StackId.java |  14 +-
 .../server/state/cluster/ClusterImpl.java       | 118 ++--
 .../server/state/cluster/ClustersImpl.java      |  33 +-
 .../state/configgroup/ConfigGroupImpl.java      |  54 +-
 .../svccomphost/ServiceComponentHostImpl.java   |  57 +-
 .../ambari/server/upgrade/StackUpgradeUtil.java |  73 +--
 .../server/upgrade/UpgradeCatalog150.java       |  21 +-
 .../server/upgrade/UpgradeCatalog170.java       |  27 +-
 .../main/resources/Ambari-DDL-MySQL-CREATE.sql  |  70 +-
 .../main/resources/Ambari-DDL-Oracle-CREATE.sql |  67 +-
 .../resources/Ambari-DDL-Postgres-CREATE.sql    |  69 +-
 .../Ambari-DDL-Postgres-EMBEDDED-CREATE.sql     |  70 +-
 .../resources/Ambari-DDL-SQLServer-CREATE.sql   | 634 +++++++++++++++++--
 .../ExecutionCommandWrapperTest.java            |  99 +--
 .../actionmanager/TestActionDBAccessorImpl.java |  30 +-
 .../server/actionmanager/TestActionManager.java |  10 +-
 .../server/agent/TestHeartbeatHandler.java      |  53 +-
 .../server/agent/TestHeartbeatMonitor.java      |  53 +-
 .../checks/HostsRepositoryVersionCheckTest.java |  32 +-
 .../AmbariManagementControllerTest.java         | 128 ++--
 .../server/controller/ClusterRequestTest.java   |   5 +-
 .../internal/BaseBlueprintProcessorTest.java    |  17 +-
 .../internal/BlueprintResourceProviderTest.java |  35 +-
 .../internal/ClusterResourceProviderTest.java   | 175 ++---
 ...ClusterStackVersionResourceProviderTest.java |   4 +-
 ...leRepositoryVersionResourceProviderTest.java |  21 +-
 .../HostStackVersionResourceProviderTest.java   |  22 +-
 .../RepositoryVersionResourceProviderTest.java  |  35 +-
 .../StackDefinedPropertyProviderTest.java       |  38 +-
 .../internal/UpgradeResourceProviderTest.java   |  30 +-
 .../RestMetricsPropertyProviderTest.java        |  27 +-
 .../apache/ambari/server/events/EventsTest.java |  11 +-
 .../HostVersionOutOfSyncListenerTest.java       |  21 +-
 .../apache/ambari/server/orm/OrmTestHelper.java |  40 +-
 .../apache/ambari/server/orm/TestOrmImpl.java   |  76 ++-
 .../server/orm/dao/ClusterVersionDAOTest.java   |  41 +-
 .../server/orm/dao/ConfigGroupDAOTest.java      |  35 +-
 .../ambari/server/orm/dao/CrudDAOTest.java      |  18 +-
 .../server/orm/dao/HostVersionDAOTest.java      |  87 ++-
 .../orm/dao/RepositoryVersionDAOTest.java       |  73 ++-
 .../ambari/server/orm/dao/RequestDAOTest.java   |  10 +-
 .../server/orm/dao/RequestScheduleDAOTest.java  |  21 +-
 .../server/orm/dao/ServiceConfigDAOTest.java    |  33 +-
 .../orm/entities/BlueprintEntityTest.java       |  72 ++-
 .../scheduler/ExecutionScheduleManagerTest.java |   3 +-
 .../upgrades/UpgradeActionTest.java             |  66 +-
 .../ambari/server/state/ConfigGroupTest.java    |   3 +-
 .../ambari/server/state/ConfigHelperTest.java   |   3 +-
 .../server/state/RequestExecutionTest.java      |   3 +-
 .../server/state/ServiceComponentTest.java      |  27 +-
 .../apache/ambari/server/state/ServiceTest.java |   9 +-
 .../ambari/server/state/UpgradeHelperTest.java  |  13 +-
 .../state/alerts/AlertEventPublisherTest.java   |   3 +-
 .../state/alerts/InitialAlertEventTest.java     |   3 +-
 .../state/cluster/ClusterDeadlockTest.java      |  34 +-
 .../server/state/cluster/ClusterTest.java       | 464 ++++++++------
 .../state/cluster/ClustersDeadlockTest.java     |  40 +-
 .../server/state/cluster/ClustersTest.java      |  79 ++-
 .../ambari/server/state/host/HostTest.java      |  20 +-
 .../svccomphost/ServiceComponentHostTest.java   |  75 ++-
 .../server/upgrade/UpgradeCatalog150Test.java   |  36 +-
 .../server/upgrade/UpgradeCatalog170Test.java   |  68 +-
 .../server/upgrade/UpgradeCatalog200Test.java   |  21 +-
 .../server/upgrade/UpgradeCatalogHelper.java    |  24 +-
 .../ambari/server/upgrade/UpgradeTest.java      |   2 +
 .../ambari/server/utils/TestStageUtils.java     |   4 +-
 101 files changed, 3402 insertions(+), 1687 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/746df034/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 e4170a3..0db7e2e 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
@@ -23,6 +23,7 @@ import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.controller.PrereqCheckRequest;
 import org.apache.ambari.server.orm.entities.HostVersionEntity;
 import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
+import org.apache.ambari.server.orm.entities.StackEntity;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Host;
 import org.apache.ambari.server.state.MaintenanceState;
@@ -59,14 +60,24 @@ public class HostsRepositoryVersionCheck extends AbstractCheckDescriptor {
     for (Map.Entry<String, Host> hostEntry : clusterHosts.entrySet()) {
       final Host host = hostEntry.getValue();
       if (host.getMaintenanceState(cluster.getClusterId()) == MaintenanceState.OFF) {
-        final RepositoryVersionEntity repositoryVersion = repositoryVersionDaoProvider.get().findByStackAndVersion(stackId.getStackId(), request.getRepositoryVersion());
+        final RepositoryVersionEntity repositoryVersion = repositoryVersionDaoProvider.get().findByStackAndVersion(
+            stackId, request.getRepositoryVersion());
         if (repositoryVersion == null) {
           prerequisiteCheck.setStatus(PrereqCheckStatus.FAIL);
           prerequisiteCheck.setFailReason(getFailReason(KEY_NO_REPO_VERSION, prerequisiteCheck, request));
           prerequisiteCheck.getFailedOn().addAll(clusterHosts.keySet());
           return;
         }
-        final HostVersionEntity hostVersion = hostVersionDaoProvider.get().findByClusterStackVersionAndHost(clusterName, repositoryVersion.getStack(), repositoryVersion.getVersion(), host.getHostName());
+
+        StackEntity repositoryStackEntity = repositoryVersion.getStack();
+        StackId repositoryStackId = new StackId(
+            repositoryStackEntity.getStackName(),
+            repositoryStackEntity.getStackVersion());
+
+        final HostVersionEntity hostVersion = hostVersionDaoProvider.get().findByClusterStackVersionAndHost(
+            clusterName, repositoryStackId, repositoryVersion.getVersion(),
+            host.getHostName());
+
         if (hostVersion == null || hostVersion.getState() != RepositoryVersionState.INSTALLED) {
           prerequisiteCheck.getFailedOn().add(host.getHostName());
         }

http://git-wip-us.apache.org/repos/asf/ambari/blob/746df034/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 a4ddf14..b2120ab 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
@@ -18,14 +18,45 @@
 
 package org.apache.ambari.server.controller;
 
-import com.google.common.cache.Cache;
-import com.google.common.cache.CacheBuilder;
-import com.google.gson.Gson;
-import com.google.gson.reflect.TypeToken;
-import com.google.inject.Inject;
-import com.google.inject.Injector;
-import com.google.inject.Singleton;
-import com.google.inject.persist.Transactional;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_DRIVER;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_PASSWORD;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_URL;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_USERNAME;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.CLIENTS_TO_UPDATE_CONFIGS;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.COMMAND_TIMEOUT;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.DB_DRIVER_FILENAME;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.GROUP_LIST;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.HOOKS_FOLDER;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.PACKAGE_LIST;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.REPO_INFO;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SCRIPT;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SCRIPT_TYPE;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SERVICE_PACKAGE_FOLDER;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SERVICE_REPO_INFO;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.USER_LIST;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.VERSION;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.lang.reflect.Type;
+import java.net.InetAddress;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.concurrent.TimeUnit;
+
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.ClusterNotFoundException;
 import org.apache.ambari.server.DuplicateResourceException;
@@ -124,43 +155,15 @@ import org.apache.commons.lang.math.NumberUtils;
 import org.apache.http.client.utils.URIBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.lang.reflect.Type;
-import java.net.InetAddress;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumMap;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.concurrent.TimeUnit;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_DRIVER;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_PASSWORD;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_URL;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_USERNAME;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.CLIENTS_TO_UPDATE_CONFIGS;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.COMMAND_TIMEOUT;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.DB_DRIVER_FILENAME;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.GROUP_LIST;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.HOOKS_FOLDER;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.PACKAGE_LIST;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.REPO_INFO;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SCRIPT;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SCRIPT_TYPE;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SERVICE_PACKAGE_FOLDER;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SERVICE_REPO_INFO;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.USER_LIST;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.VERSION;
+
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Singleton;
+import com.google.inject.persist.Transactional;
 
 @Singleton
 public class AmbariManagementControllerImpl implements AmbariManagementController {
@@ -348,9 +351,11 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
       throw new IllegalArgumentException("Stack information should be"
           + " provided when creating a cluster");
     }
+
     StackId stackId = new StackId(request.getStackVersion());
     StackInfo stackInfo = ambariMetaInfo.getStack(stackId.getStackName(),
         stackId.getStackVersion());
+
     if (stackInfo == null) {
       throw new StackAccessException("stackName=" + stackId.getStackName() + ", stackVersion=" + stackId.getStackVersion());
     }
@@ -372,17 +377,13 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
         }
       }
     }
+
     if (foundInvalidHosts) {
       throw new HostNotFoundException(invalidHostsStr.toString());
     }
 
-    clusters.addCluster(request.getClusterName());
+    clusters.addCluster(request.getClusterName(), stackId);
     Cluster c = clusters.getCluster(request.getClusterName());
-    if (request.getStackVersion() != null) {
-      StackId newStackId = new StackId(request.getStackVersion());
-      c.setDesiredStackVersion(newStackId);
-      clusters.setCurrentStackVersion(request.getClusterName(), newStackId);
-    }
 
     if (request.getHostNames() != null) {
       clusters.mapHostsToCluster(request.getHostNames(),
@@ -2267,6 +2268,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
     return requestStages;
   }
 
+  @Override
   public ExecutionCommand getExecutionCommand(Cluster cluster,
                                               ServiceComponentHost scHost,
                                               RoleCommand roleCommand) throws AmbariException {

http://git-wip-us.apache.org/repos/asf/ambari/blob/746df034/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
index a24eb60..2451438 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
@@ -47,7 +47,6 @@ import org.apache.ambari.server.configuration.ComponentSSLConfiguration;
 import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.controller.internal.AbstractControllerResourceProvider;
 import org.apache.ambari.server.controller.internal.AmbariPrivilegeResourceProvider;
-import org.apache.ambari.server.controller.internal.BlueprintResourceProvider;
 import org.apache.ambari.server.controller.internal.ClusterPrivilegeResourceProvider;
 import org.apache.ambari.server.controller.internal.ClusterResourceProvider;
 import org.apache.ambari.server.controller.internal.PermissionResourceProvider;
@@ -602,8 +601,6 @@ public class AmbariServer {
     SecurityFilter.init(injector.getInstance(Configuration.class));
     StackDefinedPropertyProvider.init(injector);
     AbstractControllerResourceProvider.init(injector.getInstance(ResourceProviderFactory.class));
-    BlueprintResourceProvider.init(injector.getInstance(BlueprintDAO.class),
-        injector.getInstance(Gson.class), ambariMetaInfo);
     StackDependencyResourceProvider.init(ambariMetaInfo);
     ClusterResourceProvider.init(injector.getInstance(BlueprintDAO.class), ambariMetaInfo, injector.getInstance(ConfigHelper.class));
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/746df034/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseBlueprintProcessor.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseBlueprintProcessor.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseBlueprintProcessor.java
index c2ddad8..73ea1a5 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseBlueprintProcessor.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseBlueprintProcessor.java
@@ -18,7 +18,12 @@
 
 package org.apache.ambari.server.controller.internal;
 
-import com.google.gson.Gson;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.StackAccessException;
@@ -31,6 +36,7 @@ import org.apache.ambari.server.controller.spi.ResourceProvider;
 import org.apache.ambari.server.controller.spi.SystemException;
 import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
 import org.apache.ambari.server.orm.dao.BlueprintDAO;
+import org.apache.ambari.server.orm.dao.StackDAO;
 import org.apache.ambari.server.orm.entities.BlueprintConfigEntity;
 import org.apache.ambari.server.orm.entities.BlueprintEntity;
 import org.apache.ambari.server.orm.entities.HostGroupComponentEntity;
@@ -40,12 +46,7 @@ import org.apache.ambari.server.state.AutoDeployInfo;
 import org.apache.ambari.server.state.ConfigHelper;
 import org.apache.ambari.server.state.DependencyInfo;
 
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
+import com.google.gson.Gson;
 
 /**
  * Base blueprint processing resource provider.
@@ -60,10 +61,15 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
   protected static BlueprintDAO blueprintDAO;
 
   /**
+   * Data access object used to lookup value stacks parsed from the resources.
+   */
+  protected static StackDAO stackDAO;
+
+  /**
    * Stack related information.
    */
   protected static AmbariMetaInfo stackInfo;
-  
+
   protected static ConfigHelper configHelper;
 
 
@@ -121,11 +127,11 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
   protected Stack parseStack(BlueprintEntity blueprint) throws SystemException {
     Stack stack;
     try {
-      stack = new Stack(blueprint.getStackName(), blueprint.getStackVersion(), getManagementController());
+      stack = new Stack(blueprint.getStack(), getManagementController());
     } catch (StackAccessException e) {
-      throw new IllegalArgumentException("Invalid stack information provided for cluster.  " +
-          "stack name: " + blueprint.getStackName() +
-          " stack version: " + blueprint.getStackVersion());
+      throw new IllegalArgumentException(
+          "Invalid stack information provided for cluster. "
+              + blueprint.getStack());
     } catch (AmbariException e) {
       throw new SystemException("Unable to obtain stack information.", e);
     }
@@ -146,7 +152,7 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
    * @throws IllegalArgumentException when validation fails
    */
   protected BlueprintEntity validateTopology(BlueprintEntity blueprint) throws AmbariException {
-    Stack stack = new Stack(blueprint.getStackName(), blueprint.getStackVersion(), getManagementController());
+    Stack stack = new Stack(blueprint.getStack(), getManagementController());
     Map<String, HostGroupImpl> hostGroupMap = parseBlueprintHostGroups(blueprint, stack);
     Collection<HostGroupImpl> hostGroups = hostGroupMap.values();
     Map<String, Map<String, String>> clusterConfig = processBlueprintConfigurations(blueprint, null);
@@ -595,12 +601,12 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
 
     @Override
     public Collection<String> getComponents() {
-      return this.components;
+      return components;
     }
 
     @Override
     public Collection<String> getHostInfo() {
-      return this.hosts;
+      return hosts;
     }
 
     /**
@@ -609,7 +615,7 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
      * @param fqdn  fully qualified domain name of the host being added
      */
     public void addHostInfo(String fqdn) {
-      this.hosts.add(fqdn);
+      hosts.add(fqdn);
     }
 
     /**
@@ -661,6 +667,7 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
      *
      * @return map of configuration type to a map of properties
      */
+    @Override
     public Map<String, Map<String, String>> getConfigurationProperties() {
       return configurations;
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/746df034/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintResourceProvider.java
index 4a1f596..29a95c4 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintResourceProvider.java
@@ -18,11 +18,19 @@
 
 package org.apache.ambari.server.controller.internal;
 
-import com.google.gson.Gson;
-import com.google.inject.Inject;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.DuplicateResourceException;
+import org.apache.ambari.server.StaticallyInject;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
@@ -36,29 +44,24 @@ import org.apache.ambari.server.controller.spi.SystemException;
 import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.apache.ambari.server.orm.dao.BlueprintDAO;
+import org.apache.ambari.server.orm.dao.StackDAO;
 import org.apache.ambari.server.orm.entities.BlueprintConfigEntity;
 import org.apache.ambari.server.orm.entities.BlueprintConfiguration;
 import org.apache.ambari.server.orm.entities.BlueprintEntity;
 import org.apache.ambari.server.orm.entities.HostGroupComponentEntity;
 import org.apache.ambari.server.orm.entities.HostGroupConfigEntity;
 import org.apache.ambari.server.orm.entities.HostGroupEntity;
+import org.apache.ambari.server.orm.entities.StackEntity;
 import org.apache.ambari.server.state.ComponentInfo;
 import org.apache.ambari.server.state.ServiceInfo;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import com.google.gson.Gson;
 
 
 /**
  * Resource Provider for Blueprint resources.
  */
+@StaticallyInject
 public class BlueprintResourceProvider extends BaseBlueprintProcessor {
 
   // ----- Property ID constants ---------------------------------------------
@@ -117,18 +120,21 @@ public class BlueprintResourceProvider extends BaseBlueprintProcessor {
   /**
    * Static initialization.
    *
-   * @param dao       blueprint data access object
-   * @param gson      json serializer
-   * @param metaInfo  stack related information
+   * @param dao
+   *          blueprint data access object
+   * @param gson
+   *          json serializer
+   * @param metaInfo
+   *          stack related information
    */
-  @Inject
-  public static void init(BlueprintDAO dao, Gson gson, AmbariMetaInfo metaInfo) {
-    blueprintDAO   = dao;
+  public static void init(BlueprintDAO dao, StackDAO stacks, Gson gson,
+      AmbariMetaInfo metaInfo) {
+    blueprintDAO = dao;
+    stackDAO = stacks;
     jsonSerializer = gson;
-    stackInfo      = metaInfo;
+    stackInfo = metaInfo;
   }
 
-
   // ----- ResourceProvider ------------------------------------------------
 
   @Override
@@ -241,10 +247,11 @@ public class BlueprintResourceProvider extends BaseBlueprintProcessor {
    * @return a new resource instance for the given blueprint entity
    */
   protected Resource toResource(BlueprintEntity entity, Set<String> requestedIds) {
+    StackEntity stackEntity = entity.getStack();
     Resource resource = new ResourceImpl(Resource.Type.Blueprint);
     setResourceProperty(resource, BLUEPRINT_NAME_PROPERTY_ID, entity.getBlueprintName(), requestedIds);
-    setResourceProperty(resource, STACK_NAME_PROPERTY_ID, entity.getStackName(), requestedIds);
-    setResourceProperty(resource, STACK_VERSION_PROPERTY_ID, entity.getStackVersion(), requestedIds);
+    setResourceProperty(resource, STACK_NAME_PROPERTY_ID, stackEntity.getStackName(), requestedIds);
+    setResourceProperty(resource, STACK_VERSION_PROPERTY_ID, stackEntity.getStackVersion(), requestedIds);
 
     List<Map<String, Object>> listGroupProps = new ArrayList<Map<String, Object>>();
     Collection<HostGroupEntity> hostGroups = entity.getHostGroups();
@@ -285,10 +292,13 @@ public class BlueprintResourceProvider extends BaseBlueprintProcessor {
       throw new IllegalArgumentException("Blueprint name must be provided");
     }
 
+    String stackName = (String) properties.get(STACK_NAME_PROPERTY_ID);
+    String stackVersion = (String) properties.get(STACK_VERSION_PROPERTY_ID);
+    StackEntity stackEntity = stackDAO.find(stackName, stackVersion);
+
     BlueprintEntity blueprint = new BlueprintEntity();
     blueprint.setBlueprintName(name);
-    blueprint.setStackName((String) properties.get(STACK_NAME_PROPERTY_ID));
-    blueprint.setStackVersion((String) properties.get(STACK_VERSION_PROPERTY_ID));
+    blueprint.setStack(stackEntity);
 
     createHostGroupEntities(blueprint,
         (HashSet<HashMap<String, Object>>) properties.get(HOST_GROUP_PROPERTY_ID));
@@ -314,8 +324,11 @@ public class BlueprintResourceProvider extends BaseBlueprintProcessor {
     }
 
     Collection<HostGroupEntity> entities = new ArrayList<HostGroupEntity>();
+
+    StackEntity stackEntity = blueprint.getStack();
+
     Collection<String> stackComponentNames = getAllStackComponents(
-        blueprint.getStackName(), blueprint.getStackVersion());
+        stackEntity.getStackName(), stackEntity.getStackVersion());
 
     for (HashMap<String, Object> hostGroupProperties : setHostGroups) {
       HostGroupEntity hostGroup = new HostGroupEntity();
@@ -350,7 +363,7 @@ public class BlueprintResourceProvider extends BaseBlueprintProcessor {
   @SuppressWarnings("unchecked")
   private void createComponentEntities(HostGroupEntity group, HashSet<HashMap<String, String>> setComponents,
                                        Collection<String> componentNames) {
-    
+
     Collection<HostGroupComponentEntity> components = new ArrayList<HostGroupComponentEntity>();
     String groupName = group.getName();
     group.setComponents(components);
@@ -638,7 +651,7 @@ public class BlueprintResourceProvider extends BaseBlueprintProcessor {
   /**
    * New blueprint configuration format where configs are a map from 'properties' and
    * 'properties_attributes' to a map of strings.
-   * 
+   *
    * @since 1.7.0
    */
   protected static class BlueprintConfigPopulationStrategyV2 extends BlueprintConfigPopulationStrategy {

http://git-wip-us.apache.org/repos/asf/ambari/blob/746df034/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 e872fe9..b952c7c 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
@@ -27,10 +27,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
 
-import com.google.inject.Injector;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.Role;
 import org.apache.ambari.server.StaticallyInject;
@@ -66,6 +63,7 @@ import org.apache.ambari.server.orm.entities.HostVersionEntity;
 import org.apache.ambari.server.orm.entities.OperatingSystemEntity;
 import org.apache.ambari.server.orm.entities.RepositoryEntity;
 import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
+import org.apache.ambari.server.orm.entities.StackEntity;
 import org.apache.ambari.server.serveraction.upgrades.FinalizeUpgradeAction;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Host;
@@ -78,6 +76,7 @@ import org.apache.ambari.server.utils.StageUtils;
 
 import com.google.gson.Gson;
 import com.google.inject.Inject;
+import com.google.inject.Injector;
 import com.google.inject.Provider;
 
 /**
@@ -211,12 +210,18 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
       for (RepositoryVersionState state: RepositoryVersionState.values()) {
         hostStates.put(state.name(), new ArrayList<String>());
       }
-      for (HostVersionEntity hostVersionEntity: hostVersionDAO.findByClusterStackAndVersion(entity.getClusterEntity().getClusterName(),
-          entity.getRepositoryVersion().getStack(), entity.getRepositoryVersion().getVersion())) {
+
+      StackEntity repoVersionStackEntity = entity.getRepositoryVersion().getStack();
+      StackId repoVersionStackId = new StackId(repoVersionStackEntity);
+
+      for (HostVersionEntity hostVersionEntity : hostVersionDAO.findByClusterStackAndVersion(
+          entity.getClusterEntity().getClusterName(), repoVersionStackId,
+          entity.getRepositoryVersion().getVersion())) {
         hostStates.get(hostVersionEntity.getState().name()).add(hostVersionEntity.getHostName());
       }
       StackId stackId = new StackId(entity.getRepositoryVersion().getStack());
-      RepositoryVersionEntity repoVerEntity = repositoryVersionDAO.findByStackAndVersion(stackId.getStackId(), entity.getRepositoryVersion().getVersion());
+      RepositoryVersionEntity repoVerEntity = repositoryVersionDAO.findByStackAndVersion(
+          stackId, entity.getRepositoryVersion().getVersion());
 
       setResourceProperty(resource, CLUSTER_STACK_VERSION_CLUSTER_NAME_PROPERTY_ID, entity.getClusterEntity().getClusterName(), requestedIds);
       setResourceProperty(resource, CLUSTER_STACK_VERSION_HOST_STATES_PROPERTY_ID, hostStates, requestedIds);
@@ -281,12 +286,12 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
       throw new NoSuchParentResourceException(e.getMessage(), e);
     }
 
-    final String stackId;
+    final StackId stackId;
     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).getStackId();
+      stackId = new StackId(stackName, stackVersion);
       if (! ami.isSupportedStack(stackName, stackVersion)) {
         throw new NoSuchParentResourceException(String.format("Stack %s is not supported",
                 stackId));
@@ -295,10 +300,11 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
       StackId currentStackVersion = cluster.getCurrentStackVersion();
       stackName = currentStackVersion.getStackName();
       stackVersion = currentStackVersion.getStackVersion();
-      stackId = currentStackVersion.getStackId();
+      stackId = currentStackVersion;
     }
 
-    RepositoryVersionEntity repoVersionEnt = repositoryVersionDAO.findByStackAndVersion(stackId, desiredRepoVersion);
+    RepositoryVersionEntity repoVersionEnt = repositoryVersionDAO.findByStackAndVersion(
+        stackId, desiredRepoVersion);
     if (repoVersionEnt == null) {
       throw new IllegalArgumentException(String.format(
               "Repo version %s is not available for stack %s",
@@ -365,7 +371,7 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
       final String repoList = gson.toJson(repoInfo);
 
       Map<String, String> params = new HashMap<String, String>() {{
-        put("stack_id", stackId);
+        put("stack_id", stackId.getStackId());
         put("repository_version", desiredRepoVersion);
         put("base_urls", repoList);
         put("package_list", packageList);
@@ -389,22 +395,28 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
     }
 
     try {
-      ClusterVersionEntity existingCSVer = clusterVersionDAO.findByClusterAndStackAndVersion(clName, stackId, desiredRepoVersion);
+      ClusterVersionEntity existingCSVer = clusterVersionDAO.findByClusterAndStackAndVersion(
+          clName, stackId, desiredRepoVersion);
       if (existingCSVer == null) {
-        try {  // Create/persist new cluster stack version
-          cluster.createClusterVersion(stackId, desiredRepoVersion, managementController.getAuthName(), RepositoryVersionState.INSTALLING);
-          existingCSVer = clusterVersionDAO.findByClusterAndStackAndVersion(clName, stackId, desiredRepoVersion);
+        try {
+          // Create/persist new cluster stack version
+          cluster.createClusterVersion(stackId,
+              desiredRepoVersion, managementController.getAuthName(),
+              RepositoryVersionState.INSTALLING);
+          existingCSVer = clusterVersionDAO.findByClusterAndStackAndVersion(
+              clName, stackId, desiredRepoVersion);
         } catch (AmbariException e) {
           throw new SystemException(
                   String.format(
                           "Can not create cluster stack version %s for cluster %s",
-                          desiredRepoVersion, clName),
-                  e);
+              desiredRepoVersion, clName), e);
         }
       } else {
         // Move CSV into INSTALLING state (retry installation)
-        cluster.transitionClusterVersion(stackId, desiredRepoVersion, RepositoryVersionState.INSTALLING);
+        cluster.transitionClusterVersion(stackId,
+            desiredRepoVersion, RepositoryVersionState.INSTALLING);
       }
+
       // Will also initialize all Host Versions in an INSTALLING state.
       cluster.inferHostVersions(existingCSVer);
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/746df034/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/CompatibleRepositoryVersionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/CompatibleRepositoryVersionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/CompatibleRepositoryVersionResourceProvider.java
index ec8d495..add4285 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/CompatibleRepositoryVersionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/CompatibleRepositoryVersionResourceProvider.java
@@ -45,7 +45,6 @@ import org.apache.ambari.server.state.stack.UpgradePack;
 import org.apache.ambari.server.state.stack.upgrade.RepositoryVersionHelper;
 
 import com.google.common.collect.Sets;
-import com.google.gson.Gson;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 
@@ -86,9 +85,6 @@ public class CompatibleRepositoryVersionResourceProvider extends ReadOnlyResourc
   };
 
   @Inject
-  private static Gson s_gson;
-
-  @Inject
   private static RepositoryVersionDAO s_repositoryVersionDAO;
 
   @Inject
@@ -119,14 +115,15 @@ public class CompatibleRepositoryVersionResourceProvider extends ReadOnlyResourc
       final StackId stackId = getStackInformationFromUrl(propertyMap);
 
       if (propertyMaps.size() == 1 && propertyMap.get(REPOSITORY_VERSION_ID_PROPERTY_ID) == null) {
-        requestedEntities.addAll(s_repositoryVersionDAO.findByStack(stackId.getStackId()));
+        requestedEntities.addAll(s_repositoryVersionDAO.findByStack(stackId));
 
         Map<String, UpgradePack> packs = s_ambariMetaInfo.get().getUpgradePacks(
             stackId.getStackName(), stackId.getStackVersion());
 
         for (UpgradePack up : packs.values()) {
           if (null != up.getTargetStack()) {
-            requestedEntities.addAll(s_repositoryVersionDAO.findByStack(up.getTargetStack()));
+            StackId targetStackId = new StackId(up.getTargetStack());
+            requestedEntities.addAll(s_repositoryVersionDAO.findByStack(targetStackId));
           }
         }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/746df034/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostStackVersionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostStackVersionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostStackVersionResourceProvider.java
index 044f03f..88b9415 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostStackVersionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostStackVersionResourceProvider.java
@@ -17,6 +17,8 @@
  */
 package org.apache.ambari.server.controller.internal;
 
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.JDK_LOCATION;
+
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -26,14 +28,12 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import com.google.gson.Gson;
-import com.google.inject.Provider;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.StaticallyInject;
 import org.apache.ambari.server.actionmanager.ActionManager;
+import org.apache.ambari.server.actionmanager.RequestFactory;
 import org.apache.ambari.server.actionmanager.Stage;
 import org.apache.ambari.server.actionmanager.StageFactory;
-import org.apache.ambari.server.actionmanager.RequestFactory;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.controller.ActionExecutionContext;
@@ -45,17 +45,16 @@ import org.apache.ambari.server.controller.spi.Predicate;
 import org.apache.ambari.server.controller.spi.Request;
 import org.apache.ambari.server.controller.spi.RequestStatus;
 import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.Resource.Type;
 import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
 import org.apache.ambari.server.controller.spi.SystemException;
 import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
-import org.apache.ambari.server.controller.spi.Resource.Type;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.apache.ambari.server.orm.dao.HostVersionDAO;
 import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
 import org.apache.ambari.server.orm.entities.HostVersionEntity;
 import org.apache.ambari.server.orm.entities.OperatingSystemEntity;
 import org.apache.ambari.server.orm.entities.RepositoryEntity;
-import com.google.inject.Inject;
 import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Host;
@@ -66,7 +65,9 @@ import org.apache.ambari.server.state.ServiceOsSpecific;
 import org.apache.ambari.server.state.StackId;
 import org.apache.ambari.server.utils.StageUtils;
 
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.JDK_LOCATION;
+import com.google.gson.Gson;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
 
 /**
  * Resource provider for host stack versions resources.
@@ -213,7 +214,8 @@ public class HostStackVersionResourceProvider extends AbstractControllerResource
     for (HostVersionEntity entity: requestedEntities) {
       StackId stackId = new StackId(entity.getRepositoryVersion().getStack());
 
-      RepositoryVersionEntity repoVerEntity = repositoryVersionDAO.findByStackAndVersion(stackId.getStackId(), entity.getRepositoryVersion().getVersion());
+      RepositoryVersionEntity repoVerEntity = repositoryVersionDAO.findByStackAndVersion(
+          stackId, entity.getRepositoryVersion().getVersion());
 
       final Resource resource = new ResourceImpl(Resource.Type.HostStackVersion);
 
@@ -282,7 +284,7 @@ public class HostStackVersionResourceProvider extends AbstractControllerResource
 
     stackName = (String) propertyMap.get(HOST_STACK_VERSION_STACK_PROPERTY_ID);
     stackVersion = (String) propertyMap.get(HOST_STACK_VERSION_VERSION_PROPERTY_ID);
-    final String stackId = new StackId(stackName, stackVersion).getStackId();
+    final StackId stackId = new StackId(stackName, stackVersion);
     if (!ami.isSupportedStack(stackName, stackVersion)) {
       throw new NoSuchParentResourceException(String.format("Stack %s is not supported",
               stackId));
@@ -312,7 +314,7 @@ public class HostStackVersionResourceProvider extends AbstractControllerResource
     // Select all clusters that contain the desired repo version
     Set<Cluster> selectedClusters = new HashSet<Cluster>();
     for (Cluster cluster : clusterSet) {
-      if(cluster.getCurrentStackVersion().getStackId().equals(stackId)) {
+      if (cluster.getCurrentStackVersion().equals(stackId)) {
         selectedClusters.add(cluster);
       }
     }
@@ -385,7 +387,7 @@ public class HostStackVersionResourceProvider extends AbstractControllerResource
     final String repoList = gson.toJson(repoInfo);
 
     Map<String, String> params = new HashMap<String, String>(){{
-      put("stack_id", stackId);
+      put("stack_id", stackId.getStackId());
       put("repository_version", desiredRepoVersion);
       put("base_urls", repoList);
       put("package_list", packageList);

http://git-wip-us.apache.org/repos/asf/ambari/blob/746df034/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProvider.java
index 9a80ad8..9707ec9 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProvider.java
@@ -42,10 +42,12 @@ import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.apache.ambari.server.orm.dao.ClusterVersionDAO;
 import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
+import org.apache.ambari.server.orm.dao.StackDAO;
 import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
 import org.apache.ambari.server.orm.entities.OperatingSystemEntity;
 import org.apache.ambari.server.orm.entities.RepositoryEntity;
 import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
+import org.apache.ambari.server.orm.entities.StackEntity;
 import org.apache.ambari.server.state.OperatingSystemInfo;
 import org.apache.ambari.server.state.RepositoryVersionState;
 import org.apache.ambari.server.state.StackId;
@@ -119,6 +121,12 @@ public class RepositoryVersionResourceProvider extends AbstractResourceProvider
   private RepositoryVersionHelper repositoryVersionHelper;
 
   /**
+   * Data access object used for lookup up stacks.
+   */
+  @Inject
+  private StackDAO stackDAO;
+
+  /**
    * Create a new resource provider.
    *
    */
@@ -181,7 +189,7 @@ public class RepositoryVersionResourceProvider extends AbstractResourceProvider
       final StackId stackId = getStackInformationFromUrl(propertyMap);
 
       if (propertyMaps.size() == 1 && propertyMap.get(REPOSITORY_VERSION_ID_PROPERTY_ID) == null) {
-        requestedEntities.addAll(repositoryVersionDAO.findByStack(stackId.getStackId()));
+        requestedEntities.addAll(repositoryVersionDAO.findByStack(stackId));
       } else {
         final Long id;
         try {
@@ -235,8 +243,12 @@ public class RepositoryVersionResourceProvider extends AbstractResourceProvider
           }
 
           if (StringUtils.isNotBlank(ObjectUtils.toString(propertyMap.get(REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID)))) {
-            final List<ClusterVersionEntity> clusterVersionEntities =
-                clusterVersionDAO.findByStackAndVersion(entity.getStack(), entity.getVersion());
+            StackEntity stackEntity = entity.getStack();
+            String stackName = stackEntity.getStackName();
+            String stackVersion = stackEntity.getStackVersion();
+
+            final List<ClusterVersionEntity> clusterVersionEntities = clusterVersionDAO.findByStackAndVersion(
+                stackName, stackVersion, entity.getVersion());
 
             if (!clusterVersionEntities.isEmpty()) {
               final ClusterVersionEntity firstClusterVersion = clusterVersionEntities.get(0);
@@ -292,8 +304,12 @@ public class RepositoryVersionResourceProvider extends AbstractResourceProvider
         throw new NoSuchResourceException("There is no repository version with id " + id);
       }
 
-      final List<ClusterVersionEntity> clusterVersionEntities =
-          clusterVersionDAO.findByStackAndVersion(entity.getStack(), entity.getVersion());
+      StackEntity stackEntity = entity.getStack();
+      String stackName = stackEntity.getStackName();
+      String stackVersion = stackEntity.getStackVersion();
+
+      final List<ClusterVersionEntity> clusterVersionEntities = clusterVersionDAO.findByStackAndVersion(
+          stackName, stackVersion, entity.getVersion());
 
       final List<RepositoryVersionState> forbiddenToDeleteStates = Lists.newArrayList(
           RepositoryVersionState.CURRENT,
@@ -343,7 +359,7 @@ public class RepositoryVersionResourceProvider extends AbstractResourceProvider
 
     // List of all repo urls that are already added at stack
     Set<String> existingRepoUrls = new HashSet<String>();
-    List<RepositoryVersionEntity> existingRepoVersions = repositoryVersionDAO.findByStack(requiredStack.getStackId());
+    List<RepositoryVersionEntity> existingRepoVersions = repositoryVersionDAO.findByStack(requiredStack);
     for (RepositoryVersionEntity existingRepoVersion : existingRepoVersions) {
       for (OperatingSystemEntity operatingSystemEntity : existingRepoVersion.getOperatingSystems()) {
         for (RepositoryEntity repositoryEntity : operatingSystemEntity.getRepositories()) {
@@ -393,8 +409,12 @@ public class RepositoryVersionResourceProvider extends AbstractResourceProvider
     final RepositoryVersionEntity entity = new RepositoryVersionEntity();
     final String stackName = properties.get(REPOSITORY_VERSION_STACK_NAME_PROPERTY_ID).toString();
     final String stackVersion = properties.get(REPOSITORY_VERSION_STACK_VERSION_PROPERTY_ID).toString();
+
+    StackEntity stackEntity = stackDAO.find(stackName, stackVersion);
+
     entity.setDisplayName(properties.get(REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID).toString());
-    entity.setStack(new StackId(stackName, stackVersion).getStackId());
+    entity.setStack(stackEntity);
+
     entity.setVersion(properties.get(REPOSITORY_VERSION_REPOSITORY_VERSION_PROPERTY_ID).toString());
     final Object operatingSystems = properties.get(SUBRESOURCE_OPERATING_SYSTEMS_PROPERTY_ID);
     final String operatingSystemsJson = gson.toJson(operatingSystems);

http://git-wip-us.apache.org/repos/asf/ambari/blob/746df034/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/Stack.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/Stack.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/Stack.java
index 6da2b54..9ef13ba 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/Stack.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/Stack.java
@@ -34,6 +34,7 @@ import org.apache.ambari.server.controller.StackServiceComponentRequest;
 import org.apache.ambari.server.controller.StackServiceComponentResponse;
 import org.apache.ambari.server.controller.StackServiceRequest;
 import org.apache.ambari.server.controller.StackServiceResponse;
+import org.apache.ambari.server.orm.entities.StackEntity;
 import org.apache.ambari.server.state.AutoDeployInfo;
 import org.apache.ambari.server.state.DependencyInfo;
 
@@ -143,6 +144,22 @@ class Stack {
   /**
    * Constructor.
    *
+   * @param stack
+   *          the stack (not {@code null}).
+   * @param ambariManagementController
+   *          the management controller (not {@code null}).
+   * @throws AmbariException
+   */
+  public Stack(StackEntity stack,
+      AmbariManagementController ambariManagementController)
+      throws AmbariException {
+    this(stack.getStackName(), stack.getStackVersion(),
+        ambariManagementController);
+  }
+
+  /**
+   * Constructor.
+   *
    * @param name     stack name
    * @param version  stack version
    *

http://git-wip-us.apache.org/repos/asf/ambari/blob/746df034/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
index 9733eff..926d9bb 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
@@ -424,7 +424,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     }
 
     RepositoryVersionEntity versionEntity = s_repoVersionDAO.findByStackAndVersion(
-        stack.getStackId(), repoVersion);
+        stack, repoVersion);
 
     if (null == versionEntity) {
       throw new AmbariException(String.format("Version %s for stack %s was not found",

http://git-wip-us.apache.org/repos/asf/ambari/blob/746df034/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/DatabaseChecker.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/DatabaseChecker.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/DatabaseChecker.java
index 3bc4fa0..c4a4e4c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/DatabaseChecker.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/DatabaseChecker.java
@@ -18,9 +18,9 @@
 
 package org.apache.ambari.server.controller.utilities;
 
-import com.google.gson.Gson;
-import com.google.inject.Inject;
-import com.google.inject.Injector;
+import java.util.Collection;
+import java.util.List;
+
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.configuration.Configuration;
@@ -39,8 +39,8 @@ import org.apache.ambari.server.utils.VersionUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.Collection;
-import java.util.List;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
 
 public class DatabaseChecker {
 
@@ -62,8 +62,7 @@ public class DatabaseChecker {
     ClusterDAO clusterDAO = injector.getInstance(ClusterDAO.class);
     List<ClusterEntity> clusters = clusterDAO.findAll();
     for (ClusterEntity clusterEntity: clusters) {
-      String desiredStackVersion = clusterEntity.getDesiredStackVersion();
-      StackId stackId = new Gson().fromJson(desiredStackVersion, StackId.class);
+      StackId stackId = new StackId(clusterEntity.getDesiredStack());
 
       Collection<ClusterServiceEntity> serviceEntities =
         clusterEntity.getClusterServiceEntities();

http://git-wip-us.apache.org/repos/asf/ambari/blob/746df034/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/upgrade/DistributeRepositoriesActionListener.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/upgrade/DistributeRepositoriesActionListener.java b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/upgrade/DistributeRepositoriesActionListener.java
index 85e92af..5a32a82 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/upgrade/DistributeRepositoriesActionListener.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/upgrade/DistributeRepositoriesActionListener.java
@@ -32,6 +32,7 @@ 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.RepositoryVersionState;
+import org.apache.ambari.server.state.StackId;
 import org.apache.ambari.server.utils.StageUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -119,8 +120,9 @@ public class DistributeRepositoriesActionListener {
             // !!! getInstalledRepositoryVersion() from the agent is the one
             // entered in the UI.  getActualVersion() is computed.
 
+            StackId stackId = new StackId(structuredOutput.getStackId());
             RepositoryVersionEntity version = repoVersionDAO.findByStackAndVersion(
-                structuredOutput.getStackId(), structuredOutput.getInstalledRepositoryVersion());
+                stackId, structuredOutput.getInstalledRepositoryVersion());
 
             if (null != version) {
               LOG.info("Repository version {} was found, but {} is the actual value",
@@ -132,8 +134,9 @@ public class DistributeRepositoriesActionListener {
               repositoryVersion = structuredOutput.getActualVersion();
             } else {
               // !!! extra check that the actual version is correct
-              version = repoVersionDAO.findByStackAndVersion(
-                  structuredOutput.getStackId(), structuredOutput.getActualVersion());
+              stackId = new StackId(structuredOutput.getStackId());
+              version = repoVersionDAO.findByStackAndVersion(stackId,
+                  structuredOutput.getActualVersion());
 
               LOG.debug("Repository version {} was not found, check for {}.  Found={}",
                   structuredOutput.getInstalledRepositoryVersion(),

http://git-wip-us.apache.org/repos/asf/ambari/blob/746df034/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterVersionDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterVersionDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterVersionDAO.java
index b7e0d1c..d3326b1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterVersionDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterVersionDAO.java
@@ -26,6 +26,7 @@ import javax.persistence.TypedQuery;
 import org.apache.ambari.server.orm.RequiresSession;
 import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
 import org.apache.ambari.server.state.RepositoryVersionState;
+import org.apache.ambari.server.state.StackId;
 
 import com.google.inject.Singleton;
 
@@ -47,33 +48,46 @@ public class ClusterVersionDAO extends CrudDAO<ClusterVersionEntity, Long>{
   /**
    * Retrieve all of the cluster versions for the given stack and version.
    *
-   * @param stack Stack id (e.g., HDP-2.2)
-   * @param version Repository version (e.g., 2.2.0.1-995)
+   * @param stackName
+   *          the stack name (for example "HDP")
+   * @param stackVersion
+   *          the stack version (for example "2.2")
+   * @param version
+   *          Repository version (e.g., 2.2.0.1-995)
    * @return Return a list of cluster versions that match the stack and version.
    */
   @RequiresSession
-  public List<ClusterVersionEntity> findByStackAndVersion(String stack, String version) {
+  public List<ClusterVersionEntity> findByStackAndVersion(String stackName,
+      String stackVersion, String version) {
     final TypedQuery<ClusterVersionEntity> query = entityManagerProvider.get().createNamedQuery("clusterVersionByStackVersion", ClusterVersionEntity.class);
-    query.setParameter("stack", stack);
+    query.setParameter("stackName", stackName);
+    query.setParameter("stackVersion", stackVersion);
     query.setParameter("version", version);
 
     return daoUtils.selectList(query);
   }
 
   /**
-   * Get the cluster version for the given cluster name, stack name, and stack version.
+   * Get the cluster version for the given cluster name, stack name, and stack
+   * version.
    *
-   * @param clusterName Cluster name
-   * @param stack Stack id (e.g., HDP-2.2)
-   * @param version Repository version (e.g., 2.2.0.1-995)
-   * @return Return all of the cluster versions associated with the given cluster.
+   * @param clusterName
+   *          Cluster name
+   * @param stackId
+   *          Stack id (e.g., HDP-2.2)
+   * @param version
+   *          Repository version (e.g., 2.2.0.1-995)
+   * @return Return all of the cluster versions associated with the given
+   *         cluster.
    */
   @RequiresSession
-  public ClusterVersionEntity findByClusterAndStackAndVersion(String  clusterName, String stack, String version) {
+  public ClusterVersionEntity findByClusterAndStackAndVersion(
+      String clusterName, StackId stackId, String version) {
     final TypedQuery<ClusterVersionEntity> query = entityManagerProvider.get()
         .createNamedQuery("clusterVersionByClusterAndStackAndVersion", ClusterVersionEntity.class);
     query.setParameter("clusterName", clusterName);
-    query.setParameter("stack", stack);
+    query.setParameter("stackName", stackId.getStackName());
+    query.setParameter("stackVersion", stackId.getStackVersion());
     query.setParameter("version", version);
 
     return daoUtils.selectSingle(query);
@@ -86,7 +100,7 @@ public class ClusterVersionDAO extends CrudDAO<ClusterVersionEntity, Long>{
    * @return Return all of the cluster versions associated with the given cluster.
    */
   @RequiresSession
-  public List<ClusterVersionEntity> findByCluster(String  clusterName) {
+  public List<ClusterVersionEntity> findByCluster(String clusterName) {
     final TypedQuery<ClusterVersionEntity> query = entityManagerProvider.get()
         .createNamedQuery("clusterVersionByCluster", ClusterVersionEntity.class);
     query.setParameter("clusterName", clusterName);

http://git-wip-us.apache.org/repos/asf/ambari/blob/746df034/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java
index d816102..de3b8cb 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java
@@ -18,21 +18,22 @@
 
 package org.apache.ambari.server.orm.dao;
 
-import com.google.inject.Inject;
-import com.google.inject.Provider;
-import com.google.inject.Singleton;
-import com.google.inject.persist.Transactional;
-
-import org.apache.ambari.server.orm.RequiresSession;
-import org.apache.ambari.server.orm.entities.HostVersionEntity;
-import org.apache.ambari.server.state.RepositoryVersionState;
+import java.util.List;
 
 import javax.persistence.EntityManager;
 import javax.persistence.NoResultException;
 import javax.persistence.NonUniqueResultException;
 import javax.persistence.TypedQuery;
 
-import java.util.List;
+import org.apache.ambari.server.orm.RequiresSession;
+import org.apache.ambari.server.orm.entities.HostVersionEntity;
+import org.apache.ambari.server.state.RepositoryVersionState;
+import org.apache.ambari.server.state.StackId;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+import com.google.inject.persist.Transactional;
 
 /**
  * The {@link org.apache.ambari.server.orm.dao.HostVersionDAO} class manages the {@link org.apache.ambari.server.orm.entities.HostVersionEntity}
@@ -59,18 +60,24 @@ public class HostVersionDAO {
   }
 
   /**
-   * Retrieve all of the host versions for the given cluster name, stack name, and stack version.
+   * Retrieve all of the host versions for the given cluster name, stack name,
+   * and stack version.
    *
-   * @param clusterName Cluster name
-   * @param stack Stack name (e.g., HDP)
-   * @param version Stack version (e.g., 2.2.0.1-995)
+   * @param clusterName
+   *          Cluster name
+   * @param stackId
+   *          Stack (e.g., HDP-2.2)
+   * @param version
+   *          Stack version (e.g., 2.2.0.1-995)
    * @return Return all of the host versions that match the criteria.
    */
   @RequiresSession
-  public List<HostVersionEntity> findByClusterStackAndVersion(String clusterName, String stack, String version) {
+  public List<HostVersionEntity> findByClusterStackAndVersion(
+      String clusterName, StackId stackId, String version) {
     final TypedQuery<HostVersionEntity> query = entityManagerProvider.get().createNamedQuery("hostVersionByClusterAndStackAndVersion", HostVersionEntity.class);
     query.setParameter("clusterName", clusterName);
-    query.setParameter("stack", stack);
+    query.setParameter("stackName", stackId.getStackName());
+    query.setParameter("stackVersion", stackId.getStackVersion());
     query.setParameter("version", version);
 
     return daoUtils.selectList(query);
@@ -153,20 +160,28 @@ public class HostVersionDAO {
   }
 
   /**
-   * Retrieve the single host version for the given cluster, stack name, stack version, and host name.
+   * Retrieve the single host version for the given cluster, stack name, stack
+   * version, and host name.
    *
-   * @param clusterName Cluster name
-   * @param stack Stack name (e.g., HDP-2.2)
-   * @param version Stack version (e.g., 2.2.0.1-995)
-   * @param hostName FQDN of host
+   * @param clusterName
+   *          Cluster name
+   * @param stackId
+   *          Stack ID (e.g., HDP-2.2)
+   * @param version
+   *          Stack version (e.g., 2.2.0.1-995)
+   * @param hostName
+   *          FQDN of host
    * @return Returns the single host version that matches the criteria.
    */
   @RequiresSession
-  public HostVersionEntity findByClusterStackVersionAndHost(String clusterName, String stack, String version, String hostName) {
+  public HostVersionEntity findByClusterStackVersionAndHost(String clusterName,
+      StackId stackId, String version, String hostName) {
+
     final TypedQuery<HostVersionEntity> query = entityManagerProvider.get()
         .createNamedQuery("hostVersionByClusterStackVersionAndHostname", HostVersionEntity.class);
     query.setParameter("clusterName", clusterName);
-    query.setParameter("stack", stack);
+    query.setParameter("stackName", stackId.getStackName());
+    query.setParameter("stackVersion", stackId.getStackVersion());
     query.setParameter("version", version);
     query.setParameter("hostName", hostName);
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/746df034/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAO.java
index 7099c5c..db5e956 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAO.java
@@ -24,6 +24,8 @@ import javax.persistence.TypedQuery;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.orm.RequiresSession;
 import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
+import org.apache.ambari.server.orm.entities.StackEntity;
+import org.apache.ambari.server.state.StackId;
 
 import com.google.inject.Singleton;
 
@@ -56,14 +58,49 @@ public class RepositoryVersionDAO extends CrudDAO<RepositoryVersionEntity, Long>
   /**
    * Retrieves repository version by stack.
    *
+   * @param stackId
+   *          stackId
+   * @param version
+   *          version
+   * @return null if there is no suitable repository version
+   */
+  public RepositoryVersionEntity findByStackAndVersion(StackId stackId,
+      String version) {
+    return findByStackAndVersion(stackId.getStackName(),
+        stackId.getStackVersion(), version);
+  }
+
+  /**
+   * Retrieves repository version by stack.
+   *
    * @param stack stack
    * @param version version
    * @return null if there is no suitable repository version
    */
+  public RepositoryVersionEntity findByStackAndVersion(StackEntity stackEntity,
+      String version) {
+    return findByStackAndVersion(stackEntity.getStackName(),
+        stackEntity.getStackVersion(), version);
+  }
+
+  /**
+   * Retrieves repository version by stack.
+   *
+   * @param stackName
+   *          stack name
+   * @param stackVersion
+   *          stack version
+   * @param version
+   *          version
+   * @return null if there is no suitable repository version
+   */
   @RequiresSession
-  public RepositoryVersionEntity findByStackAndVersion(String stack, String version) {
-    final TypedQuery<RepositoryVersionEntity> query = entityManagerProvider.get().createNamedQuery("repositoryVersionByStackVersion", RepositoryVersionEntity.class);
-    query.setParameter("stack", stack);
+  private RepositoryVersionEntity findByStackAndVersion(String stackName,
+      String stackVersion, String version) {
+    final TypedQuery<RepositoryVersionEntity> query = entityManagerProvider.get().createNamedQuery(
+        "repositoryVersionByStackVersion", RepositoryVersionEntity.class);
+    query.setParameter("stackName", stackName);
+    query.setParameter("stackVersion", stackVersion);
     query.setParameter("version", version);
     return daoUtils.selectSingle(query);
   }
@@ -71,13 +108,15 @@ public class RepositoryVersionDAO extends CrudDAO<RepositoryVersionEntity, Long>
   /**
    * Retrieves repository version by stack.
    *
-   * @param stack stack with major version (like HDP-2.2)
+   * @param stack
+   *          stack with major version (like HDP-2.2)
    * @return null if there is no suitable repository version
    */
   @RequiresSession
-  public List<RepositoryVersionEntity> findByStack(String stack) {
+  public List<RepositoryVersionEntity> findByStack(StackId stackId) {
     final TypedQuery<RepositoryVersionEntity> query = entityManagerProvider.get().createNamedQuery("repositoryVersionByStack", RepositoryVersionEntity.class);
-    query.setParameter("stack", stack);
+    query.setParameter("stackName", stackId.getStackName());
+    query.setParameter("stackVersion", stackId.getStackVersion());
     return daoUtils.selectList(query);
   }
 
@@ -91,23 +130,31 @@ public class RepositoryVersionDAO extends CrudDAO<RepositoryVersionEntity, Long>
    * @return Returns the object created if successful, and throws an exception otherwise.
    * @throws AmbariException
    */
-  public RepositoryVersionEntity create(String stack, String version, String displayName, String upgradePack, String operatingSystems) throws AmbariException {
-    if (stack == null || stack.isEmpty() || version == null || version.isEmpty() || displayName == null || displayName.isEmpty()) {
+  public RepositoryVersionEntity create(StackEntity stackEntity,
+      String version, String displayName, String upgradePack,
+      String operatingSystems) throws AmbariException {
+
+    if (stackEntity == null || version == null || version.isEmpty()
+        || displayName == null || displayName.isEmpty()) {
       throw new AmbariException("At least one of the required properties is null or empty");
     }
 
-    RepositoryVersionEntity existingByDisplayName = this.findByDisplayName(displayName);
+    RepositoryVersionEntity existingByDisplayName = findByDisplayName(displayName);
 
     if (existingByDisplayName != null) {
       throw new AmbariException("Repository version with display name '" + displayName + "' already exists");
     }
 
-    RepositoryVersionEntity existingByStackAndVersion = this.findByStackAndVersion(stack, version);
+    RepositoryVersionEntity existingByStackAndVersion = findByStackAndVersion(
+        stackEntity, version);
+
     if (existingByStackAndVersion != null) {
-      throw new AmbariException("Repository version for stack " + stack + " and version " + version + " already exists");
+      throw new AmbariException("Repository version for stack " + stackEntity
+          + " and version " + version + " already exists");
     }
 
-    RepositoryVersionEntity newEntity = new RepositoryVersionEntity(stack, version, displayName, upgradePack, operatingSystems);
+    RepositoryVersionEntity newEntity = new RepositoryVersionEntity(
+        stackEntity, version, displayName, upgradePack, operatingSystems);
     this.create(newEntity);
     return newEntity;
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/746df034/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/BlueprintEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/BlueprintEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/BlueprintEntity.java
index 36a0f26..71a64af 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/BlueprintEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/BlueprintEntity.java
@@ -18,26 +18,29 @@
 
 package org.apache.ambari.server.orm.entities;
 
-import com.google.gson.Gson;
-import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.api.services.AmbariMetaInfo;
-import org.apache.ambari.server.state.PropertyInfo;
-import org.apache.ambari.server.state.ServiceInfo;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
 
-import javax.persistence.Basic;
 import javax.persistence.CascadeType;
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.Id;
+import javax.persistence.JoinColumn;
 import javax.persistence.NamedQuery;
 import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
 import javax.persistence.Table;
 import javax.persistence.Transient;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.state.PropertyInfo;
+import org.apache.ambari.server.state.ServiceInfo;
+
+import com.google.gson.Gson;
 
 /**
  * Entity representing a Blueprint.
@@ -53,13 +56,13 @@ public class BlueprintEntity {
       updatable = false, unique = true, length = 100)
   private String blueprintName;
 
-  @Column(name = "stack_name", nullable = false, insertable = true, updatable = false)
-  @Basic
-  private String stackName;
 
-  @Column(name = "stack_version", nullable = false, insertable = true, updatable = false)
-  @Basic
-  private String stackVersion;
+  /**
+   * Unidirectional one-to-one association to {@link StackEntity}
+   */
+  @OneToOne
+  @JoinColumn(name = "stack_id", unique = false, nullable = false, insertable = true, updatable = false)
+  private StackEntity stack;
 
   @OneToMany(cascade = CascadeType.ALL, mappedBy = "blueprint")
   private Collection<HostGroupEntity> hostGroups;
@@ -90,39 +93,22 @@ public class BlueprintEntity {
   }
 
   /**
-   * Get the stack name.
-   *
-   * @return the stack name
-   */
-  public String getStackName() {
-    return stackName;
-  }
-
-  /**
-   * Set the stack name.
-   *
-   * @param stackName  the stack name
-   */
-  public void setStackName(String stackName) {
-    this.stackName = stackName;
-  }
-
-  /**
-   * Get the stack version.
+   * Gets the blueprint's stack.
    *
-   * @return the stack version
+   * @return the stack.
    */
-  public String getStackVersion() {
-    return stackVersion;
+  public StackEntity getStack() {
+    return stack;
   }
 
   /**
-   * Set the stack version.
+   * Sets the blueprint's stack.
    *
-   * @param stackVersion the stack version
+   * @param stack
+   *          the stack to set for the blueprint (not {@code null}).
    */
-  public void setStackVersion(String stackVersion) {
-    this.stackVersion = stackVersion;
+  public void setStack(StackEntity stack) {
+    this.stack = stack;
   }
 
   /**
@@ -175,8 +161,9 @@ public class BlueprintEntity {
   public Map<String, Map<String, Collection<String>>> validateConfigurations(
       AmbariMetaInfo stackInfo, boolean validatePasswords) {
 
-    String stackName = getStackName();
-    String stackVersion = getStackVersion();
+    StackEntity stack = getStack();
+    String stackName = stack.getStackName();
+    String stackVersion = stack.getStackVersion();
 
     Map<String, Map<String, Collection<String>>> missingProperties =
         new HashMap<String, Map<String, Collection<String>>>();

http://git-wip-us.apache.org/repos/asf/ambari/blob/746df034/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigEntity.java
index cb36923..68d88ca 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigEntity.java
@@ -18,9 +18,25 @@
 
 package org.apache.ambari.server.orm.entities;
 
-import javax.persistence.*;
 import java.util.Collection;
 
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.Lob;
+import javax.persistence.ManyToMany;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import javax.persistence.TableGenerator;
+import javax.persistence.UniqueConstraint;
+
 @Entity
 @Table(name = "clusterconfig",
   uniqueConstraints = {@UniqueConstraint(name = "UQ_config_type_tag", columnNames = {"cluster_id", "type_name", "version_tag"}),
@@ -73,6 +89,13 @@ public class ClusterConfigEntity {
   @ManyToMany(mappedBy = "clusterConfigEntities")
   private Collection<ServiceConfigEntity> serviceConfigEntities;
 
+  /**
+   * Unidirectional one-to-one association to {@link StackEntity}
+   */
+  @OneToOne
+  @JoinColumn(name = "stack_id", unique = false, nullable = false, insertable = true, updatable = true)
+  private StackEntity stack;
+
   public Long getConfigId() {
     return configId;
   }
@@ -118,7 +141,7 @@ public class ClusterConfigEntity {
   }
 
   public void setData(String data) {
-    this.configJson = data;
+    configJson = data;
   }
 
   public long getTimestamp() {
@@ -134,22 +157,56 @@ public class ClusterConfigEntity {
   }
 
   public void setAttributes(String attributes) {
-    this.configAttributesJson = attributes;
+    configAttributesJson = attributes;
+  }
+
+  /**
+   * Gets the cluster configuration's stack.
+   *
+   * @return the stack.
+   */
+  public StackEntity getStack() {
+    return stack;
+  }
+
+  /**
+   * Sets the cluster configuration's stack.
+   *
+   * @param stack
+   *          the stack to set for the cluster config (not {@code null}).
+   */
+  public void setStack(StackEntity stack) {
+    this.stack = stack;
   }
 
   @Override
   public boolean equals(Object o) {
-    if (this == o) return true;
-    if (o == null || getClass() != o.getClass()) return false;
+    if (this == o) {
+      return true;
+    }
+
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
 
     ClusterConfigEntity that = (ClusterConfigEntity) o;
 
-    if (clusterId != null ? !clusterId.equals(that.clusterId) : that.clusterId != null) return false;
-    if (configJson != null ? !configJson.equals(that.configJson) : that.configJson != null)
+    if (clusterId != null ? !clusterId.equals(that.clusterId) : that.clusterId != null) {
+      return false;
+    }
+
+    if (configJson != null ? !configJson.equals(that.configJson) : that.configJson != null) {
       return false;
+    }
+
     if (configAttributesJson != null ? !configAttributesJson
-      .equals(that.configAttributesJson) : that.configAttributesJson != null)
+      .equals(that.configAttributesJson) : that.configAttributesJson != null) {
+      return false;
+    }
+
+    if (stack != null ? !stack.equals(that.stack) : that.stack != null) {
       return false;
+    }
 
     return true;
   }
@@ -159,6 +216,7 @@ public class ClusterConfigEntity {
     int result = clusterId != null ? clusterId.intValue() : 0;
     result = 31 * result + (configJson != null ? configJson.hashCode() : 0);
     result = 31 * result + (configAttributesJson != null ? configAttributesJson.hashCode() : 0);
+    result = 31 * result + (stack != null ? stack.hashCode() : 0);
     return result;
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/746df034/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterEntity.java
index 3577dc4..e4a35a7 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterEntity.java
@@ -97,9 +97,12 @@ public class ClusterEntity {
   @Column(name = "cluster_info", insertable = true, updatable = true)
   private String clusterInfo = "";
 
-  @Basic
-  @Column(name = "desired_stack_version", insertable = true, updatable = true)
-  private String desiredStackVersion = "";
+  /**
+   * Unidirectional one-to-one association to {@link StackEntity}
+   */
+  @OneToOne
+  @JoinColumn(name = "desired_stack_id", unique = false, nullable = false, insertable = true, updatable = true)
+  private StackEntity desiredStack;
 
   @OneToMany(mappedBy = "clusterEntity")
   private Collection<ClusterServiceEntity> clusterServiceEntities;
@@ -175,12 +178,12 @@ public class ClusterEntity {
     this.clusterInfo = clusterInfo;
   }
 
-  public String getDesiredStackVersion() {
-    return defaultString(desiredStackVersion);
+  public StackEntity getDesiredStack() {
+    return desiredStack;
   }
 
-  public void setDesiredStackVersion(String desiredStackVersion) {
-    this.desiredStackVersion = desiredStackVersion;
+  public void setDesiredStack(StackEntity desiredStack) {
+    this.desiredStack = desiredStack;
   }
 
   /**
@@ -326,10 +329,10 @@ public class ClusterEntity {
   public void setClusterVersionEntities(Collection<ClusterVersionEntity> clusterVersionEntities) { this.clusterVersionEntities = clusterVersionEntities; }
 
   public void addClusterVersionEntity(ClusterVersionEntity clusterVersionEntity) {
-    if (this.clusterVersionEntities == null) {
-      this.clusterVersionEntities = new ArrayList<ClusterVersionEntity>();
+    if (clusterVersionEntities == null) {
+      clusterVersionEntities = new ArrayList<ClusterVersionEntity>();
     }
-    this.clusterVersionEntities.add(clusterVersionEntity);
+    clusterVersionEntities.add(clusterVersionEntity);
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/746df034/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterStateEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterStateEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterStateEntity.java
index 49afa84..d959641 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterStateEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterStateEntity.java
@@ -39,14 +39,17 @@ public class ClusterStateEntity {
   @Column(name = "current_cluster_state", insertable = true, updatable = true)
   private String currentClusterState = "";
 
-  @Basic
-  @Column(name = "current_stack_version", insertable = true, updatable = true)
-  private String currentStackVersion = "";
-
   @OneToOne
   @JoinColumn(name = "cluster_id", referencedColumnName = "cluster_id", nullable = false)
   private ClusterEntity clusterEntity;
 
+  /**
+   * Unidirectional one-to-one association to {@link StackEntity}
+   */
+  @OneToOne
+  @JoinColumn(name = "current_stack_id", unique = false, nullable = false, insertable = true, updatable = true)
+  private StackEntity currentStack;
+
   public Long getClusterId() {
     return clusterId;
   }
@@ -63,26 +66,38 @@ public class ClusterStateEntity {
     this.currentClusterState = currentClusterState;
   }
 
-  public String getCurrentStackVersion() {
-    return defaultString(currentStackVersion);
+  public StackEntity getCurrentStack() {
+    return currentStack;
   }
 
-  public void setCurrentStackVersion(String currentStackVersion) {
-    this.currentStackVersion = currentStackVersion;
+  public void setCurrentStack(StackEntity currentStack) {
+    this.currentStack = currentStack;
   }
 
   @Override
   public boolean equals(Object o) {
-    if (this == o) return true;
-    if (o == null || getClass() != o.getClass()) return false;
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
 
     ClusterStateEntity that = (ClusterStateEntity) o;
 
-    if (clusterId != null ? !clusterId.equals(that.clusterId) : that.clusterId != null) return false;
+    if (clusterId != null ? !clusterId.equals(that.clusterId) : that.clusterId != null) {
+      return false;
+    }
+
     if (currentClusterState != null
-        ? !currentClusterState.equals(that.currentClusterState) : that.currentClusterState != null) return false;
-    if (currentStackVersion != null
-        ? !currentStackVersion.equals(that.currentStackVersion) : that.currentStackVersion != null) return false;
+        ? !currentClusterState.equals(that.currentClusterState) : that.currentClusterState != null) {
+      return false;
+    }
+
+    if (currentStack != null ? !currentStack.equals(that.currentStack)
+        : that.currentStack != null) {
+      return false;
+    }
 
     return true;
   }