You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by rn...@apache.org on 2015/04/21 03:30:33 UTC
ambari git commit: AMBARI-10487. Blueprint processor fails to handle
direct host names properly in HA Blueprints. (rnettleton)
Repository: ambari
Updated Branches:
refs/heads/trunk cf0169c91 -> c79bd1245
AMBARI-10487. Blueprint processor fails to handle direct host names properly in HA Blueprints. (rnettleton)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/c79bd124
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/c79bd124
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/c79bd124
Branch: refs/heads/trunk
Commit: c79bd1245bcbfd8de3d2710e529db843aee90a53
Parents: cf0169c
Author: Bob Nettleton <rn...@hortonworks.com>
Authored: Mon Apr 20 21:29:21 2015 -0400
Committer: Bob Nettleton <rn...@hortonworks.com>
Committed: Mon Apr 20 21:30:17 2015 -0400
----------------------------------------------------------------------
.../BlueprintConfigurationProcessor.java | 96 +++++-
.../BlueprintConfigurationProcessorTest.java | 331 +++++++++++++++++++
2 files changed, 419 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/c79bd124/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 8247c63..cec93bf 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
@@ -131,7 +131,7 @@ public class BlueprintConfigurationProcessor {
Map<String, String> typeMap = properties.get(type);
if (typeMap != null && typeMap.containsKey(propertyName)) {
typeMap.put(propertyName, updater.updateForClusterCreate(
- hostGroups, typeMap.get(propertyName), properties, stackDefinition));
+ hostGroups, propertyName, typeMap.get(propertyName), properties, stackDefinition));
}
}
}
@@ -322,6 +322,29 @@ public class BlueprintConfigurationProcessor {
/**
+ * Static convenience function to determine if Yarn ResourceManager HA is enabled
+ * @param configProperties configuration properties for this cluster
+ * @return true if Yarn ResourceManager HA is enabled
+ * false if Yarn ResourceManager HA is not enabled
+ */
+ static boolean isYarnResourceManagerHAEnabled(Map<String, Map<String, String>> configProperties) {
+ return configProperties.containsKey("yarn-site") && configProperties.get("yarn-site").containsKey("yarn.resourcemanager.ha.enabled")
+ && configProperties.get("yarn-site").get("yarn.resourcemanager.ha.enabled").equals("true");
+ }
+
+ /**
+ * Static convenience function to determine if Oozie HA is enabled
+ * @param configProperties configuration properties for this cluster
+ * @return true if Oozie HA is enabled
+ * false if Oozie HA is not enabled
+ */
+ static boolean isOozieServerHAEnabled(Map<String, Map<String, String>> configProperties) {
+ return configProperties.containsKey("oozie-site") && configProperties.get("oozie-site").containsKey("oozie.services.ext")
+ && configProperties.get("oozie-site").get("oozie.services.ext").contains("org.apache.oozie.service.ZKLocksService");
+ }
+
+
+ /**
* Convenience method to examine the current configuration, to determine
* if the hostname of the initial active namenode in an HA deployment has
* been included.
@@ -595,6 +618,7 @@ public class BlueprintConfigurationProcessor {
*
*
* @param hostGroups host groups
+ * @param propertyName name of property
* @param origValue original value of property
* @param properties all properties
* @param stackDefinition definition of stack used for this cluster
@@ -603,7 +627,7 @@ public class BlueprintConfigurationProcessor {
* @return new property value
*/
public String updateForClusterCreate(Map<String, ? extends HostGroup> hostGroups,
- String origValue, Map<String, Map<String, String>> properties, Stack stackDefinition
+ String propertyName, String origValue, Map<String, Map<String, String>> properties, Stack stackDefinition
);
}
@@ -631,6 +655,7 @@ public class BlueprintConfigurationProcessor {
*
*
* @param hostGroups host groups
+ * @param propertyName name of property
* @param origValue original value of property
* @param properties all properties
* @param stackDefinition stack used for cluster creation
@@ -639,6 +664,7 @@ public class BlueprintConfigurationProcessor {
*/
@Override
public String updateForClusterCreate(Map<String, ? extends HostGroup> hostGroups,
+ String propertyName,
String origValue,
Map<String, Map<String, String>> properties,
Stack stackDefinition) {
@@ -681,6 +707,12 @@ public class BlueprintConfigurationProcessor {
// reference must point to the logical nameservice, rather than an individual namenode
return origValue;
}
+
+ if (!origValue.contains("localhost")) {
+ // if this NameNode HA property is a FDQN, then simply return it
+ return origValue;
+ }
+
}
if (isNameNodeHAEnabled(properties) && isComponentSecondaryNameNode() && (matchingGroups.isEmpty())) {
@@ -689,7 +721,21 @@ public class BlueprintConfigurationProcessor {
return origValue;
}
- throw new IllegalArgumentException("Unable to update configuration property with topology information. " +
+ if (isYarnResourceManagerHAEnabled(properties) && isComponentResourceManager() && (matchingGroups.size() == 2)) {
+ if (!origValue.contains("localhost")) {
+ // if this Yarn property is a FQDN, then simply return it
+ return origValue;
+ }
+ }
+
+ if ((isOozieServerHAEnabled(properties)) && isComponentOozieServer() && (matchingGroups.size() > 1)) {
+ if (!origValue.contains("localhost")) {
+ // if this Oozie property is a FQDN, then simply return i
+ return origValue;
+ }
+ }
+
+ throw new IllegalArgumentException("Unable to update configuration property " + "'" + propertyName + "'"+ " with topology information. " +
"Component '" + component + "' is not mapped to any host group or is mapped to multiple groups.");
}
}
@@ -719,6 +765,28 @@ public class BlueprintConfigurationProcessor {
}
/**
+ * Utility method to determine if the component associated with this updater
+ * instance is a Yarn ResourceManager
+ *
+ * @return true if the component associated is a Yarn ResourceManager
+ * false if the component is not a Yarn ResourceManager
+ */
+ private boolean isComponentResourceManager() {
+ return component.equals("RESOURCEMANAGER");
+ }
+
+ /**
+ * Utility method to determine if the component associated with this updater
+ * instance is an Oozie Server
+ *
+ * @return true if the component associated is an Oozie Server
+ * false if the component is not an Oozie Server
+ */
+ private boolean isComponentOozieServer() {
+ return component.equals("OOZIE_SERVER");
+ }
+
+ /**
* Provides access to the name of the component associated
* with this updater instance.
*
@@ -747,9 +815,9 @@ public class BlueprintConfigurationProcessor {
}
@Override
- public String updateForClusterCreate(Map<String, ? extends HostGroup> hostGroups, String origValue, Map<String, Map<String, String>> properties, Stack stackDefinition) {
+ public String updateForClusterCreate(Map<String, ? extends HostGroup> hostGroups, String propertyName, String origValue, Map<String, Map<String, String>> properties, Stack stackDefinition) {
try {
- return super.updateForClusterCreate(hostGroups, origValue, properties, stackDefinition);
+ return super.updateForClusterCreate(hostGroups, propertyName, origValue, properties, stackDefinition);
} catch (IllegalArgumentException illegalArgumentException) {
// return the original value, since the optional component is not available in this cluster
return origValue;
@@ -803,11 +871,12 @@ public class BlueprintConfigurationProcessor {
*/
@Override
public String updateForClusterCreate(Map<String, ? extends HostGroup> hostGroups,
+ String propertyName,
String origValue, Map<String, Map<String, String>> properties,
Stack stackDefinition) {
if (isDatabaseManaged(properties)) {
- return super.updateForClusterCreate(hostGroups, origValue, properties, stackDefinition);
+ return super.updateForClusterCreate(hostGroups, propertyName, origValue, properties, stackDefinition);
} else {
return origValue;
}
@@ -871,6 +940,7 @@ public class BlueprintConfigurationProcessor {
*
*
* @param hostGroups host groups
+ *
* @param origValue original value of property
* @param properties all properties
* @param stackDefinition stack used for cluster creation
@@ -879,9 +949,16 @@ public class BlueprintConfigurationProcessor {
*/
@Override
public String updateForClusterCreate(Map<String, ? extends HostGroup> hostGroups,
+ String propertyName,
String origValue,
Map<String, Map<String, String>> properties,
Stack stackDefinition) {
+ if (!origValue.contains("%HOSTGROUP") &&
+ (!origValue.contains("localhost"))) {
+ // this property must contain FQDNs specified directly by the user
+ // of the Blueprint, so the processor should not attempt to update them
+ return origValue;
+ }
Collection<String> hostStrings = getHostStrings(hostGroups, origValue);
if (hostStrings.isEmpty()) {
@@ -964,6 +1041,7 @@ public class BlueprintConfigurationProcessor {
*/
@Override
public String updateForClusterCreate(Map<String, ? extends HostGroup> hostGroups,
+ String propertyName,
String origValue, Map<String,
Map<String, String>> properties,
Stack stackDefinition) {
@@ -999,11 +1077,12 @@ public class BlueprintConfigurationProcessor {
*/
@Override
public String updateForClusterCreate(Map<String, ? extends HostGroup> hostGroupMap,
+ String propertyName,
String origValue,
Map<String, Map<String, String>> properties,
Stack stackDefinition) {
- return doFormat(propertyUpdater.updateForClusterCreate(hostGroupMap, origValue, properties, stackDefinition));
+ return doFormat(propertyUpdater.updateForClusterCreate(hostGroupMap, propertyName, origValue, properties, stackDefinition));
}
/**
@@ -1063,7 +1142,8 @@ public class BlueprintConfigurationProcessor {
*/
private static class OriginalValuePropertyUpdater implements PropertyUpdater {
@Override
- public String updateForClusterCreate(Map<String, ? extends HostGroup> hostGroups, String origValue,
+ public String updateForClusterCreate(Map<String, ? extends HostGroup> hostGroups,
+ String propertyName, String origValue,
Map<String, Map<String, String>> properties,
Stack stackDefinition) {
// always return the original value, since these properties do not require update handling
http://git-wip-us.apache.org/repos/asf/ambari/blob/c79bd124/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 1839a5f..aa9fa00 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
@@ -1742,6 +1742,125 @@ public class BlueprintConfigurationProcessorTest {
}
@Test
+ public void testDoUpdateForClusterWithNameNodeHAEnabledSpecifyingHostNamesDirectly() throws Exception {
+ final String expectedNameService = "mynameservice";
+ final String expectedHostName = "c6401.apache.ambari.org";
+ final String expectedHostNameTwo = "serverTwo";
+ final String expectedPortNum = "808080";
+ final String expectedNodeOne = "nn1";
+ final String expectedNodeTwo = "nn2";
+ final String expectedHostGroupName = "host_group_1";
+
+ EasyMockSupport mockSupport = new EasyMockSupport();
+
+ HostGroup mockHostGroupOne = mockSupport.createMock(HostGroup.class);
+ HostGroup mockHostGroupTwo = mockSupport.createMock(HostGroup.class);
+
+ Stack mockStack = mockSupport.createMock(Stack.class);
+
+ expect(mockHostGroupOne.getHostInfo()).andReturn(Arrays.asList(expectedHostName)).atLeastOnce();
+ expect(mockHostGroupTwo.getHostInfo()).andReturn(Arrays.asList(expectedHostNameTwo)).atLeastOnce();
+ expect(mockHostGroupOne.getComponents()).andReturn(Collections.singleton("NAMENODE")).atLeastOnce();
+ expect(mockHostGroupTwo.getComponents()).andReturn(Collections.singleton("NAMENODE")).atLeastOnce();
+ expect(mockStack.getCardinality("NAMENODE")).andReturn(new Cardinality("1-2")).atLeastOnce();
+ expect(mockStack.getCardinality("SECONDARY_NAMENODE")).andReturn(new Cardinality("1")).atLeastOnce();
+
+ mockSupport.replayAll();
+
+ Map<String, Map<String, String>> configProperties =
+ new HashMap<String, Map<String, String>>();
+
+ Map<String, String> hdfsSiteProperties =
+ new HashMap<String, String>();
+ Map<String, String> hbaseSiteProperties =
+ new HashMap<String, String>();
+ Map<String, String> hadoopEnvProperties =
+ new HashMap<String, String>();
+ Map<String, String> coreSiteProperties =
+ new HashMap<String, String>();
+ Map<String, String> accumuloSiteProperties =
+ new HashMap<String, String>();
+
+
+ configProperties.put("hdfs-site", hdfsSiteProperties);
+ configProperties.put("hadoop-env", hadoopEnvProperties);
+ configProperties.put("core-site", coreSiteProperties);
+ configProperties.put("hbase-site", hbaseSiteProperties);
+ configProperties.put("accumulo-site", accumuloSiteProperties);
+
+ // setup hdfs HA config for test
+ hdfsSiteProperties.put("dfs.nameservices", expectedNameService);
+ hdfsSiteProperties.put("dfs.ha.namenodes.mynameservice", expectedNodeOne + ", " + expectedNodeTwo);
+
+
+ // setup properties that include exported host group information
+ hdfsSiteProperties.put("dfs.namenode.https-address." + expectedNameService + "." + expectedNodeOne, createHostAddress(expectedHostName, expectedPortNum));
+ hdfsSiteProperties.put("dfs.namenode.https-address." + expectedNameService + "." + expectedNodeTwo, createHostAddress(expectedHostNameTwo, expectedPortNum));
+ hdfsSiteProperties.put("dfs.namenode.http-address." + expectedNameService + "." + expectedNodeOne, createHostAddress(expectedHostName, expectedPortNum));
+ hdfsSiteProperties.put("dfs.namenode.http-address." + expectedNameService + "." + expectedNodeTwo, createHostAddress(expectedHostNameTwo, expectedPortNum));
+ hdfsSiteProperties.put("dfs.namenode.rpc-address." + expectedNameService + "." + expectedNodeOne, createHostAddress(expectedHostName, expectedPortNum));
+ hdfsSiteProperties.put("dfs.namenode.rpc-address." + expectedNameService + "." + expectedNodeTwo, createHostAddress(expectedHostNameTwo, expectedPortNum));
+
+ // add properties that require the SECONDARY_NAMENODE, which
+ // is not included in this test
+ hdfsSiteProperties.put("dfs.secondary.http.address", "localhost:8080");
+ hdfsSiteProperties.put("dfs.namenode.secondary.http-address", "localhost:8080");
+
+ // configure the defaultFS to use the nameservice URL
+ coreSiteProperties.put("fs.defaultFS", "hdfs://" + expectedNameService);
+
+ // configure the hbase rootdir to use the nameservice URL
+ hbaseSiteProperties.put("hbase.rootdir", "hdfs://" + expectedNameService + "/hbase/test/root/dir");
+
+ // configure the hbase rootdir to use the nameservice URL
+ accumuloSiteProperties.put("instance.volumes", "hdfs://" + expectedNameService + "/accumulo/test/instance/volumes");
+
+ BlueprintConfigurationProcessor configProcessor =
+ new BlueprintConfigurationProcessor(configProperties);
+
+ Map<String, HostGroup> mapOfHostGroups = new LinkedHashMap<String, HostGroup>();
+ mapOfHostGroups.put(expectedHostGroupName, mockHostGroupOne);
+ mapOfHostGroups.put("host-group-2", mockHostGroupTwo);
+
+ configProcessor.doUpdateForClusterCreate(mapOfHostGroups, mockStack);
+
+ // verify that the expected hostname was substituted for the host group name in the config
+ assertEquals("HTTPS address HA property not properly exported",
+ expectedHostName + ":" + expectedPortNum, hdfsSiteProperties.get("dfs.namenode.https-address." + expectedNameService + "." + expectedNodeOne));
+ assertEquals("HTTPS address HA property not properly exported",
+ expectedHostNameTwo + ":" + expectedPortNum, hdfsSiteProperties.get("dfs.namenode.https-address." + expectedNameService + "." + expectedNodeTwo));
+
+ assertEquals("HTTPS address HA property not properly exported",
+ expectedHostName + ":" + expectedPortNum, hdfsSiteProperties.get("dfs.namenode.http-address." + expectedNameService + "." + expectedNodeOne));
+ assertEquals("HTTPS address HA property not properly exported",
+ expectedHostNameTwo + ":" + expectedPortNum, hdfsSiteProperties.get("dfs.namenode.http-address." + expectedNameService + "." + expectedNodeTwo));
+
+ assertEquals("HTTPS address HA property not properly exported",
+ expectedHostName + ":" + expectedPortNum, hdfsSiteProperties.get("dfs.namenode.rpc-address." + expectedNameService + "." + expectedNodeOne));
+ assertEquals("HTTPS address HA property not properly exported",
+ expectedHostNameTwo + ":" + expectedPortNum, hdfsSiteProperties.get("dfs.namenode.rpc-address." + expectedNameService + "." + expectedNodeTwo));
+
+ // verify that the Blueprint config processor has set the internal required properties
+ // that determine the active and standby node hostnames for this HA setup
+ assertEquals("Active Namenode hostname was not set correctly",
+ expectedHostName, hadoopEnvProperties.get("dfs_ha_initial_namenode_active"));
+
+ assertEquals("Standby Namenode hostname was not set correctly",
+ expectedHostNameTwo, hadoopEnvProperties.get("dfs_ha_initial_namenode_standby"));
+
+ assertEquals("fs.defaultFS should not be modified by cluster update when NameNode HA is enabled.",
+ "hdfs://" + expectedNameService, coreSiteProperties.get("fs.defaultFS"));
+
+ assertEquals("hbase.rootdir should not be modified by cluster update when NameNode HA is enabled.",
+ "hdfs://" + expectedNameService + "/hbase/test/root/dir", hbaseSiteProperties.get("hbase.rootdir"));
+
+ assertEquals("instance.volumes should not be modified by cluster update when NameNode HA is enabled.",
+ "hdfs://" + expectedNameService + "/accumulo/test/instance/volumes", accumuloSiteProperties.get("instance.volumes"));
+
+ mockSupport.verifyAll();
+ }
+
+ @Test
public void testDoUpdateForClusterWithNameNodeHAEnabledAndActiveNodeSet() throws Exception {
final String expectedNameService = "mynameservice";
final String expectedHostName = "serverThree";
@@ -2240,6 +2359,90 @@ public class BlueprintConfigurationProcessorTest {
}
@Test
+ public void testYarnHighAvailabilityConfigClusterUpdateSpecifyingHostNamesDirectly() throws Exception {
+ final String expectedHostName = "c6401.apache.ambari.org";
+ final String expectedPortNum = "808080";
+ final String expectedHostGroupName = "host_group_1";
+ final String expectedHostGroupNameTwo = "host_group_2";
+
+ EasyMockSupport mockSupport = new EasyMockSupport();
+
+ HostGroup mockHostGroupOne = mockSupport.createMock(HostGroup.class);
+ HostGroup mockHostGroupTwo = mockSupport.createMock(HostGroup.class);
+
+ Stack mockStack = mockSupport.createMock(Stack.class);
+
+ Set<String> setOfComponents = new HashSet<String>();
+ setOfComponents.add("RESOURCEMANAGER");
+ setOfComponents.add("APP_TIMELINE_SERVER");
+ setOfComponents.add("HISTORYSERVER");
+ expect(mockHostGroupOne.getComponents()).andReturn(setOfComponents).atLeastOnce();
+ expect(mockHostGroupOne.getHostInfo()).andReturn(Collections.singleton(expectedHostName)).atLeastOnce();
+ expect(mockHostGroupTwo.getComponents()).andReturn(Collections.singleton("RESOURCEMANAGER")).atLeastOnce();
+
+ expect(mockStack.getCardinality("RESOURCEMANAGER")).andReturn(new Cardinality("1-2")).atLeastOnce();
+ //expect(mockStack.getCardinality("APP_TIMELINE_SERVER")).andReturn(new Cardinality("1")).atLeastOnce();
+ //expect(mockStack.getCardinality("HISTORYSERVER")).andReturn(new Cardinality("1")).atLeastOnce();
+
+ mockSupport.replayAll();
+
+ Map<String, Map<String, String>> configProperties =
+ new HashMap<String, Map<String, String>>();
+
+ Map<String, String> yarnSiteProperties =
+ new HashMap<String, String>();
+
+ configProperties.put("yarn-site", yarnSiteProperties);
+
+ // setup properties that include host information
+ yarnSiteProperties.put("yarn.log.server.url", "http://" + expectedHostName +":19888/jobhistory/logs");
+ yarnSiteProperties.put("yarn.resourcemanager.hostname", expectedHostName);
+ yarnSiteProperties.put("yarn.resourcemanager.resource-tracker.address", expectedHostName + ":" + expectedPortNum);
+ yarnSiteProperties.put("yarn.resourcemanager.webapp.address", expectedHostName + ":" + expectedPortNum);
+ yarnSiteProperties.put("yarn.resourcemanager.scheduler.address", expectedHostName + ":" + expectedPortNum);
+ yarnSiteProperties.put("yarn.resourcemanager.address", expectedHostName + ":" + expectedPortNum);
+ yarnSiteProperties.put("yarn.resourcemanager.admin.address", expectedHostName + ":" + expectedPortNum);
+ yarnSiteProperties.put("yarn.timeline-service.address", expectedHostName + ":" + expectedPortNum);
+ yarnSiteProperties.put("yarn.timeline-service.webapp.address", expectedHostName + ":" + expectedPortNum);
+ yarnSiteProperties.put("yarn.timeline-service.webapp.https.address", expectedHostName + ":" + expectedPortNum);
+ yarnSiteProperties.put("yarn.resourcemanager.ha.enabled", "true");
+
+ BlueprintConfigurationProcessor configProcessor =
+ new BlueprintConfigurationProcessor(configProperties);
+
+ Map<String, HostGroup> mapOfHostGroups = new HashMap<String, HostGroup>();
+ mapOfHostGroups.put(expectedHostGroupName, mockHostGroupOne);
+ mapOfHostGroups.put(expectedHostGroupNameTwo, mockHostGroupTwo);
+
+ configProcessor.doUpdateForClusterCreate(mapOfHostGroups, mockStack);
+
+ // verify that the properties with hostname information was correctly preserved
+ assertEquals("Yarn Log Server URL was incorrectly updated",
+ "http://" + expectedHostName +":19888/jobhistory/logs", yarnSiteProperties.get("yarn.log.server.url"));
+ assertEquals("Yarn ResourceManager hostname was incorrectly exported",
+ expectedHostName, yarnSiteProperties.get("yarn.resourcemanager.hostname"));
+ assertEquals("Yarn ResourceManager tracker address was incorrectly updated",
+ createHostAddress(expectedHostName, expectedPortNum), yarnSiteProperties.get("yarn.resourcemanager.resource-tracker.address"));
+ assertEquals("Yarn ResourceManager webapp address was incorrectly updated",
+ createHostAddress(expectedHostName, expectedPortNum), yarnSiteProperties.get("yarn.resourcemanager.webapp.address"));
+ assertEquals("Yarn ResourceManager scheduler address was incorrectly updated",
+ createHostAddress(expectedHostName, expectedPortNum), yarnSiteProperties.get("yarn.resourcemanager.scheduler.address"));
+ assertEquals("Yarn ResourceManager address was incorrectly updated",
+ createHostAddress(expectedHostName, expectedPortNum), yarnSiteProperties.get("yarn.resourcemanager.address"));
+ assertEquals("Yarn ResourceManager admin address was incorrectly updated",
+ createHostAddress(expectedHostName, expectedPortNum), yarnSiteProperties.get("yarn.resourcemanager.admin.address"));
+ assertEquals("Yarn ResourceManager timeline-service address was incorrectly updated",
+ createHostAddress(expectedHostName, expectedPortNum), yarnSiteProperties.get("yarn.timeline-service.address"));
+ assertEquals("Yarn ResourceManager timeline webapp address was incorrectly updated",
+ createHostAddress(expectedHostName, expectedPortNum), yarnSiteProperties.get("yarn.timeline-service.webapp.address"));
+ assertEquals("Yarn ResourceManager timeline webapp HTTPS address was incorrectly updated",
+ createHostAddress(expectedHostName, expectedPortNum), yarnSiteProperties.get("yarn.timeline-service.webapp.https.address"));
+
+ mockSupport.verifyAll();
+
+ }
+
+ @Test
public void testYarnConfigExportedWithDefaultZeroHostAddress() throws Exception {
final String expectedHostName = "c6401.apache.ambari.org";
final String expectedPortNum = "808080";
@@ -2443,6 +2646,56 @@ public class BlueprintConfigurationProcessorTest {
}
@Test
+ public void testHDFSConfigClusterUpdateQuorumJournalURLSpecifyingHostNamesDirectly() throws Exception {
+ final String expectedHostNameOne = "c6401.apache.ambari.org";
+ final String expectedHostNameTwo = "c6402.apache.ambari.org";
+ final String expectedPortNum = "808080";
+ final String expectedHostGroupName = "host_group_1";
+ final String expectedHostGroupNameTwo = "host_group_2";
+ final String expectedQuorumJournalURL = "qjournal://" + createHostAddress(expectedHostNameOne, expectedPortNum) + ";" +
+ createHostAddress(expectedHostNameTwo, expectedPortNum) + "/mycluster";
+
+ EasyMockSupport mockSupport = new EasyMockSupport();
+
+ HostGroup mockHostGroupOne = mockSupport.createMock(HostGroup.class);
+ HostGroup mockHostGroupTwo = mockSupport.createMock(HostGroup.class);
+
+ mockSupport.replayAll();
+
+ Map<String, Map<String, String>> configProperties =
+ new HashMap<String, Map<String, String>>();
+
+ Map<String, String> hdfsSiteProperties =
+ new HashMap<String, String>();
+
+ configProperties.put("hdfs-site", hdfsSiteProperties);
+
+ // setup properties that include host information
+ // setup shared edit property, that includes a qjournal URL scheme
+
+ hdfsSiteProperties.put("dfs.namenode.shared.edits.dir", expectedQuorumJournalURL);
+
+ BlueprintConfigurationProcessor configProcessor =
+ new BlueprintConfigurationProcessor(configProperties);
+
+ Map<String, HostGroup> mapOfHostGroups =
+ new HashMap<String, HostGroup>();
+ mapOfHostGroups.put(expectedHostGroupName, mockHostGroupOne);
+ mapOfHostGroups.put(expectedHostGroupNameTwo, mockHostGroupTwo);
+
+ // call top-level export method
+ configProcessor.doUpdateForClusterCreate(mapOfHostGroups, null);
+
+ // expect that all servers are included in configuration property without changes, and that the qjournal URL format is preserved
+ assertEquals("HDFS HA shared edits directory property should not have been modified, since FQDNs were specified.",
+ expectedQuorumJournalURL,
+ hdfsSiteProperties.get("dfs.namenode.shared.edits.dir"));
+
+ mockSupport.verifyAll();
+
+ }
+
+ @Test
public void testHDFSConfigClusterUpdateQuorumJournalURL_UsingMinusSymbolInHostName() throws Exception {
final String expectedHostNameOne = "c6401.apache.ambari.org";
final String expectedHostNameTwo = "c6402.apache.ambari.org";
@@ -2658,6 +2911,84 @@ public class BlueprintConfigurationProcessorTest {
}
@Test
+ public void testOozieConfigClusterUpdateHAEnabledSpecifyingHostNamesDirectly() throws Exception {
+ final String expectedHostName = "c6401.apache.ambari.org";
+ final String expectedHostNameTwo = "c6402.ambari.apache.org";
+ final String expectedExternalHost = "c6408.ambari.apache.org";
+ final String expectedHostGroupName = "host_group_1";
+ final String expectedHostGroupNameTwo = "host_group_2";
+
+ EasyMockSupport mockSupport = new EasyMockSupport();
+
+ HostGroup mockHostGroupOne = mockSupport.createMock(HostGroup.class);
+ HostGroup mockHostGroupTwo = mockSupport.createMock(HostGroup.class);
+
+ Stack mockStack = mockSupport.createMock(Stack.class);
+
+ expect(mockHostGroupOne.getComponents()).andReturn(Collections.singleton("OOZIE_SERVER")).atLeastOnce();
+ expect(mockHostGroupTwo.getComponents()).andReturn(Collections.singleton("OOZIE_SERVER")).atLeastOnce();
+
+ expect(mockStack.getCardinality("OOZIE_SERVER")).andReturn(new Cardinality("1+")).atLeastOnce();
+
+ mockSupport.replayAll();
+
+ Map<String, Map<String, String>> configProperties =
+ new HashMap<String, Map<String, String>>();
+
+ Map<String, String> oozieSiteProperties =
+ new HashMap<String, String>();
+ Map<String, String> oozieEnvProperties =
+ new HashMap<String, String>();
+ Map<String, String> coreSiteProperties =
+ new HashMap<String, String>();
+
+ configProperties.put("oozie-site", oozieSiteProperties);
+ configProperties.put("oozie-env", oozieEnvProperties);
+ configProperties.put("hive-env", oozieEnvProperties);
+ configProperties.put("core-site", coreSiteProperties);
+
+ oozieSiteProperties.put("oozie.base.url", expectedHostName);
+ oozieSiteProperties.put("oozie.authentication.kerberos.principal", expectedHostName);
+ oozieSiteProperties.put("oozie.service.HadoopAccessorService.kerberos.principal", expectedHostName);
+ oozieSiteProperties.put("oozie.service.JPAService.jdbc.url", "jdbc:mysql://" + expectedExternalHost + "/ooziedb");
+
+ // simulate the Oozie HA configuration
+ oozieSiteProperties.put("oozie.services.ext",
+ "org.apache.oozie.service.ZKLocksService,org.apache.oozie.service.ZKXLogStreamingService,org.apache.oozie.service.ZKJobsConcurrencyService,org.apache.oozie.service.ZKUUIDService");
+
+
+ oozieEnvProperties.put("oozie_hostname", expectedHostName);
+ oozieEnvProperties.put("oozie_existing_mysql_host", expectedExternalHost);
+
+ coreSiteProperties.put("hadoop.proxyuser.oozie.hosts", expectedHostName + "," + expectedHostNameTwo);
+
+ BlueprintConfigurationProcessor configProcessor =
+ new BlueprintConfigurationProcessor(configProperties);
+
+ Map<String, HostGroup> hostGroups =
+ new HashMap<String, HostGroup>();
+ hostGroups.put(expectedHostGroupName, mockHostGroupOne);
+ hostGroups.put(expectedHostGroupNameTwo, mockHostGroupTwo);
+
+ // call top-level update method
+ configProcessor.doUpdateForClusterCreate(hostGroups, mockStack);
+
+ assertEquals("oozie property not updated correctly",
+ expectedHostName, oozieSiteProperties.get("oozie.base.url"));
+ assertEquals("oozie property not updated correctly",
+ expectedHostName, oozieSiteProperties.get("oozie.authentication.kerberos.principal"));
+ assertEquals("oozie property not updated correctly",
+ expectedHostName, oozieSiteProperties.get("oozie.service.HadoopAccessorService.kerberos.principal"));
+ assertEquals("oozie property not updated correctly",
+ expectedHostName, oozieEnvProperties.get("oozie_hostname"));
+ assertEquals("oozie property not updated correctly",
+ expectedHostName + "," + expectedHostNameTwo, coreSiteProperties.get("hadoop.proxyuser.oozie.hosts"));
+
+ mockSupport.verifyAll();
+
+ }
+
+ @Test
public void testZookeeperConfigExported() throws Exception {
final String expectedHostName = "c6401.apache.ambari.org";
final String expectedHostNameTwo = "c6402.ambari.apache.org";