Repository: ambari Updated Branches: refs/heads/trunk fc15fdef2 -> 8388c7d06
AMBARI-12532. Blueprint deployment results in some configurations not being resolved properly. (rnettleton) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/8388c7d0 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/8388c7d0 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/8388c7d0 Branch: refs/heads/trunk Commit: 8388c7d0607e0010831e02acf6ad24e88fbb5f41 Parents: fc15fde Author: Bob Nettleton <rnettle...@hortonworks.com> Authored: Fri Jul 24 17:13:07 2015 -0400 Committer: Bob Nettleton <rnettle...@hortonworks.com> Committed: Fri Jul 24 17:14:30 2015 -0400 ---------------------------------------------------------------------- .../AmbariManagementControllerImpl.java | 5 +- .../BlueprintConfigurationProcessor.java | 60 +++++++++++++++----- .../ambari/server/topology/AmbariContext.java | 45 +++++++++++++++ .../topology/ClusterConfigurationRequest.java | 25 ++++++-- .../ambari/server/topology/HostRequest.java | 14 +++-- .../BlueprintConfigurationProcessorTest.java | 52 +++++++++++++++-- .../server/topology/AmbariContextTest.java | 46 +++++++++++++++ 7 files changed, 214 insertions(+), 33 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/8388c7d0/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java index 1ded566..1f4e7cd 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java @@ -1360,9 +1360,10 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle !all.containsKey(cr.getVersionTag()) || // tag not set cr.getProperties().size() > 0) { // properties to set - LOG.info(MessageFormat.format("Applying configuration with tag ''{0}'' to cluster ''{1}''", + LOG.info(MessageFormat.format("Applying configuration with tag ''{0}'' to cluster ''{1}'' for configuration type {2}", cr.getVersionTag(), - request.getClusterName())); + request.getClusterName(), + cr.getType())); cr.setClusterName(cluster.getClusterName()); configurationResponses.add(createConfiguration(cr)); http://git-wip-us.apache.org/repos/asf/ambari/blob/8388c7d0/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessor.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessor.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessor.java index 14b13ef..bf05326 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessor.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessor.java @@ -197,14 +197,17 @@ public class BlueprintConfigurationProcessor { /** * Update properties for cluster creation. This involves updating topology related properties with * concrete topology information. + * + * @return Set of config type names that were updated by this update call */ - public void doUpdateForClusterCreate() throws ConfigurationTopologyException { + public Set<String> doUpdateForClusterCreate() throws ConfigurationTopologyException { + Set<String> configTypesUpdated = new HashSet<String>(); Configuration clusterConfig = clusterTopology.getConfiguration(); Map<String, HostGroupInfo> groupInfoMap = clusterTopology.getHostGroupInfo(); // filter out any properties that should not be included, based on the dependencies // specified in the stacks, and the filters defined in this class - doFilterPriorToClusterUpdate(clusterConfig); + doFilterPriorToClusterUpdate(clusterConfig, configTypesUpdated); // this needs to be called after doFilterPriorToClusterUpdate() to ensure that the returned // set of properties (copy) doesn't include the removed properties. If an updater @@ -221,8 +224,15 @@ public class BlueprintConfigurationProcessor { // topo cluster scoped configuration which also includes all default and BP properties Map<String, String> typeMap = clusterProps.get(type); if (typeMap != null && typeMap.containsKey(propertyName)) { - clusterConfig.setProperty(type, propertyName, updater.updateForClusterCreate( - propertyName, typeMap.get(propertyName), clusterProps, clusterTopology)); + final String originalValue = typeMap.get(propertyName); + final String updatedValue = + updater.updateForClusterCreate(propertyName, originalValue, clusterProps, clusterTopology); + + if (!updatedValue.equals(originalValue)) { + configTypesUpdated.add(type); + } + + clusterConfig.setProperty(type, propertyName, updatedValue); } // host group configs @@ -231,8 +241,15 @@ public class BlueprintConfigurationProcessor { Map<String, Map<String, String>> hgConfigProps = hgConfig.getFullProperties(1); Map<String, String> hgTypeMap = hgConfigProps.get(type); if (hgTypeMap != null && hgTypeMap.containsKey(propertyName)) { - hgConfig.setProperty(type, propertyName, updater.updateForClusterCreate( - propertyName, hgTypeMap.get(propertyName), hgConfigProps, clusterTopology)); + final String originalValue = hgTypeMap.get(propertyName); + final String updatedValue = + updater.updateForClusterCreate(propertyName, originalValue, hgConfigProps, clusterTopology); + + if (!updatedValue.equals(originalValue)) { + configTypesUpdated.add(type); + } + + hgConfig.setProperty(type, propertyName, updatedValue); } } } @@ -254,9 +271,14 @@ public class BlueprintConfigurationProcessor { Iterator<String> nnHostIterator = nnHosts.iterator(); clusterConfig.setProperty("hadoop-env", "dfs_ha_initial_namenode_active", nnHostIterator.next()); clusterConfig.setProperty("hadoop-env", "dfs_ha_initial_namenode_standby", nnHostIterator.next()); + + configTypesUpdated.add("hadoop-env"); } } - setMissingConfigurations(clusterConfig); + + setMissingConfigurations(clusterConfig, configTypesUpdated); + + return configTypesUpdated; } /** @@ -340,7 +362,7 @@ public class BlueprintConfigurationProcessor { } } - private void doFilterPriorToClusterUpdate(Configuration configuration) { + private void doFilterPriorToClusterUpdate(Configuration configuration, Set<String> configTypesUpdated) { // getFullProperties returns a copy so changes to it are not reflected in config properties Map<String, Map<String, String>> properties = configuration.getFullProperties(); for (Map.Entry<String, Map<String, String>> configEntry : properties.entrySet()) { @@ -351,6 +373,7 @@ public class BlueprintConfigurationProcessor { String propName = propertyEntry.getKey(); if (shouldPropertyBeExcludedForClusterUpdate(propName, propertyEntry.getValue(), configType, clusterTopology)) { configuration.removeProperty(configType, propName); + configTypesUpdated.add(configType); } } } @@ -2038,11 +2061,11 @@ public class BlueprintConfigurationProcessor { * * @param configuration configuration where properties are to be added */ - void setMissingConfigurations(Configuration configuration) { + void setMissingConfigurations(Configuration configuration, Set<String> configTypesUpdated) { // AMBARI-5206 final Map<String , String> userProps = new HashMap<String , String>(); - setRetryConfiguration(configuration); + setRetryConfiguration(configuration, configTypesUpdated); Collection<String> services = clusterTopology.getBlueprint().getServices(); // only add user properties to the map for @@ -2074,8 +2097,8 @@ public class BlueprintConfigurationProcessor { if (configs != null) { String user = configs.get(property); if (user != null && !user.isEmpty()) { - ensureProperty(configuration, "core-site", String.format(proxyUserHosts, user), "*"); - ensureProperty(configuration, "core-site", String.format(proxyUserGroups, user), "users"); + ensureProperty(configuration, "core-site", String.format(proxyUserHosts, user), "*", configTypesUpdated); + ensureProperty(configuration, "core-site", String.format(proxyUserGroups, user), "users", configTypesUpdated); } } else { LOG.debug("setMissingConfigurations: no user configuration found for type = " + configType + @@ -2096,18 +2119,26 @@ public class BlueprintConfigurationProcessor { * * @param configuration cluster configuration */ - private static void setRetryConfiguration(Configuration configuration) { + private static void setRetryConfiguration(Configuration configuration, Set<String> configTypesUpdated) { + boolean wasUpdated = false; if (configuration.getPropertyValue(CLUSTER_ENV_CONFIG_TYPE_NAME, COMMAND_RETRY_ENABLED_PROPERTY_NAME) == null) { configuration.setProperty(CLUSTER_ENV_CONFIG_TYPE_NAME, COMMAND_RETRY_ENABLED_PROPERTY_NAME, COMMAND_RETRY_ENABLED_DEFAULT); + wasUpdated = true; } if (configuration.getPropertyValue(CLUSTER_ENV_CONFIG_TYPE_NAME, COMMANDS_TO_RETRY_PROPERTY_NAME) == null) { configuration.setProperty(CLUSTER_ENV_CONFIG_TYPE_NAME, COMMANDS_TO_RETRY_PROPERTY_NAME, COMMANDS_TO_RETRY_DEFAULT); + wasUpdated = true; } if (configuration.getPropertyValue(CLUSTER_ENV_CONFIG_TYPE_NAME, COMMAND_RETRY_MAX_TIME_IN_SEC_PROPERTY_NAME) == null) { configuration.setProperty(CLUSTER_ENV_CONFIG_TYPE_NAME, COMMAND_RETRY_MAX_TIME_IN_SEC_PROPERTY_NAME, COMMAND_RETRY_MAX_TIME_IN_SEC_DEFAULT); + wasUpdated = true; + } + + if (wasUpdated) { + configTypesUpdated.add(CLUSTER_ENV_CONFIG_TYPE_NAME); } } @@ -2121,9 +2152,10 @@ public class BlueprintConfigurationProcessor { * @param property property name * @param defaultValue default value */ - private void ensureProperty(Configuration configuration, String type, String property, String defaultValue) { + private void ensureProperty(Configuration configuration, String type, String property, String defaultValue, Set<String> configTypesUpdated) { if (configuration.getPropertyValue(type, property) == null) { configuration.setProperty(type, property, defaultValue); + configTypesUpdated.add(type); } } http://git-wip-us.apache.org/repos/asf/ambari/blob/8388c7d0/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java index 42676aa..41b7717 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java @@ -342,6 +342,51 @@ public class AmbariContext { } } + /** + * Verifies that all desired configurations have reached the resolved state + * before proceeding with the install + * + * @param clusterName name of the cluster + * @param updatedConfigTypes set of config types that are required to be in the TOPOLOGY_RESOLVED state + * + * @throws AmbariException upon any system-level error that occurs + */ + public void waitForConfigurationResolution(String clusterName, Set<String> updatedConfigTypes) throws AmbariException { + Cluster cluster = getController().getClusters().getCluster(clusterName); + boolean shouldWaitForResolution = true; + while (shouldWaitForResolution) { + int numOfRequestsStillRequiringResolution = 0; + + // for all config types specified + for (String actualConfigType : updatedConfigTypes) { + // get the actual cluster config for comparison + DesiredConfig actualConfig = cluster.getDesiredConfigs().get(actualConfigType); + if (!actualConfig.getTag().equals(TopologyManager.TOPOLOGY_RESOLVED_TAG)) { + // if any expected config is not resolved, deployment must wait + LOG.info("Config type " + actualConfigType + " not resolved yet, Blueprint deployment will wait until configuration update is completed"); + numOfRequestsStillRequiringResolution++; + } else { + LOG.info("Config type " + actualConfigType + " is resolved in the cluster config."); + } + } + + if (numOfRequestsStillRequiringResolution == 0) { + // all configs are resolved, deployment can continue + LOG.info("All required configuration types are in the " + TopologyManager.TOPOLOGY_RESOLVED_TAG + " state. Blueprint deployment can now continue."); + shouldWaitForResolution = false; + } else { + LOG.info("Waiting for " + numOfRequestsStillRequiringResolution + " configuration types to be resolved before Blueprint deployment can continue"); + + try { + // sleep before checking the config again + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } + public boolean doesConfigurationWithTagExist(String clusterName, String tag) { boolean isTopologyResolved = false; try { http://git-wip-us.apache.org/repos/asf/ambari/blob/8388c7d0/ambari-server/src/main/java/org/apache/ambari/server/topology/ClusterConfigurationRequest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/ClusterConfigurationRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/ClusterConfigurationRequest.java index eb583fd..b9f2eb8 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/topology/ClusterConfigurationRequest.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/ClusterConfigurationRequest.java @@ -57,7 +57,7 @@ public class ClusterConfigurationRequest { // set initial configuration (not topology resolved) this.configurationProcessor = new BlueprintConfigurationProcessor(clusterTopology); if (setInitial) { - setConfigurationsOnCluster(clusterTopology, TopologyManager.INITIAL_CONFIG_TAG); + setConfigurationsOnCluster(clusterTopology, TopologyManager.INITIAL_CONFIG_TAG, Collections.<String>emptySet()); } } @@ -68,13 +68,16 @@ public class ClusterConfigurationRequest { public void process() throws AmbariException, ConfigurationTopologyException { // this will update the topo cluster config and all host group configs in the cluster topology + Set<String> updatedConfigTypes = Collections.emptySet(); try { - configurationProcessor.doUpdateForClusterCreate(); + updatedConfigTypes = + configurationProcessor.doUpdateForClusterCreate(); } catch (ConfigurationTopologyException e) { //log and continue to set configs on cluster to make progress LOG.error("An exception occurred while doing configuration topology update: " + e, e); } - setConfigurationsOnCluster(clusterTopology, TopologyManager.TOPOLOGY_RESOLVED_TAG); + + setConfigurationsOnCluster(clusterTopology, TopologyManager.TOPOLOGY_RESOLVED_TAG, updatedConfigTypes); } /** @@ -82,7 +85,7 @@ public class ClusterConfigurationRequest { * @param clusterTopology cluster topology * @param tag config tag */ - public void setConfigurationsOnCluster(ClusterTopology clusterTopology, String tag) { + public void setConfigurationsOnCluster(ClusterTopology clusterTopology, String tag, Set<String> updatedConfigTypes) { //todo: also handle setting of host group scoped configuration which is updated by config processor List<BlueprintServiceConfigRequest> configurationRequests = new LinkedList<BlueprintServiceConfigRequest>(); @@ -120,7 +123,7 @@ public class ClusterConfigurationRequest { globalConfigRequest.addConfigElement("cluster-env", clusterEnvProps,clusterEnvAttributes); configurationRequests.add(globalConfigRequest); - setConfigurationsOnCluster(configurationRequests, tag); + setConfigurationsOnCluster(configurationRequests, tag, updatedConfigTypes); } /** @@ -134,7 +137,7 @@ public class ClusterConfigurationRequest { * @param configurationRequests a list of requests to send to the AmbariManagementController. */ private void setConfigurationsOnCluster(List<BlueprintServiceConfigRequest> configurationRequests, - String tag) { + String tag, Set<String> updatedConfigTypes) { // iterate over services to deploy for (BlueprintServiceConfigRequest blueprintConfigRequest : configurationRequests) { ClusterRequest clusterRequest = null; @@ -198,6 +201,16 @@ public class ClusterConfigurationRequest { LOG.error("ClusterRequest should not be null for service = " + blueprintConfigRequest.getServiceName()); } } + + if (tag.equals(TopologyManager.TOPOLOGY_RESOLVED_TAG)) { + // if this is a request to resolve config, then wait until resolution is completed + try { + // wait until the cluster topology configuration is set/resolved + ambariContext.waitForConfigurationResolution(clusterTopology.getClusterName(), updatedConfigTypes); + } catch (AmbariException e) { + LOG.error("Error while attempting to wait for the cluster configuration to reach TOPOLOGY_RESOLVED state.", e); + } + } } /** http://git-wip-us.apache.org/repos/asf/ambari/blob/8388c7d0/ambari-server/src/main/java/org/apache/ambari/server/topology/HostRequest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/HostRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/HostRequest.java index 5d76f7a..afd7711 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/topology/HostRequest.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/HostRequest.java @@ -87,7 +87,7 @@ public class HostRequest implements Comparable<HostRequest> { this.topology = topology; createTasks(); - System.out.println("HostRequest: Created request for host: " + + LOG.info("HostRequest: Created request for host: " + (hostname == null ? "Host Assignment Pending" : hostname)); } @@ -120,7 +120,7 @@ public class HostRequest implements Comparable<HostRequest> { isOutstanding = hostname == null || !topology.getAmbariContext(). isHostRegisteredWithCluster(cluster, hostname); - System.out.println("HostRequest: Successfully recovered host request for host: " + + LOG.info("HostRequest: Successfully recovered host request for host: " + (hostname == null ? "Host Assignment Pending" : hostname)); } @@ -187,7 +187,7 @@ public class HostRequest implements Comparable<HostRequest> { HostGroup hostGroup = getHostGroup(); for (String component : hostGroup.getComponents()) { if (component == null || component.equals("AMBARI_SERVER")) { - System.out.printf("Skipping component %s when creating request\n", component); + LOG.info("Skipping component %s when creating request\n", component); continue; } @@ -469,7 +469,7 @@ public class HostRequest implements Comparable<HostRequest> { @Override public void run() { - System.out.println("HostRequest.InstallHostTask: Executing INSTALL task for host: " + hostname); + LOG.info("HostRequest.InstallHostTask: Executing INSTALL task for host: " + hostname); RequestStatusResponse response = clusterTopology.installHost(hostname); // map logical install tasks to physical install tasks List<ShortTaskStatus> underlyingTasks = response.getTasks(); @@ -489,6 +489,8 @@ public class HostRequest implements Comparable<HostRequest> { } } } + + LOG.info("HostRequest.InstallHostTask: Exiting INSTALL task for host: " + hostname); } } @@ -508,7 +510,7 @@ public class HostRequest implements Comparable<HostRequest> { @Override public void run() { - System.out.println("HostRequest.StartHostTask: Executing START task for host: " + hostname); + LOG.info("HostRequest.StartHostTask: Executing START task for host: " + hostname); RequestStatusResponse response = clusterTopology.startHost(hostname); // map logical install tasks to physical install tasks List<ShortTaskStatus> underlyingTasks = response.getTasks(); @@ -526,6 +528,8 @@ public class HostRequest implements Comparable<HostRequest> { } } } + + LOG.info("HostRequest.StartHostTask: Exiting START task for host: " + hostname); } } http://git-wip-us.apache.org/repos/asf/ambari/blob/8388c7d0/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessorTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessorTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessorTest.java index 7117b05..5f5e317 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessorTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessorTest.java @@ -1764,13 +1764,24 @@ public class BlueprintConfigurationProcessorTest { ClusterTopology topology = createClusterTopology(bp, clusterConfig, hostGroups); BlueprintConfigurationProcessor updater = new BlueprintConfigurationProcessor(topology); - updater.doUpdateForClusterCreate(); + Set<String> configTypesUpdated = + updater.doUpdateForClusterCreate(); + String updatedVal = properties.get("yarn-site").get("yarn.resourcemanager.hostname"); assertEquals("testhost", updatedVal); String updatedVal1 = properties.get("oozie-env").get("oozie_heapsize"); assertEquals("1024m", updatedVal1); String updatedVal2 = properties.get("oozie-env").get("oozie_permsize"); assertEquals("128m", updatedVal2); + + assertEquals("Incorrect number of config types updated", + 3, configTypesUpdated.size()); + assertTrue("Expected config type not updated", + configTypesUpdated.contains("oozie-env")); + assertTrue("Expected config type not updated", + configTypesUpdated.contains("yarn-site")); + assertTrue("Expected config type not updated", + configTypesUpdated.contains("cluster-env")); } @Test @@ -2190,7 +2201,8 @@ public class BlueprintConfigurationProcessorTest { BlueprintConfigurationProcessor updater = new BlueprintConfigurationProcessor(topology); - updater.doUpdateForClusterCreate(); + Set<String> updatedConfigTypes = + updater.doUpdateForClusterCreate(); // after update, verify that the retry properties for commands and installs are set as expected assertEquals("Incorrect number of properties added to cluster-env for retry", @@ -2201,6 +2213,12 @@ public class BlueprintConfigurationProcessorTest { "INSTALL,START", clusterEnvProperties.get("commands_to_retry")); assertEquals("command_retry_max_time_in_sec was not set to the expected default", "600", clusterEnvProperties.get("command_retry_max_time_in_sec")); + + assertEquals("Incorrect number of config types updated by this operation", + 1, updatedConfigTypes.size()); + + assertTrue("Expected type not included in the updated set", + updatedConfigTypes.contains("cluster-env")); } @Test @@ -2223,7 +2241,8 @@ public class BlueprintConfigurationProcessorTest { BlueprintConfigurationProcessor updater = new BlueprintConfigurationProcessor(topology); - updater.doUpdateForClusterCreate(); + Set<String> updatedConfigTypes = + updater.doUpdateForClusterCreate(); // after update, verify that the retry properties for commands and installs are set as expected // in this case, the customer-provided overrides should be honored, rather than the retry defaults @@ -2235,6 +2254,9 @@ public class BlueprintConfigurationProcessorTest { "TEST", clusterEnvProperties.get("commands_to_retry")); assertEquals("command_retry_max_time_in_sec was not set to the expected default", "1", clusterEnvProperties.get("command_retry_max_time_in_sec")); + + assertEquals("Incorrect number of config types updated", + 0, updatedConfigTypes.size()); } @Test @@ -4405,7 +4427,8 @@ public class BlueprintConfigurationProcessorTest { ClusterTopology topology = createClusterTopology(bp, clusterConfig, hostGroups); BlueprintConfigurationProcessor updater = new BlueprintConfigurationProcessor(topology); - updater.doUpdateForClusterCreate(); + Set<String> updatedConfigTypes = + updater.doUpdateForClusterCreate(); // verify that the expected hostname was substituted for the host group name in the config assertEquals("HTTPS address HA property not properly exported", @@ -4456,13 +4479,22 @@ public class BlueprintConfigurationProcessorTest { assertFalse("dfs.namenode.rpc-address should have been filtered out of this HA configuration", hdfsSiteProperties.containsKey("dfs.namenode.rpc-address")); + + // verify that correct configuration types were listed as updated in the returned set + assertEquals("Incorrect number of updated config types returned, set = " + updatedConfigTypes, + 3, updatedConfigTypes.size()); + assertTrue("Expected config type not found in updated set", + updatedConfigTypes.contains("cluster-env")); + assertTrue("Expected config type not found in updated set", + updatedConfigTypes.contains("hdfs-site")); + assertTrue("Expected config type not found in updated set", + updatedConfigTypes.contains("hadoop-env")); } @Test public void testDoUpdateForClusterWithNameNodeHANotEnabled() throws Exception { final String expectedHostName = "c6401.apache.ambari.org"; final String expectedHostNameTwo = "serverTwo"; - final String expectedPortNum = "808080"; final String expectedHostGroupName = "host_group_1"; Map<String, Map<String, String>> properties = new HashMap<String, Map<String, String>>(); @@ -4511,7 +4543,8 @@ public class BlueprintConfigurationProcessorTest { ClusterTopology topology = createClusterTopology(bp, clusterConfig, hostGroups); BlueprintConfigurationProcessor updater = new BlueprintConfigurationProcessor(topology); - updater.doUpdateForClusterCreate(); + Set<String> updatedConfigTypes = + updater.doUpdateForClusterCreate(); // verify that the non-HA properties are not filtered out in a non-HA cluster assertTrue("dfs.namenode.http-address should have been included in this HA configuration", @@ -4521,6 +4554,13 @@ public class BlueprintConfigurationProcessorTest { assertTrue("dfs.namenode.rpc-address should have been included in this HA configuration", hdfsSiteProperties.containsKey("dfs.namenode.rpc-address")); + // verify that correct configuration types were listed as updated in the returned set + assertEquals("Incorrect number of updated config types returned, set = " + updatedConfigTypes, + 2, updatedConfigTypes.size()); + assertTrue("Expected config type 'cluster-env' not found in updated set", + updatedConfigTypes.contains("cluster-env")); + assertTrue("Expected config type 'hdfs-site' not found in updated set", + updatedConfigTypes.contains("hdfs-site")); } @Test http://git-wip-us.apache.org/repos/asf/ambari/blob/8388c7d0/ambari-server/src/test/java/org/apache/ambari/server/topology/AmbariContextTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/topology/AmbariContextTest.java b/ambari-server/src/test/java/org/apache/ambari/server/topology/AmbariContextTest.java index 4ebf9a9..8c94f1e 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/topology/AmbariContextTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/topology/AmbariContextTest.java @@ -48,11 +48,13 @@ import org.apache.ambari.server.state.Cluster; import org.apache.ambari.server.state.Clusters; import org.apache.ambari.server.state.Config; import org.apache.ambari.server.state.ConfigHelper; +import org.apache.ambari.server.state.DesiredConfig; import org.apache.ambari.server.state.Host; import org.apache.ambari.server.state.Service; import org.apache.ambari.server.state.StackId; import org.apache.ambari.server.state.configgroup.ConfigGroup; import org.easymock.Capture; +import org.easymock.EasyMockSupport; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -381,4 +383,48 @@ public class AmbariContextTest { // test context.registerHostWithConfigGroup(HOST1, topology, HOST_GROUP_1); } + + @Test + public void testWaitForTopologyResolvedStateWithEmptyUpdatedSet() throws Exception { + replayAll(); + + // verify that wait returns successfully with empty updated list passed in + context.waitForConfigurationResolution(CLUSTER_NAME, Collections.<String>emptySet()); + } + + @Test + public void testWaitForTopologyResolvedStateWithRequiredUpdatedSet() throws Exception { + final String topologyResolvedState = "TOPOLOGY_RESOLVED"; + DesiredConfig testHdfsDesiredConfig = + new DesiredConfig(); + testHdfsDesiredConfig.setTag(topologyResolvedState); + DesiredConfig testCoreSiteDesiredConfig = + new DesiredConfig(); + testCoreSiteDesiredConfig.setTag(topologyResolvedState); + DesiredConfig testClusterEnvDesiredConfig = + new DesiredConfig(); + testClusterEnvDesiredConfig.setTag(topologyResolvedState); + + Map<String, DesiredConfig> testDesiredConfigs = + new HashMap<String, DesiredConfig>(); + testDesiredConfigs.put("hdfs-site", testHdfsDesiredConfig); + testDesiredConfigs.put("core-site", testCoreSiteDesiredConfig); + testDesiredConfigs.put("cluster-env", testClusterEnvDesiredConfig); + + expect(cluster.getDesiredConfigs()).andReturn(testDesiredConfigs).atLeastOnce(); + + replayAll(); + + Set<String> testUpdatedConfigTypes = + new HashSet<String>(); + testUpdatedConfigTypes.add("hdfs-site"); + testUpdatedConfigTypes.add("core-site"); + testUpdatedConfigTypes.add("cluster-env"); + + // verify that wait returns successfully with non-empty list + // with all configuration types tagged as "TOPOLOGY_RESOLVED" + context.waitForConfigurationResolution(CLUSTER_NAME, testUpdatedConfigTypes); + } + + }