You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by jo...@apache.org on 2017/02/21 22:37:01 UTC

[2/6] ambari git commit: AMBARI-20054 - Remove Entities Associated With clusterconfigmapping (jonathanhurley)

AMBARI-20054 - Remove Entities Associated With clusterconfigmapping (jonathanhurley)


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

Branch: refs/heads/trunk
Commit: f4638d24dd5f9d320392ef8b7b064c73c50f649c
Parents: 347ba2a
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Thu Feb 16 15:58:40 2017 -0500
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Fri Feb 17 08:07:19 2017 -0500

----------------------------------------------------------------------
 .../checks/DatabaseConsistencyCheckHelper.java  |  79 +----
 .../controller/utilities/DatabaseChecker.java   | 100 +++---
 .../ambari/server/orm/dao/ClusterDAO.java       | 136 ++------
 .../orm/entities/ClusterConfigEntity.java       | 125 ++++---
 .../entities/ClusterConfigMappingEntity.java    | 207 ------------
 .../entities/ClusterConfigMappingEntityPK.java  |  83 -----
 .../server/orm/entities/ClusterEntity.java      |  13 +-
 .../orm/entities/ServiceConfigEntity.java       |   2 +-
 .../ambari/server/state/DesiredConfig.java      |  20 --
 .../apache/ambari/server/state/ServiceImpl.java |  33 +-
 .../server/state/cluster/ClusterImpl.java       | 238 ++++----------
 .../ambari/server/state/host/HostImpl.java      |  13 +-
 .../main/resources/Ambari-DDL-Derby-CREATE.sql  |  12 +-
 .../main/resources/Ambari-DDL-MySQL-CREATE.sql  |  12 +-
 .../main/resources/Ambari-DDL-Oracle-CREATE.sql |  12 +-
 .../resources/Ambari-DDL-Postgres-CREATE.sql    |  12 +-
 .../resources/Ambari-DDL-SQLAnywhere-CREATE.sql |  12 +-
 .../resources/Ambari-DDL-SQLServer-CREATE.sql   |  12 +-
 .../DatabaseConsistencyCheckHelperTest.java     |  56 +---
 .../server/orm/dao/ServiceConfigDAOTest.java    | 324 +++++++++----------
 .../ambari/server/state/DesiredConfigTest.java  |   2 -
 .../server/state/cluster/ClusterTest.java       | 323 ++++++++----------
 .../server/state/cluster/ClustersTest.java      |   7 +-
 .../ambari/server/state/host/HostTest.java      |  10 +-
 24 files changed, 563 insertions(+), 1280 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/f4638d24/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelper.java
index 926ec65..79c5868 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelper.java
@@ -167,7 +167,6 @@ public class DatabaseConsistencyCheckHelper {
       checkSchemaName();
       checkMySQLEngine();
       checkForConfigsNotMappedToService();
-      checkForNotMappedConfigsToCluster();
       checkForConfigsSelectedMoreThanOnce();
       checkForHostsWithoutState();
       checkHostComponentStates();
@@ -221,62 +220,21 @@ public class DatabaseConsistencyCheckHelper {
     LOG.info("DB store version is compatible");
   }
 
-  static void checkForNotMappedConfigsToCluster() {
-    LOG.info("Checking for configs not mapped to any cluster");
-
-    String GET_NOT_MAPPED_CONFIGS_QUERY = "select type_name from clusterconfig where type_name not in (select type_name from clusterconfigmapping)";
-    Set<String> nonSelectedConfigs = new HashSet<>();
-    ResultSet rs = null;
-    Statement statement = null;
-
-    ensureConnection();
-
-    try {
-      statement = connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
-      rs = statement.executeQuery(GET_NOT_MAPPED_CONFIGS_QUERY);
-      if (rs != null) {
-        while (rs.next()) {
-          nonSelectedConfigs.add(rs.getString("type_name"));
-        }
-      }
-      if (!nonSelectedConfigs.isEmpty()) {
-        warning("You have config(s): {} that is(are) not mapped (in clusterconfigmapping table) to any cluster!",
-            nonSelectedConfigs);
-      }
-    } catch (SQLException e) {
-      LOG.error("Exception occurred during check for not mapped configs to cluster procedure: ", e);
-    } finally {
-      if (rs != null) {
-        try {
-          rs.close();
-        } catch (SQLException e) {
-          LOG.error("Exception occurred during result set closing procedure: ", e);
-        }
-      }
-
-      if (statement != null) {
-        try {
-          statement.close();
-        } catch (SQLException e) {
-          LOG.error("Exception occurred during statement closing procedure: ", e);
-        }
-      }
-    }
-  }
-
   /**
-  * This method checks if any config type in clusterconfigmapping table, has
-  * more than one versions selected. If config version is selected(in selected column = 1),
-  * it means that this version of config is actual. So, if any config type has more
-  * than one selected version it's a bug and we are showing error message for user.
-  * */
+   * This method checks if any config type in clusterconfig table, has more than
+   * one versions selected. If config version is selected(in selected column =
+   * 1), it means that this version of config is actual. So, if any config type
+   * has more than one selected version it's a bug and we are showing error
+   * message for user.
+   */
   static void checkForConfigsSelectedMoreThanOnce() {
-    LOG.info("Checking for configs selected more than once");
+    LOG.info("Checking for more than 1 configuration of the same type being enabled.");
 
-    String GET_CONFIGS_SELECTED_MORE_THAN_ONCE_QUERY = "select c.cluster_name, ccm.type_name from clusterconfigmapping ccm " +
-            "join clusters c on ccm.cluster_id=c.cluster_id " +
-            "group by c.cluster_name, ccm.type_name " +
+    String GET_CONFIGS_SELECTED_MORE_THAN_ONCE_QUERY = "select c.cluster_name, cc.type_name from clusterconfig cc "
+        + "join clusters c on cc.cluster_id=c.cluster_id "
+        + "group by c.cluster_name, cc.type_name " +
             "having sum(selected) > 1";
+
     Multimap<String, String> clusterConfigTypeMap = HashMultimap.create();
     ResultSet rs = null;
     Statement statement = null;
@@ -292,7 +250,7 @@ public class DatabaseConsistencyCheckHelper {
         }
 
         for (String clusterName : clusterConfigTypeMap.keySet()) {
-          error("You have config(s), in cluster {}, that is(are) selected more than once in clusterconfigmapping table: {}",
+          error("You have config(s), in cluster {}, that is(are) selected more than once in clusterconfig table: {}",
                   clusterName ,StringUtils.join(clusterConfigTypeMap.get(clusterName), ","));
         }
       }
@@ -544,8 +502,6 @@ public class DatabaseConsistencyCheckHelper {
       List<String> types = new ArrayList<>();
       String type = clusterConfigEntity.getType();
       types.add(type);
-      LOG.error("Removing cluster config mapping of type {} that is not mapped to any service", type);
-      clusterDAO.removeClusterConfigMappingEntityByTypes(clusterConfigEntity.getClusterId(),types);
       LOG.error("Removing config that is not mapped to any service", clusterConfigEntity);
       clusterDAO.removeConfig(clusterConfigEntity);
     }
@@ -761,7 +717,7 @@ public class DatabaseConsistencyCheckHelper {
   * 1) Check if we have services in cluster which doesn't have service config id(not available in serviceconfig table).
   * 2) Check if service has no mapped configs to it's service config id.
   * 3) Check if service has all required configs mapped to it.
-  * 4) Check if service has config which is not selected(has no actual config version) in clusterconfigmapping table.
+  * 4) Check if service has config which is not selected(has no actual config version)
   * If any issue was discovered, we are showing error message for user.
   * */
   static void checkServiceConfigs()  {
@@ -786,11 +742,10 @@ public class DatabaseConsistencyCheckHelper {
             "join serviceconfig sc on cs.service_name=sc.service_name and cs.cluster_id=sc.cluster_id " +
             "join serviceconfigmapping scm on sc.service_config_id=scm.service_config_id " +
             "join clusterconfig cc on scm.config_id=cc.config_id and cc.cluster_id=sc.cluster_id " +
-            "join clusterconfigmapping ccm on cc.type_name=ccm.type_name and cc.version_tag=ccm.version_tag and cc.cluster_id=ccm.cluster_id " +
-            "join clusters c on ccm.cluster_id=c.cluster_id " +
+            "join clusters c on cc.cluster_id=c.cluster_id " +
             "where sc.group_id is null and sc.service_config_id = (select max(service_config_id) from serviceconfig sc2 where sc2.service_name=sc.service_name and sc2.cluster_id=sc.cluster_id) " +
             "group by c.cluster_name, cs.service_name, cc.type_name " +
-            "having sum(ccm.selected) < 1";
+            "having sum(cc.selected) < 1";
     Multimap<String, String> clusterServiceMap = HashMultimap.create();
     Map<String, Map<String, String>>  clusterStackInfo = new HashMap<>();
     Map<String, Multimap<String, String>> clusterServiceVersionMap = new HashMap<>();
@@ -945,8 +900,8 @@ public class DatabaseConsistencyCheckHelper {
         }
       }
 
-      //getting services which has mapped configs which are not selected in clusterconfigmapping
-      LOG.info("Getting services which has mapped configs which are not selected in clusterconfigmapping");
+      // getting services which has mapped configs which are not selected in clusterconfig
+      LOG.info("Getting services which has mapped configs which are not selected in clusterconfig");
       rs = statement.executeQuery(GET_NOT_SELECTED_SERVICE_CONFIGS_QUERY);
       if (rs != null) {
         String serviceName = null, configType = null, clusterName = null;

http://git-wip-us.apache.org/repos/asf/ambari/blob/f4638d24/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/DatabaseChecker.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/DatabaseChecker.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/DatabaseChecker.java
index d35fc1a..ab2fd14 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/DatabaseChecker.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/DatabaseChecker.java
@@ -32,7 +32,6 @@ import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.orm.dao.ClusterDAO;
 import org.apache.ambari.server.orm.dao.MetainfoDAO;
 import org.apache.ambari.server.orm.entities.ClusterConfigEntity;
-import org.apache.ambari.server.orm.entities.ClusterConfigMappingEntity;
 import org.apache.ambari.server.orm.entities.ClusterEntity;
 import org.apache.ambari.server.orm.entities.ClusterServiceEntity;
 import org.apache.ambari.server.orm.entities.ClusterStateEntity;
@@ -174,11 +173,14 @@ public class DatabaseChecker {
   }
 
   /**
-   * Validates configuration consistency. Checks that every config type from stack is presented in
-   * ClusterConfigMapping. Checks that for each config type exactly one is selected. Checks that ClusterConfig
-   * contains type_names and tags from ClusterConfigMapping.
+   * Validates configuration consistency by ensuring that configuration types
+   * only have a single entry in {@link ClusterConfigEntity} which is enabled.
+   * Additionally will check to ensure that every installed service's
+   * configurations are present in the configuration table.
    *
-   * @throws AmbariException if check failed
+   * @throws AmbariException
+   *           if check failed
+   * @see ClusterConfigEntity#isSelected()
    */
   public static void checkDBConfigsConsistency() throws AmbariException {
     LOG.info("Checking DB configs consistency");
@@ -193,57 +195,55 @@ public class DatabaseChecker {
     List<ClusterEntity> clusters = clusterDAO.findAll();
     if (clusters != null) {
       for (ClusterEntity clusterEntity : clusters) {
-        Collection<ClusterConfigMappingEntity> configMappingEntities = clusterEntity.getConfigMappingEntities();
         Collection<ClusterConfigEntity> clusterConfigEntities = clusterEntity.getClusterConfigEntities();
+        if (null == clusterConfigEntities) {
+          return;
+        }
 
-        if (configMappingEntities != null) {
-          Map<String, Integer> selectedCountForType = new HashMap<>();
-          for (ClusterConfigMappingEntity clusterConfigMappingEntity : configMappingEntities) {
-            String typeName = clusterConfigMappingEntity.getType();
-            if (clusterConfigMappingEntity.isSelected() > 0) {
-              int selectedCount = selectedCountForType.get(typeName) != null ? selectedCountForType.get(typeName) : 0;
-              selectedCountForType.put(typeName, selectedCount + 1);
-
-              // Check that ClusterConfig contains type_name and tag from ClusterConfigMapping
-              if (!clusterConfigsContainTypeAndTag(clusterConfigEntities, typeName, clusterConfigMappingEntity.getTag())) {
-                checkPassed = false;
-                LOG.error("ClusterConfig does not contain mapping for type_name=" + typeName + " tag="
-                    + clusterConfigMappingEntity.getTag());
-              }
-            } else {
-              if (!selectedCountForType.containsKey(typeName)) {
-                selectedCountForType.put(typeName, 0);
-              }
+        Map<String, Integer> selectedCountForType = new HashMap<>();
+        for (ClusterConfigEntity configEntity : clusterConfigEntities) {
+          String typeName = configEntity.getType();
+          if (configEntity.isSelected()) {
+            int selectedCount = selectedCountForType.get(typeName) != null
+                ? selectedCountForType.get(typeName) : 0;
+            selectedCountForType.put(typeName, selectedCount + 1);
+          } else {
+            if (!selectedCountForType.containsKey(typeName)) {
+              selectedCountForType.put(typeName, 0);
             }
           }
+        }
 
-          // Check that every config type from stack is presented in ClusterConfigMapping
-          Collection<ClusterServiceEntity> clusterServiceEntities = clusterEntity.getClusterServiceEntities();
-          ClusterStateEntity clusterStateEntity = clusterEntity.getClusterStateEntity();
-          if (clusterStateEntity != null) {
-            StackEntity currentStack = clusterStateEntity.getCurrentStack();
-            StackInfo stack = ambariMetaInfo.getStack(currentStack.getStackName(), currentStack.getStackVersion());
-
-            for (ClusterServiceEntity clusterServiceEntity : clusterServiceEntities) {
-              if (!State.INIT.equals(clusterServiceEntity.getServiceDesiredStateEntity().getDesiredState())) {
-                String serviceName = clusterServiceEntity.getServiceName();
-                ServiceInfo serviceInfo = ambariMetaInfo.getService(stack.getName(), stack.getVersion(), serviceName);
-                for (String configTypeName : serviceInfo.getConfigTypeAttributes().keySet()) {
-                  if (selectedCountForType.get(configTypeName) == null) {
+        // Check that every config type from stack is present
+        Collection<ClusterServiceEntity> clusterServiceEntities = clusterEntity.getClusterServiceEntities();
+        ClusterStateEntity clusterStateEntity = clusterEntity.getClusterStateEntity();
+        if (clusterStateEntity != null) {
+          StackEntity currentStack = clusterStateEntity.getCurrentStack();
+          StackInfo stack = ambariMetaInfo.getStack(currentStack.getStackName(),
+              currentStack.getStackVersion());
+
+          for (ClusterServiceEntity clusterServiceEntity : clusterServiceEntities) {
+            if (!State.INIT.equals(
+                clusterServiceEntity.getServiceDesiredStateEntity().getDesiredState())) {
+              String serviceName = clusterServiceEntity.getServiceName();
+              ServiceInfo serviceInfo = ambariMetaInfo.getService(stack.getName(),
+                  stack.getVersion(), serviceName);
+
+              for (String configTypeName : serviceInfo.getConfigTypeAttributes().keySet()) {
+                if (selectedCountForType.get(configTypeName) == null) {
+                  checkPassed = false;
+                  LOG.error("Configuration {} is missing for service {}", configTypeName,
+                      serviceName);
+                } else {
+                  // Check that for each config type exactly one is selected
+                  if (selectedCountForType.get(configTypeName) == 0) {
+                    checkPassed = false;
+                    LOG.error("Configuration {} has no enabled entries for service {}",
+                        configTypeName, serviceName);
+                  } else if (selectedCountForType.get(configTypeName) > 1) {
                     checkPassed = false;
-                    LOG.error("ClusterConfigMapping does not contain mapping for service=" + serviceName + " type_name="
-                        + configTypeName);
-                  } else {
-                    // Check that for each config type exactly one is selected
-                    if (selectedCountForType.get(configTypeName) == 0) {
-                      checkPassed = false;
-                      LOG.error("ClusterConfigMapping selected count is 0 for service=" + serviceName + " type_name="
-                          + configTypeName);
-                    } else if (selectedCountForType.get(configTypeName) > 1) {
-                      checkPassed = false;
-                      LOG.error("ClusterConfigMapping selected count is more than 1 for service=" + serviceName
-                          + " type_name=" + configTypeName);
-                    }
+                    LOG.error("Configuration {} has more than 1 enabled entry for service {}",
+                        configTypeName, serviceName);
                   }
                 }
               }

http://git-wip-us.apache.org/repos/asf/ambari/blob/f4638d24/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterDAO.java
index b727c72..3817570 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterDAO.java
@@ -30,7 +30,6 @@ import javax.persistence.criteria.Root;
 
 import org.apache.ambari.server.orm.RequiresSession;
 import org.apache.ambari.server.orm.entities.ClusterConfigEntity;
-import org.apache.ambari.server.orm.entities.ClusterConfigMappingEntity;
 import org.apache.ambari.server.orm.entities.ClusterEntity;
 import org.apache.ambari.server.orm.entities.StackEntity;
 import org.apache.ambari.server.state.StackId;
@@ -116,9 +115,9 @@ public class ClusterDAO {
   }
 
   @RequiresSession
-  public List<ClusterConfigEntity> getLatestClusterConfigsByTypes(Long clusterId, List<String> types) {
+  public List<ClusterConfigEntity> getEnabledConfigsByTypes(Long clusterId, Collection<String> types) {
     TypedQuery<ClusterConfigEntity> query = entityManagerProvider.get().createNamedQuery(
-      "ClusterConfigEntity.findLatestClusterConfigsByTypes",
+        "ClusterConfigEntity.findEnabledConfigsByTypes",
       ClusterConfigEntity.class);
 
     query.setParameter("clusterId", clusterId);
@@ -191,7 +190,9 @@ public class ClusterDAO {
 
   /**
    * Gets the latest configurations for a given stack for all of the
-   * configurations of the specified cluster.
+   * configurations of the specified cluster. This method does not take into
+   * account the configuration being enabled, as the latest for a given stack
+   * may not be "selected".
    *
    * @param clusterId
    *          the cluster that the service is a part of.
@@ -226,14 +227,11 @@ public class ClusterDAO {
    * @return the latest configurations for the specified cluster and stack.
    */
   @RequiresSession
-  public List<ClusterConfigMappingEntity> getClusterConfigMappingsByStack(long clusterId,
-      StackId stackId) {
-    StackEntity stackEntity = stackDAO.find(stackId.getStackName(),
-        stackId.getStackVersion());
+  public List<ClusterConfigEntity> getEnabledConfigsByStack(long clusterId, StackId stackId) {
+    StackEntity stackEntity = stackDAO.find(stackId.getStackName(), stackId.getStackVersion());
 
-    TypedQuery<ClusterConfigMappingEntity> query = entityManagerProvider.get().createNamedQuery(
-        "ClusterConfigEntity.findClusterConfigMappingsByStack",
-        ClusterConfigMappingEntity.class);
+    TypedQuery<ClusterConfigEntity> query = entityManagerProvider.get().createNamedQuery(
+        "ClusterConfigEntity.findEnabledConfigsByStack", ClusterConfigEntity.class);
 
     query.setParameter("clusterId", clusterId);
     query.setParameter("stack", stackEntity);
@@ -241,46 +239,26 @@ public class ClusterDAO {
     return daoUtils.selectList(query);
   }
 
-  @RequiresSession
-  public List<ClusterConfigMappingEntity> getClusterConfigMappingEntitiesByCluster(long clusterId) {
-    TypedQuery<ClusterConfigMappingEntity> query = entityManagerProvider.get().createQuery(
-      "SELECT mapping FROM ClusterConfigMappingEntity mapping " +
-        "WHERE mapping.clusterId = :clusterId", ClusterConfigMappingEntity.class);
-
-    query.setParameter("clusterId", clusterId);
-
-    return daoUtils.selectList(query);
-  }
-
-  @RequiresSession
-  public List<ClusterConfigMappingEntity> getLatestClusterConfigMappingsEntityByType(long clusterId, String configType) {
-    TypedQuery<ClusterConfigMappingEntity> query = entityManagerProvider.get().createNamedQuery(
-      "ClusterConfigMappingEntity.findLatestClusterConfigMappingsByType",
-      ClusterConfigMappingEntity.class);
-
-    query.setParameter("clusterId", clusterId);
-    query.setParameter("typeName", configType);
-
-    return daoUtils.selectList(query);
-  }
-
   /**
-   * Gets selected mappings for provided config types
-   * @param clusterId cluster id
-   * @param types config types for mappings
-   * @return
+   * Gets the latest config in the given cluster by type name. Only a config
+   * which is enabled can be returned.
+   *
+   * @param clusterId
+   *          the ID of the cluster.
+   * @param type
+   *          the config type (not {@code null}).
+   * @return a config, or {@code null} if there is none enabled.
    */
   @RequiresSession
-  public List<ClusterConfigMappingEntity> getSelectedConfigMappingByTypes(long clusterId, List<String> types) {
-    TypedQuery<ClusterConfigMappingEntity> query = entityManagerProvider.get().createQuery(
-        "SELECT mapping FROM ClusterConfigMappingEntity mapping " +
-            "WHERE mapping.clusterId = :clusterId AND mapping.typeName IN :type " +
-            "AND mapping.selectedInd > 0", ClusterConfigMappingEntity.class);
+  public ClusterConfigEntity findEnabledConfigByType(long clusterId, String type) {
+
+    TypedQuery<ClusterConfigEntity> query = entityManagerProvider.get().createNamedQuery(
+        "ClusterConfigEntity.findEnabledConfigByType", ClusterConfigEntity.class);
 
     query.setParameter("clusterId", clusterId);
-    query.setParameter("type", types);
+    query.setParameter("type", type);
 
-    return daoUtils.selectList(query);
+    return daoUtils.selectOne(query);
   }
 
   /**
@@ -309,63 +287,6 @@ public class ClusterDAO {
   }
 
   /**
-   * Bulk update config mappings in DB
-   */
-  @Transactional
-  public void mergeConfigMappings(Collection<ClusterConfigMappingEntity> mappingEntities) {
-    for (ClusterConfigMappingEntity mappingEntity : mappingEntities) {
-      entityManagerProvider.get().merge(mappingEntity);
-    }
-  }
-
-  /**
-   * Update config mapping in DB
-   */
-  @Transactional
-  public ClusterConfigMappingEntity mergeConfigMapping(ClusterConfigMappingEntity mappingEntity) {
-    return entityManagerProvider.get().merge(mappingEntity);
-  }
-
-  /**
-   * Create cluster config mapping in DB
-   */
-  @Transactional
-  public void persistConfigMapping(ClusterConfigMappingEntity entity) {
-    entityManagerProvider.get().persist(entity);
-  }
-
-  /**
-   * Remove a cluster configuration mapping from the DB.
-   */
-  @Transactional
-  public void removeConfigMapping(ClusterConfigMappingEntity entity) {
-    entityManagerProvider.get().remove(entity);
-  }
-
-
-  /**
-   * Sets selected = 0, for clusterConfigEntities which has type_name which is in the given types list
-   *
-   * @param clusterId
-   *          the cluster that the service is a part of.
-   * @param types
-   *          the names of the configuration types.
-   */
-    @Transactional
-    public void removeClusterConfigMappingEntityByTypes(Long clusterId, List<String> types) {
-      if(types.isEmpty()) {
-        return;
-      }
-
-      TypedQuery<Long> query = entityManagerProvider.get().createQuery
-          ("DELETE FROM ClusterConfigMappingEntity configs WHERE configs" +
-            ".clusterId=?1 AND configs.typeName IN ?2", Long.class);
-
-      daoUtils.executeUpdate(query, clusterId, types);
-    }
-
-
-  /**
    * Retrieve entity data from DB
    *
    * @param clusterEntity
@@ -413,6 +334,17 @@ public class ClusterDAO {
     return clusterEntity;
   }
 
+  /**
+   * Merge the specified entity into the current persistence context.
+   *
+   * @param clusterConfigEntity
+   *          the entity to merge (not {@code null}).
+   * @return the managed entity which was merged (never {@code null}).
+   */
+  public ClusterConfigEntity merge(ClusterConfigEntity clusterConfigEntity) {
+    EntityManager entityManager = entityManagerProvider.get();
+    return entityManager.merge(clusterConfigEntity);
+  }
 
   @Transactional
   public void remove(ClusterEntity clusterEntity) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/f4638d24/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigEntity.java
index d14e60e..876063d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigEntity.java
@@ -19,6 +19,7 @@
 package org.apache.ambari.server.orm.entities;
 
 import java.util.Collection;
+import java.util.Objects;
 
 import javax.persistence.Basic;
 import javax.persistence.Column;
@@ -39,7 +40,7 @@ import javax.persistence.Table;
 import javax.persistence.TableGenerator;
 import javax.persistence.UniqueConstraint;
 
-import com.google.common.base.Objects;
+import org.apache.commons.lang.builder.EqualsBuilder;
 
 @Entity
 @Table(name = "clusterconfig",
@@ -51,20 +52,27 @@ import com.google.common.base.Objects;
   , initialValue = 1
 )
 @NamedQueries({
-    @NamedQuery(name = "ClusterConfigEntity.findNextConfigVersion", query = "SELECT COALESCE(MAX(clusterConfig.version),0) + 1 as nextVersion FROM ClusterConfigEntity clusterConfig WHERE clusterConfig.type=:configType AND clusterConfig.clusterId=:clusterId"),
-    @NamedQuery(name = "ClusterConfigEntity.findAllConfigsByStack", query = "SELECT clusterConfig FROM ClusterConfigEntity clusterConfig WHERE clusterConfig.clusterId=:clusterId AND clusterConfig.stack=:stack"),
-    @NamedQuery(name = "ClusterConfigEntity.findLatestConfigsByStack", query = "SELECT clusterConfig FROM ClusterConfigEntity clusterConfig WHERE clusterConfig.clusterId=:clusterId AND clusterConfig.timestamp = (SELECT MAX(clusterConfig2.timestamp) FROM ClusterConfigEntity clusterConfig2 WHERE clusterConfig2.clusterId=:clusterId AND clusterConfig2.stack=:stack AND clusterConfig2.type = clusterConfig.type)"),
-    @NamedQuery(name = "ClusterConfigEntity.findNotMappedClusterConfigsToService", query = "SELECT clusterConfig FROM ClusterConfigEntity clusterConfig WHERE clusterConfig.serviceConfigEntities IS EMPTY AND clusterConfig.type != 'cluster-env'"),
-    @NamedQuery(name = "ClusterConfigEntity.findClusterConfigMappingsByStack",
-      query = "SELECT mapping FROM ClusterConfigMappingEntity mapping " +
-        "JOIN ClusterConfigEntity config ON mapping.typeName = config.type AND mapping.tag = config.tag " +
-        "WHERE mapping.clusterId = :clusterId AND config.stack = :stack"),
-    @NamedQuery(name = "ClusterConfigEntity.findLatestClusterConfigsByTypes",
-      query = "SELECT cc FROM ClusterConfigEntity cc " +
-        "JOIN ClusterConfigMappingEntity ccm " +
-        "ON cc.clusterId = ccm.clusterId AND cc.type = ccm.typeName AND cc.tag = ccm.tag " +
-        "WHERE cc.clusterId = :clusterId AND ccm.selectedInd > 0 AND ccm.typeName IN :types")
-})
+    @NamedQuery(
+        name = "ClusterConfigEntity.findNextConfigVersion",
+        query = "SELECT COALESCE(MAX(clusterConfig.version),0) + 1 as nextVersion FROM ClusterConfigEntity clusterConfig WHERE clusterConfig.type=:configType AND clusterConfig.clusterId=:clusterId"),
+    @NamedQuery(
+        name = "ClusterConfigEntity.findAllConfigsByStack",
+        query = "SELECT clusterConfig FROM ClusterConfigEntity clusterConfig WHERE clusterConfig.clusterId=:clusterId AND clusterConfig.stack=:stack"),
+    @NamedQuery(
+        name = "ClusterConfigEntity.findLatestConfigsByStack",
+        query = "SELECT clusterConfig FROM ClusterConfigEntity clusterConfig WHERE clusterConfig.clusterId = :clusterId AND clusterConfig.stack = :stack AND clusterConfig.selectedTimestamp = (SELECT MAX(clusterConfig2.selectedTimestamp) FROM ClusterConfigEntity clusterConfig2 WHERE clusterConfig2.clusterId=:clusterId AND clusterConfig2.stack=:stack AND clusterConfig2.type = clusterConfig.type)"),
+    @NamedQuery(
+        name = "ClusterConfigEntity.findNotMappedClusterConfigsToService",
+        query = "SELECT clusterConfig FROM ClusterConfigEntity clusterConfig WHERE clusterConfig.serviceConfigEntities IS EMPTY AND clusterConfig.type != 'cluster-env'"),
+    @NamedQuery(
+        name = "ClusterConfigEntity.findEnabledConfigsByStack",
+        query = "SELECT config FROM ClusterConfigEntity config WHERE config.clusterId = :clusterId AND config.selected = 1 AND config.stack = :stack"),
+    @NamedQuery(
+        name = "ClusterConfigEntity.findEnabledConfigByType",
+        query = "SELECT config FROM ClusterConfigEntity config WHERE config.clusterId = :clusterId AND config.selected = 1 and config.type = :type"),
+    @NamedQuery(
+        name = "ClusterConfigEntity.findEnabledConfigsByTypes",
+        query = "SELECT config FROM ClusterConfigEntity config WHERE config.clusterId = :clusterId AND config.selected = 1 and config.type in :types") })
 
 public class ClusterConfigEntity {
 
@@ -85,6 +93,9 @@ public class ClusterConfigEntity {
   @Column(name = "version_tag")
   private String tag;
 
+  @Column(name = "selected", insertable = true, updatable = true, nullable = false)
+  private int selected = 0;
+
   @Basic(fetch = FetchType.LAZY)
   @Column(name = "config_data", nullable = false, insertable = true)
   @Lob
@@ -98,6 +109,16 @@ public class ClusterConfigEntity {
   @Column(name = "create_timestamp", nullable = false, insertable = true, updatable = false)
   private long timestamp;
 
+  /**
+   * The most recent time that this configuration was marked as
+   * {@link #selected}. This is useful when configruations are being reverted
+   * since a reversion does not create a new instance. Another configuration may
+   * technically be newer via its creation date ({@link #timestamp}), however
+   * that does not indicate it was the most recently enabled configuration.
+   */
+  @Column(name = "selected_timestamp", nullable = false, insertable = true, updatable = true)
+  private long selectedTimestamp = 0;
+
   @ManyToOne
   @JoinColumn(name = "cluster_id", referencedColumnName = "cluster_id", nullable = false)
   private ClusterEntity clusterEntity;
@@ -171,6 +192,10 @@ public class ClusterConfigEntity {
     timestamp = stamp;
   }
 
+  public long getSelectedTimestamp() {
+    return selectedTimestamp;
+  }
+
   public String getAttributes() {
     return configAttributesJson;
   }
@@ -198,51 +223,37 @@ public class ClusterConfigEntity {
     this.stack = stack;
   }
 
+  /**
+   * {@inheritDoc}
+   */
   @Override
-  public boolean equals(Object o) {
-    if (this == o) {
+  public boolean equals(Object object) {
+    if (this == object) {
       return true;
     }
 
-    if (o == null || getClass() != o.getClass()) {
+    if (object == null || getClass() != object.getClass()) {
       return false;
     }
 
-    ClusterConfigEntity that = (ClusterConfigEntity) o;
+    ClusterConfigEntity that = (ClusterConfigEntity) object;
+    EqualsBuilder equalsBuilder = new EqualsBuilder();
 
-    if (configId != null ? !configId.equals(that.configId) : that.configId != null) {
-      return false;
-    }
-
-    if (clusterId != null ? !clusterId.equals(that.clusterId) : that.clusterId != null) {
-      return false;
-    }
-
-    if (type != null ? !type.equals(that.type) : that.type != null) {
-      return false;
-    }
-
-    if (tag != null ? !tag.equals(that.tag) : that.tag != null) {
-      return false;
-    }
-
-    if (stack != null ? !stack.equals(that.stack) : that.stack != null) {
-      return false;
-    }
-
-    return true;
+    equalsBuilder.append(configId, that.configId);
+    equalsBuilder.append(clusterId, that.clusterId);
+    equalsBuilder.append(type, that.type);
+    equalsBuilder.append(tag, that.tag);
+    equalsBuilder.append(stack, that.stack);
 
+    return equalsBuilder.isEquals();
   }
 
+  /**
+   * {@inheritDoc}
+   */
   @Override
   public int hashCode() {
-    int result = configId != null ? configId.hashCode() : 0;
-    result = 31 * result + (clusterId != null ? clusterId.hashCode() : 0);
-    result = 31 * result + (type != null ? type.hashCode() : 0);
-    result = 31 * result + (tag != null ? tag.hashCode() : 0);
-    result = 31 * result + (stack != null ? stack.hashCode() : 0);
-
-    return result;
+    return Objects.hash(configId, clusterId, type, tag, stack);
   }
 
   public ClusterEntity getClusterEntity() {
@@ -275,12 +286,28 @@ public class ClusterConfigEntity {
    */
   @Override
   public String toString() {
-    return Objects.toStringHelper(this)
+    return com.google.common.base.Objects.toStringHelper(this)
       .add("clusterId", clusterId)
       .add("type", type)
       .add("version", version)
       .add("tag", tag)
-      .add("timestamp", timestamp)
+      .add("selected", selected == 1)
+      .add("selectedTimeStamp", selectedTimestamp)
+      .add("created", timestamp)
       .toString();
   }
+
+  public boolean isSelected() {
+    return selected == 1;
+  }
+
+  public void setSelected(boolean selected) {
+    this.selected = selected ? 1 : 0;
+
+    // if this config is being selected, then also update the selected timestamp
+    if (selected) {
+      selectedTimestamp = System.currentTimeMillis();
+    }
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/f4638d24/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigMappingEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigMappingEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigMappingEntity.java
deleted file mode 100644
index 5748dc9..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigMappingEntity.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ambari.server.orm.entities;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.IdClass;
-import javax.persistence.JoinColumn;
-import javax.persistence.ManyToOne;
-import javax.persistence.NamedQueries;
-import javax.persistence.NamedQuery;
-import javax.persistence.Table;
-
-import com.google.common.base.Objects;
-
-/**
- * Entity that maps to a cluster config mapping.
- */
-@Entity
-@Table(name = "clusterconfigmapping")
-@IdClass(ClusterConfigMappingEntityPK.class)
-@NamedQueries({ @NamedQuery(
-    name = "ClusterConfigMappingEntity.findLatestClusterConfigMappingsByType",
-    query = "SELECT mapping FROM ClusterConfigMappingEntity mapping WHERE mapping.clusterId = :clusterId AND mapping.selectedInd > 0 AND mapping.typeName = :typeName") })
-
-public class ClusterConfigMappingEntity {
-
-  @Id
-  @Column(name = "cluster_id", insertable = false, updatable = false, nullable = false)
-  private Long clusterId;
-
-  @Id
-  @Column(name = "type_name", insertable = true, updatable = false, nullable = false)
-  private String typeName;
-
-  @Id
-  @Column(name = "create_timestamp", insertable = true, updatable = false, nullable = false)
-  private Long createTimestamp;
-
-  @Column(name = "version_tag", insertable = true, updatable = false, nullable = false)
-  private String tag;
-
-  @Column(name = "selected", insertable = true, updatable = true, nullable = false)
-  private int selectedInd = 0;
-
-  @Column(name = "user_name", insertable = true, updatable = true, nullable = false)
-  private String user;
-
-  @ManyToOne
-  @JoinColumn(name = "cluster_id", referencedColumnName = "cluster_id", nullable = false)
-  private ClusterEntity clusterEntity;
-
-  public Long getClusterId() {
-    return clusterId;
-  }
-
-  public void setClusterId(Long id) {
-    clusterId = id;
-  }
-
-  public String getType() {
-    return typeName;
-  }
-
-  public void setType(String type) {
-    typeName = type;
-  }
-
-  public Long getCreateTimestamp() {
-    return createTimestamp;
-  }
-
-  public void setCreateTimestamp(Long timestamp) {
-    createTimestamp = timestamp;
-  }
-
-  public String getTag() {
-    return tag;
-  }
-
-  public void setTag(String version) {
-    tag = version;
-  }
-
-  public int isSelected() {
-    return selectedInd;
-  }
-
-  public void setSelected(int selected) {
-    selectedInd = selected;
-  }
-
-  /**
-   * @return the user
-   */
-  public String getUser() {
-    return user;
-  }
-
-  /**
-   * @param userName the user
-   */
-  public void setUser(String userName) {
-    user = userName;
-  }
-
-  public ClusterEntity getClusterEntity() {
-    return clusterEntity;
-  }
-
-  public void setClusterEntity(ClusterEntity entity) {
-    clusterEntity = entity;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public int hashCode() {
-    final int prime = 31;
-    int result = 1;
-    result = prime * result + ((clusterId == null) ? 0 : clusterId.hashCode());
-    result = prime * result + ((createTimestamp == null) ? 0 : createTimestamp.hashCode());
-    result = prime * result + ((tag == null) ? 0 : tag.hashCode());
-    result = prime * result + ((typeName == null) ? 0 : typeName.hashCode());
-    return result;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public boolean equals(Object obj) {
-    if (this == obj) {
-      return true;
-    }
-
-    if (obj == null) {
-      return false;
-    }
-
-    if (getClass() != obj.getClass()) {
-      return false;
-    }
-
-    ClusterConfigMappingEntity other = (ClusterConfigMappingEntity) obj;
-    if (clusterId == null) {
-      if (other.clusterId != null) {
-        return false;
-      }
-    } else if (!clusterId.equals(other.clusterId)) {
-      return false;
-    }
-
-    if (createTimestamp == null) {
-      if (other.createTimestamp != null) {
-        return false;
-      }
-    } else if (!createTimestamp.equals(other.createTimestamp)) {
-      return false;
-    }
-
-    if (tag == null) {
-      if (other.tag != null) {
-        return false;
-      }
-    } else if (!tag.equals(other.tag)) {
-      return false;
-    }
-
-    if (typeName == null) {
-      if (other.typeName != null) {
-        return false;
-      }
-    } else if (!typeName.equals(other.typeName)) {
-      return false;
-    }
-
-    return true;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public String toString() {
-    return Objects.toStringHelper(this).add("clusterId", clusterId).add("type", typeName).add("tag",
-        tag).add("selected", selectedInd).add("created", createTimestamp).toString();
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/f4638d24/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigMappingEntityPK.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigMappingEntityPK.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigMappingEntityPK.java
deleted file mode 100644
index e5ba5af..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigMappingEntityPK.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ambari.server.orm.entities;
-
-import javax.persistence.Column;
-import javax.persistence.Id;
-
-/**
- * PK class for cluster config mappings.
- */
-public class ClusterConfigMappingEntityPK {
-  private Long clusterId;
-  private String typeName;
-  private Long createTimestamp;
-  
-  @Id
-  @Column(name = "cluster_id", nullable = false, insertable = true, updatable = true, length = 10)
-  public Long getClusterId() {
-    return clusterId;
-  }
-
-  public void setClusterId(Long clusterId) {
-    this.clusterId = clusterId;
-  }
-
-  @Id
-  @Column(name = "type_name", nullable = false, insertable = true, updatable = false)
-  public String getType() {
-    return typeName;
-  }
-
-  public void setType(String type) {
-    typeName = type;
-  }
-
-  @Id
-  @Column(name = "create_timestamp", nullable = false, insertable = true, updatable = false)
-  public Long getCreateTimestamp() {
-    return createTimestamp;
-  }
-
-  public void setCreateTimestamp(Long timestamp) {
-    createTimestamp = timestamp;
-  }
-
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) return true;
-    if (o == null || getClass() != o.getClass()) return false;
-
-    ClusterConfigMappingEntityPK that = (ClusterConfigMappingEntityPK) o;
-
-    if (clusterId != null ? !clusterId.equals(that.clusterId) : that.clusterId != null) return false;
-    if (typeName != null ? !typeName.equals(that.typeName) : that.typeName != null) return false;
-    if (createTimestamp != null ? !createTimestamp.equals (that.createTimestamp) : that.createTimestamp != null) return false;
-
-    return true;
-  }
-
-  @Override
-  public int hashCode() {
-    int result = clusterId !=null ? clusterId.intValue() : 0;
-    result = 31 * result + (typeName != null ? typeName.hashCode() : 0);
-    result = 31 * result + createTimestamp.intValue();
-    return result;
-  }
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/f4638d24/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterEntity.java
index 2e0a15d..89b0646 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterEntity.java
@@ -115,9 +115,6 @@ public class ClusterEntity {
   @OneToMany(mappedBy = "clusterEntity", cascade = CascadeType.ALL)
   private Collection<ClusterConfigEntity> configEntities;
 
-  @OneToMany(mappedBy = "clusterEntity", cascade = CascadeType.REMOVE)
-  private Collection<ClusterConfigMappingEntity> configMappingEntities;
-
   @OneToMany(mappedBy = "clusterEntity", cascade = CascadeType.ALL)
   private Collection<ConfigGroupEntity> configGroupEntities;
 
@@ -292,14 +289,6 @@ public class ClusterEntity {
     configEntities = entities;
   }
 
-  public Collection<ClusterConfigMappingEntity> getConfigMappingEntities() {
-    return configMappingEntities;
-  }
-
-  public void setConfigMappingEntities(Collection<ClusterConfigMappingEntity> entities) {
-    configMappingEntities = entities;
-  }
-
   public Collection<ConfigGroupEntity> getConfigGroupEntities() {
     return configGroupEntities;
   }
@@ -336,7 +325,7 @@ public class ClusterEntity {
 
   public void addClusterVersionEntity(ClusterVersionEntity clusterVersionEntity) {
     if (clusterVersionEntities == null) {
-      clusterVersionEntities = new ArrayList<ClusterVersionEntity>();
+      clusterVersionEntities = new ArrayList<>();
     }
     clusterVersionEntities.add(clusterVersionEntity);
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/f4638d24/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceConfigEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceConfigEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceConfigEntity.java
index dae7ef8..a7ee0f6 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceConfigEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceConfigEntity.java
@@ -96,12 +96,12 @@ public class ServiceConfigEntity {
    * the contract of configs being associated with only the cluster and the
    * same config can technically belong to multiple serviceConfig versions.
    */
+  @ManyToMany
   @JoinTable(
     name = "serviceconfigmapping",
     joinColumns = {@JoinColumn(name = "service_config_id", referencedColumnName = "service_config_id")},
     inverseJoinColumns = {@JoinColumn(name = "config_id", referencedColumnName = "config_id")}
   )
-  @ManyToMany
   private List<ClusterConfigEntity> clusterConfigEntities;
 
   @ManyToOne

http://git-wip-us.apache.org/repos/asf/ambari/blob/f4638d24/ambari-server/src/main/java/org/apache/ambari/server/state/DesiredConfig.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/DesiredConfig.java b/ambari-server/src/main/java/org/apache/ambari/server/state/DesiredConfig.java
index 80d05f7..f133078 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/DesiredConfig.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/DesiredConfig.java
@@ -34,7 +34,6 @@ public class DesiredConfig {
 
   private String tag;
   private String serviceName;
-  private String user;
   private Long version;
   private List<HostOverride> hostOverrides = new ArrayList<HostOverride>();
 
@@ -80,23 +79,6 @@ public class DesiredConfig {
   public void setHostOverrides(List<HostOverride> overrides) {
     hostOverrides = overrides;
   }
-
-  /**
-   * Gets the user that set the desired config.
-   */
-  @JsonSerialize(include = Inclusion.NON_EMPTY)
-  public String getUser() {
-    return user;
-  }
-  
-  /**
-   * Sets the user that set the desired config.
-   * @param userName the username
-   */
-  public void setUser(String userName) {
-    user = userName;
-  }
-  
   
   /**
    * Gets the host overrides for the desired config.  Cluster-based desired configs only.
@@ -208,7 +190,6 @@ public class DesiredConfig {
     return new EqualsBuilder()
       .append(tag, that.tag)
       .append(serviceName, that.serviceName)
-      .append(user, that.user)
       .append(version, that.version)
       .append(hostOverrides, that.hostOverrides)
       .isEquals();
@@ -219,7 +200,6 @@ public class DesiredConfig {
     return new HashCodeBuilder(17, 37)
       .append(tag)
       .append(serviceName)
-      .append(user)
       .append(version)
       .append(hostOverrides)
       .toHashCode();

http://git-wip-us.apache.org/repos/asf/ambari/blob/f4638d24/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java
index 713c189..9ef32b5 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java
@@ -18,7 +18,6 @@
 
 package org.apache.ambari.server.state;
 
-import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -41,7 +40,6 @@ import org.apache.ambari.server.orm.dao.ServiceConfigDAO;
 import org.apache.ambari.server.orm.dao.ServiceDesiredStateDAO;
 import org.apache.ambari.server.orm.dao.StackDAO;
 import org.apache.ambari.server.orm.entities.ClusterConfigEntity;
-import org.apache.ambari.server.orm.entities.ClusterConfigMappingEntity;
 import org.apache.ambari.server.orm.entities.ClusterEntity;
 import org.apache.ambari.server.orm.entities.ClusterServiceEntity;
 import org.apache.ambari.server.orm.entities.ClusterServiceEntityPK;
@@ -192,7 +190,7 @@ public class ServiceImpl implements Service {
 
   @Override
   public Map<String, ServiceComponent> getServiceComponents() {
-    return new HashMap<String, ServiceComponent>(components);
+    return new HashMap<>(components);
   }
 
   @Override
@@ -461,30 +459,19 @@ public class ServiceImpl implements Service {
 
   @Transactional
   void deleteAllServiceConfigs() throws AmbariException {
-    ArrayList<String> serviceConfigTypes = new ArrayList<>();
-    ServiceConfigEntity lastServiceConfigEntity = serviceConfigDAO.findMaxVersion(getClusterId(), getName());
-    //ensure service config version exist
-    if (lastServiceConfigEntity != null) {
-      for (ClusterConfigEntity configEntity : lastServiceConfigEntity.getClusterConfigEntities()) {
-        serviceConfigTypes.add(configEntity.getType());
-      }
-
-      LOG.info("Deselecting config mapping for cluster, clusterId={}, configTypes={} ",
-          getClusterId(), serviceConfigTypes);
+    long clusterId = getClusterId();
+    ServiceConfigEntity lastServiceConfigEntity = serviceConfigDAO.findMaxVersion(clusterId, getName());
 
-      List<ClusterConfigMappingEntity> configMappingEntities =
-          clusterDAO.getSelectedConfigMappingByTypes(getClusterId(), serviceConfigTypes);
-
-      for (ClusterConfigMappingEntity configMappingEntity : configMappingEntities) {
-        configMappingEntity.setSelected(0);
+    // de-select every configuration from the service
+    if (lastServiceConfigEntity != null) {
+      for (ClusterConfigEntity serviceConfigEntity : lastServiceConfigEntity.getClusterConfigEntities()) {
+        LOG.info("Disabling configuration {}", serviceConfigEntity);
+        serviceConfigEntity.setSelected(false);
+        clusterDAO.merge(serviceConfigEntity);
       }
-
-      clusterDAO.mergeConfigMappings(configMappingEntities);
     }
 
-    LOG.info("Deleting all serviceconfigs for service"
-        + ", clusterName=" + cluster.getClusterName()
-        + ", serviceName=" + getName());
+    LOG.info("Deleting all configuration associations for {} on cluster {}", getName(), cluster.getClusterName());
 
     List<ServiceConfigEntity> serviceConfigEntities =
       serviceConfigDAO.findByService(cluster.getClusterId(), getName());

http://git-wip-us.apache.org/repos/asf/ambari/blob/f4638d24/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
index db4aa21..90c44ff 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
@@ -89,7 +89,6 @@ import org.apache.ambari.server.orm.dao.StackDAO;
 import org.apache.ambari.server.orm.dao.TopologyRequestDAO;
 import org.apache.ambari.server.orm.dao.UpgradeDAO;
 import org.apache.ambari.server.orm.entities.ClusterConfigEntity;
-import org.apache.ambari.server.orm.entities.ClusterConfigMappingEntity;
 import org.apache.ambari.server.orm.entities.ClusterEntity;
 import org.apache.ambari.server.orm.entities.ClusterServiceEntity;
 import org.apache.ambari.server.orm.entities.ClusterStateEntity;
@@ -2187,40 +2186,39 @@ public class ClusterImpl implements Cluster {
     try {
       Map<String, Set<DesiredConfig>> map = new HashMap<>();
       Collection<String> types = new HashSet<>();
-      Collection<ClusterConfigMappingEntity> entities = getClusterEntity().getConfigMappingEntities();
-
-      for (ClusterConfigMappingEntity e : entities) {
-        if (allVersions || e.isSelected() > 0) {
-          DesiredConfig c = new DesiredConfig();
-          c.setServiceName(null);
-          c.setTag(e.getTag());
-          c.setUser(e.getUser());
-          if(!allConfigs.containsKey(e.getType())) {
-            LOG.error("Config inconsistency exists:" +
-                " unknown configType=" + e.getType());
+      Collection<ClusterConfigEntity> entities = getClusterEntity().getClusterConfigEntities();
+
+      for (ClusterConfigEntity configEntity : entities) {
+        if (allVersions || configEntity.isSelected()) {
+          DesiredConfig desiredConfig = new DesiredConfig();
+          desiredConfig.setServiceName(null);
+          desiredConfig.setTag(configEntity.getTag());
+
+          if (!allConfigs.containsKey(configEntity.getType())) {
+            LOG.error("An inconsistency exists for configuration {}", configEntity.getType());
             continue;
           }
 
-          Map<String, Config> configMap = allConfigs.get(e.getType());
-          if(!configMap.containsKey(e.getTag())) {
-            LOG.debug("Config inconsistency exists for typeName=" +
-                    e.getType() +
-                    ", unknown versionTag=" + e.getTag());
+          Map<String, Config> configMap = allConfigs.get(configEntity.getType());
+          if(!configMap.containsKey(configEntity.getTag())) {
+            LOG.error("An inconsistency exists for the configuration {} with tag {}",
+                configEntity.getType(), configEntity.getTag());
+
             continue;
           }
 
-          Config config = configMap.get(e.getTag());
-          c.setVersion(config.getVersion());
+          Config config = configMap.get(configEntity.getTag());
+          desiredConfig.setVersion(config.getVersion());
 
-          Set<DesiredConfig> configs = map.get(e.getType());
+          Set<DesiredConfig> configs = map.get(configEntity.getType());
           if (configs == null) {
             configs = new HashSet<>();
           }
 
-          configs.add(c);
+          configs.add(desiredConfig);
 
-          map.put(e.getType(), configs);
-          types.add(e.getType());
+          map.put(configEntity.getType(), configs);
+          types.add(configEntity.getType());
         }
       }
 
@@ -2557,18 +2555,18 @@ public class ClusterImpl implements Cluster {
       throw new ObjectNotFoundException("Service config version with serviceName={} and version={} not found");
     }
 
-    //disable all configs related to service
+    // disable all configs related to service
     if (serviceConfigEntity.getGroupId() == null) {
       Collection<String> configTypes = serviceConfigTypes.get(serviceName);
-      List<ClusterConfigMappingEntity> mappingEntities =
-          clusterDAO.getSelectedConfigMappingByTypes(getClusterId(), new ArrayList<>(configTypes));
-      for (ClusterConfigMappingEntity entity : mappingEntities) {
-        entity.setSelected(0);
-        clusterDAO.mergeConfigMapping(entity);
+      List<ClusterConfigEntity> enabledConfigs = clusterDAO.getEnabledConfigsByTypes(clusterId, configTypes);
+      for (ClusterConfigEntity enabledConfig : enabledConfigs) {
+        enabledConfig.setSelected(false);
+        clusterDAO.merge(enabledConfig);
       }
 
       for (ClusterConfigEntity configEntity : serviceConfigEntity.getClusterConfigEntities()) {
-        selectConfig(configEntity.getType(), configEntity.getTag(), user);
+        configEntity.setSelected(true);
+        clusterDAO.merge(configEntity);
       }
     } else {
       Long configGroupId = serviceConfigEntity.getGroupId();
@@ -2621,32 +2619,6 @@ public class ClusterImpl implements Cluster {
   }
 
   @Transactional
-  void selectConfig(String type, String tag, String user) {
-    Collection<ClusterConfigMappingEntity> entities =
-      clusterDAO.getLatestClusterConfigMappingsEntityByType(getClusterId(), type);
-
-    //disable previous config
-    for (ClusterConfigMappingEntity e : entities) {
-      e.setSelected(0);
-      clusterDAO.mergeConfigMapping(e);
-    }
-
-    ClusterEntity clusterEntity = getClusterEntity();
-    ClusterConfigMappingEntity entity = new ClusterConfigMappingEntity();
-    entity.setClusterEntity(clusterEntity);
-    entity.setClusterId(clusterEntity.getClusterId());
-    entity.setCreateTimestamp(System.currentTimeMillis());
-    entity.setSelected(1);
-    entity.setUser(user);
-    entity.setType(type);
-    entity.setTag(tag);
-    clusterDAO.persistConfigMapping(entity);
-
-    clusterEntity.getConfigMappingEntities().add(entity);
-    clusterDAO.merge(clusterEntity);
-  }
-
-  @Transactional
   ServiceConfigVersionResponse applyConfigs(Set<Config> configs, String user, String serviceConfigVersionNote) {
 
     String serviceName = null;
@@ -2670,10 +2642,25 @@ public class ClusterImpl implements Cluster {
       }
     }
 
+    // update the selected flag for every config type
+    ClusterEntity clusterEntity = getClusterEntity();
+    Collection<ClusterConfigEntity> clusterConfigs = clusterEntity.getClusterConfigEntities();
     for (Config config: configs) {
-      selectConfig(config.getType(), config.getTag(), user);
+      for (ClusterConfigEntity clusterConfigEntity : clusterConfigs) {
+        // unset for this config type
+        if (StringUtils.equals(clusterConfigEntity.getType(), config.getType())) {
+          clusterConfigEntity.setSelected(false);
+
+          // unless both the tag and type match, then enable it
+          if (StringUtils.equals(clusterConfigEntity.getTag(), config.getTag())) {
+            clusterConfigEntity.setSelected(true);
+          }
+        }
+      }
     }
 
+    clusterEntity = clusterDAO.merge(clusterEntity);
+
     if (serviceName == null) {
       ArrayList<String> configTypes = new ArrayList<>();
       for (Config config: configs) {
@@ -2695,29 +2682,23 @@ public class ClusterImpl implements Cluster {
 
   private List<ClusterConfigEntity> getClusterConfigEntitiesByService(String serviceName) {
     Collection<String> configTypes = serviceConfigTypes.get(serviceName);
-    return clusterDAO.getLatestClusterConfigsByTypes(getClusterId(), new ArrayList<>(configTypes));
+    return clusterDAO.getEnabledConfigsByTypes(getClusterId(), new ArrayList<>(configTypes));
   }
 
   @Override
   public Config getDesiredConfigByType(String configType) {
-    List<ClusterConfigMappingEntity> entities = clusterDAO.getLatestClusterConfigMappingsEntityByType(getClusterId(), configType);
-    if (!entities.isEmpty()) {
-      return getConfig(configType, entities.get(0).getTag());
+    ClusterConfigEntity config = clusterDAO.findEnabledConfigByType(getClusterId(), configType);
+    if (null == config) {
+      return null;
     }
 
-    return null;
+    return getConfig(configType, config.getTag());
   }
 
   @Override
   public boolean isConfigTypeExists(String configType) {
-    for (ClusterConfigMappingEntity e : clusterDAO.getClusterConfigMappingEntitiesByCluster(
-        getClusterId())) {
-      if (e.getType().equals(configType)) {
-        return true;
-      }
-    }
-
-    return false;
+    ClusterConfigEntity config = clusterDAO.findEnabledConfigByType(getClusterId(), configType);
+    return null != config;
   }
 
   @Override
@@ -2740,7 +2721,6 @@ public class ClusterImpl implements Cluster {
       DesiredConfig desiredConfig = new DesiredConfig();
       desiredConfig.setTag(mappingEntity.getVersion());
       desiredConfig.setServiceName(mappingEntity.getServiceName());
-      desiredConfig.setUser(mappingEntity.getUser());
 
       desiredConfigsByHost.get(mappingEntity.getHostId()).put(mappingEntity.getType(), desiredConfig);
     }
@@ -3102,38 +3082,37 @@ public class ClusterImpl implements Cluster {
 
     try {
       ClusterEntity clusterEntity = getClusterEntity();
-      Collection<ClusterConfigMappingEntity> configMappingEntities = clusterEntity.getConfigMappingEntities();
+      Collection<ClusterConfigEntity> configEntities = clusterEntity.getClusterConfigEntities();
 
-      // hash them for easier retrieval later - these are the same entity
-      // instances which exist on the cluster entity, so modification of the CCM
-      // entity here will affect the cluster CCM entities as well
-      ImmutableMap<Object, ClusterConfigMappingEntity> ccmMap = Maps.uniqueIndex(configMappingEntities, Functions.identity());
+      // hash them for easier retrieval later
+      ImmutableMap<Object, ClusterConfigEntity> clusterConfigEntityMap = Maps.uniqueIndex(
+          configEntities, Functions.identity());
 
       // disable all configs
-      for (ClusterConfigMappingEntity e : configMappingEntities) {
-        LOG.debug("{} with tag {} is unselected", e.getType(), e.getTag());
-        e.setSelected(0);
+      for (ClusterConfigEntity e : configEntities) {
+        LOG.debug("Disabling configuration {} with tag {}", e.getType(), e.getTag());
+        e.setSelected(false);
       }
 
       // work through the in-memory list, finding only the most recent mapping per type
-      Collection<ClusterConfigMappingEntity> latestConfigMappingByStack = getLatestConfigMappingsForStack(
-          clusterEntity.getClusterId(), stackId);
+      Collection<ClusterConfigEntity> latestConfigsByStack = clusterDAO.getLatestConfigurations(
+          clusterId, stackId);
 
-      for( ClusterConfigMappingEntity latestConfigMapping : latestConfigMappingByStack ){
-        ClusterConfigMappingEntity mapping = ccmMap.get(latestConfigMapping);
-        mapping.setSelected(1);
+      // pull the correct latest mapping for the stack out of the cached map
+      // from the cluster entity
+      for (ClusterConfigEntity latestConfigByStack : latestConfigsByStack) {
+        ClusterConfigEntity entity = clusterConfigEntityMap.get(latestConfigByStack);
+        entity.setSelected(true);
 
-        LOG.info("Settting {} with version tag {} created on {} to selected for stack {}",
-            mapping.getType(), mapping.getTag(), new Date(mapping.getCreateTimestamp()),
+        LOG.info("Setting {} with version tag {} created on {} to selected for stack {}",
+            entity.getType(), entity.getTag(), new Date(entity.getTimestamp()),
             stackId.toString());
       }
 
       // since the entities which were modified came from the cluster entity's
       // list to begin with, we can just save them right back - no need for a
-      // new collection since the CCM entity instances were modified directly
-      clusterEntity.setConfigMappingEntities(configMappingEntities);
+      // new collection since the entity instances were modified directly
       clusterEntity = clusterDAO.merge(clusterEntity);
-      clusterDAO.mergeConfigMappings(configMappingEntities);
 
       cacheConfigurations();
     } finally {
@@ -3153,62 +3132,6 @@ public class ClusterImpl implements Cluster {
   }
 
   /**
-   * Retrieves all of the configuration mappings (selected and unselected) for
-   * the specified stack and then iterates through them, returning the most
-   * recent mapping for every type/tag combination.
-   * <p/>
-   * Because of how configuration revert works, mappings can be created for the
-   * same type/tag combinations. The only difference being that the timestamp
-   * reflects when each mapping was created.
-   * <p/>
-   * JPQL cannot be used directly here easily because some databases cannot
-   * support the necessary grouping and IN clause. For example: <br/>
-   *
-   * <pre>
-   * SELECT mapping FROM clusterconfigmappingentity mapping
-   *   WHERE (mapping.typename, mapping.createtimestamp) IN
-   *     (SELECT latest.typename, MAX(latest.createtimestamp)
-   *      FROM clusterconfigmappingentity latest
-   *      GROUP BY latest.typename)
-   * </pre>
-   *
-   * @param clusterId
-   *          the cluster ID
-   * @param stackId
-   *          the stack to retrieve the mappings for (not {@code null}).
-   * @return the most recent mapping (selected or unselected) for the specified
-   *         stack for every type.
-   */
-  public Collection<ClusterConfigMappingEntity> getLatestConfigMappingsForStack(long clusterId,
-      StackId stackId) {
-
-    // get all mappings for the specified stack (which could include
-    // duplicates since a config revert creates a duplicate mapping with a
-    // different timestamp)
-    List<ClusterConfigMappingEntity> clusterConfigMappingsForStack = clusterDAO.getClusterConfigMappingsByStack(
-        clusterId, stackId);
-
-    Map<String, ClusterConfigMappingEntity> latestMappingsByType = new HashMap<>();
-    for (ClusterConfigMappingEntity mapping : clusterConfigMappingsForStack) {
-      String type = mapping.getType();
-
-      if (!latestMappingsByType.containsKey(type)) {
-        latestMappingsByType.put(type, mapping);
-        continue;
-      }
-
-      ClusterConfigMappingEntity entityStored = latestMappingsByType.get(type);
-      Long timestampStored = entityStored.getCreateTimestamp();
-      Long timestamp = mapping.getCreateTimestamp();
-      if (timestamp > timestampStored) {
-        latestMappingsByType.put(type, mapping);
-      }
-    }
-
-    return latestMappingsByType.values();
-  }
-
-  /**
    * {@inheritDoc}
    */
   @Override
@@ -3275,31 +3198,6 @@ public class ClusterImpl implements Cluster {
 
     clusterEntity.setClusterConfigEntities(clusterConfigEntities);
     clusterEntity = clusterDAO.merge(clusterEntity);
-
-    // remove config mappings
-    Collection<ClusterConfigMappingEntity> configMappingEntities =
-        clusterDAO.getClusterConfigMappingEntitiesByCluster(getClusterId());
-
-    for (ClusterConfigEntity removedClusterConfig : removedClusterConfigs) {
-      String removedClusterConfigType = removedClusterConfig.getType();
-      String removedClusterConfigTag = removedClusterConfig.getTag();
-
-      Iterator<ClusterConfigMappingEntity> clusterConfigMappingIterator = configMappingEntities.iterator();
-      while (clusterConfigMappingIterator.hasNext()) {
-        ClusterConfigMappingEntity clusterConfigMapping = clusterConfigMappingIterator.next();
-        String mappingType = clusterConfigMapping.getType();
-        String mappingTag = clusterConfigMapping.getTag();
-
-        if (removedClusterConfigTag.equals(mappingTag)
-          && removedClusterConfigType.equals(mappingType)) {
-          clusterConfigMappingIterator.remove();
-          clusterDAO.removeConfigMapping(clusterConfigMapping);
-        }
-      }
-    }
-
-    clusterEntity.setConfigMappingEntities(configMappingEntities);
-    clusterEntity = clusterDAO.merge(clusterEntity);
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/f4638d24/ambari-server/src/main/java/org/apache/ambari/server/state/host/HostImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/host/HostImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/host/HostImpl.java
index 328fe22..db228b1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/host/HostImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/host/HostImpl.java
@@ -148,7 +148,7 @@ public class HostImpl implements Host {
 
   private long lastHeartbeatTime = 0L;
   private AgentEnv lastAgentEnv = null;
-  private List<DiskInfo> disksInfo = new CopyOnWriteArrayList<DiskInfo>();
+  private List<DiskInfo> disksInfo = new CopyOnWriteArrayList<>();
   private RecoveryReport recoveryReport = new RecoveryReport();
   private Integer currentPingPort = null;
 
@@ -481,7 +481,7 @@ public class HostImpl implements Host {
     // FIXME add all other information into host attributes
     setAgentVersion(new AgentVersion(hostInfo.getAgentUserId()));
 
-    Map<String, String> attrs = new HashMap<String, String>();
+    Map<String, String> attrs = new HashMap<>();
     if (hostInfo.getHardwareIsa() != null) {
       attrs.put(HARDWAREISA, hostInfo.getHardwareIsa());
     }
@@ -828,7 +828,7 @@ public class HostImpl implements Host {
     Map<String, String> hostAttrs = gson.fromJson(hostEntity.getHostAttributes(), hostAttributesType);
 
     if (hostAttrs == null) {
-      hostAttrs = new ConcurrentHashMap<String, String>();
+      hostAttrs = new ConcurrentHashMap<>();
     }
 
     hostAttrs.putAll(hostAttributes);
@@ -1024,7 +1024,7 @@ public class HostImpl implements Host {
 
   @Override
   public Map<String, DesiredConfig> getDesiredConfigs(long clusterId) {
-    Map<String, DesiredConfig> map = new HashMap<String, DesiredConfig>();
+    Map<String, DesiredConfig> map = new HashMap<>();
 
     for (HostConfigMapping e : hostConfigMappingDAO.findSelected(
         clusterId, getHostId())) {
@@ -1032,7 +1032,6 @@ public class HostImpl implements Host {
       DesiredConfig dc = new DesiredConfig();
       dc.setTag(e.getVersion());
       dc.setServiceName(e.getServiceName());
-      dc.setUser(e.getUser());
       map.put(e.getType(), dc);
 
     }
@@ -1045,10 +1044,10 @@ public class HostImpl implements Host {
   @Override
   public Map<String, HostConfig> getDesiredHostConfigs(Cluster cluster,
       Map<String, DesiredConfig> clusterDesiredConfigs) throws AmbariException {
-    Map<String, HostConfig> hostConfigMap = new HashMap<String, HostConfig>();
+    Map<String, HostConfig> hostConfigMap = new HashMap<>();
 
     if( null == cluster ){
-      clusterDesiredConfigs = new HashMap<String, DesiredConfig>();
+      clusterDesiredConfigs = new HashMap<>();
     }
 
     // per method contract, fetch if not supplied

http://git-wip-us.apache.org/repos/asf/ambari/blob/f4638d24/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
index f007b53..840433f 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
@@ -72,25 +72,17 @@ CREATE TABLE clusterconfig (
   type_name VARCHAR(255) NOT NULL,
   cluster_id BIGINT NOT NULL,
   stack_id BIGINT NOT NULL,
+  selected SMALLINT NOT NULL DEFAULT 0,
   config_data VARCHAR(3000) NOT NULL,
   config_attributes VARCHAR(3000),
   create_timestamp BIGINT NOT NULL,
+  selected_timestamp BIGINT NOT NULL DEFAULT 0,
   CONSTRAINT PK_clusterconfig PRIMARY KEY (config_id),
   CONSTRAINT FK_clusterconfig_cluster_id FOREIGN KEY (cluster_id) REFERENCES clusters (cluster_id),
   CONSTRAINT FK_clusterconfig_stack_id FOREIGN KEY (stack_id) REFERENCES stack(stack_id),
   CONSTRAINT UQ_config_type_tag UNIQUE (version_tag, type_name, cluster_id),
   CONSTRAINT UQ_config_type_version UNIQUE (cluster_id, type_name, version));
 
-CREATE TABLE clusterconfigmapping (
-  cluster_id BIGINT NOT NULL,
-  type_name VARCHAR(255) NOT NULL,
-  version_tag VARCHAR(255) NOT NULL,
-  create_timestamp BIGINT NOT NULL,
-  selected INTEGER NOT NULL DEFAULT 0,
-  user_name VARCHAR(255) NOT NULL DEFAULT '_db',
-  CONSTRAINT PK_clusterconfigmapping PRIMARY KEY (cluster_id, type_name, create_timestamp),
-  CONSTRAINT clusterconfigmappingcluster_id FOREIGN KEY (cluster_id) REFERENCES clusters (cluster_id));
-
 CREATE TABLE serviceconfig (
   service_config_id BIGINT NOT NULL,
   cluster_id BIGINT NOT NULL,

http://git-wip-us.apache.org/repos/asf/ambari/blob/f4638d24/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
index f6cb896..fb4921f 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
@@ -92,9 +92,11 @@ CREATE TABLE clusterconfig (
   type_name VARCHAR(100) NOT NULL,
   cluster_id BIGINT NOT NULL,
   stack_id BIGINT NOT NULL,
+  selected SMALLINT NOT NULL DEFAULT 0,
   config_data LONGTEXT NOT NULL,
   config_attributes LONGTEXT,
   create_timestamp BIGINT NOT NULL,
+  selected_timestamp BIGINT NOT NULL DEFAULT 0,
   CONSTRAINT PK_clusterconfig PRIMARY KEY (config_id),
   CONSTRAINT FK_clusterconfig_cluster_id FOREIGN KEY (cluster_id) REFERENCES clusters (cluster_id),
   CONSTRAINT FK_clusterconfig_stack_id FOREIGN KEY (stack_id) REFERENCES stack(stack_id),
@@ -441,16 +443,6 @@ CREATE TABLE key_value_store (`key` VARCHAR(255),
   `value` LONGTEXT,
   CONSTRAINT PK_key_value_store PRIMARY KEY (`key`));
 
-CREATE TABLE clusterconfigmapping (
-  type_name VARCHAR(255) NOT NULL,
-  create_timestamp BIGINT NOT NULL,
-  cluster_id BIGINT NOT NULL,
-  selected INTEGER NOT NULL DEFAULT 0,
-  version_tag VARCHAR(255) NOT NULL,
-  user_name VARCHAR(255) NOT NULL DEFAULT '_db',
-  CONSTRAINT PK_clusterconfigmapping PRIMARY KEY (type_name, create_timestamp, cluster_id),
-  CONSTRAINT clusterconfigmappingcluster_id FOREIGN KEY (cluster_id) REFERENCES clusters (cluster_id));
-
 CREATE TABLE hostconfigmapping (
   create_timestamp BIGINT NOT NULL,
   host_id BIGINT NOT NULL,

http://git-wip-us.apache.org/repos/asf/ambari/blob/f4638d24/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
index 19253e8..b482ee1 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
@@ -72,9 +72,11 @@ CREATE TABLE clusterconfig (
   type_name VARCHAR2(255) NOT NULL,
   cluster_id NUMBER(19) NOT NULL,
   stack_id NUMBER(19) NOT NULL,
+  selected NUMBER(1) DEFAULT 0 NOT NULL,
   config_data CLOB NOT NULL,
   config_attributes CLOB,
   create_timestamp NUMBER(19) NOT NULL,
+  selected_timestamp NUMBER(19) DEFAULT 0 NOT NULL,
   CONSTRAINT PK_clusterconfig PRIMARY KEY (config_id),
   CONSTRAINT FK_clusterconfig_cluster_id FOREIGN KEY (cluster_id) REFERENCES clusters (cluster_id),
   CONSTRAINT FK_clusterconfig_stack_id FOREIGN KEY (stack_id) REFERENCES stack(stack_id),
@@ -422,16 +424,6 @@ CREATE TABLE key_value_store (
   "value" CLOB NULL,
   CONSTRAINT PK_key_value_store PRIMARY KEY ("key"));
 
-CREATE TABLE clusterconfigmapping (
-  type_name VARCHAR2(255) NOT NULL,
-  create_timestamp NUMBER(19) NOT NULL,
-  cluster_id NUMBER(19) NOT NULL,
-  selected NUMBER(10) NOT NULL,
-  version_tag VARCHAR2(255) NOT NULL,
-  user_name VARCHAR(255) DEFAULT '_db',
-  CONSTRAINT PK_clusterconfigmapping PRIMARY KEY (type_name, create_timestamp, cluster_id),
-  CONSTRAINT clusterconfigmappingcluster_id FOREIGN KEY (cluster_id) REFERENCES clusters (cluster_id));
-
 CREATE TABLE hostconfigmapping (
   create_timestamp NUMBER(19) NOT NULL,
   host_id NUMBER(19) NOT NULL,

http://git-wip-us.apache.org/repos/asf/ambari/blob/f4638d24/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
index b13a9e3..e5851cc 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
@@ -72,25 +72,17 @@ CREATE TABLE clusterconfig (
   type_name VARCHAR(255) NOT NULL,
   cluster_id BIGINT NOT NULL,
   stack_id BIGINT NOT NULL,
+  selected SMALLINT NOT NULL DEFAULT 0,
   config_data TEXT NOT NULL,
   config_attributes TEXT,
   create_timestamp BIGINT NOT NULL,
+  selected_timestamp BIGINT NOT NULL DEFAULT 0,
   CONSTRAINT PK_clusterconfig PRIMARY KEY (config_id),
   CONSTRAINT FK_clusterconfig_cluster_id FOREIGN KEY (cluster_id) REFERENCES clusters (cluster_id),
   CONSTRAINT FK_clusterconfig_stack_id FOREIGN KEY (stack_id) REFERENCES stack(stack_id),
   CONSTRAINT UQ_config_type_tag UNIQUE (cluster_id, type_name, version_tag),
   CONSTRAINT UQ_config_type_version UNIQUE (cluster_id, type_name, version));
 
-CREATE TABLE clusterconfigmapping (
-  cluster_id BIGINT NOT NULL,
-  type_name VARCHAR(255) NOT NULL,
-  version_tag VARCHAR(255) NOT NULL,
-  create_timestamp BIGINT NOT NULL,
-  selected INTEGER NOT NULL DEFAULT 0,
-  user_name VARCHAR(255) NOT NULL DEFAULT '_db',
-  CONSTRAINT PK_clusterconfigmapping PRIMARY KEY (cluster_id, type_name, create_timestamp),
-  CONSTRAINT clusterconfigmappingcluster_id FOREIGN KEY (cluster_id) REFERENCES clusters (cluster_id));
-
 CREATE TABLE serviceconfig (
   service_config_id BIGINT NOT NULL,
   cluster_id BIGINT NOT NULL,

http://git-wip-us.apache.org/repos/asf/ambari/blob/f4638d24/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
index cf2954a..dc06f2e 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
@@ -71,9 +71,11 @@ CREATE TABLE clusterconfig (
   type_name VARCHAR(255) NOT NULL,
   cluster_id NUMERIC(19) NOT NULL,
   stack_id NUMERIC(19) NOT NULL,
+  selected SMALLINT NOT NULL DEFAULT 0,
   config_data TEXT NOT NULL,
   config_attributes TEXT,
   create_timestamp NUMERIC(19) NOT NULL,
+  selected_timestamp NUMERIC(19) NOT NULL DEFAULT 0,  
   CONSTRAINT PK_clusterconfig PRIMARY KEY (config_id),
   CONSTRAINT FK_clusterconfig_cluster_id FOREIGN KEY (cluster_id) REFERENCES clusters (cluster_id),
   CONSTRAINT FK_clusterconfig_stack_id FOREIGN KEY (stack_id) REFERENCES stack(stack_id),
@@ -419,16 +421,6 @@ CREATE TABLE key_value_store ("key" VARCHAR(255),
   "value" TEXT,
   CONSTRAINT PK_key_value_store PRIMARY KEY ("key"));
 
-CREATE TABLE clusterconfigmapping (
-  type_name VARCHAR(255) NOT NULL,
-  create_timestamp NUMERIC(19) NOT NULL,
-  cluster_id NUMERIC(19) NOT NULL,
-  selected INTEGER NOT NULL DEFAULT 0,
-  version_tag VARCHAR(255) NOT NULL,
-  user_name VARCHAR(255) NOT NULL DEFAULT '_db',
-  CONSTRAINT PK_clusterconfigmapping PRIMARY KEY (type_name, create_timestamp, cluster_id),
-  CONSTRAINT clusterconfigmappingcluster_id FOREIGN KEY (cluster_id) REFERENCES clusters (cluster_id));
-
 CREATE TABLE hostconfigmapping (
   create_timestamp NUMERIC(19) NOT NULL,
   host_id NUMERIC(19) NOT NULL,

http://git-wip-us.apache.org/repos/asf/ambari/blob/f4638d24/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
index 16c269a..5ec5e0d 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
@@ -85,9 +85,11 @@ CREATE TABLE clusterconfig (
   type_name VARCHAR(255) NOT NULL,
   cluster_id BIGINT NOT NULL,
   stack_id BIGINT NOT NULL,
+  selected SMALLINT NOT NULL DEFAULT 0,
   config_data VARCHAR(MAX) NOT NULL,
   config_attributes VARCHAR(MAX),
   create_timestamp BIGINT NOT NULL,
+  selected_timestamp BIGINT NOT NULL DEFAULT 0,
   CONSTRAINT PK_clusterconfig PRIMARY KEY CLUSTERED (config_id),
   CONSTRAINT FK_clusterconfig_cluster_id FOREIGN KEY (cluster_id) REFERENCES clusters (cluster_id),
   CONSTRAINT FK_clusterconfig_stack_id FOREIGN KEY (stack_id) REFERENCES stack(stack_id),
@@ -142,16 +144,6 @@ CREATE TABLE serviceconfigmapping (
   CONSTRAINT FK_scvm_config FOREIGN KEY (config_id) REFERENCES clusterconfig(config_id),
   CONSTRAINT FK_scvm_scv FOREIGN KEY (service_config_id) REFERENCES serviceconfig(service_config_id));
 
-CREATE TABLE clusterconfigmapping (
-  cluster_id BIGINT NOT NULL,
-  type_name VARCHAR(255) NOT NULL,
-  version_tag VARCHAR(255) NOT NULL,
-  create_timestamp BIGINT NOT NULL,
-  selected INT NOT NULL DEFAULT 0,
-  user_name VARCHAR(255) NOT NULL DEFAULT '_db',
-  CONSTRAINT PK_clusterconfigmapping PRIMARY KEY CLUSTERED (cluster_id, type_name, create_timestamp ),
-  CONSTRAINT clusterconfigmappingcluster_id FOREIGN KEY (cluster_id) REFERENCES clusters (cluster_id));
-
 CREATE TABLE clusterservices (
   service_name VARCHAR(255) NOT NULL,
   cluster_id BIGINT NOT NULL,

http://git-wip-us.apache.org/repos/asf/ambari/blob/f4638d24/ambari-server/src/test/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelperTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelperTest.java
index fddbb6a..7d8ba50 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelperTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelperTest.java
@@ -58,46 +58,6 @@ import com.google.inject.Injector;
 public class DatabaseConsistencyCheckHelperTest {
 
   @Test
-  public void testCheckForNotMappedConfigs() throws Exception {
-    EasyMockSupport easyMockSupport = new EasyMockSupport();
-
-    final DBAccessor mockDBDbAccessor = easyMockSupport.createNiceMock(DBAccessor.class);
-    final Connection mockConnection = easyMockSupport.createNiceMock(Connection.class);
-    final ResultSet mockResultSet = easyMockSupport.createNiceMock(ResultSet.class);
-    final Statement mockStatement = easyMockSupport.createNiceMock(Statement.class);
-
-    final StackManagerFactory mockStackManagerFactory = easyMockSupport.createNiceMock(StackManagerFactory.class);
-    final EntityManager mockEntityManager = easyMockSupport.createNiceMock(EntityManager.class);
-    final Clusters mockClusters = easyMockSupport.createNiceMock(Clusters.class);
-    final OsFamily mockOSFamily = easyMockSupport.createNiceMock(OsFamily.class);
-    final Injector mockInjector = Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-
-        bind(StackManagerFactory.class).toInstance(mockStackManagerFactory);
-        bind(EntityManager.class).toInstance(mockEntityManager);
-        bind(DBAccessor.class).toInstance(mockDBDbAccessor);
-        bind(Clusters.class).toInstance(mockClusters);
-        bind(OsFamily.class).toInstance(mockOSFamily);
-      }
-    });
-
-
-
-    expect(mockConnection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE)).andReturn(mockStatement);
-    expect(mockStatement.executeQuery("select type_name from clusterconfig where type_name not in (select type_name from clusterconfigmapping)")).andReturn(mockResultSet);
-
-    DatabaseConsistencyCheckHelper.setInjector(mockInjector);
-    DatabaseConsistencyCheckHelper.setConnection(mockConnection);
-
-    easyMockSupport.replayAll();
-
-    DatabaseConsistencyCheckHelper.checkForNotMappedConfigsToCluster();
-
-    easyMockSupport.verifyAll();
-  }
-
-  @Test
   public void testCheckForConfigsSelectedMoreThanOnce() throws Exception {
     EasyMockSupport easyMockSupport = new EasyMockSupport();
 
@@ -123,9 +83,9 @@ public class DatabaseConsistencyCheckHelperTest {
     });
 
     expect(mockConnection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE)).andReturn(mockStatement);
-    expect(mockStatement.executeQuery("select c.cluster_name, ccm.type_name from clusterconfigmapping ccm " +
-            "join clusters c on ccm.cluster_id=c.cluster_id " +
-            "group by c.cluster_name, ccm.type_name " +
+    expect(mockStatement.executeQuery("select c.cluster_name, cc.type_name from clusterconfig cc "
+        + "join clusters c on cc.cluster_id=c.cluster_id "
+        + "group by c.cluster_name, cc.type_name " +
             "having sum(selected) > 1")).andReturn(mockResultSet);
 
 
@@ -349,11 +309,10 @@ public class DatabaseConsistencyCheckHelperTest {
             "join serviceconfig sc on cs.service_name=sc.service_name and cs.cluster_id=sc.cluster_id " +
             "join serviceconfigmapping scm on sc.service_config_id=scm.service_config_id " +
             "join clusterconfig cc on scm.config_id=cc.config_id and cc.cluster_id=sc.cluster_id " +
-            "join clusterconfigmapping ccm on cc.type_name=ccm.type_name and cc.version_tag=ccm.version_tag and cc.cluster_id=ccm.cluster_id " +
-            "join clusters c on ccm.cluster_id=c.cluster_id " +
+            "join clusters c on cc.cluster_id=c.cluster_id " +
             "where sc.group_id is null and sc.service_config_id = (select max(service_config_id) from serviceconfig sc2 where sc2.service_name=sc.service_name and sc2.cluster_id=sc.cluster_id) " +
             "group by c.cluster_name, cs.service_name, cc.type_name " +
-            "having sum(ccm.selected) < 1")).andReturn(mockResultSet);
+            "having sum(cc.selected) < 1")).andReturn(mockResultSet);
 
     DatabaseConsistencyCheckHelper.setInjector(mockInjector);
     DatabaseConsistencyCheckHelper.setConnection(mockConnection);
@@ -550,11 +509,10 @@ public class DatabaseConsistencyCheckHelperTest {
         "join serviceconfig sc on cs.service_name=sc.service_name and cs.cluster_id=sc.cluster_id " +
         "join serviceconfigmapping scm on sc.service_config_id=scm.service_config_id " +
         "join clusterconfig cc on scm.config_id=cc.config_id and cc.cluster_id=sc.cluster_id " +
-        "join clusterconfigmapping ccm on cc.type_name=ccm.type_name and cc.version_tag=ccm.version_tag and cc.cluster_id=ccm.cluster_id " +
-        "join clusters c on ccm.cluster_id=c.cluster_id " +
+        "join clusters c on cc.cluster_id=c.cluster_id " +
         "where sc.group_id is null and sc.service_config_id = (select max(service_config_id) from serviceconfig sc2 where sc2.service_name=sc.service_name and sc2.cluster_id=sc.cluster_id) " +
         "group by c.cluster_name, cs.service_name, cc.type_name " +
-        "having sum(ccm.selected) < 1")).andReturn(mockResultSet);
+        "having sum(cc.selected) < 1")).andReturn(mockResultSet);
 
     DatabaseConsistencyCheckHelper.setInjector(mockInjector);
     DatabaseConsistencyCheckHelper.setConnection(mockConnection);