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 2016/12/08 22:34:56 UTC
ambari git commit: AMBARI-19130 - Downgrade Can Create Multiple
Mappings For Latest Configs (jonathanhurley)
Repository: ambari
Updated Branches:
refs/heads/trunk b2a8edf8e -> 72586a1ed
AMBARI-19130 - Downgrade Can Create Multiple Mappings For Latest Configs (jonathanhurley)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/72586a1e
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/72586a1e
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/72586a1e
Branch: refs/heads/trunk
Commit: 72586a1ed95728dff642758545cc9676fb77aa9e
Parents: b2a8edf
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Wed Dec 7 20:55:38 2016 -0500
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Thu Dec 8 17:34:49 2016 -0500
----------------------------------------------------------------------
.../entities/ClusterConfigMappingEntity.java | 20 ++-
.../server/state/cluster/ClusterImpl.java | 104 +++++++++-----
.../server/orm/dao/ServiceConfigDAOTest.java | 144 +++++++++----------
.../server/state/cluster/ClusterTest.java | 95 ++++++++++++
4 files changed, 253 insertions(+), 110 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/72586a1e/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
index 04c6030..5748dc9 100644
--- 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
@@ -27,15 +27,17 @@ 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.
*/
-@Table(name = "clusterconfigmapping")
@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")})
+@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 {
@@ -192,4 +194,14 @@ public class ClusterConfigMappingEntity {
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/72586a1e/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 649fe38..b62c834 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
@@ -22,6 +22,7 @@ import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.Date;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
@@ -144,8 +145,10 @@ import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Functions;
import com.google.common.base.Predicate;
import com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Maps;
@@ -3072,6 +3075,7 @@ public class ClusterImpl implements Cluster {
* {@inheritDoc}
*/
@Override
+ @Transactional
public void applyLatestConfigurations(StackId stackId) {
clusterGlobalLock.writeLock().lock();
@@ -3079,36 +3083,33 @@ public class ClusterImpl implements Cluster {
ClusterEntity clusterEntity = getClusterEntity();
Collection<ClusterConfigMappingEntity> configMappingEntities = clusterEntity.getConfigMappingEntities();
+ // 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());
+
// disable all configs
for (ClusterConfigMappingEntity e : configMappingEntities) {
LOG.debug("{} with tag {} is unselected", e.getType(), e.getTag());
e.setSelected(0);
}
- List<ClusterConfigMappingEntity> clusterConfigMappingsForStack = clusterDAO.getClusterConfigMappingsByStack(
+ // work through the in-memory list, finding only the most recent mapping per type
+ Collection<ClusterConfigMappingEntity> latestConfigMappingByStack = getLatestConfigMappingsForStack(
clusterEntity.getClusterId(), stackId);
- Collection<ClusterConfigMappingEntity> latestConfigMappingByStack = getLatestConfigMapping(
- clusterConfigMappingsForStack);
-
- // loop through all configs and set the latest to enabled for the
- // specified stack
- for(ClusterConfigMappingEntity configMappingEntity: configMappingEntities){
- String type = configMappingEntity.getType();
- String tag = configMappingEntity.getTag();
+ for( ClusterConfigMappingEntity latestConfigMapping : latestConfigMappingByStack ){
+ ClusterConfigMappingEntity mapping = ccmMap.get(latestConfigMapping);
+ mapping.setSelected(1);
- for (ClusterConfigMappingEntity latest : latestConfigMappingByStack) {
- String latestType = latest.getType();
- String latestTag = latest.getTag();
-
- // find the latest config of a given mapping entity
- if (StringUtils.equals(type, latestType) && StringUtils.equals(tag, latestTag)) {
- LOG.info("{} with version tag {} is selected for stack {}", type, tag, stackId.toString());
- configMappingEntity.setSelected(1);
- }
- }
+ LOG.info("Settting {} with version tag {} created on {} to selected for stack {}",
+ mapping.getType(), mapping.getTag(), new Date(mapping.getCreateTimestamp()),
+ 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);
clusterEntity = clusterDAO.merge(clusterEntity);
clusterDAO.mergeConfigMappings(configMappingEntities);
@@ -3130,23 +3131,60 @@ public class ClusterImpl implements Cluster {
jpaEventPublisher.publish(event);
}
- public Collection<ClusterConfigMappingEntity> getLatestConfigMapping(List<ClusterConfigMappingEntity> clusterConfigMappingEntities){
- Map<String, ClusterConfigMappingEntity> temp = new HashMap<String, ClusterConfigMappingEntity>();
- for (ClusterConfigMappingEntity e : clusterConfigMappingEntities) {
- String type = e.getType();
- if(temp.containsKey(type)){
- ClusterConfigMappingEntity entityStored = temp.get(type);
- Long timestampStored = entityStored.getCreateTimestamp();
- Long timestamp = e.getCreateTimestamp();
- if(timestamp > timestampStored){
- temp.put(type, e); //find a newer config for the given type
- }
- } else {
- temp.put(type, e); //first time encounter a type, add it
+ /**
+ * 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<String, ClusterConfigMappingEntity>();
+ 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 temp.values();
+ return latestMappingsByType.values();
}
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/72586a1e/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/ServiceConfigDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/ServiceConfigDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/ServiceConfigDAOTest.java
index 2388c11..aafe557 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/ServiceConfigDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/ServiceConfigDAOTest.java
@@ -17,15 +17,11 @@
*/
package org.apache.ambari.server.orm.dao;
-import static org.easymock.EasyMock.createMockBuilder;
-
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
-import junit.framework.Assert;
-
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.orm.GuiceJpaInitializer;
@@ -40,9 +36,12 @@ import org.apache.ambari.server.orm.entities.ResourceTypeEntity;
import org.apache.ambari.server.orm.entities.ServiceConfigEntity;
import org.apache.ambari.server.orm.entities.StackEntity;
import org.apache.ambari.server.security.authorization.ResourceType;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.state.StackId;
import org.apache.ambari.server.state.cluster.ClusterImpl;
import org.junit.After;
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -393,7 +392,7 @@ public class ServiceConfigDAOTest {
serviceConfigs = serviceConfigDAO.getLatestServiceConfigs(clusterId, HDP_02);
Assert.assertEquals(2, serviceConfigs.size());
}
-
+
@Test
public void testConfiguration() throws Exception{
initClusterEntities();
@@ -401,17 +400,17 @@ public class ServiceConfigDAOTest {
Assert.assertTrue(!clusterEntity.getClusterConfigEntities().isEmpty());
Assert.assertTrue(!clusterEntity.getConfigMappingEntities().isEmpty());
-
+
Assert.assertEquals(5, clusterEntity.getClusterConfigEntities().size());
Assert.assertEquals(3, clusterEntity.getConfigMappingEntities().size());
}
-
+
@Test
public void testGetClusterConfigMappingByStack() throws Exception{
initClusterEntities();
-
+
ClusterEntity clusterEntity = clusterDAO.findByName("c1");
-
+
List<ClusterConfigMappingEntity> clusterConfigMappingEntities = clusterDAO.getClusterConfigMappingsByStack(clusterEntity.getClusterId(), HDP_01);
Assert.assertEquals(2, clusterConfigMappingEntities .size());
@@ -420,14 +419,14 @@ public class ServiceConfigDAOTest {
Assert.assertEquals("version1", tag1);
String type1 = e1.getType();
Assert.assertEquals("oozie-site", type1);
-
+
ClusterConfigMappingEntity e2 = clusterConfigMappingEntities.get(1);
String tag2 = e2.getTag();
Assert.assertEquals("version2", tag2);
String type2 = e2.getType();
Assert.assertEquals("oozie-site", type2);
}
-
+
/**
* Test the get latest configuration query against clusterconfig table with configuration groups inserted
* */
@@ -435,9 +434,9 @@ public class ServiceConfigDAOTest {
public void testGetClusterConfigMappingByStackCG() throws Exception{
initClusterEntitiesWithConfigGroups();
ClusterEntity clusterEntity = clusterDAO.findByName("c1");
-
+
List<ConfigGroupEntity> configGroupEntities = configGroupDAO.findAllByTag("OOZIE");
-
+
Assert.assertNotNull(configGroupEntities);
ConfigGroupEntity configGroupEntity = configGroupEntities.get(0);
Assert.assertNotNull(configGroupEntity);
@@ -447,7 +446,7 @@ public class ServiceConfigDAOTest {
Assert.assertEquals("oozie_server", configGroupEntity.getGroupName());
Assert.assertEquals("OOZIE", configGroupEntity.getTag());
Assert.assertEquals("oozie server", configGroupEntity.getDescription());
-
+
List<ClusterConfigMappingEntity> clusterConfigMappingEntities = clusterDAO.getClusterConfigMappingsByStack(clusterEntity.getClusterId(), HDP_01);
Assert.assertEquals(2, clusterConfigMappingEntities .size());
@@ -456,97 +455,95 @@ public class ServiceConfigDAOTest {
Assert.assertEquals("version1", tag1);
String type1 = e1.getType();
Assert.assertEquals("oozie-site", type1);
-
+
ClusterConfigMappingEntity e2 = clusterConfigMappingEntities.get(1);
String tag2 = e2.getTag();
Assert.assertEquals("version2", tag2);
String type2 = e2.getType();
Assert.assertEquals("oozie-site", type2);
}
-
+
/**
- * Test
+ * Test
*
- * When the last configuration of a given configuration type to be stored into the clusterconfig table is
+ * When the last configuration of a given configuration type to be stored into the clusterconfig table is
* for a configuration group, there is no corresponding entry generated in the clusterconfigmapping.
*
* Therefore, the getlatestconfiguration query should skip configuration groups stored in the clusterconfig table.
*
- * Test to determine the latest configuration of a given type whose version_tag
+ * Test to determine the latest configuration of a given type whose version_tag
* exists in the clusterconfigmapping table.
*
* */
@Test
- public void testGetLatestClusterConfigMappingByStack() throws Exception{
- ClusterImpl cluster =
- createMockBuilder(ClusterImpl.class).
- addMockedMethod("getSessionManager").
- addMockedMethod("getClusterName").
- addMockedMethod("getSessionAttributes").
- createMock();
-
+ public void testGetLatestClusterConfigMappingByStack() throws Exception {
+ Clusters clusters = injector.getInstance(Clusters.class);
+ clusters.addCluster("c1", HDP_01);
+
+ Cluster cluster = clusters.getCluster("c1");
+
initClusterEntities();
- ClusterEntity clusterEntity = clusterDAO.findByName("c1");
- List<ClusterConfigMappingEntity> clusterConfigMappingEntities = clusterDAO.getClusterConfigMappingsByStack(clusterEntity.getClusterId(), HDP_01);
- Collection<ClusterConfigMappingEntity> latestMapingEntities = cluster.getLatestConfigMapping(clusterConfigMappingEntities);
+
+ Collection<ClusterConfigMappingEntity> latestMapingEntities = ((ClusterImpl) cluster).getLatestConfigMappingsForStack(
+ cluster.getClusterId(), HDP_01);
+
Assert.assertEquals(1, latestMapingEntities.size());
for(ClusterConfigMappingEntity e: latestMapingEntities){
Assert.assertEquals("version2", e.getTag());
Assert.assertEquals("oozie-site", e.getType());
}
}
-
+
/**
- * Test
+ * Test
*
- * When the last configuration of a given configuration type to be stored into the clusterconfig table is
+ * When the last configuration of a given configuration type to be stored into the clusterconfig table is
* for a configuration group, there is no corresponding entry generated in the clusterconfigmapping.
*
* Therefore, the getlatestconfiguration query should skip configuration groups stored in the clusterconfig table.
*
- * Test to determine the latest configuration of a given type whose version_tag
+ * Test to determine the latest configuration of a given type whose version_tag
* exists in the clusterconfigmapping table.
*
* */
@Test
public void testGetLatestClusterConfigMappingByStackCG() throws Exception{
- ClusterImpl cluster =
- createMockBuilder(ClusterImpl.class).
- addMockedMethod("getSessionManager").
- addMockedMethod("getClusterName").
- addMockedMethod("getSessionAttributes").
- createMock();
-
+ Clusters clusters = injector.getInstance(Clusters.class);
+ clusters.addCluster("c1", HDP_01);
+
+ Cluster cluster = clusters.getCluster("c1");
+
initClusterEntitiesWithConfigGroups();
- ClusterEntity clusterEntity = clusterDAO.findByName("c1");
- List<ClusterConfigMappingEntity> clusterConfigMappingEntities = clusterDAO.getClusterConfigMappingsByStack(clusterEntity.getClusterId(), HDP_01);
- Collection<ClusterConfigMappingEntity> latestMapingEntities = cluster.getLatestConfigMapping(clusterConfigMappingEntities);
+
+ Collection<ClusterConfigMappingEntity> latestMapingEntities = ((ClusterImpl) cluster).getLatestConfigMappingsForStack(
+ cluster.getClusterId(), HDP_01);
+
Assert.assertEquals(1, latestMapingEntities.size());
for(ClusterConfigMappingEntity e: latestMapingEntities){
Assert.assertEquals("version2", e.getTag());
Assert.assertEquals("oozie-site", e.getType());
}
}
-
+
private void initClusterEntities() throws Exception{
String userName = "admin";
-
+
ServiceConfigEntity oozieServiceConfigEntity = createServiceConfig("OOZIE", userName, 1L, 1L, System.currentTimeMillis(), null);
ClusterEntity clusterEntity = oozieServiceConfigEntity.getClusterEntity();
-
+
Long clusterId = clusterEntity.getClusterId();
-
+
if(null == clusterId){
clusterId = 1L;
clusterEntity.setClusterId(clusterId);
clusterEntity = clusterDAO.merge(clusterEntity);
}
-
+
StackEntity stackEntityHDP01 = stackDAO.find(HDP_01.getStackName(),HDP_01.getStackVersion());
StackEntity stackEntityHDP02 = stackDAO.find(HDP_02.getStackName(),HDP_02.getStackVersion());
-
+
String oozieSite = "oozie-site";
-
+
for (int i = 1; i < 6; i++){
ClusterConfigEntity entity = new ClusterConfigEntity();
entity.setClusterEntity(clusterEntity);
@@ -555,22 +552,23 @@ public class ServiceConfigDAOTest {
entity.setVersion(Long.valueOf(i));
entity.setTag("version"+i);
entity.setTimestamp(new Date().getTime());
- if(i < 4)
+ if(i < 4) {
entity.setStack(stackEntityHDP01);
- else
+ } else {
entity.setStack(stackEntityHDP02);
+ }
entity.setData("");
clusterDAO.createConfig(entity);
clusterEntity.getClusterConfigEntities().add(entity);
clusterDAO.merge(clusterEntity);
}
-
+
Collection<ClusterConfigMappingEntity> entities = clusterEntity.getConfigMappingEntities();
if(null == entities){
entities = new ArrayList<ClusterConfigMappingEntity>();
clusterEntity.setConfigMappingEntities(entities);
- }
-
+ }
+
ClusterConfigMappingEntity e1 = new ClusterConfigMappingEntity();
e1.setClusterEntity(clusterEntity);
e1.setClusterId(clusterEntity.getClusterId());
@@ -581,7 +579,7 @@ public class ServiceConfigDAOTest {
e1.setTag("version1");
entities.add(e1);
clusterDAO.merge(clusterEntity);
-
+
ClusterConfigMappingEntity e2 = new ClusterConfigMappingEntity();
e2.setClusterEntity(clusterEntity);
e2.setClusterId(clusterEntity.getClusterId());
@@ -592,7 +590,7 @@ public class ServiceConfigDAOTest {
e2.setTag("version2");
entities.add(e2);
clusterDAO.merge(clusterEntity);
-
+
ClusterConfigMappingEntity e3 = new ClusterConfigMappingEntity();
e3.setClusterEntity(clusterEntity);
e3.setClusterId(clusterEntity.getClusterId());
@@ -603,25 +601,25 @@ public class ServiceConfigDAOTest {
e3.setTag("version4");
entities.add(e3);
clusterDAO.merge(clusterEntity);
- }
-
+ }
+
private void initClusterEntitiesWithConfigGroups() throws Exception{
String userName = "admin";
-
+
ServiceConfigEntity oozieServiceConfigEntity = createServiceConfig("OOZIE", userName, 1L, 1L, System.currentTimeMillis(), null);
ClusterEntity clusterEntity = oozieServiceConfigEntity.getClusterEntity();
-
+
Long clusterId = clusterEntity.getClusterId();
-
+
if(null == clusterId){
clusterId = 1L;
clusterEntity.setClusterId(clusterId);
clusterEntity = clusterDAO.merge(clusterEntity);
}
-
+
StackEntity stackEntityHDP01 = stackDAO.find(HDP_01.getStackName(),HDP_01.getStackVersion());
String oozieSite = "oozie-site";
-
+
int count = 3;
for (int i = 1; i < count; i++){
ClusterConfigEntity entity = new ClusterConfigEntity();
@@ -637,13 +635,13 @@ public class ServiceConfigDAOTest {
clusterEntity.getClusterConfigEntities().add(entity);
clusterDAO.merge(clusterEntity);
}
-
+
Collection<ClusterConfigMappingEntity> entities = clusterEntity.getConfigMappingEntities();
if(null == entities){
entities = new ArrayList<ClusterConfigMappingEntity>();
clusterEntity.setConfigMappingEntities(entities);
- }
-
+ }
+
ClusterConfigMappingEntity e1 = new ClusterConfigMappingEntity();
e1.setClusterEntity(clusterEntity);
e1.setClusterId(clusterEntity.getClusterId());
@@ -654,7 +652,7 @@ public class ServiceConfigDAOTest {
e1.setTag("version1");
entities.add(e1);
clusterDAO.merge(clusterEntity);
-
+
ClusterConfigMappingEntity e2 = new ClusterConfigMappingEntity();
e2.setClusterEntity(clusterEntity);
e2.setClusterId(clusterEntity.getClusterId());
@@ -665,7 +663,7 @@ public class ServiceConfigDAOTest {
e2.setTag("version2");
entities.add(e2);
clusterDAO.merge(clusterEntity);
-
+
ConfigGroupEntity configGroupEntity = new ConfigGroupEntity();
ResourceTypeEntity resourceTypeEntity = resourceTypeDAO.findById(ResourceType.CLUSTER.getId());
@@ -695,9 +693,9 @@ public class ServiceConfigDAOTest {
List<ClusterConfigEntity> configEntities = new
ArrayList<ClusterConfigEntity>();
configEntities.add(configEntity);
-
+
configGroupDAO.create(configGroupEntity);
-
+
if (configEntities != null && !configEntities.isEmpty()) {
List<ConfigGroupConfigMappingEntity> configMappingEntities = new
ArrayList<ConfigGroupConfigMappingEntity>();
@@ -719,7 +717,7 @@ public class ServiceConfigDAOTest {
configMappingEntities.add(configMappingEntity);
configGroupConfigMappingDAO.create(configMappingEntity);
}
-
+
configGroupEntity.setConfigGroupConfigMappingEntities(configMappingEntities);
configGroupDAO.merge(configGroupEntity);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/72586a1e/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/ClusterTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/ClusterTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/ClusterTest.java
index fc3646a..daa3abc 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/ClusterTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/ClusterTest.java
@@ -2467,6 +2467,101 @@ public class ClusterTest {
}
/**
+ * Tests that {@link Cluster#applyLatestConfigurations(StackId)} sets the
+ * right configs to enabled when there are duplicate mappings for type/tag.
+ * Only the most recent should be enabled.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testApplyLatestConfigurationsWithMultipleMappings() throws Exception {
+ createDefaultCluster();
+ Cluster cluster = clusters.getCluster("c1");
+ ClusterEntity clusterEntity = clusterDAO.findByName("c1");
+ StackId stackId = cluster.getCurrentStackVersion();
+
+ StackEntity currentStack = stackDAO.find(stackId.getStackName(), stackId.getStackVersion());
+
+ String configType = "foo-type";
+ String configTag = "version-1";
+
+ // create the config for the mappings
+ ClusterConfigEntity clusterConfig = new ClusterConfigEntity();
+ clusterConfig.setClusterEntity(clusterEntity);
+ clusterConfig.setConfigId(1L);
+ clusterConfig.setStack(currentStack);
+ clusterConfig.setTag(configTag);
+ clusterConfig.setData("{}");
+ clusterConfig.setType(configType);
+ clusterConfig.setTimestamp(1L);
+ clusterConfig.setVersion(1L);
+
+ clusterDAO.createConfig(clusterConfig);
+ clusterEntity.getClusterConfigEntities().add(clusterConfig);
+ clusterEntity = clusterDAO.merge(clusterEntity);
+
+ // create 3 mappings for the same type/tag, each with a different time
+
+ // config mapping 1
+ ClusterConfigMappingEntity configMapping = new ClusterConfigMappingEntity();
+ configMapping.setClusterEntity(clusterEntity);
+ configMapping.setCreateTimestamp(1L);
+ configMapping.setSelected(0);
+ configMapping.setTag(configTag);
+ configMapping.setType(configType);
+ configMapping.setUser("admin");
+ clusterDAO.persistConfigMapping(configMapping);
+ clusterEntity.getConfigMappingEntities().add(configMapping);
+
+ // config mapping 2
+ configMapping = new ClusterConfigMappingEntity();
+ configMapping.setClusterEntity(clusterEntity);
+ configMapping.setCreateTimestamp(2L);
+ configMapping.setSelected(0);
+ configMapping.setTag(configTag);
+ configMapping.setType(configType);
+ configMapping.setUser("admin");
+ clusterDAO.persistConfigMapping(configMapping);
+ clusterEntity.getConfigMappingEntities().add(configMapping);
+
+ // config mapping 3
+ configMapping = new ClusterConfigMappingEntity();
+ configMapping.setClusterEntity(clusterEntity);
+ configMapping.setCreateTimestamp(3L);
+ configMapping.setSelected(0);
+ configMapping.setTag(configTag);
+ configMapping.setType(configType);
+ configMapping.setUser("admin");
+ clusterDAO.persistConfigMapping(configMapping);
+ clusterEntity.getConfigMappingEntities().add(configMapping);
+
+ clusterEntity = clusterDAO.merge(clusterEntity);
+
+ // check all 3 mappings are disabled
+ Collection<ClusterConfigMappingEntity> clusterConfigMappings = clusterEntity.getConfigMappingEntities();
+ Assert.assertEquals(3, clusterConfigMappings.size());
+ for (ClusterConfigMappingEntity clusterConfigMapping : clusterConfigMappings) {
+ Assert.assertEquals(0, clusterConfigMapping.isSelected());
+ }
+
+ // apply configurations and check to see we've set the one with the latest
+ // timestamp ONLY
+ cluster.applyLatestConfigurations(cluster.getCurrentStackVersion());
+ clusterEntity = clusterDAO.findByName("c1");
+
+ // now check that the new config mapping is enabled
+ clusterConfigMappings = clusterEntity.getConfigMappingEntities();
+ Assert.assertEquals(3, clusterConfigMappings.size());
+ for (ClusterConfigMappingEntity clusterConfigMapping : clusterConfigMappings) {
+ if (clusterConfigMapping.getCreateTimestamp() < 3) {
+ Assert.assertEquals(0, clusterConfigMapping.isSelected());
+ } else {
+ Assert.assertEquals(1, clusterConfigMapping.isSelected());
+ }
+ }
+ }
+
+ /**
* Tests that applying configurations for a given stack correctly sets
* {@link DesiredConfig}s.
*/