Przeglądaj źródła

AMBARI-12392. RU - Repo version should be unique within the stack (alejandro)

Alejandro Fernandez 10 lat temu
rodzic
commit
71f80203df
26 zmienionych plików z 441 dodań i 339 usunięć
  1. 4 2
      ambari-server/src/main/java/org/apache/ambari/server/checks/ConfigurationMergeCheck.java
  2. 1 1
      ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostStackVersionResourceProvider.java
  3. 3 1
      ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PreUpgradeCheckResourceProvider.java
  4. 6 0
      ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProvider.java
  5. 7 6
      ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
  6. 1 3
      ambari-server/src/main/java/org/apache/ambari/server/events/listeners/upgrade/DistributeRepositoriesActionListener.java
  7. 3 4
      ambari-server/src/main/java/org/apache/ambari/server/events/listeners/upgrade/HostVersionOutOfSyncListener.java
  8. 5 3
      ambari-server/src/main/java/org/apache/ambari/server/events/listeners/upgrade/StackVersionListener.java
  9. 25 65
      ambari-server/src/main/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAO.java
  10. 27 2
      ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryVersionEntity.java
  11. 2 3
      ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java
  12. 3 2
      ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentHost.java
  13. 4 0
      ambari-server/src/main/java/org/apache/ambari/server/state/StackId.java
  14. 10 9
      ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
  15. 18 6
      ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
  16. 10 8
      ambari-server/src/test/java/org/apache/ambari/server/checks/ConfigurationMergeCheckTest.java
  17. 1 1
      ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java
  18. 15 15
      ambari-server/src/test/java/org/apache/ambari/server/events/listeners/upgrade/HostVersionOutOfSyncListenerTest.java
  19. 5 8
      ambari-server/src/test/java/org/apache/ambari/server/events/listeners/upgrade/StackVersionListenerTest.java
  20. 5 1
      ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java
  21. 1 1
      ambari-server/src/test/java/org/apache/ambari/server/orm/dao/ClusterVersionDAOTest.java
  22. 33 30
      ambari-server/src/test/java/org/apache/ambari/server/orm/dao/HostVersionDAOTest.java
  23. 56 1
      ambari-server/src/test/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAOTest.java
  24. 35 31
      ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/ConfigureActionTest.java
  25. 128 105
      ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/UpgradeActionTest.java
  26. 33 31
      ambari-server/src/test/java/org/apache/ambari/server/state/cluster/ClusterTest.java

+ 4 - 2
ambari-server/src/main/java/org/apache/ambari/server/checks/ConfigurationMergeCheck.java

@@ -55,12 +55,13 @@ public class ConfigurationMergeCheck extends AbstractCheckDescriptor {
       return false;
     }
 
+    String stackName = request.getTargetStackId().getStackName();
     String repoVersion = request.getRepositoryVersion();
     if (null == repoVersion) {
       return false;
     }
 
-    RepositoryVersionEntity rve = repositoryVersionDaoProvider.get().findMaxByVersion(repoVersion);
+    RepositoryVersionEntity rve = repositoryVersionDaoProvider.get().findByStackNameAndVersion(stackName, repoVersion);
     if (null == rve) {
       return false;
     }
@@ -87,7 +88,8 @@ public class ConfigurationMergeCheck extends AbstractCheckDescriptor {
   public void perform(PrerequisiteCheck prerequisiteCheck, PrereqCheckRequest request)
       throws AmbariException {
 
-    RepositoryVersionEntity rve = repositoryVersionDaoProvider.get().findMaxByVersion(request.getRepositoryVersion());
+    String stackName = request.getTargetStackId().getStackName();
+    RepositoryVersionEntity rve = repositoryVersionDaoProvider.get().findByStackNameAndVersion(stackName, request.getRepositoryVersion());
 
     Map<String, Map<String, ThreeWayValue>> changes =
         m_mergeHelper.getConflicts(request.getClusterName(), rve.getStackId());

+ 1 - 1
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostStackVersionResourceProvider.java

@@ -437,7 +437,7 @@ public class HostStackVersionResourceProvider extends AbstractControllerResource
       hostVersionDAO.merge(hostVersEntity);
 
       StackId desiredStackId = cluster.getDesiredStackVersion();
-      cluster.recalculateClusterVersionState(desiredStackId, desiredRepoVersion);
+      cluster.recalculateClusterVersionState(repoVersionEnt);
       req.persist();
     } catch (AmbariException e) {
       throw new SystemException("Can not persist request", e);

+ 3 - 1
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PreUpgradeCheckResourceProvider.java

@@ -127,12 +127,14 @@ public class PreUpgradeCheckResourceProvider extends ReadOnlyResourceProvider {
         throw new NoSuchResourceException(ambariException.getMessage());
       }
 
+      String stackName = cluster.getCurrentStackVersion().getStackName();
+
       final PrereqCheckRequest upgradeCheckRequest = new PrereqCheckRequest(clusterName);
       upgradeCheckRequest.setSourceStackId(cluster.getCurrentStackVersion());
 
       if (propertyMap.containsKey(UPGRADE_CHECK_REPOSITORY_VERSION_PROPERTY_ID)) {
         String repositoryVersionId = propertyMap.get(UPGRADE_CHECK_REPOSITORY_VERSION_PROPERTY_ID).toString();
-        RepositoryVersionEntity repositoryVersionEntity = repositoryVersionDAO.findMaxByVersion(repositoryVersionId);
+        RepositoryVersionEntity repositoryVersionEntity = repositoryVersionDAO.findByStackNameAndVersion(stackName, repositoryVersionId);
 
         // set some required properties on the check request
         upgradeCheckRequest.setRepositoryVersion(repositoryVersionId);

+ 6 - 0
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProvider.java

@@ -17,6 +17,7 @@
  */
 package org.apache.ambari.server.controller.internal;
 
+import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -396,6 +397,11 @@ public class RepositoryVersionResourceProvider extends AbstractResourceProvider
         throw new AmbariException("Operating system type " + os + " is not supported by stack " + stackFullName);
       }
     }
+
+    if (!RepositoryVersionEntity.isVersionInStack(repositoryVersion.getStackId(), repositoryVersion.getVersion())) {
+      throw new AmbariException(MessageFormat.format("Version {0} needs to belong to stack {1}",
+          repositoryVersion.getVersion(), repositoryVersion.getStackName() + "-" + repositoryVersion.getStackVersion()));
+    }
   }
 
   /**

+ 7 - 6
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java

@@ -465,7 +465,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
       repoVersion = versionForUpgradePack;
     }
 
-    RepositoryVersionEntity versionEntity = s_repoVersionDAO.findMaxByVersion(repoVersion);
+    RepositoryVersionEntity versionEntity = s_repoVersionDAO.findByStackNameAndVersion(stack.getStackName(), repoVersion);
 
     if (null == versionEntity) {
       throw new AmbariException(String.format("Repository version %s was not found", repoVersion));
@@ -559,8 +559,8 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
       case UPGRADE:
         sourceStackId = cluster.getCurrentStackVersion();
 
-        RepositoryVersionEntity targetRepositoryVersion = s_repoVersionDAO.findMaxByVersion(
-            version);
+        RepositoryVersionEntity targetRepositoryVersion = s_repoVersionDAO.findByStackNameAndVersion(
+            sourceStackId.getStackName(), version);
         targetStackId = targetRepositoryVersion.getStackId();
         break;
       case DOWNGRADE:
@@ -592,7 +592,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
 
     // desired configs must be set before creating stages because the config tag
     // names are read and set on the command for filling in later
-    processConfigurations(cluster, version, direction, pack);
+    processConfigurations(targetStackId.getStackName(), cluster, version, direction, pack);
 
     for (UpgradeGroupHolder group : groups) {
       UpgradeGroupEntity groupEntity = new UpgradeGroupEntity();
@@ -680,6 +680,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
    * </ul>
    *
    *
+   * @param stackName Stack name such as HDP, HDPWIN, BIGTOP
    * @param cluster
    *          the cluster
    * @param version
@@ -691,9 +692,9 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
    *          which services are effected.
    * @throws AmbariException
    */
-  void processConfigurations(Cluster cluster, String version, Direction direction, UpgradePack upgradePack)
+  void processConfigurations(String stackName, Cluster cluster, String version, Direction direction, UpgradePack upgradePack)
       throws AmbariException {
-    RepositoryVersionEntity targetRve = s_repoVersionDAO.findMaxByVersion(version);
+    RepositoryVersionEntity targetRve = s_repoVersionDAO.findByStackNameAndVersion(stackName, version);
     if (null == targetRve) {
       LOG.info("Could not find version entity for {}; not setting new configs", version);
       return;

+ 1 - 3
ambari-server/src/main/java/org/apache/ambari/server/events/listeners/upgrade/DistributeRepositoriesActionListener.java

@@ -175,9 +175,7 @@ public class DistributeRepositoriesActionListener {
         // Update state of a cluster stack version
         try {
           Cluster cluster = clusters.get().getClusterById(clusterId);
-          cluster.recalculateClusterVersionState(
-              hostVersion.getRepositoryVersion().getStackId(),
-              hostVersion.getRepositoryVersion().getVersion());
+          cluster.recalculateClusterVersionState(hostVersion.getRepositoryVersion());
         } catch (AmbariException e) {
           LOG.error("Cannot get cluster with Id " + clusterId.toString() + " to recalculate its ClusterVersion.", e);
         }

+ 3 - 4
ambari-server/src/main/java/org/apache/ambari/server/events/listeners/upgrade/HostVersionOutOfSyncListener.java

@@ -117,8 +117,7 @@ public class HostVersionOutOfSyncListener {
         if (hostVersionEntity.getState().equals(RepositoryVersionState.INSTALLED)) {
           hostVersionEntity.setState(RepositoryVersionState.OUT_OF_SYNC);
           hostVersionDAO.get().merge(hostVersionEntity);
-          cluster.recalculateClusterVersionState(hostStackId,
-              hostVersionEntity.getRepositoryVersion().getVersion());
+          cluster.recalculateClusterVersionState(hostVersionEntity.getRepositoryVersion());
         }
       }
     } catch (AmbariException e) {
@@ -179,7 +178,7 @@ public class HostVersionOutOfSyncListener {
       }
       for (RepositoryVersionEntity repositoryVersion : changedRepositoryVersions) {
         StackId stackId = new StackId(repositoryVersion.getStackName(), repositoryVersion.getStackVersion());
-        cluster.recalculateClusterVersionState(stackId, repositoryVersion.getVersion());
+        cluster.recalculateClusterVersionState(repositoryVersion);
       }
     } catch (AmbariException e) {
       LOG.error("Can not update hosts about out of sync", e);
@@ -206,7 +205,7 @@ public class HostVersionOutOfSyncListener {
                   repositoryVersion, RepositoryVersionState.OUT_OF_SYNC);
           hostVersionDAO.get().create(missingHostVersion);
           StackId stackId = new StackId(repositoryVersion.getStackName(), repositoryVersion.getStackVersion());
-          cluster.recalculateClusterVersionState(stackId, repositoryVersion.getVersion());
+          cluster.recalculateClusterVersionState(repositoryVersion);
         }
       }
     } catch (AmbariException e) {

+ 5 - 3
ambari-server/src/main/java/org/apache/ambari/server/events/listeners/upgrade/StackVersionListener.java

@@ -23,6 +23,7 @@ import java.util.concurrent.locks.ReentrantLock;
 import org.apache.ambari.server.EagerSingleton;
 import org.apache.ambari.server.events.HostComponentVersionEvent;
 import org.apache.ambari.server.events.publishers.VersionEventPublisher;
+import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.ServiceComponentHost;
 import org.apache.ambari.server.state.StackId;
@@ -72,15 +73,16 @@ public class StackVersionListener {
     LOG.debug("Received event {}", event);
 
     Cluster cluster = event.getCluster();
-    StackId desiredStackId = cluster.getDesiredStackVersion();
 
     ServiceComponentHost sch = event.getServiceComponentHost();
 
     m_stackVersionLock.lock();
 
     try {
-      String repoVersion = sch.recalculateHostVersionState();
-      cluster.recalculateClusterVersionState(desiredStackId, repoVersion);
+      RepositoryVersionEntity repoVersion = sch.recalculateHostVersionState();
+      if (null != repoVersion) {
+        cluster.recalculateClusterVersionState(repoVersion);
+      }
     } catch (Exception e) {
       LOG.error(
           "Unable to propagate version for ServiceHostComponent on component: {}, host: {}. Error: {}",

+ 25 - 65
ambari-server/src/main/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAO.java

@@ -17,6 +17,7 @@
  */
 package org.apache.ambari.server.orm.dao;
 
+import java.text.MessageFormat;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
@@ -54,6 +55,7 @@ public class RepositoryVersionDAO extends CrudDAO<RepositoryVersionEntity, Long>
    */
   @RequiresSession
   public RepositoryVersionEntity findByDisplayName(String displayName) {
+    // TODO, this assumes that the display name is unique, but neither the code nor the DB schema enforces this.
     final TypedQuery<RepositoryVersionEntity> query = entityManagerProvider.get().createNamedQuery("repositoryVersionByDisplayName", RepositoryVersionEntity.class);
     query.setParameter("displayname", displayName);
     return daoUtils.selectSingle(query);
@@ -71,8 +73,7 @@ public class RepositoryVersionDAO extends CrudDAO<RepositoryVersionEntity, Long>
   @RequiresSession
   public RepositoryVersionEntity findByStackAndVersion(StackId stackId,
       String version) {
-    return findByStackAndVersion(stackId.getStackName(),
-        stackId.getStackVersion(), version);
+    return findByStackNameAndVersion(stackId.getStackName(), version);
   }
 
   /**
@@ -85,45 +86,28 @@ public class RepositoryVersionDAO extends CrudDAO<RepositoryVersionEntity, Long>
   @RequiresSession
   public RepositoryVersionEntity findByStackAndVersion(StackEntity stackEntity,
       String version) {
-    return findByStackAndVersion(stackEntity.getStackName(),
-        stackEntity.getStackVersion(), version);
+    return findByStackNameAndVersion(stackEntity.getStackName(), version);
   }
 
   /**
-   * Retrieves repository version by stack.
+   * Retrieves repository version, which is unique in this stack.
    *
-   * @param stackName
-   *          stack name
-   * @param stackVersion
-   *          stack version
-   * @param version
-   *          version
+   * @param stackName Stack name such as HDP, HDPWIN, BIGTOP
+   * @param version version
    * @return null if there is no suitable repository version
    */
   @RequiresSession
-  private RepositoryVersionEntity findByStackAndVersion(String stackName,
-      String stackVersion, String version) {
-    final TypedQuery<RepositoryVersionEntity> query = entityManagerProvider.get().createNamedQuery(
-        "repositoryVersionByStackVersion", RepositoryVersionEntity.class);
+  public RepositoryVersionEntity findByStackNameAndVersion(String stackName, String version) {
+    // TODO, need to make a unique composite key in DB using the repo_version's stack_id and version.
+    // Ideally, 1.0-1234 foo should be unique in all HDP stacks.
+    // The composite key is slightly more relaxed since it would only prevent 2.3.0-1234 multiple times in the HDP 2.3 stack.
+    // There's already business logic to prevent creating 2.3-1234 in the wrong stack such as HDP 2.2.
+    final TypedQuery<RepositoryVersionEntity> query = entityManagerProvider.get().createNamedQuery("repositoryVersionByStackNameAndVersion", RepositoryVersionEntity.class);
     query.setParameter("stackName", stackName);
-    query.setParameter("stackVersion", stackVersion);
     query.setParameter("version", version);
     return daoUtils.selectSingle(query);
   }
 
-  /**
-   * Retrieves repository version by stack.
-   *
-   * @param version version
-   * @return null if there is no suitable repository version
-   */
-  @RequiresSession
-  public List<RepositoryVersionEntity> findByVersion(String version) {
-    final TypedQuery<RepositoryVersionEntity> query = entityManagerProvider.get().createNamedQuery("repositoryVersionByVersion", RepositoryVersionEntity.class);
-    query.setParameter("version", version);
-    return daoUtils.selectList(query);
-  }
-
   /**
    * Retrieves repository version by stack.
    *
@@ -141,7 +125,8 @@ public class RepositoryVersionDAO extends CrudDAO<RepositoryVersionEntity, Long>
 
   /**
    * Validates and creates an object.
-   * @param stackEntity Stack entity
+   * The version must be unique within this stack name (e.g., HDP, HDPWIN, BIGTOP).
+   * @param stackEntity Stack entity.
    * @param version Stack version, e.g., 2.2 or 2.2.0.1-885
    * @param displayName Unique display name
    * @param upgradePack Optional upgrade pack, e.g, upgrade-2.2
@@ -165,12 +150,17 @@ public class RepositoryVersionDAO extends CrudDAO<RepositoryVersionEntity, Long>
       throw new AmbariException("Repository version with display name '" + displayName + "' already exists");
     }
 
-    RepositoryVersionEntity existingByStackAndVersion = findByStackAndVersion(
-        stackEntity, version);
+    RepositoryVersionEntity existingVersionInStack = findByStackNameAndVersion(stackEntity.getStackName(), version);
 
-    if (existingByStackAndVersion != null) {
-      throw new AmbariException("Repository version for stack " + stackEntity
-          + " and version " + version + " already exists");
+    if (existingVersionInStack != null) {
+      throw new AmbariException(MessageFormat.format("Repository Version for version {0} already exists, in stack {1}-{2}",
+          version, existingVersionInStack.getStack().getStackName(), existingVersionInStack.getStack().getStackVersion()));
+    }
+
+
+    StackId stackId = new StackId(stackEntity.getStackName(), stackEntity.getStackVersion() );
+    if (!RepositoryVersionEntity.isVersionInStack(stackId, version)) {
+      throw new AmbariException(MessageFormat.format("Version {0} needs to belong to stack {1}", version, stackEntity.getStackName() + "-" + stackEntity.getStackVersion()));
     }
 
     RepositoryVersionEntity newEntity = new RepositoryVersionEntity(
@@ -178,34 +168,4 @@ public class RepositoryVersionDAO extends CrudDAO<RepositoryVersionEntity, Long>
     this.create(newEntity);
     return newEntity;
   }
-
-  /**
-   * Finds the repository version, making sure if there is more than one match
-   * (unlikely) that the latest stack is chosen.
-   * @param version the version to find
-   * @return the matching repo version entity
-   */
-  @RequiresSession
-  public RepositoryVersionEntity findMaxByVersion(String version) {
-    List<RepositoryVersionEntity> list = findByVersion(version);
-    if (null == list || 0 == list.size()) {
-      return null;
-    } else if (1 == list.size()) {
-      return list.get(0);
-    } else {
-      Collections.sort(list, new Comparator<RepositoryVersionEntity>() {
-        @Override
-        public int compare(RepositoryVersionEntity o1, RepositoryVersionEntity o2) {
-          return VersionUtils.compareVersions(o1.getVersion(), o2.getVersion());
-        }
-      });
-
-      Collections.reverse(list);
-
-      return list.get(0);
-    }
-
-  }
-
-
 }

+ 27 - 2
ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryVersionEntity.java

@@ -61,9 +61,8 @@ import com.google.inject.Provider;
     )
 @NamedQueries({
     @NamedQuery(name = "repositoryVersionByDisplayName", query = "SELECT repoversion FROM RepositoryVersionEntity repoversion WHERE repoversion.displayName=:displayname"),
-    @NamedQuery(name = "repositoryVersionByStackVersion", query = "SELECT repoversion FROM RepositoryVersionEntity repoversion WHERE repoversion.stack.stackName=:stackName AND repoversion.stack.stackVersion=:stackVersion AND repoversion.version=:version"),
     @NamedQuery(name = "repositoryVersionByStack", query = "SELECT repoversion FROM RepositoryVersionEntity repoversion WHERE repoversion.stack.stackName=:stackName AND repoversion.stack.stackVersion=:stackVersion"),
-    @NamedQuery(name = "repositoryVersionByVersion", query = "SELECT repoversion FROM RepositoryVersionEntity repoversion WHERE repoversion.version=:version")
+        @NamedQuery(name = "repositoryVersionByStackNameAndVersion", query = "SELECT repoversion FROM RepositoryVersionEntity repoversion WHERE repoversion.stack.stackName=:stackName AND repoversion.version=:version")
 })
 @StaticallyInject
 public class RepositoryVersionEntity {
@@ -255,4 +254,30 @@ public class RepositoryVersionEntity {
     return result;
   }
 
+  /**
+   * Determine if the version belongs to the stack.
+   * Right now, this is only applicable for the HDP stack.
+   * @param stackId Stack, such as HDP-2.3
+   * @param version Version number, such as 2.3.0.0, or 2.3.0.0-1234
+   * @return Return true if the version starts with the digits of the stack.
+   */
+  public static boolean isVersionInStack(StackId stackId, String version) {
+    if (null != version && !StringUtils.isBlank(version)) {
+      // HDP Stack
+      if (stackId.getStackName().equalsIgnoreCase(StackId.HDP_STACK) ||
+          stackId.getStackName().equalsIgnoreCase(StackId.HDPWIN_STACK)) {
+
+        String leading = stackId.getStackVersion();  // E.g, 2.3
+        // In some cases during unit tests, the leading can contain 3 digits, so only the major number (first two parts) are needed.
+        String[] leadingParts = leading.split(".");
+        if (null != leadingParts && leadingParts.length > 2) {
+          leading = leadingParts[0] + "." + leadingParts[1];
+        }
+        return version.startsWith(leading);
+      }
+      // For other stacks, don't make the check.
+      return true;
+    }
+    return false;
+  }
 }

+ 2 - 3
ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java

@@ -199,11 +199,10 @@ public interface Cluster {
 
   /**
    * Update state of a cluster stack version for cluster based on states of host versions and stackids.
-   * @param stackId           the stack id with the version
-   * @param repositoryVersion the repository version (e.g. 2.2.1.0-100)
+   * @param repositoryVersion the repository version entity whose version is a value like 2.2.1.0-100)
    * @throws AmbariException
    */
-  void recalculateClusterVersionState(StackId stackId, String repositoryVersion) throws AmbariException;
+  void recalculateClusterVersionState(RepositoryVersionEntity repositoryVersion) throws AmbariException;
 
   /**
    * Update state of all cluster stack versions for cluster based on states of host versions.

+ 3 - 2
ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentHost.java

@@ -23,6 +23,7 @@ import java.util.Map;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.controller.ServiceComponentHostResponse;
+import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 import org.apache.ambari.server.state.fsm.InvalidStateTransitionException;
 
 import com.google.inject.persist.Transactional;
@@ -209,9 +210,9 @@ public interface ServiceComponentHost {
 
   /**
    * Changes host version state according to state of the components installed on the host.
-   * @return The version number associated with that component in the host
+   * @return The Repository Version Entity with that component in the host
    * @throws AmbariException if host is detached from the cluster
    */
-  public String recalculateHostVersionState() throws AmbariException;
+  public RepositoryVersionEntity recalculateHostVersionState() throws AmbariException;
 
 }

+ 4 - 0
ambari-server/src/main/java/org/apache/ambari/server/state/StackId.java

@@ -25,6 +25,10 @@ public class StackId implements Comparable<StackId> {
 
   private static final String NAME_SEPARATOR = "-";
 
+  public static final String HDP_STACK = "HDP";
+  public static final String HDPWIN_STACK = "HDPWIN";
+  public static final String BIGTOP_STACK = "BIGTOP";
+
   private String stackName;
   private String stackVersion;
 

+ 10 - 9
ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java

@@ -1235,11 +1235,14 @@ public class ClusterImpl implements Cluster {
    * {@inheritDoc}
    */
   @Override
-  public void recalculateClusterVersionState(StackId stackId, String repositoryVersion) throws AmbariException {
+  public void recalculateClusterVersionState(RepositoryVersionEntity repositoryVersion) throws AmbariException {
     if (repositoryVersion == null) {
       return;
     }
 
+    StackId stackId = repositoryVersion.getStackId();
+    String version = repositoryVersion.getVersion();
+
     Map<String, Host> hosts = clusters.getHostsForCluster(getClusterName());
     clusterGlobalLock.writeLock().lock();
 
@@ -1247,7 +1250,7 @@ public class ClusterImpl implements Cluster {
       // Part 1, bootstrap cluster version if necessary.
 
       ClusterVersionEntity clusterVersion = clusterVersionDAO.findByClusterAndStackAndVersion(
-          getClusterName(), stackId, repositoryVersion);
+          getClusterName(), stackId, version);
 
       boolean performingInitialBootstrap = false;
       if (clusterVersion == null) {
@@ -1260,11 +1263,11 @@ public class ClusterImpl implements Cluster {
           performingInitialBootstrap = true;
           createClusterVersionInternal(
               stackId,
-              repositoryVersion,
+              version,
               AuthorizationHelper.getAuthenticatedName(configuration.getAnonymousAuditName()),
               RepositoryVersionState.UPGRADING);
           clusterVersion = clusterVersionDAO.findByClusterAndStackAndVersion(
-              getClusterName(), stackId, repositoryVersion);
+              getClusterName(), stackId, version);
 
           if (clusterVersion == null) {
             LOG.warn(String.format(
@@ -1298,7 +1301,7 @@ public class ClusterImpl implements Cluster {
       //hack until better hostversion integration into in-memory cluster structure
 
       List<HostVersionEntity> hostVersionEntities =
-              hostVersionDAO.findByClusterStackAndVersion(getClusterName(), stackId, repositoryVersion);
+              hostVersionDAO.findByClusterStackAndVersion(getClusterName(), stackId, version);
 
       Set<String> hostsWithState = new HashSet<String>();
       for (HostVersionEntity hostVersionEntity : hostVersionEntities) {
@@ -1358,7 +1361,7 @@ public class ClusterImpl implements Cluster {
         // Any mismatch will be caught while transitioning, and raise an
         // exception.
         try {
-          transitionClusterVersion(stackId, repositoryVersion,
+          transitionClusterVersion(stackId, version,
               effectiveClusterVersionState);
         } catch (AmbariException e) {
           ;
@@ -1441,9 +1444,7 @@ public class ClusterImpl implements Cluster {
         if (clusterVersionEntity.getRepositoryVersion().getStack().equals(
             currentStackId.getStackId())
             && clusterVersionEntity.getState() != RepositoryVersionState.CURRENT) {
-          recalculateClusterVersionState(
-              clusterVersionEntity.getRepositoryVersion().getStackId(),
-              clusterVersionEntity.getRepositoryVersion().getVersion());
+          recalculateClusterVersionState(clusterVersionEntity.getRepositoryVersion());
         }
       }
     } finally {

+ 18 - 6
ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java

@@ -18,6 +18,7 @@
 
 package org.apache.ambari.server.state.svccomphost;
 
+import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -77,6 +78,7 @@ import org.apache.ambari.server.state.fsm.SingleArcTransition;
 import org.apache.ambari.server.state.fsm.StateMachine;
 import org.apache.ambari.server.state.fsm.StateMachineFactory;
 import org.apache.ambari.server.state.stack.upgrade.RepositoryVersionHelper;
+import org.apache.ambari.server.utils.VersionUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -1511,6 +1513,13 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
     StackEntity stackEntity = stackDAO.find(stackId.getStackName(),
         stackId.getStackVersion());
 
+    // Ensure that the version provided is part of the Stack.
+    // E.g., version 2.3.0.0 is part of HDP 2.3, so is 2.3.0.0-1234
+    if (null == version) {
+      throw new AmbariException(MessageFormat.format("Cannot create Repository Version for Stack {0}-{1} if the version is empty",
+          stackId.getStackName(), stackId.getStackVersion()));
+    }
+
     return repositoryVersionDAO.create(
         stackEntity,
         version,
@@ -1523,11 +1532,12 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
    * Bootstrap any Repo Version, and potentially transition the Host Version across states.
    * If a Host Component has a valid version, then create a Host Version if it does not already exist.
    * If a Host Component does not have a version, return right away because no information is known.
-   * @return Return the version
+   * @return Return the Repository Version object
    * @throws AmbariException
    */
   @Override
-  public String recalculateHostVersionState() throws AmbariException {
+  public RepositoryVersionEntity recalculateHostVersionState() throws AmbariException {
+    RepositoryVersionEntity repositoryVersion = null;
     String version = getVersion();
     if (version == null || version.isEmpty() || version.equalsIgnoreCase(State.UNKNOWN.toString())) {
       // Recalculate only if some particular version is set
@@ -1545,9 +1555,11 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
 
     writeLock.lock();
     try {
-      RepositoryVersionEntity repositoryVersion = repositoryVersionDAO.findByStackAndVersion(
-          stackId, version);
-      if (repositoryVersion == null) {
+      // Check if there is a Repo Version already for the version.
+      // If it doesn't exist, will have to create it.
+      repositoryVersion = repositoryVersionDAO.findByStackNameAndVersion(stackId.getStackName(), version);
+
+      if (null == repositoryVersion) {
         repositoryVersion = createRepositoryVersion(version, stackId, stackInfo);
       }
 
@@ -1556,7 +1568,7 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
     } finally {
       writeLock.unlock();
     }
-    return version;
+    return repositoryVersion;
   }
 
   // Get the cached desired state entity or load it fresh through the DAO.

+ 10 - 8
ambari-server/src/test/java/org/apache/ambari/server/checks/ConfigurationMergeCheckTest.java

@@ -58,12 +58,13 @@ public class ConfigurationMergeCheckTest {
   private Clusters clusters = EasyMock.createMock(Clusters.class);
   private Map<String, String> m_configMap = new HashMap<String, String>();
 
+  private static final StackId stackId_1_0 = new StackId("HDP-1.0");
+
   @Before
   public void before() throws Exception {
     Cluster cluster = EasyMock.createMock(Cluster.class);
-    StackId stackId = new StackId("HDP-1.0");
 
-    expect(cluster.getCurrentStackVersion()).andReturn(stackId).anyTimes();
+    expect(cluster.getCurrentStackVersion()).andReturn(stackId_1_0).anyTimes();
     expect(clusters.getCluster((String) anyObject())).andReturn(cluster).anyTimes();
 
     expect(cluster.getServices()).andReturn(new HashMap<String, Service>() {{
@@ -84,14 +85,15 @@ public class ConfigurationMergeCheckTest {
   public void testApplicable() throws Exception {
 
     PrereqCheckRequest request = new PrereqCheckRequest("cluster");
+    request.setTargetStackId(stackId_1_0);
 
     ConfigurationMergeCheck cmc = new ConfigurationMergeCheck();
     Assert.assertFalse(cmc.isApplicable(request));
 
     final RepositoryVersionDAO repositoryVersionDAO = EasyMock.createMock(RepositoryVersionDAO.class);
-    expect(repositoryVersionDAO.findMaxByVersion("1.0")).andReturn(createFor("1.0")).anyTimes();
-    expect(repositoryVersionDAO.findMaxByVersion("1.1")).andReturn(createFor("1.1")).anyTimes();
-    expect(repositoryVersionDAO.findMaxByVersion("1.2")).andReturn(null).anyTimes();
+    expect(repositoryVersionDAO.findByStackNameAndVersion("HDP", "1.0")).andReturn(createFor("1.0")).anyTimes();
+    expect(repositoryVersionDAO.findByStackNameAndVersion("HDP", "1.1")).andReturn(createFor("1.1")).anyTimes();
+    expect(repositoryVersionDAO.findByStackNameAndVersion("HDP", "1.2")).andReturn(null).anyTimes();
 
     replay(repositoryVersionDAO);
 
@@ -117,7 +119,6 @@ public class ConfigurationMergeCheckTest {
 
     request.setRepositoryVersion("1.2");
     Assert.assertFalse(cmc.isApplicable(request));
-
   }
 
   @Test
@@ -125,8 +126,8 @@ public class ConfigurationMergeCheckTest {
     ConfigurationMergeCheck cmc = new ConfigurationMergeCheck();
 
     final RepositoryVersionDAO repositoryVersionDAO = EasyMock.createMock(RepositoryVersionDAO.class);
-    expect(repositoryVersionDAO.findMaxByVersion("1.0")).andReturn(createFor("1.0")).anyTimes();
-    expect(repositoryVersionDAO.findMaxByVersion("1.1")).andReturn(createFor("1.1")).anyTimes();
+    expect(repositoryVersionDAO.findByStackNameAndVersion("HDP", "1.0")).andReturn(createFor("1.0")).anyTimes();
+    expect(repositoryVersionDAO.findByStackNameAndVersion("HDP", "1.1")).andReturn(createFor("1.1")).anyTimes();
 
     replay(repositoryVersionDAO);
 
@@ -183,6 +184,7 @@ public class ConfigurationMergeCheckTest {
     replay(ami);
 
     PrereqCheckRequest request = new PrereqCheckRequest("cluster");
+    request.setTargetStackId(stackId_1_0);
     request.setRepositoryVersion("1.1");
 
     PrerequisiteCheck check = new PrerequisiteCheck(null, "cluster");

+ 1 - 1
ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java

@@ -852,7 +852,7 @@ public class UpgradeResourceProviderTest {
     UpgradeResourceProvider upgradeResourceProvider = createProvider(amc);
 
     Map<String, UpgradePack> upgradePacks = ambariMetaInfo.getUpgradePacks("HDP", "2.1.1");
-    upgradeResourceProvider.processConfigurations(cluster, "2.2.0.0", Direction.UPGRADE, upgradePacks.get("upgrade_to_new_stack"));
+    upgradeResourceProvider.processConfigurations(stack211.getStackName(), cluster, "2.2.0.0", Direction.UPGRADE, upgradePacks.get("upgrade_to_new_stack"));
 
     Map<String, Map<String, String>> expectedConfigurations = expectedConfigurationsCapture.getValue();
     Map<String, String> expectedFooType = expectedConfigurations.get("foo-site");

+ 15 - 15
ambari-server/src/test/java/org/apache/ambari/server/events/listeners/upgrade/HostVersionOutOfSyncListenerTest.java

@@ -132,7 +132,7 @@ public class HostVersionOutOfSyncListenerTest {
    */
   private void createClusterAndHosts(String INSTALLED_VERSION, StackId stackId) throws AmbariException {
     // Configuring 3-node cluster with 2 repo versions
-    String CURRENT_VERSION = "1.0-2086";
+    String CURRENT_VERSION = "2.2.0-2086";
 
     Host h1 = clusters.getHost("h1");
     h1.setState(HostState.HEALTHY);
@@ -211,8 +211,8 @@ public class HostVersionOutOfSyncListenerTest {
    */
   @Test
   public void testOnServiceEvent() throws AmbariException {
-    String INSTALLED_VERSION = "1.0-1000";
-    String INSTALLED_VERSION_2 = "2.0-2000";
+    String INSTALLED_VERSION = "2.2.0-1000";
+    String INSTALLED_VERSION_2 = "2.1.1-2000";
     StackId stackId = new StackId(this.stackId);
     StackId yaStackId = new StackId(this.yetAnotherStackId);
 
@@ -262,7 +262,7 @@ public class HostVersionOutOfSyncListenerTest {
    */
   @Test
   public void testOnServiceEvent_component_does_not_advertise_version() throws AmbariException {
-    String INSTALLED_VERSION = "1.0-1000";
+    String INSTALLED_VERSION = "2.2.0-1000";
     StackId stackId = new StackId(this.stackId);
 
     createClusterAndHosts(INSTALLED_VERSION, stackId);
@@ -301,8 +301,8 @@ public class HostVersionOutOfSyncListenerTest {
    */
   @Test
   public void testOnServiceComponentEvent() throws AmbariException {
-    String INSTALLED_VERSION = "1.0-1000";
-    String INSTALLED_VERSION_2 = "2.0-2000";
+    String INSTALLED_VERSION = "2.2.0-1000";
+    String INSTALLED_VERSION_2 = "2.1.1-2000";
     StackId stackId = new StackId(this.stackId);
     StackId yaStackId = new StackId(this.yetAnotherStackId);
 
@@ -351,20 +351,20 @@ public class HostVersionOutOfSyncListenerTest {
 
     StackId stackId = new StackId(this.stackId);
     StackId yaStackId = new StackId(this.yetAnotherStackId);
-    RepositoryVersionEntity repositoryVersionEntity = helper.getOrCreateRepositoryVersion(stackId,"1.0-1000");
-    RepositoryVersionEntity repositoryVersionEntity2 = helper.getOrCreateRepositoryVersion(stackId,"2.0-2000");
-    c1.createClusterVersion(stackId, "1.0-1000", "admin", RepositoryVersionState.INSTALLING);
+    RepositoryVersionEntity repositoryVersionEntity = helper.getOrCreateRepositoryVersion(stackId,"2.2.0-1000");
+    RepositoryVersionEntity repositoryVersionEntity2 = helper.getOrCreateRepositoryVersion(stackId,"2.2.0-2000");
+    c1.createClusterVersion(stackId, "2.2.0-1000", "admin", RepositoryVersionState.INSTALLING);
     c1.setCurrentStackVersion(stackId);
     c1.recalculateAllClusterVersionStates();
-    checkStackVersionState(stackId.getStackId(), "1.0-1000", RepositoryVersionState.INSTALLING);
-    checkStackVersionState(stackId.getStackId(), "1.0-2086", RepositoryVersionState.CURRENT);
+    checkStackVersionState(stackId.getStackId(), "2.2.0-1000", RepositoryVersionState.INSTALLING);
+    checkStackVersionState(stackId.getStackId(), "2.2.0-2086", RepositoryVersionState.CURRENT);
 
     HostVersionEntity hv1 = helper.createHostVersion("h1", repositoryVersionEntity, RepositoryVersionState.INSTALLED);
     HostVersionEntity hv2 = helper.createHostVersion("h1", repositoryVersionEntity2, RepositoryVersionState.INSTALLED);
     c1.recalculateAllClusterVersionStates();
-    checkStackVersionState(stackId.getStackId(), "1.0-1000", RepositoryVersionState.INSTALLED);
-    checkStackVersionState(stackId.getStackId(), "2.0-2000", RepositoryVersionState.INSTALLED);
-    checkStackVersionState(stackId.getStackId(), "1.0-2086", RepositoryVersionState.CURRENT);
+    checkStackVersionState(stackId.getStackId(), "2.2.0-1000", RepositoryVersionState.INSTALLED);
+    checkStackVersionState(stackId.getStackId(), "2.2.0-2000", RepositoryVersionState.INSTALLED);
+    checkStackVersionState(stackId.getStackId(), "2.2.0-2086", RepositoryVersionState.CURRENT);
 
     // Add new host and verify that it has all host versions present
     addHost("h2");
@@ -373,7 +373,7 @@ public class HostVersionOutOfSyncListenerTest {
     List<HostVersionEntity> h2Versions = hostVersionDAO.findByHost("h2");
 
     for (HostVersionEntity hostVersionEntity : h2Versions) {
-      if (hostVersionEntity.getRepositoryVersion().toString().equals("1.0-2086")) {
+      if (hostVersionEntity.getRepositoryVersion().toString().equals("2.2.0-2086")) {
         assertEquals(hostVersionEntity.getState(), RepositoryVersionState.CURRENT);
       } else {
         assertEquals(hostVersionEntity.getState(), RepositoryVersionState.OUT_OF_SYNC);

+ 5 - 8
ambari-server/src/test/java/org/apache/ambari/server/events/listeners/upgrade/StackVersionListenerTest.java

@@ -24,9 +24,9 @@ import static org.easymock.EasyMock.verify;
 
 import org.apache.ambari.server.events.HostComponentVersionEvent;
 import org.apache.ambari.server.events.publishers.VersionEventPublisher;
+import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.ServiceComponentHost;
-import org.apache.ambari.server.state.StackId;
 import org.easymock.EasyMock;
 import org.junit.Test;
 
@@ -37,21 +37,18 @@ public class StackVersionListenerTest {
 
   @Test
   public void testOnAmbariEvent() throws Exception {
-    StackId stackId = new StackId("HDP-0.1");
-
     VersionEventPublisher publisher = createNiceMock(VersionEventPublisher.class);
-
     Cluster cluster = createNiceMock(Cluster.class);
     ServiceComponentHost sch = createNiceMock(ServiceComponentHost.class);
+    RepositoryVersionEntity repositoryVersionEntity = createNiceMock(RepositoryVersionEntity.class);
 
     expect(cluster.getClusterId()).andReturn(99L);
-    expect(cluster.getDesiredStackVersion()).andReturn(stackId);
+    expect(sch.recalculateHostVersionState()).andReturn(repositoryVersionEntity).atLeastOnce();
 
-    cluster.recalculateClusterVersionState(stackId, "1.0.0");
+    cluster.recalculateClusterVersionState(repositoryVersionEntity);
     EasyMock.expectLastCall().atLeastOnce();
 
-    expect(sch.recalculateHostVersionState()).andReturn("1.0.0").atLeastOnce();
-
+    // Replay and assert expectations
     replay(cluster, sch);
 
     HostComponentVersionEvent event = new HostComponentVersionEvent(cluster, sch);

+ 5 - 1
ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java

@@ -22,6 +22,7 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
+import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -34,6 +35,7 @@ import java.util.UUID;
 
 import javax.persistence.EntityManager;
 
+import junit.framework.Assert;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.Role;
 import org.apache.ambari.server.RoleCommand;
@@ -593,7 +595,7 @@ public class OrmTestHelper {
   /**
    * Convenient method to create or to get repository version for given stack.
    *
-   * @param stack stack name
+   * @param stackId stack object
    * @param version stack version
    * @return repository version
    */
@@ -613,6 +615,8 @@ public class OrmTestHelper {
         repositoryVersion = repositoryVersionDAO.create(stackEntity, version,
             String.valueOf(System.currentTimeMillis()), "pack", "");
       } catch (Exception ex) {
+        Assert.fail(MessageFormat.format("Unable to create Repo Version for Stack {0} and version {1}",
+            stackEntity.getStackName() + "-" + stackEntity.getStackVersion(), version));
       }
     }
     return repositoryVersion;

+ 1 - 1
ambari-server/src/test/java/org/apache/ambari/server/orm/dao/ClusterVersionDAOTest.java

@@ -109,7 +109,7 @@ public class ClusterVersionDAOTest {
     // Start upgrading C
     if (currStep >= 4) {
       if (lastStep <= 3) {
-        cvC = new ClusterVersionEntity(cluster, helper.getOrCreateRepositoryVersion(HDP_22_STACK, "2.2.1.0-100"), RepositoryVersionState.UPGRADING, System.currentTimeMillis(), "admin");
+        cvC = new ClusterVersionEntity(cluster, helper.getOrCreateRepositoryVersion(HDP_22_STACK, "2.2.0.0-100"), RepositoryVersionState.UPGRADING, System.currentTimeMillis(), "admin");
         clusterVersionDAO.create(cvC);
         cvCId = cvC.getId();
       } else {

+ 33 - 30
ambari-server/src/test/java/org/apache/ambari/server/orm/dao/HostVersionDAOTest.java

@@ -26,13 +26,7 @@ import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.orm.GuiceJpaInitializer;
 import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
 import org.apache.ambari.server.orm.OrmTestHelper;
-import org.apache.ambari.server.orm.entities.ClusterEntity;
-import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
-import org.apache.ambari.server.orm.entities.HostEntity;
-import org.apache.ambari.server.orm.entities.HostVersionEntity;
-import org.apache.ambari.server.orm.entities.ResourceEntity;
-import org.apache.ambari.server.orm.entities.ResourceTypeEntity;
-import org.apache.ambari.server.orm.entities.StackEntity;
+import org.apache.ambari.server.orm.entities.*;
 import org.apache.ambari.server.state.RepositoryVersionState;
 import org.apache.ambari.server.state.StackId;
 import org.junit.After;
@@ -62,6 +56,10 @@ public class HostVersionDAOTest {
   private final static StackId HDP_22_STACK = new StackId("HDP", "2.2.0");
   private final static StackId BAD_STACK = new StackId("BADSTACK", "1.0");
 
+  private final static String repoVersion_2200 = "2.2.0.0-1";
+  private final static String repoVersion_2201 = "2.2.0.1-2";
+  private final static String repoVersion_2202 = "2.2.0.2-3";
+
   @Before
   public void before() {
     injector = Guice.createInjector(new InMemoryDefaultTestModule());
@@ -105,10 +103,11 @@ public class HostVersionDAOTest {
 
     clusterDAO.create(clusterEntity);
 
+    RepositoryVersionEntity repoVersionEntity = helper.getOrCreateRepositoryVersion(HDP_22_STACK, repoVersion_2200);
+
     // Create the Cluster Version and link it to the cluster
     ClusterVersionEntity clusterVersionEntity = new ClusterVersionEntity(
-        clusterEntity, helper.getOrCreateRepositoryVersion(HDP_22_STACK,
-            "2.2.0.0-995"), RepositoryVersionState.CURRENT,
+        clusterEntity, repoVersionEntity, RepositoryVersionState.CURRENT,
         System.currentTimeMillis(), System.currentTimeMillis(), "admin");
     List<ClusterVersionEntity> clusterVersionEntities = new ArrayList<ClusterVersionEntity>();
     clusterVersionEntities.add(clusterVersionEntity);
@@ -171,7 +170,9 @@ public class HostVersionDAOTest {
       Assert.fail("Cluster is expected to have at least one cluster version");
     }
 
-    ClusterVersionEntity newClusterVersionEntity = new ClusterVersionEntity(clusterEntity, helper.getOrCreateRepositoryVersion(HDP_22_STACK, "2.2.0.1-996"), RepositoryVersionState.CURRENT, System.currentTimeMillis(), System.currentTimeMillis(), "admin");
+    RepositoryVersionEntity repositoryVersionEnt_2_2_0_1 = helper.getOrCreateRepositoryVersion(HDP_22_STACK, repoVersion_2201);
+
+    ClusterVersionEntity newClusterVersionEntity = new ClusterVersionEntity(clusterEntity, repositoryVersionEnt_2_2_0_1, RepositoryVersionState.CURRENT, System.currentTimeMillis(), System.currentTimeMillis(), "admin");
     clusterEntity.addClusterVersionEntity(newClusterVersionEntity);
     clusterVersionDAO.create(newClusterVersionEntity);
 
@@ -181,11 +182,12 @@ public class HostVersionDAOTest {
 
     // For each of the hosts, add a host version
     for (HostEntity host : hostEntities) {
-      HostVersionEntity hostVersionEntity = new HostVersionEntity(host, helper.getOrCreateRepositoryVersion(HDP_22_STACK, "2.2.0.1-996"), RepositoryVersionState.INSTALLED);
+      HostVersionEntity hostVersionEntity = new HostVersionEntity(host, helper.getOrCreateRepositoryVersion(HDP_22_STACK, repoVersion_2201), RepositoryVersionState.INSTALLED);
       hostVersionDAO.create(hostVersionEntity);
     }
 
     // For each of the hosts, add one more host version
+    RepositoryVersionEntity repositoryVersionEnt_2_2_0_2 = helper.getOrCreateRepositoryVersion(HDP_22_STACK, repoVersion_2202);
     for (int i = 0; i < hostEntities.length; i++) {
       RepositoryVersionState desiredState = null;
       if (i % 3 == 0) {
@@ -198,7 +200,8 @@ public class HostVersionDAOTest {
         desiredState = RepositoryVersionState.UPGRADE_FAILED;
       }
 
-      HostVersionEntity hostVersionEntity = new HostVersionEntity(hostEntities[i], helper.getOrCreateRepositoryVersion(HDP_22_STACK, "2.2.1.0-500"), desiredState);
+
+      HostVersionEntity hostVersionEntity = new HostVersionEntity(hostEntities[i], repositoryVersionEnt_2_2_0_2, desiredState);
       hostVersionDAO.create(hostVersionEntity);
     }
   }
@@ -232,13 +235,13 @@ public class HostVersionDAOTest {
    */
   @Test
   public void testFindByClusterStackAndVersion() {
-    Assert.assertEquals(3, hostVersionDAO.findByClusterStackAndVersion("test_cluster1", HDP_22_STACK, "2.2.0.0-995").size());
+    Assert.assertEquals(3, hostVersionDAO.findByClusterStackAndVersion("test_cluster1", HDP_22_STACK, repoVersion_2200).size());
     Assert.assertEquals(3, hostVersionDAO.findAll().size());
 
     addMoreVersions();
 
-    Assert.assertEquals(3, hostVersionDAO.findByClusterStackAndVersion("test_cluster1", HDP_22_STACK, "2.2.0.1-996").size());
-    Assert.assertEquals(3, hostVersionDAO.findByClusterStackAndVersion("test_cluster1", HDP_22_STACK, "2.2.1.0-500").size());
+    Assert.assertEquals(3, hostVersionDAO.findByClusterStackAndVersion("test_cluster1", HDP_22_STACK, repoVersion_2201).size());
+    Assert.assertEquals(3, hostVersionDAO.findByClusterStackAndVersion("test_cluster1", HDP_22_STACK, repoVersion_2202).size());
     Assert.assertEquals(9, hostVersionDAO.findAll().size());
   }
 
@@ -280,7 +283,7 @@ public class HostVersionDAOTest {
   }
 
   /**
-   * Test the {@link HostVersionDAO#findByClusterStackVersionAndHost(String, String, String, String)} method.
+   * Test the {@link HostVersionDAO#findByClusterStackVersionAndHost(String, StackId, String, String)} method.
    */
   @Test
   public void testFindByClusterStackVersionAndHost() {
@@ -289,22 +292,22 @@ public class HostVersionDAOTest {
     HostEntity host3 = hostDAO.findByName("test_host3");
 
     HostVersionEntity hostVersionEntity1 = new HostVersionEntity(host1,
-        helper.getOrCreateRepositoryVersion(HDP_22_STACK, "2.2.0.0-995"), RepositoryVersionState.CURRENT);
+        helper.getOrCreateRepositoryVersion(HDP_22_STACK, repoVersion_2200), RepositoryVersionState.CURRENT);
     hostVersionEntity1.setId(1L);
     HostVersionEntity hostVersionEntity2 = new HostVersionEntity(host2,
-        helper.getOrCreateRepositoryVersion(HDP_22_STACK, "2.2.0.0-995"), RepositoryVersionState.INSTALLED);
+        helper.getOrCreateRepositoryVersion(HDP_22_STACK, repoVersion_2200), RepositoryVersionState.INSTALLED);
     hostVersionEntity2.setId(2L);
     HostVersionEntity hostVersionEntity3 = new HostVersionEntity(host3,
-        helper.getOrCreateRepositoryVersion(HDP_22_STACK, "2.2.0.0-995"), RepositoryVersionState.INSTALLED);
+        helper.getOrCreateRepositoryVersion(HDP_22_STACK, repoVersion_2200), RepositoryVersionState.INSTALLED);
     hostVersionEntity3.setId(3L);
 
-    Assert.assertEquals(hostVersionEntity1, hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", HDP_22_STACK, "2.2.0.0-995", "test_host1"));
-    Assert.assertEquals(hostVersionEntity2, hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", HDP_22_STACK, "2.2.0.0-995", "test_host2"));
-    Assert.assertEquals(hostVersionEntity3, hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", HDP_22_STACK, "2.2.0.0-995", "test_host3"));
+    Assert.assertEquals(hostVersionEntity1, hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", HDP_22_STACK, repoVersion_2200, "test_host1"));
+    Assert.assertEquals(hostVersionEntity2, hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", HDP_22_STACK, repoVersion_2200, "test_host2"));
+    Assert.assertEquals(hostVersionEntity3, hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", HDP_22_STACK, repoVersion_2200, "test_host3"));
 
     // Test non-existent objects
-    Assert.assertEquals(null, hostVersionDAO.findByClusterStackVersionAndHost("non_existent_cluster", HDP_22_STACK, "2.2.0.0-995", "test_host3"));
-    Assert.assertEquals(null, hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", BAD_STACK, "2.2.0.0-995", "test_host3"));
+    Assert.assertEquals(null, hostVersionDAO.findByClusterStackVersionAndHost("non_existent_cluster", HDP_22_STACK, repoVersion_2200, "test_host3"));
+    Assert.assertEquals(null, hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", BAD_STACK, repoVersion_2200, "test_host3"));
     Assert.assertEquals(null, hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", HDP_22_STACK, "non_existent_version", "test_host3"));
     Assert.assertEquals(null, hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", HDP_22_STACK, "non_existent_version", "non_existent_host"));
 
@@ -312,16 +315,16 @@ public class HostVersionDAOTest {
 
     // Expected
     HostVersionEntity hostVersionEntity1LastExpected = new HostVersionEntity(host1,
-        helper.getOrCreateRepositoryVersion(HDP_22_STACK, "2.2.1.0-500"), RepositoryVersionState.INSTALLED);
+        helper.getOrCreateRepositoryVersion(HDP_22_STACK, repoVersion_2202), RepositoryVersionState.INSTALLED);
     HostVersionEntity hostVersionEntity2LastExpected = new HostVersionEntity(host2,
-        helper.getOrCreateRepositoryVersion(HDP_22_STACK, "2.2.1.0-500"), RepositoryVersionState.UPGRADING);
+        helper.getOrCreateRepositoryVersion(HDP_22_STACK, repoVersion_2202), RepositoryVersionState.UPGRADING);
     HostVersionEntity hostVersionEntity3LastExpected = new HostVersionEntity(host3,
-        helper.getOrCreateRepositoryVersion(HDP_22_STACK, "2.2.1.0-500"), RepositoryVersionState.UPGRADE_FAILED);
+        helper.getOrCreateRepositoryVersion(HDP_22_STACK, repoVersion_2202), RepositoryVersionState.UPGRADE_FAILED);
 
     // Actual
-    HostVersionEntity hostVersionEntity1LastActual = hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", HDP_22_STACK, "2.2.1.0-500", "test_host1");
-    HostVersionEntity hostVersionEntity2LastActual = hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", HDP_22_STACK, "2.2.1.0-500", "test_host2");
-    HostVersionEntity hostVersionEntity3LastActual = hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", HDP_22_STACK, "2.2.1.0-500", "test_host3");
+    HostVersionEntity hostVersionEntity1LastActual = hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", HDP_22_STACK, repoVersion_2202, "test_host1");
+    HostVersionEntity hostVersionEntity2LastActual = hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", HDP_22_STACK, repoVersion_2202, "test_host2");
+    HostVersionEntity hostVersionEntity3LastActual = hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", HDP_22_STACK, repoVersion_2202, "test_host3");
 
     // Trying to Mock the actual objects to override the getId() method will not work because the class that mockito creates
     // is still a Mockito wrapper. Instead, take advantage of an overloaded constructor that ignores the Id.

+ 56 - 1
ambari-server/src/test/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAOTest.java

@@ -18,6 +18,7 @@
 
 package org.apache.ambari.server.orm.dao;
 
+import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.orm.GuiceJpaInitializer;
 import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
@@ -37,6 +38,8 @@ import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.persist.PersistService;
 
+import java.util.UUID;
+
 /**
  * RepositoryVersionDAO unit tests.
  */
@@ -68,7 +71,7 @@ public class RepositoryVersionDAOTest {
     injector.getInstance(AmbariMetaInfo.class);
   }
 
-  private void createSingleRecord() {
+  private RepositoryVersionEntity createSingleRecord() {
     StackEntity stackEntity = stackDAO.find(HDP_206.getStackName(),
         HDP_206.getStackVersion());
 
@@ -81,6 +84,58 @@ public class RepositoryVersionDAOTest {
     entity.setUpgradePackage("upgrade package");
     entity.setVersion("version");
     repositoryVersionDAO.create(entity);
+
+    return entity;
+  }
+
+  @Test
+  public void testCreate() {
+    UUID uuid = UUID.randomUUID();
+
+    RepositoryVersionEntity first = createSingleRecord();
+    Assert.assertNotNull(first);
+
+    StackEntity stackEntity = stackDAO.find(first.getStackName(), first.getStackVersion());
+    Assert.assertNotNull(stackEntity);
+
+    // Assert the version must be unique
+    RepositoryVersionEntity dupVersion = new RepositoryVersionEntity();
+    dupVersion.setDisplayName("display name " + uuid.toString());
+    dupVersion.setOperatingSystems("repositories");
+    dupVersion.setStack(stackEntity);
+    dupVersion.setUpgradePackage("upgrade package");
+    dupVersion.setVersion(first.getVersion());
+
+    boolean exceptionThrown = false;
+    try {
+      repositoryVersionDAO.create(stackEntity, dupVersion.getVersion(), dupVersion.getDisplayName(), dupVersion.getUpgradePackage(), dupVersion.getOperatingSystemsJson());
+    } catch (AmbariException e) {
+      exceptionThrown = true;
+      Assert.assertTrue(e.getMessage().contains("already exists"));
+    }
+    // Expected the exception to be thrown since the build version was reused in the second record.
+    Assert.assertTrue(exceptionThrown);
+
+    exceptionThrown = false;
+
+    // The version must belong to the stack
+    dupVersion.setVersion("2.3-1234");
+    try {
+      repositoryVersionDAO.create(stackEntity, dupVersion.getVersion(), dupVersion.getDisplayName(), dupVersion.getUpgradePackage(), dupVersion.getOperatingSystemsJson());
+    } catch (AmbariException e) {
+      exceptionThrown = true;
+      Assert.assertTrue(e.getMessage().contains("needs to belong to stack"));
+    }
+    // Expected the exception to be thrown since the version does not belong to the stack.
+    Assert.assertTrue(exceptionThrown);
+
+    // Success
+    dupVersion.setVersion(stackEntity.getStackVersion() + "-1234");
+    try {
+      repositoryVersionDAO.create(stackEntity, dupVersion.getVersion(), dupVersion.getDisplayName(), dupVersion.getUpgradePackage(), dupVersion.getOperatingSystemsJson());
+    } catch (AmbariException e) {
+      Assert.fail("Did not expect a failure creating the Repository Version");
+    }
   }
 
   @Test

+ 35 - 31
ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/ConfigureActionTest.java

@@ -73,10 +73,11 @@ import com.google.inject.persist.PersistService;
  * Tests upgrade-related server side actions
  */
 public class ConfigureActionTest {
-  private static final String HDP_2_2_1_0 = "2.2.1.0-2270";
+  
   private static final String HDP_2_2_0_0 = "2.2.0.0-2041";
-  private static final StackId HDP_21_STACK = new StackId("HDP-2.1.1");
-  private static final StackId HDP_22_STACK = new StackId("HDP-2.2.0");
+  private static final String HDP_2_2_0_1 = "2.2.0.1-2270";
+  private static final StackId HDP_211_STACK = new StackId("HDP-2.1.1");
+  private static final StackId HDP_220_STACK = new StackId("HDP-2.2.0");
 
   private Injector m_injector;
 
@@ -117,7 +118,8 @@ public class ConfigureActionTest {
     Cluster c = m_injector.getInstance(Clusters.class).getCluster("c1");
     assertEquals(1, c.getConfigsByType("zoo.cfg").size());
 
-    c.setDesiredStackVersion(HDP_22_STACK);
+    c.setCurrentStackVersion(HDP_211_STACK);
+    c.setDesiredStackVersion(HDP_220_STACK);
     ConfigFactory cf = m_injector.getInstance(ConfigFactory.class);
     Config config = cf.createNew(c, "zoo.cfg", new HashMap<String, String>() {{
           put("initLimit", "10");
@@ -137,7 +139,7 @@ public class ConfigureActionTest {
 
     Map<String, String> commandParams = new HashMap<String, String>();
     commandParams.put("upgrade_direction", "upgrade");
-    commandParams.put("version", HDP_2_2_1_0);
+    commandParams.put("version", HDP_2_2_0_1);
     commandParams.put("clusterName", "c1");
     commandParams.put(ConfigureTask.PARAMETER_CONFIG_TYPE, "zoo.cfg");
     commandParams.put(ConfigureTask.PARAMETER_KEY_VALUE_PAIRS, new Gson().toJson(configurations));
@@ -179,7 +181,7 @@ public class ConfigureActionTest {
     Cluster c = m_injector.getInstance(Clusters.class).getCluster("c1");
     assertEquals(1, c.getConfigsByType("zoo.cfg").size());
 
-    c.setDesiredStackVersion(HDP_21_STACK);
+    c.setDesiredStackVersion(HDP_220_STACK);
 
     // create a config for zoo.cfg with two values; one is a stack value and the
     // other is custom
@@ -199,7 +201,7 @@ public class ConfigureActionTest {
 
     Map<String, String> commandParams = new HashMap<String, String>();
     commandParams.put("upgrade_direction", "upgrade");
-    commandParams.put("version", HDP_2_2_1_0);
+    commandParams.put("version", HDP_2_2_0_1);
     commandParams.put("clusterName", "c1");
     commandParams.put(ConfigureTask.PARAMETER_CONFIG_TYPE, "zoo.cfg");
 
@@ -249,7 +251,7 @@ public class ConfigureActionTest {
     Cluster c = m_injector.getInstance(Clusters.class).getCluster("c1");
     assertEquals(1, c.getConfigsByType("zoo.cfg").size());
 
-    c.setDesiredStackVersion(HDP_21_STACK);
+    c.setDesiredStackVersion(HDP_220_STACK);
     ConfigFactory cf = m_injector.getInstance(ConfigFactory.class);
     Config config = cf.createNew(c, "zoo.cfg", new HashMap<String, String>() {{
           put("initLimit", "10");
@@ -272,7 +274,7 @@ public class ConfigureActionTest {
 
     Map<String, String> commandParams = new HashMap<String, String>();
     commandParams.put("upgrade_direction", "upgrade");
-    commandParams.put("version", HDP_2_2_1_0);
+    commandParams.put("version", HDP_2_2_0_1);
     commandParams.put("clusterName", "c1");
     commandParams.put(ConfigureTask.PARAMETER_CONFIG_TYPE, "zoo.cfg");
     commandParams.put(ConfigureTask.PARAMETER_KEY_VALUE_PAIRS, new Gson().toJson(configurations));
@@ -381,7 +383,7 @@ public class ConfigureActionTest {
     Cluster c = m_injector.getInstance(Clusters.class).getCluster("c1");
     assertEquals(1, c.getConfigsByType("zoo.cfg").size());
 
-    c.setDesiredStackVersion(HDP_21_STACK);
+    c.setDesiredStackVersion(HDP_220_STACK);
     ConfigFactory cf = m_injector.getInstance(ConfigFactory.class);
     Config config = cf.createNew(c, "zoo.cfg", new HashMap<String, String>() {
       {
@@ -397,7 +399,7 @@ public class ConfigureActionTest {
 
     Map<String, String> commandParams = new HashMap<String, String>();
     commandParams.put("upgrade_direction", "upgrade");
-    commandParams.put("version", HDP_2_2_1_0);
+    commandParams.put("version", HDP_2_2_0_1);
     commandParams.put("clusterName", "c1");
     commandParams.put(ConfigureTask.PARAMETER_CONFIG_TYPE, "zoo.cfg");
 
@@ -448,7 +450,7 @@ public class ConfigureActionTest {
     Cluster c = m_injector.getInstance(Clusters.class).getCluster("c1");
     assertEquals(1, c.getConfigsByType("zoo.cfg").size());
 
-    c.setDesiredStackVersion(HDP_21_STACK);
+    c.setDesiredStackVersion(HDP_220_STACK);
     ConfigFactory cf = m_injector.getInstance(ConfigFactory.class);
     Config config = cf.createNew(c, "zoo.cfg", new HashMap<String, String>() {
       {
@@ -465,7 +467,7 @@ public class ConfigureActionTest {
 
     Map<String, String> commandParams = new HashMap<String, String>();
     commandParams.put("upgrade_direction", "upgrade");
-    commandParams.put("version", HDP_2_2_1_0);
+    commandParams.put("version", HDP_2_2_0_1);
     commandParams.put("clusterName", "c1");
     commandParams.put(ConfigureTask.PARAMETER_CONFIG_TYPE, "zoo.cfg");
 
@@ -519,7 +521,8 @@ public class ConfigureActionTest {
     Cluster c = m_injector.getInstance(Clusters.class).getCluster("c1");
     assertEquals(1, c.getConfigsByType("zoo.cfg").size());
 
-    c.setDesiredStackVersion(HDP_22_STACK);
+    c.setCurrentStackVersion(HDP_211_STACK);
+    c.setDesiredStackVersion(HDP_220_STACK);
     ConfigFactory cf = m_injector.getInstance(ConfigFactory.class);
     Config config = cf.createNew(c, "zoo.cfg", new HashMap<String, String>() {
       {
@@ -549,7 +552,7 @@ public class ConfigureActionTest {
 
     Map<String, String> commandParams = new HashMap<String, String>();
     commandParams.put("upgrade_direction", "upgrade");
-    commandParams.put("version", HDP_2_2_1_0);
+    commandParams.put("version", HDP_2_2_0_1);
     commandParams.put("clusterName", "c1");
     commandParams.put(ConfigureTask.PARAMETER_CONFIG_TYPE, "zoo.cfg");
     commandParams.put(ConfigureTask.PARAMETER_KEY_VALUE_PAIRS, new Gson().toJson(configurations));
@@ -584,16 +587,16 @@ public class ConfigureActionTest {
     String hostName = "h1";
 
     Clusters clusters = m_injector.getInstance(Clusters.class);
-    clusters.addCluster(clusterName, HDP_21_STACK);
+    clusters.addCluster(clusterName, HDP_220_STACK);
 
     StackDAO stackDAO = m_injector.getInstance(StackDAO.class);
-    StackEntity stackEntity = stackDAO.find(HDP_21_STACK.getStackName(),
-        HDP_21_STACK.getStackVersion());
+    StackEntity stackEntity = stackDAO.find(HDP_220_STACK.getStackName(),
+        HDP_220_STACK.getStackVersion());
 
     assertNotNull(stackEntity);
 
     Cluster c = clusters.getCluster(clusterName);
-    c.setDesiredStackVersion(HDP_21_STACK);
+    c.setDesiredStackVersion(HDP_220_STACK);
 
     // !!! very important, otherwise the loops that walk the list of installed
     // service properties will not run!
@@ -622,22 +625,23 @@ public class ConfigureActionTest {
     host.setHostAttributes(hostAttributes);
     host.persist();
 
+    // Creating starting repo
+    m_helper.getOrCreateRepositoryVersion(HDP_220_STACK, HDP_2_2_0_0);
+    c.createClusterVersion(HDP_220_STACK, HDP_2_2_0_0, "admin", RepositoryVersionState.UPGRADING);
+    c.transitionClusterVersion(HDP_220_STACK, HDP_2_2_0_0, RepositoryVersionState.CURRENT);
+
     String urlInfo = "[{'repositories':["
-        + "{'Repositories/base_url':'http://foo1','Repositories/repo_name':'HDP','Repositories/repo_id':'HDP-2.1.1'}"
+        + "{'Repositories/base_url':'http://foo1','Repositories/repo_name':'HDP','Repositories/repo_id':'HDP-2.2.0'}"
         + "], 'OperatingSystems/os_type':'redhat6'}]";
-
-    m_helper.getOrCreateRepositoryVersion(HDP_21_STACK, HDP_2_2_0_0);
-    repoVersionDAO.create(stackEntity, HDP_2_2_1_0, String.valueOf(System.currentTimeMillis()),
+    repoVersionDAO.create(stackEntity, HDP_2_2_0_1, String.valueOf(System.currentTimeMillis()),
         "pack", urlInfo);
 
-    c.createClusterVersion(HDP_21_STACK, HDP_2_2_0_0, "admin", RepositoryVersionState.UPGRADING);
-    c.createClusterVersion(HDP_21_STACK, HDP_2_2_1_0, "admin", RepositoryVersionState.INSTALLING);
 
-    c.transitionClusterVersion(HDP_21_STACK, HDP_2_2_0_0, RepositoryVersionState.CURRENT);
-    c.transitionClusterVersion(HDP_21_STACK, HDP_2_2_1_0, RepositoryVersionState.INSTALLED);
-    c.transitionClusterVersion(HDP_21_STACK, HDP_2_2_1_0, RepositoryVersionState.UPGRADING);
-    c.transitionClusterVersion(HDP_21_STACK, HDP_2_2_1_0, RepositoryVersionState.UPGRADED);
-    c.setCurrentStackVersion(HDP_21_STACK);
+    c.createClusterVersion(HDP_220_STACK, HDP_2_2_0_1, "admin", RepositoryVersionState.INSTALLING);
+    c.transitionClusterVersion(HDP_220_STACK, HDP_2_2_0_1, RepositoryVersionState.INSTALLED);
+    c.transitionClusterVersion(HDP_220_STACK, HDP_2_2_0_1, RepositoryVersionState.UPGRADING);
+    c.transitionClusterVersion(HDP_220_STACK, HDP_2_2_0_1, RepositoryVersionState.UPGRADED);
+    c.setCurrentStackVersion(HDP_220_STACK);
 
     c.mapHostVersions(Collections.singleton(hostName), c.getCurrentClusterVersion(),
         RepositoryVersionState.CURRENT);
@@ -646,7 +650,7 @@ public class ConfigureActionTest {
 
     HostVersionEntity entity = new HostVersionEntity();
     entity.setHostEntity(hostDAO.findByName(hostName));
-    entity.setRepositoryVersion(repoVersionDAO.findByStackAndVersion(HDP_21_STACK, HDP_2_2_1_0));
+    entity.setRepositoryVersion(repoVersionDAO.findByStackAndVersion(HDP_220_STACK, HDP_2_2_0_1));
     entity.setState(RepositoryVersionState.UPGRADED);
     hostVersionDAO.create(entity);
 

+ 128 - 105
ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/UpgradeActionTest.java

@@ -84,12 +84,16 @@ import com.google.inject.persist.UnitOfWork;
  * Tests upgrade-related server side actions
  */
 public class UpgradeActionTest {
-  private static final String HDP_2_1_1_0 = "2.1.1.0-118";
-  private static final String HDP_2_2_1_0 = "2.2.1.0-2270";
-  private static final String HDP_2_2_0_0 = "2.2.0.0-2041";
+  private static final String HDP_2_1_1_0 = "2.1.1.0-1";
+  private static final String HDP_2_1_1_1 = "2.1.1.1-2";
+
+  private static final String HDP_2_2_1_0 = "2.2.0.1-3";
+
   private static final StackId HDP_21_STACK = new StackId("HDP-2.1.1");
   private static final StackId HDP_22_STACK = new StackId("HDP-2.2.0");
 
+  private static final String HDP_211_CENTOS6_REPO_URL = "http://s3.amazonaws.com/dev.hortonworks.com/HDP/centos6/2.x/BUILDS/2.1.1.0-118";
+
   private Injector m_injector;
 
   @Inject
@@ -133,12 +137,12 @@ public class UpgradeActionTest {
     m_injector.getInstance(PersistService.class).stop();
   }
 
-  private void makeDowngradeCluster() throws Exception {
+  private void makeDowngradeCluster(StackId sourceStack, String sourceRepo, StackId targetStack, String targetRepo) throws Exception {
     String clusterName = "c1";
     String hostName = "h1";
 
     Clusters clusters = m_injector.getInstance(Clusters.class);
-    clusters.addCluster(clusterName, HDP_21_STACK);
+    clusters.addCluster(clusterName, sourceStack);
 
     Cluster c = clusters.getCluster(clusterName);
 
@@ -153,41 +157,42 @@ public class UpgradeActionTest {
     host.setHostAttributes(hostAttributes);
     host.persist();
 
-    m_helper.getOrCreateRepositoryVersion(HDP_21_STACK, HDP_2_2_0_0);
-    m_helper.getOrCreateRepositoryVersion(HDP_21_STACK, HDP_2_2_1_0);
+    // Create the starting repo version
+    m_helper.getOrCreateRepositoryVersion(sourceStack, sourceRepo);
+    c.createClusterVersion(sourceStack, sourceRepo, "admin", RepositoryVersionState.UPGRADING);
+    c.transitionClusterVersion(sourceStack, sourceRepo, RepositoryVersionState.CURRENT);
 
-    c.createClusterVersion(HDP_21_STACK, HDP_2_2_0_0, "admin", RepositoryVersionState.UPGRADING);
-    c.createClusterVersion(HDP_21_STACK, HDP_2_2_1_0, "admin", RepositoryVersionState.INSTALLING);
-
-    c.transitionClusterVersion(HDP_21_STACK, HDP_2_2_0_0, RepositoryVersionState.CURRENT);
-    c.transitionClusterVersion(HDP_21_STACK, HDP_2_2_1_0, RepositoryVersionState.INSTALLED);
-    c.transitionClusterVersion(HDP_21_STACK, HDP_2_2_1_0, RepositoryVersionState.UPGRADING);
+    // Start upgrading the newer repo
+    m_helper.getOrCreateRepositoryVersion(targetStack, targetRepo);
+    c.createClusterVersion(targetStack, targetRepo, "admin", RepositoryVersionState.INSTALLING);
+    c.transitionClusterVersion(targetStack, targetRepo, RepositoryVersionState.INSTALLED);
+    c.transitionClusterVersion(targetStack, targetRepo, RepositoryVersionState.UPGRADING);
 
     c.mapHostVersions(Collections.singleton(hostName), c.getCurrentClusterVersion(),
         RepositoryVersionState.CURRENT);
 
     HostVersionEntity entity = new HostVersionEntity();
     entity.setHostEntity(hostDAO.findByName(hostName));
-    entity.setRepositoryVersion(repoVersionDAO.findByStackAndVersion(HDP_21_STACK, HDP_2_2_1_0));
+    entity.setRepositoryVersion(repoVersionDAO.findByStackAndVersion(targetStack, targetRepo));
     entity.setState(RepositoryVersionState.UPGRADING);
     hostVersionDAO.create(entity);
   }
 
-  private void makeUpgradeCluster() throws Exception {
+  private void makeUpgradeCluster(StackId sourceStack, String sourceRepo, StackId targetStack, String targetRepo) throws Exception {
     String clusterName = "c1";
     String hostName = "h1";
 
     Clusters clusters = m_injector.getInstance(Clusters.class);
-    clusters.addCluster(clusterName, HDP_21_STACK);
+    clusters.addCluster(clusterName, sourceStack);
 
     StackDAO stackDAO = m_injector.getInstance(StackDAO.class);
-    StackEntity stackEntity = stackDAO.find(HDP_21_STACK.getStackName(),
-        HDP_21_STACK.getStackVersion());
-
-    assertNotNull(stackEntity);
+    StackEntity stackEntitySource = stackDAO.find(sourceStack.getStackName(), sourceStack.getStackVersion());
+    StackEntity stackEntityTarget = stackDAO.find(targetStack.getStackName(), targetStack.getStackVersion());
+    assertNotNull(stackEntitySource);
+    assertNotNull(stackEntityTarget);
 
     Cluster c = clusters.getCluster(clusterName);
-    c.setDesiredStackVersion(HDP_21_STACK);
+    c.setDesiredStackVersion(sourceStack);
 
     // add a host component
     clusters.addHost(hostName);
@@ -200,22 +205,24 @@ public class UpgradeActionTest {
     host.setHostAttributes(hostAttributes);
     host.persist();
 
+    // Create the starting repo version
+    m_helper.getOrCreateRepositoryVersion(sourceStack, sourceRepo);
+    c.createClusterVersion(sourceStack, sourceRepo, "admin", RepositoryVersionState.UPGRADING);
+    c.transitionClusterVersion(sourceStack, sourceRepo, RepositoryVersionState.CURRENT);
+
+    // Create the new repo version
     String urlInfo = "[{'repositories':["
-        + "{'Repositories/base_url':'http://foo1','Repositories/repo_name':'HDP','Repositories/repo_id':'HDP-2.1.1'}"
+        + "{'Repositories/base_url':'http://foo1','Repositories/repo_name':'HDP','Repositories/repo_id':'" + targetStack.getStackId() + "'}"
         + "], 'OperatingSystems/os_type':'redhat6'}]";
-
-    m_helper.getOrCreateRepositoryVersion(HDP_21_STACK, HDP_2_2_0_0);
-    repoVersionDAO.create(stackEntity, HDP_2_2_1_0, String.valueOf(System.currentTimeMillis()),
+    repoVersionDAO.create(stackEntityTarget, targetRepo, String.valueOf(System.currentTimeMillis()),
         "pack", urlInfo);
 
-    c.createClusterVersion(HDP_21_STACK, HDP_2_2_0_0, "admin", RepositoryVersionState.UPGRADING);
-    c.createClusterVersion(HDP_21_STACK, HDP_2_2_1_0, "admin", RepositoryVersionState.INSTALLING);
-
-    c.transitionClusterVersion(HDP_21_STACK, HDP_2_2_0_0, RepositoryVersionState.CURRENT);
-    c.transitionClusterVersion(HDP_21_STACK, HDP_2_2_1_0, RepositoryVersionState.INSTALLED);
-    c.transitionClusterVersion(HDP_21_STACK, HDP_2_2_1_0, RepositoryVersionState.UPGRADING);
-    c.transitionClusterVersion(HDP_21_STACK, HDP_2_2_1_0, RepositoryVersionState.UPGRADED);
-    c.setCurrentStackVersion(HDP_21_STACK);
+    // Start upgrading the newer repo
+    c.createClusterVersion(targetStack, targetRepo, "admin", RepositoryVersionState.INSTALLING);
+    c.transitionClusterVersion(targetStack, targetRepo, RepositoryVersionState.INSTALLED);
+    c.transitionClusterVersion(targetStack, targetRepo, RepositoryVersionState.UPGRADING);
+    c.transitionClusterVersion(targetStack, targetRepo, RepositoryVersionState.UPGRADED);
+    c.setCurrentStackVersion(targetStack);
 
     c.mapHostVersions(Collections.singleton(hostName), c.getCurrentClusterVersion(),
         RepositoryVersionState.CURRENT);
@@ -224,27 +231,28 @@ public class UpgradeActionTest {
 
     HostVersionEntity entity = new HostVersionEntity();
     entity.setHostEntity(hostDAO.findByName(hostName));
-    entity.setRepositoryVersion(repoVersionDAO.findByStackAndVersion(HDP_21_STACK, HDP_2_2_1_0));
+    entity.setRepositoryVersion(repoVersionDAO.findByStackAndVersion(targetStack, targetRepo));
     entity.setState(RepositoryVersionState.UPGRADED);
     hostVersionDAO.create(entity);
   }
 
-  private void makeCrossStackUpgradeCluster() throws Exception {
+  private void makeCrossStackUpgradeCluster(StackId sourceStack, String sourceRepo, StackId targetStack, String targetRepo) throws Exception {
     String clusterName = "c1";
     String hostName = "h1";
 
     Clusters clusters = m_injector.getInstance(Clusters.class);
-    clusters.addCluster(clusterName, HDP_21_STACK);
+    clusters.addCluster(clusterName, sourceStack);
 
     StackDAO stackDAO = m_injector.getInstance(StackDAO.class);
-    StackEntity stackEntity = stackDAO.find(HDP_21_STACK.getStackName(),
-        HDP_21_STACK.getStackVersion());
+    StackEntity stackEntitySource = stackDAO.find(sourceStack.getStackName(), sourceStack.getStackVersion());
+    StackEntity stackEntityTarget = stackDAO.find(targetStack.getStackName(), targetStack.getStackVersion());
 
-    assertNotNull(stackEntity);
+    assertNotNull(stackEntitySource);
+    assertNotNull(stackEntityTarget);
 
     Cluster c = clusters.getCluster(clusterName);
-    c.setCurrentStackVersion(HDP_21_STACK);
-    c.setDesiredStackVersion(HDP_21_STACK);
+    c.setCurrentStackVersion(sourceStack);
+    c.setDesiredStackVersion(sourceStack);
 
     // add a host component
     clusters.addHost(hostName);
@@ -258,23 +266,23 @@ public class UpgradeActionTest {
 
     clusters.mapHostToCluster(hostName, clusterName);
 
+    // Create the starting repo version
+    m_helper.getOrCreateRepositoryVersion(sourceStack, sourceRepo);
+    c.createClusterVersion(sourceStack, sourceRepo, "admin", RepositoryVersionState.UPGRADING);
+    c.transitionClusterVersion(sourceStack, sourceRepo, RepositoryVersionState.CURRENT);
+
+    // Create the new repo version
     String urlInfo = "[{'repositories':["
-        + "{'Repositories/base_url':'http://foo1','Repositories/repo_name':'HDP','Repositories/repo_id':'HDP-2.1.1'}"
+        + "{'Repositories/base_url':'http://foo1','Repositories/repo_name':'HDP','Repositories/repo_id':'" + targetRepo + "'}"
         + "], 'OperatingSystems/os_type':'redhat6'}]";
-
-    m_helper.getOrCreateRepositoryVersion(HDP_21_STACK, HDP_2_1_1_0);
-    m_helper.getOrCreateRepositoryVersion(HDP_22_STACK, HDP_2_2_1_0);
-
-    repoVersionDAO.create(stackEntity, HDP_2_2_1_0, String.valueOf(System.currentTimeMillis()),
+    repoVersionDAO.create(stackEntityTarget, targetRepo, String.valueOf(System.currentTimeMillis()),
         "pack", urlInfo);
 
-    c.createClusterVersion(HDP_21_STACK, HDP_2_1_1_0, "admin", RepositoryVersionState.UPGRADING);
-    c.createClusterVersion(HDP_22_STACK, HDP_2_2_1_0, "admin", RepositoryVersionState.INSTALLING);
-
-    c.transitionClusterVersion(HDP_21_STACK, HDP_2_1_1_0, RepositoryVersionState.CURRENT);
-    c.transitionClusterVersion(HDP_22_STACK, HDP_2_2_1_0, RepositoryVersionState.INSTALLED);
-    c.transitionClusterVersion(HDP_22_STACK, HDP_2_2_1_0, RepositoryVersionState.UPGRADING);
-    c.transitionClusterVersion(HDP_22_STACK, HDP_2_2_1_0, RepositoryVersionState.UPGRADED);
+    // Start upgrading the newer repo
+    c.createClusterVersion(targetStack, targetRepo, "admin", RepositoryVersionState.INSTALLING);
+    c.transitionClusterVersion(targetStack, targetRepo, RepositoryVersionState.INSTALLED);
+    c.transitionClusterVersion(targetStack, targetRepo, RepositoryVersionState.UPGRADING);
+    c.transitionClusterVersion(targetStack, targetRepo, RepositoryVersionState.UPGRADED);
 
     c.mapHostVersions(Collections.singleton(hostName), c.getCurrentClusterVersion(),
         RepositoryVersionState.CURRENT);
@@ -283,18 +291,23 @@ public class UpgradeActionTest {
 
     HostVersionEntity entity = new HostVersionEntity();
     entity.setHostEntity(hostDAO.findByName(hostName));
-    entity.setRepositoryVersion(repoVersionDAO.findByStackAndVersion(HDP_22_STACK, HDP_2_2_1_0));
+    entity.setRepositoryVersion(repoVersionDAO.findByStackAndVersion(targetStack, targetRepo));
     entity.setState(RepositoryVersionState.UPGRADED);
     hostVersionDAO.create(entity);
   }
 
   @Test
   public void testFinalizeDowngrade() throws Exception {
-    makeDowngradeCluster();
+    StackId sourceStack = HDP_21_STACK;
+    StackId targetStack = HDP_21_STACK;
+    String sourceRepo = HDP_2_1_1_0;
+    String targetRepo = HDP_2_1_1_1;
+
+    makeDowngradeCluster(sourceStack, sourceRepo, targetStack, targetRepo);
 
     Map<String, String> commandParams = new HashMap<String, String>();
     commandParams.put(FinalizeUpgradeAction.UPGRADE_DIRECTION_KEY, "downgrade");
-    commandParams.put(FinalizeUpgradeAction.VERSION_KEY, HDP_2_2_0_0);
+    commandParams.put(FinalizeUpgradeAction.VERSION_KEY, sourceRepo);
 
     ExecutionCommand executionCommand = new ExecutionCommand();
     executionCommand.setCommandParams(commandParams);
@@ -312,17 +325,17 @@ public class UpgradeActionTest {
     assertEquals(HostRoleStatus.COMPLETED.name(), report.getStatus());
 
     for (HostVersionEntity entity : hostVersionDAO.findByClusterAndHost("c1", "h1")) {
-      if (entity.getRepositoryVersion().getVersion().equals(HDP_2_2_0_0)) {
+      if (entity.getRepositoryVersion().getVersion().equals(sourceRepo)) {
         assertEquals(RepositoryVersionState.CURRENT, entity.getState());
-      } else if (entity.getRepositoryVersion().getVersion().equals(HDP_2_2_1_0)) {
+      } else if (entity.getRepositoryVersion().getVersion().equals(targetRepo)) {
         assertEquals(RepositoryVersionState.INSTALLED, entity.getState());
       }
     }
 
     for (ClusterVersionEntity entity : clusterVersionDAO.findByCluster("c1")) {
-      if (entity.getRepositoryVersion().getVersion().equals(HDP_2_2_0_0)) {
+      if (entity.getRepositoryVersion().getVersion().equals(sourceRepo)) {
         assertEquals(RepositoryVersionState.CURRENT, entity.getState());
-      } else if (entity.getRepositoryVersion().getVersion().equals(HDP_2_2_1_0)) {
+      } else if (entity.getRepositoryVersion().getVersion().equals(targetRepo)) {
         assertEquals(RepositoryVersionState.INSTALLED, entity.getState());
       }
     }
@@ -330,11 +343,28 @@ public class UpgradeActionTest {
 
   @Test
   public void testFinalizeUpgrade() throws Exception {
-    makeUpgradeCluster();
+    StackId sourceStack = HDP_21_STACK;
+    StackId targetStack = HDP_21_STACK;
+    String sourceRepo = HDP_2_1_1_0;
+    String targetRepo = HDP_2_1_1_1;
+
+    makeUpgradeCluster(sourceStack, sourceRepo, targetStack, targetRepo);
+
+    // Verify the repo before calling Finalize
+    AmbariMetaInfo metaInfo = m_injector.getInstance(AmbariMetaInfo.class);
+    AmbariCustomCommandExecutionHelper helper = m_injector.getInstance(AmbariCustomCommandExecutionHelper.class);
+    Clusters clusters = m_injector.getInstance(Clusters.class);
+    Host host = clusters.getHost("h1");
+    Cluster cluster = clusters.getCluster("c1");
+
+    RepositoryInfo repo = metaInfo.getRepository(sourceStack.getStackName(), sourceStack.getStackVersion(), "redhat6", sourceStack.getStackId());
+    assertEquals(HDP_211_CENTOS6_REPO_URL, repo.getBaseUrl());
+    verifyBaseRepoURL(helper, cluster, host, HDP_211_CENTOS6_REPO_URL);
 
+    // Finalize the upgrade
     Map<String, String> commandParams = new HashMap<String, String>();
     commandParams.put(FinalizeUpgradeAction.UPGRADE_DIRECTION_KEY, "upgrade");
-    commandParams.put(FinalizeUpgradeAction.VERSION_KEY, HDP_2_2_1_0);
+    commandParams.put(FinalizeUpgradeAction.VERSION_KEY, targetRepo);
 
     ExecutionCommand executionCommand = new ExecutionCommand();
     executionCommand.setCommandParams(commandParams);
@@ -351,50 +381,44 @@ public class UpgradeActionTest {
     assertNotNull(report);
     assertEquals(HostRoleStatus.COMPLETED.name(), report.getStatus());
 
-    // !!! verify the metainfo url has not been updated, but an output command
-    // has
-    AmbariMetaInfo metaInfo = m_injector.getInstance(AmbariMetaInfo.class);
-    RepositoryInfo repo = metaInfo.getRepository("HDP", "2.1.1", "redhat6", "HDP-2.1.1");
-    assertEquals("http://s3.amazonaws.com/dev.hortonworks.com/HDP/centos6/2.x/BUILDS/2.1.1.0-118",
-        repo.getBaseUrl());
-
-    // !!! verify that a command will return the correct host info
-    AmbariCustomCommandExecutionHelper helper = m_injector.getInstance(AmbariCustomCommandExecutionHelper.class);
-    Clusters clusters = m_injector.getInstance(Clusters.class);
-    Host host = clusters.getHost("h1");
-    Cluster cluster = clusters.getCluster("c1");
+    // Verify the metainfo url
+    verifyBaseRepoURL(helper, cluster, host, "http://foo1");
+  }
 
+  private void verifyBaseRepoURL(AmbariCustomCommandExecutionHelper helper, Cluster cluster, Host host, String expectedRepoBaseURL) throws AmbariException {
     String repoInfo = helper.getRepoInfo(cluster, host);
-
     Gson gson = new Gson();
-
     JsonElement element = gson.fromJson(repoInfo, JsonElement.class);
     assertTrue(element.isJsonArray());
-
     JsonArray list = JsonArray.class.cast(element);
     assertEquals(1, list.size());
 
     JsonObject o = list.get(0).getAsJsonObject();
     assertTrue(o.has("baseUrl"));
-    assertEquals("http://foo1", o.get("baseUrl").getAsString());
+    assertEquals(expectedRepoBaseURL, o.get("baseUrl").getAsString());
   }
 
   @Test
   public void testFinalizeUpgradeAcrossStacks() throws Exception {
-    makeCrossStackUpgradeCluster();
+    StackId sourceStack = HDP_21_STACK;
+    StackId targetStack = HDP_22_STACK;
+    String sourceRepo = HDP_2_1_1_0;
+    String targetRepo = HDP_2_2_1_0;
+
+    makeCrossStackUpgradeCluster(sourceStack, sourceRepo, targetStack, targetRepo);
 
     Clusters clusters = m_injector.getInstance(Clusters.class);
     Cluster cluster = clusters.getCluster("c1");
 
     // setup the cluster for the upgrade across stacks
-    cluster.setCurrentStackVersion(HDP_21_STACK);
-    cluster.setDesiredStackVersion(HDP_22_STACK);
+    cluster.setCurrentStackVersion(sourceStack);
+    cluster.setDesiredStackVersion(targetStack);
 
     Map<String, String> commandParams = new HashMap<String, String>();
     commandParams.put(FinalizeUpgradeAction.UPGRADE_DIRECTION_KEY, "upgrade");
-    commandParams.put(FinalizeUpgradeAction.VERSION_KEY, HDP_2_2_1_0);
-    commandParams.put(FinalizeUpgradeAction.ORIGINAL_STACK_KEY, HDP_21_STACK.getStackId());
-    commandParams.put(FinalizeUpgradeAction.TARGET_STACK_KEY, HDP_22_STACK.getStackId());
+    commandParams.put(FinalizeUpgradeAction.VERSION_KEY, targetRepo);
+    commandParams.put(FinalizeUpgradeAction.ORIGINAL_STACK_KEY, sourceStack.getStackId());
+    commandParams.put(FinalizeUpgradeAction.TARGET_STACK_KEY, targetStack.getStackId());
 
     ExecutionCommand executionCommand = new ExecutionCommand();
     executionCommand.setCommandParams(commandParams);
@@ -417,8 +441,8 @@ public class UpgradeActionTest {
 
     // verify current/desired stacks are updated to the new stack
     assertEquals(desiredStackId, currentStackId);
-    assertEquals(HDP_22_STACK, currentStackId);
-    assertEquals(HDP_22_STACK, desiredStackId);
+    assertEquals(targetStack, currentStackId);
+    assertEquals(targetStack, desiredStackId);
   }
 
   /**
@@ -429,7 +453,12 @@ public class UpgradeActionTest {
    */
   @Test
   public void testFinalizeDowngradeAcrossStacks() throws Exception {
-    makeCrossStackUpgradeCluster();
+    StackId sourceStack = HDP_21_STACK;
+    StackId targetStack = HDP_22_STACK;
+    String sourceRepo = HDP_2_1_1_0;
+    String targetRepo = HDP_2_2_1_0;
+
+    makeCrossStackUpgradeCluster(sourceStack, sourceRepo, targetStack, targetRepo);
 
     Clusters clusters = m_injector.getInstance(Clusters.class);
     Cluster cluster = clusters.getCluster("c1");
@@ -445,8 +474,8 @@ public class UpgradeActionTest {
     createConfigs(cluster);
 
     // setup the cluster for the upgrade across stacks
-    cluster.setCurrentStackVersion(HDP_21_STACK);
-    cluster.setDesiredStackVersion(HDP_22_STACK);
+    cluster.setCurrentStackVersion(sourceStack);
+    cluster.setDesiredStackVersion(targetStack);
 
     // now that the desired version is set, we can create some new configs in
     // the new stack version
@@ -459,9 +488,9 @@ public class UpgradeActionTest {
 
     Map<String, String> commandParams = new HashMap<String, String>();
     commandParams.put(FinalizeUpgradeAction.UPGRADE_DIRECTION_KEY, "downgrade");
-    commandParams.put(FinalizeUpgradeAction.VERSION_KEY, HDP_2_1_1_0);
-    commandParams.put(FinalizeUpgradeAction.ORIGINAL_STACK_KEY, HDP_21_STACK.getStackId());
-    commandParams.put(FinalizeUpgradeAction.TARGET_STACK_KEY, HDP_22_STACK.getStackId());
+    commandParams.put(FinalizeUpgradeAction.VERSION_KEY, sourceRepo);
+    commandParams.put(FinalizeUpgradeAction.ORIGINAL_STACK_KEY, sourceStack.getStackId());
+    commandParams.put(FinalizeUpgradeAction.TARGET_STACK_KEY, targetStack.getStackId());
 
     ExecutionCommand executionCommand = new ExecutionCommand();
     executionCommand.setCommandParams(commandParams);
@@ -471,11 +500,9 @@ public class UpgradeActionTest {
 
     hostRoleCommand.setExecutionCommandWrapper(new ExecutionCommandWrapper(executionCommand));
 
-
     HostVersionDAO dao = m_injector.getInstance(HostVersionDAO.class);
 
-    List<HostVersionEntity> hosts = dao.findByClusterStackAndVersion(
-        "c1", HDP_22_STACK, HDP_2_2_1_0);
+    List<HostVersionEntity> hosts = dao.findByClusterStackAndVersion("c1", targetStack, targetRepo);
     assertFalse(hosts.isEmpty());
     for (HostVersionEntity hve : hosts) {
       assertFalse(hve.getState() == RepositoryVersionState.INSTALLED);
@@ -494,27 +521,23 @@ public class UpgradeActionTest {
 
     // verify current/desired stacks are back to normal
     assertEquals(desiredStackId, currentStackId);
-    assertEquals(HDP_21_STACK, currentStackId);
-    assertEquals(HDP_21_STACK, desiredStackId);
+    assertEquals(sourceStack, currentStackId);
+    assertEquals(sourceStack, desiredStackId);
 
     // verify we have configs in only 1 stack
     cluster = clusters.getCluster("c1");
     configs = cluster.getAllConfigs();
     assertEquals(3, configs.size());
 
-    hosts = dao.findByClusterStackAndVersion(
-        "c1", HDP_22_STACK, HDP_2_2_1_0);
-
-    hosts = dao.findByClusterStackAndVersion("c1", HDP_22_STACK, HDP_2_2_1_0);
+    hosts = dao.findByClusterStackAndVersion("c1", targetStack, targetRepo);
     assertFalse(hosts.isEmpty());
     for (HostVersionEntity hve : hosts) {
       assertTrue(hve.getState() == RepositoryVersionState.INSTALLED);
     }
-
   }
 
   private ServiceComponentHost createNewServiceComponentHost(Cluster cluster, String svc,
-      String svcComponent, String hostName) throws AmbariException {
+                                                             String svcComponent, String hostName) throws AmbariException {
     Assert.assertNotNull(cluster.getConfigGroups());
     Service s = installService(cluster, svc);
     ServiceComponent sc = addServiceComponent(cluster, s, svcComponent);
@@ -546,7 +569,7 @@ public class UpgradeActionTest {
   }
 
   private ServiceComponent addServiceComponent(Cluster cluster, Service service,
-      String componentName) throws AmbariException {
+                                               String componentName) throws AmbariException {
     ServiceComponent serviceComponent = null;
     try {
       serviceComponent = service.getServiceComponent(componentName);

+ 33 - 31
ambari-server/src/test/java/org/apache/ambari/server/state/cluster/ClusterTest.java

@@ -534,14 +534,15 @@ public class ClusterTest {
         hostComponentStateDAO.merge(hce);
       }
 
+      RepositoryVersionEntity rv = helper.getOrCreateRepositoryVersion(stackId, version);
+
       // Simulate the StackVersionListener during the installation
       Service svc = cluster.getService(hce.getServiceName());
       ServiceComponent svcComp = svc.getServiceComponent(hce.getComponentName());
       ServiceComponentHost scHost = svcComp.getServiceComponentHost(hce.getHostName());
 
       scHost.recalculateHostVersionState();
-      cluster.recalculateClusterVersionState(cluster.getDesiredStackVersion(),
-          version);
+      cluster.recalculateClusterVersionState(rv);
     }
   }
 
@@ -1494,7 +1495,7 @@ public class ClusterTest {
 
     // Phase 1: Install bits during distribution
     StackId stackId = new StackId("HDP-0.1");
-    final String stackVersion = "1.0-1000";
+    final String stackVersion = "0.1-1000";
     RepositoryVersionEntity repositoryVersionEntity = helper.getOrCreateRepositoryVersion(
         stackId,
         stackVersion);
@@ -1506,13 +1507,13 @@ public class ClusterTest {
     HostVersionEntity hv1 = helper.createHostVersion("h1", repositoryVersionEntity, RepositoryVersionState.INSTALLING);
     HostVersionEntity hv2 = helper.createHostVersion("h2", repositoryVersionEntity, RepositoryVersionState.INSTALLING);
 
-    c1.recalculateClusterVersionState(c1.getDesiredStackVersion(), stackVersion);
+    c1.recalculateClusterVersionState(repositoryVersionEntity);
     //Should remain in its current state
     checkStackVersionState(stackId, stackVersion,
         RepositoryVersionState.INSTALLING);
 
     h2.setState(HostState.UNHEALTHY);
-    c1.recalculateClusterVersionState(c1.getDesiredStackVersion(), stackVersion);
+    c1.recalculateClusterVersionState(repositoryVersionEntity);
     // In order for the states to be accurately reflected, the host health status should not impact the status
     // of the host_version.
     checkStackVersionState(stackId, stackVersion,
@@ -1524,14 +1525,14 @@ public class ClusterTest {
     h2.setState(HostState.HEALTHY);
     hv2.setState(RepositoryVersionState.INSTALLED);
     hostVersionDAO.merge(hv2);
-    c1.recalculateClusterVersionState(c1.getDesiredStackVersion(), stackVersion);
+    c1.recalculateClusterVersionState(repositoryVersionEntity);
     checkStackVersionState(stackId, stackVersion,
         RepositoryVersionState.INSTALLING);
 
     // Make one host fail
     hv1.setState(RepositoryVersionState.INSTALL_FAILED);
     hostVersionDAO.merge(hv1);
-    c1.recalculateClusterVersionState(c1.getDesiredStackVersion(), stackVersion);
+    c1.recalculateClusterVersionState(repositoryVersionEntity);
     checkStackVersionState(stackId, stackVersion,
         RepositoryVersionState.INSTALL_FAILED);
     // Retry by going back to INSTALLING
@@ -1541,26 +1542,26 @@ public class ClusterTest {
     // Now, all hosts are in INSTALLED
     hv1.setState(RepositoryVersionState.INSTALLED);
     hostVersionDAO.merge(hv1);
-    c1.recalculateClusterVersionState(c1.getDesiredStackVersion(), stackVersion);
+    c1.recalculateClusterVersionState(repositoryVersionEntity);
     checkStackVersionState(stackId, stackVersion,
         RepositoryVersionState.INSTALLED);
 
     // Phase 2: Upgrade stack
     hv1.setState(RepositoryVersionState.UPGRADING);
     hostVersionDAO.merge(hv1);
-    c1.recalculateClusterVersionState(c1.getDesiredStackVersion(), stackVersion);
+    c1.recalculateClusterVersionState(repositoryVersionEntity);
     checkStackVersionState(stackId, stackVersion,
         RepositoryVersionState.UPGRADING);
 
     hv2.setState(RepositoryVersionState.UPGRADING);
     hostVersionDAO.merge(hv2);
-    c1.recalculateClusterVersionState(c1.getDesiredStackVersion(), stackVersion);
+    c1.recalculateClusterVersionState(repositoryVersionEntity);
     checkStackVersionState(stackId, stackVersion,
         RepositoryVersionState.UPGRADING);
 
     hv2.setState(RepositoryVersionState.UPGRADE_FAILED);
     hostVersionDAO.merge(hv2);
-    c1.recalculateClusterVersionState(c1.getDesiredStackVersion(), stackVersion);
+    c1.recalculateClusterVersionState(repositoryVersionEntity);
     checkStackVersionState(stackId, stackVersion,
         RepositoryVersionState.UPGRADE_FAILED);
     // Retry by going back to UPGRADING
@@ -1569,14 +1570,14 @@ public class ClusterTest {
 
     hv2.setState(RepositoryVersionState.UPGRADED);
     hostVersionDAO.merge(hv2);
-    c1.recalculateClusterVersionState(c1.getDesiredStackVersion(), stackVersion);
+    c1.recalculateClusterVersionState(repositoryVersionEntity);
     checkStackVersionState(stackId, stackVersion,
         RepositoryVersionState.UPGRADING);
 
     // Now both hosts are UPGRADED
     hv1.setState(RepositoryVersionState.UPGRADED);
     hostVersionDAO.merge(hv1);
-    c1.recalculateClusterVersionState(c1.getDesiredStackVersion(), stackVersion);
+    c1.recalculateClusterVersionState(repositoryVersionEntity);
     checkStackVersionState(stackId, stackVersion,
         RepositoryVersionState.UPGRADED);
 
@@ -1585,7 +1586,7 @@ public class ClusterTest {
     hostVersionDAO.merge(hv1);
     hv2.setState(RepositoryVersionState.CURRENT);
     hostVersionDAO.merge(hv2);
-    c1.recalculateClusterVersionState(c1.getDesiredStackVersion(), stackVersion);
+    c1.recalculateClusterVersionState(repositoryVersionEntity);
     checkStackVersionState(stackId, stackVersion,
         RepositoryVersionState.CURRENT);
   }
@@ -1603,39 +1604,39 @@ public class ClusterTest {
     StackId stackId = new StackId("HDP-0.1");
     RepositoryVersionEntity repositoryVersionEntity = helper.getOrCreateRepositoryVersion(
         stackId,
-        "1.0-1000");
-    c1.createClusterVersion(stackId, "1.0-1000", "admin",
+        "0.1-1000");
+    c1.createClusterVersion(stackId, "0.1-1000", "admin",
         RepositoryVersionState.INSTALLING);
     c1.setCurrentStackVersion(stackId);
     c1.recalculateAllClusterVersionStates();
-    checkStackVersionState(stackId, "1.0-1000",
+    checkStackVersionState(stackId, "0.1-1000",
         RepositoryVersionState.INSTALLING);
-    checkStackVersionState(stackId, "1.0-2086", RepositoryVersionState.CURRENT);
+    checkStackVersionState(stackId, "0.1-2086", RepositoryVersionState.CURRENT);
 
     HostVersionEntity hv1 = helper.createHostVersion("h1", repositoryVersionEntity, RepositoryVersionState.INSTALLING);
     HostVersionEntity hv2 = helper.createHostVersion("h2", repositoryVersionEntity, RepositoryVersionState.INSTALLING);
 
     c1.recalculateAllClusterVersionStates();
-    checkStackVersionState(stackId, "1.0-1000",
+    checkStackVersionState(stackId, "0.1-1000",
         RepositoryVersionState.INSTALLING);
     checkStackVersionState(stackId, "1.0-2086", RepositoryVersionState.CURRENT);
 
     hv1.setState(RepositoryVersionState.INSTALL_FAILED);
     hostVersionDAO.merge(hv1);
     c1.recalculateAllClusterVersionStates();
-    checkStackVersionState(stackId, "1.0-1000",
+    checkStackVersionState(stackId, "0.1-1000",
         RepositoryVersionState.INSTALL_FAILED);
-    checkStackVersionState(stackId, "1.0-2086", RepositoryVersionState.CURRENT);
+    checkStackVersionState(stackId, "0.1-2086", RepositoryVersionState.CURRENT);
     // Retry by going back to INSTALLING
-    c1.transitionClusterVersion(stackId, "1.0-1000",
+    c1.transitionClusterVersion(stackId, "0.1-1000",
         RepositoryVersionState.INSTALLING);
 
     hv1.setState(RepositoryVersionState.CURRENT);
     hostVersionDAO.merge(hv1);
     c1.recalculateAllClusterVersionStates();
-    checkStackVersionState(stackId, "1.0-1000",
+    checkStackVersionState(stackId, "0.1-1000",
         RepositoryVersionState.OUT_OF_SYNC);
-    checkStackVersionState(stackId, "1.0-2086", RepositoryVersionState.CURRENT);
+    checkStackVersionState(stackId, "0.1-2086", RepositoryVersionState.CURRENT);
   }
 
   /**
@@ -1655,6 +1656,8 @@ public class ClusterTest {
     String v1 = "2.2.0-123";
     StackId stackId = new StackId("HDP-2.2.0");
 
+    RepositoryVersionEntity rv1 = helper.getOrCreateRepositoryVersion(stackId, v1);
+
     Map<String, String> hostAttributes = new HashMap<String, String>();
     hostAttributes.put("os_family", "redhat");
     hostAttributes.put("os_release_version", "5.9");
@@ -1684,8 +1687,7 @@ public class ClusterTest {
       ServiceComponentHost scHost = svcComp.getServiceComponentHost(hce.getHostName());
 
       scHost.recalculateHostVersionState();
-      cluster.recalculateClusterVersionState(cluster.getDesiredStackVersion(),
-          v1);
+      cluster.recalculateClusterVersionState(rv1);
 
       Collection<ClusterVersionEntity> clusterVersions = cluster.getAllClusterVersions();
 
@@ -1739,8 +1741,7 @@ public class ClusterTest {
 
     // Distribute bits for a new repo
     String v2 = "2.2.0-456";
-    RepositoryVersionEntity rv2 = helper.getOrCreateRepositoryVersion(stackId,
-        v2);
+    RepositoryVersionEntity rv2 = helper.getOrCreateRepositoryVersion(stackId, v2);
     for(String hostName : clusters.getHostsForCluster(clusterName).keySet()) {
       HostEntity host = hostDAO.findByName(hostName);
       HostVersionEntity hve = new HostVersionEntity(host, rv2, RepositoryVersionState.INSTALLED);
@@ -1795,7 +1796,7 @@ public class ClusterTest {
       ServiceComponentHost scHost = svcComp.getServiceComponentHost(hce.getHostName());
 
       scHost.recalculateHostVersionState();
-      cluster.recalculateClusterVersionState(cluster.getDesiredStackVersion(),v2);
+      cluster.recalculateClusterVersionState(rv2);
 
       Collection<ClusterVersionEntity> clusterVersions = cluster.getAllClusterVersions();
 
@@ -1835,6 +1836,8 @@ public class ClusterTest {
     String v1 = "2.2.0-123";
     StackId stackId = new StackId("HDP-2.2.0");
 
+    RepositoryVersionEntity rv1 = helper.getOrCreateRepositoryVersion(stackId, v1);
+
     Map<String, String> hostAttributes = new HashMap<String, String>();
     hostAttributes.put("os_family", "redhat");
     hostAttributes.put("os_release_version", "5.9");
@@ -1872,8 +1875,7 @@ public class ClusterTest {
       ServiceComponentHost scHost = svcComp.getServiceComponentHost(hce.getHostName());
 
       scHost.recalculateHostVersionState();
-      cluster.recalculateClusterVersionState(cluster.getDesiredStackVersion(),
-              v1);
+      cluster.recalculateClusterVersionState(rv1);
 
       Collection<ClusterVersionEntity> clusterVersions = cluster.getAllClusterVersions();