Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 83487200BF1 for ; Mon, 28 Nov 2016 22:16:17 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id 8230D160B00; Mon, 28 Nov 2016 21:16:17 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 7C5E8160B0D for ; Mon, 28 Nov 2016 22:16:16 +0100 (CET) Received: (qmail 50652 invoked by uid 500); 28 Nov 2016 21:15:53 -0000 Mailing-List: contact common-commits-help@hadoop.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Delivered-To: mailing list common-commits@hadoop.apache.org Received: (qmail 47931 invoked by uid 99); 28 Nov 2016 21:15:51 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 28 Nov 2016 21:15:51 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id B81CBEEF4B; Mon, 28 Nov 2016 21:15:51 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: jianhe@apache.org To: common-commits@hadoop.apache.org Date: Mon, 28 Nov 2016 21:16:47 -0000 Message-Id: <41229a2244eb4a27a12bd13c592c82d9@git.apache.org> In-Reply-To: <3022f5161bb4468c92a2825216e9111f@git.apache.org> References: <3022f5161bb4468c92a2825216e9111f@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [59/63] [abbrv] hadoop git commit: YARN-5701. Fix issues in yarn native services apps-of-apps. Contributed by Billie Rinaldi archived-at: Mon, 28 Nov 2016 21:16:17 -0000 YARN-5701. Fix issues in yarn native services apps-of-apps. Contributed by Billie Rinaldi Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/8a9aa8a1 Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/8a9aa8a1 Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/8a9aa8a1 Branch: refs/heads/yarn-native-services Commit: 8a9aa8a199c9cea9b06d63d418fc96d96406a11d Parents: 29b1f4e Author: Jian He Authored: Sun Oct 16 17:01:09 2016 -0700 Committer: Jian He Committed: Mon Nov 28 13:09:08 2016 -0800 ---------------------------------------------------------------------- .../org/apache/slider/client/SliderClient.java | 72 ++++++++-------- .../slider/core/buildutils/InstanceBuilder.java | 4 + .../apache/slider/providers/ProviderUtils.java | 62 ++++++++++++-- .../providers/docker/DockerClientProvider.java | 4 +- .../providers/docker/DockerProviderService.java | 87 ++++++++++++++++---- 5 files changed, 164 insertions(+), 65 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hadoop/blob/8a9aa8a1/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/client/SliderClient.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/client/SliderClient.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/client/SliderClient.java index 2840c4b..94e51e5 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/client/SliderClient.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/client/SliderClient.java @@ -178,6 +178,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.BufferedReader; +import java.io.Console; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; @@ -918,57 +919,56 @@ public class SliderClient extends AbstractSliderLaunchedService implements RunSe return; } - BufferedReader br = null; - try { - for (Entry> cred : tree.credentials.entrySet()) { - String provider = cred.getKey() - .replaceAll(Pattern.quote("${CLUSTER_NAME}"), clusterName) - .replaceAll(Pattern.quote("${CLUSTER}"), clusterName); - List aliases = cred.getValue(); - if (aliases == null || aliases.isEmpty()) { - continue; - } - Configuration c = new Configuration(conf); - c.set(CredentialProviderFactory.CREDENTIAL_PROVIDER_PATH, provider); - CredentialProvider credentialProvider = CredentialProviderFactory.getProviders(c).get(0); - Set existingAliases = new HashSet<>(credentialProvider.getAliases()); - for (String alias : aliases) { - if (existingAliases.contains(alias.toLowerCase(Locale.ENGLISH))) { - log.info("Credentials for " + alias + " found in " + provider); - } else { - if (br == null) { - br = new BufferedReader(new InputStreamReader(System.in)); - } - char[] pass = readPassword(alias, br); - credentialProvider.createCredentialEntry(alias, pass); - credentialProvider.flush(); - Arrays.fill(pass, ' '); + Console console = System.console(); + for (Entry> cred : tree.credentials.entrySet()) { + String provider = cred.getKey() + .replaceAll(Pattern.quote("${CLUSTER_NAME}"), clusterName) + .replaceAll(Pattern.quote("${CLUSTER}"), clusterName); + List aliases = cred.getValue(); + if (aliases == null || aliases.isEmpty()) { + continue; + } + Configuration c = new Configuration(conf); + c.set(CredentialProviderFactory.CREDENTIAL_PROVIDER_PATH, provider); + CredentialProvider credentialProvider = CredentialProviderFactory.getProviders(c).get(0); + Set existingAliases = new HashSet<>(credentialProvider.getAliases()); + for (String alias : aliases) { + if (existingAliases.contains(alias.toLowerCase(Locale.ENGLISH))) { + log.info("Credentials for " + alias + " found in " + provider); + } else { + if (console == null) { + throw new IOException("Unable to input password for " + alias + + " because System.console() is null; provider " + provider + + " must be populated manually"); } + char[] pass = readPassword(alias, console); + credentialProvider.createCredentialEntry(alias, pass); + credentialProvider.flush(); + Arrays.fill(pass, ' '); } } - } finally { - org.apache.hadoop.io.IOUtils.closeStream(br); } } private static char[] readOnePassword(String alias) throws IOException { - try(BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) { - return readPassword(alias, br); + Console console = System.console(); + if (console == null) { + throw new IOException("Unable to input password for " + alias + + " because System.console() is null"); } + return readPassword(alias, console); } - // using a normal reader instead of a secure one, - // because stdin is not hooked up to the command line - private static char[] readPassword(String alias, BufferedReader br) + private static char[] readPassword(String alias, Console console) throws IOException { char[] cred = null; boolean noMatch; do { - log.info(String.format("%s %s: ", PASSWORD_PROMPT, alias)); - char[] newPassword1 = br.readLine().toCharArray(); - log.info(String.format("%s %s again: ", PASSWORD_PROMPT, alias)); - char[] newPassword2 = br.readLine().toCharArray(); + console.printf("%s %s: \n", PASSWORD_PROMPT, alias); + char[] newPassword1 = console.readPassword(); + console.printf("%s %s again: \n", PASSWORD_PROMPT, alias); + char[] newPassword2 = console.readPassword(); noMatch = !Arrays.equals(newPassword1, newPassword2); if (noMatch) { if (newPassword1 != null) Arrays.fill(newPassword1, ' '); http://git-wip-us.apache.org/repos/asf/hadoop/blob/8a9aa8a1/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/core/buildutils/InstanceBuilder.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/core/buildutils/InstanceBuilder.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/core/buildutils/InstanceBuilder.java index 25c65fc..f0686af 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/core/buildutils/InstanceBuilder.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/core/buildutils/InstanceBuilder.java @@ -439,6 +439,10 @@ public class InstanceBuilder { } log.info("External appdefs after {}: {}", component, externalAppDefs); + SliderUtils.mergeMapsIgnoreDuplicateKeys( + appConf.getConfTree().credentials, + componentAppConf.getConfTree().credentials); + mergeExternalComponent(appConf, componentAppConf, component, null); mergeExternalComponent(resources, componentConf.getResourceOperations(), component, getNextPriority()); http://git-wip-us.apache.org/repos/asf/hadoop/blob/8a9aa8a1/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/providers/ProviderUtils.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/providers/ProviderUtils.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/providers/ProviderUtils.java index 47556f0..c5e6782 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/providers/ProviderUtils.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/providers/ProviderUtils.java @@ -308,6 +308,7 @@ public class ProviderUtils implements RoleKeys, SliderKeys { public Map filterSiteOptions(Map options, Map tokenMap) { String prefix = OptionKeys.SITE_XML_PREFIX; + String format = "${%s}"; Map filteredOptions = new HashMap<>(); for (Map.Entry entry : options.entrySet()) { String key = entry.getKey(); @@ -319,7 +320,7 @@ public class ProviderUtils implements RoleKeys, SliderKeys { token.getValue()); } } - filteredOptions.put(key, value); + filteredOptions.put(String.format(format, key), value); } } return filteredOptions; @@ -545,9 +546,14 @@ public class ProviderUtils implements RoleKeys, SliderKeys { * @param clusterName app name * @throws IOException file cannot be created */ - private void createConfigFile(SliderFileSystem fileSystem, File file, - ConfigFormat configFormat, String configFileDN, + private synchronized void createConfigFile(SliderFileSystem fileSystem, + File file, ConfigFormat configFormat, String configFileDN, Map config, String clusterName) throws IOException { + if (file.exists()) { + log.info("Skipping writing {} file {} because it already exists", + configFormat, file); + return; + } log.info("Writing {} file {}", configFormat, file); ConfigUtils.prepConfigForTemplateOutputter(configFormat, config, @@ -643,11 +649,10 @@ public class ProviderUtils implements RoleKeys, SliderKeys { String fileName = ConfigUtils.replaceProps(config, configFileName); File localFile = new File(RESOURCE_DIR); if (!localFile.exists()) { - if (!localFile.mkdir()) { + if (!localFile.mkdir() && !localFile.exists()) { throw new IOException(RESOURCE_DIR + " could not be created!"); } } - localFile = new File(localFile, new File(fileName).getName()); String folder = null; if ("true".equals(config.get(PER_COMPONENT))) { @@ -655,12 +660,25 @@ public class ProviderUtils implements RoleKeys, SliderKeys { } else if ("true".equals(config.get(PER_GROUP))) { folder = roleGroup; } + if (folder != null) { + localFile = new File(localFile, folder); + if (!localFile.exists()) { + if (!localFile.mkdir() && !localFile.exists()) { + throw new IOException(localFile + " could not be created!"); + } + } + } + localFile = new File(localFile, new File(fileName).getName()); log.info("Localizing {} configs to config file {} (destination {}) " + "based on {} configs", config.size(), localFile, fileName, configFileDN); - createConfigFile(fileSystem, localFile, configFormat, configFileDN, config, - clusterName); + if (!localFile.exists()) { + createConfigFile(fileSystem, localFile, configFormat, configFileDN, + config, clusterName); + } else { + log.info("Local {} file {} already exists", configFormat, localFile); + } Path destPath = uploadResource(localFile, fileSystem, folder, clusterName); LocalResource configResource = fileSystem.createAmResource(destPath, LocalResourceType.FILE); @@ -807,12 +825,12 @@ public class ProviderUtils implements RoleKeys, SliderKeys { */ public Map> buildConfigurations( ConfTreeOperations appConf, ConfTreeOperations internalsConf, - String containerId, String roleName, String roleGroup, + String containerId, String clusterName, String roleName, String roleGroup, StateAccessForProviders amState) { Map> configurations = new TreeMap<>(); Map tokens = getStandardTokenMap(appConf, - internalsConf, roleName, roleGroup, containerId); + internalsConf, roleName, roleGroup, containerId, clusterName); Set configs = new HashSet<>(); configs.addAll(getApplicationConfigurationTypes(roleGroup, appConf)); @@ -1164,6 +1182,32 @@ public class ProviderUtils implements RoleKeys, SliderKeys { } /** + * Return a list of hostnames based on current ClusterNodes. + * @param values cluster nodes + * @return list of hosts + */ + public Iterable getHostNamesList(Collection values) { + List hosts = new ArrayList<>(); + for (ClusterNode cn : values) { + hosts.add(cn.hostname); + } + return hosts; + } + + /** + * Return a list of IPs based on current ClusterNodes. + * @param values cluster nodes + * @return list of hosts + */ + public Iterable getIPsList(Collection values) { + List hosts = new ArrayList<>(); + for (ClusterNode cn : values) { + hosts.add(cn.ip); + } + return hosts; + } + + /** * Update ServiceRecord in Registry with IP and hostname. * @param amState access to AM state * @param yarnRegistry acces to YARN registry http://git-wip-us.apache.org/repos/asf/hadoop/blob/8a9aa8a1/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/providers/docker/DockerClientProvider.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/providers/docker/DockerClientProvider.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/providers/docker/DockerClientProvider.java index 13473e5..d554427 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/providers/docker/DockerClientProvider.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/providers/docker/DockerClientProvider.java @@ -82,8 +82,8 @@ public class DockerClientProvider extends AbstractClientProvider if (appConf.getComponentOptBool(roleGroup, AM_CONFIG_GENERATION, false)) { // build and localize configuration files Map> configurations = - providerUtils.buildConfigurations(appConf, appConf, null, roleGroup, - roleGroup, null); + providerUtils.buildConfigurations(appConf, appConf, null, + null, roleGroup, roleGroup, null); try { providerUtils.localizeConfigFiles(null, roleGroup, roleGroup, appConf, configurations, null, fs, null); http://git-wip-us.apache.org/repos/asf/hadoop/blob/8a9aa8a1/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/providers/docker/DockerProviderService.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/providers/docker/DockerProviderService.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/providers/docker/DockerProviderService.java index bebb5f0..af36620 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/providers/docker/DockerProviderService.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/providers/docker/DockerProviderService.java @@ -41,6 +41,7 @@ import org.apache.slider.core.registry.docstore.ConfigFormat; import org.apache.slider.core.registry.docstore.ConfigUtils; import org.apache.slider.core.registry.docstore.ExportEntry; import org.apache.slider.providers.AbstractProviderService; +import org.apache.slider.providers.MonitorDetail; import org.apache.slider.providers.ProviderCore; import org.apache.slider.providers.ProviderRole; import org.apache.slider.providers.ProviderUtils; @@ -62,6 +63,9 @@ import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.Scanner; +import java.util.regex.Pattern; + +import static org.apache.slider.api.RoleKeys.ROLE_PREFIX; public class DockerProviderService extends AbstractProviderService implements ProviderCore, @@ -130,10 +134,13 @@ public class DockerProviderService extends AbstractProviderService implements DOCKER_USE_PRIVILEGED, false)); // Set the environment - launcher.putEnv(SliderUtils.buildEnvMap(appComponent, - providerUtils.getStandardTokenMap(getAmState().getAppConfSnapshot(), - getAmState().getInternalsSnapshot(), roleName, roleGroup, - getClusterName()))); + Map standardTokens = providerUtils.getStandardTokenMap( + getAmState().getAppConfSnapshot(), getAmState().getInternalsSnapshot(), + roleName, roleGroup, container.getId().toString(), getClusterName()); + Map replaceTokens = providerUtils.filterSiteOptions( + appConf.getComponent(roleGroup).options, standardTokens); + replaceTokens.putAll(standardTokens); + launcher.putEnv(SliderUtils.buildEnvMap(appComponent, replaceTokens)); String workDir = ApplicationConstants.Environment.PWD.$(); launcher.setEnv("WORK_DIR", workDir); @@ -169,8 +176,8 @@ public class DockerProviderService extends AbstractProviderService implements providerUtils.buildConfigurations( instanceDefinition.getAppConfOperations(), instanceDefinition.getInternalOperations(), - container.getId().toString(), roleName, roleGroup, - getAmState()); + container.getId().toString(), getClusterName(), + roleName, roleGroup, getAmState()); providerUtils.localizeConfigFiles(launcher, roleName, roleGroup, appConf, configurations, launcher.getEnv(), fileSystem, getClusterName()); @@ -251,8 +258,8 @@ public class DockerProviderService extends AbstractProviderService implements // build and localize configuration files Map> configurations = providerUtils.buildConfigurations(appConf, getAmState() - .getInternalsSnapshot(), null, clientName, clientName, - getAmState()); + .getInternalsSnapshot(), null, getClusterName(), clientName, + clientName, getAmState()); for (String configFileDN : configurations.keySet()) { String configFileName = appConf.getComponentOpt(clientName, @@ -316,19 +323,45 @@ public class DockerProviderService extends AbstractProviderService implements getAmState().getAppConfSnapshot(), roleGroup); String hostKeyFormat = "${%s_HOST}"; + String hostNameKeyFormat = "${%s_HOSTNAME}"; + String ipKeyFormat = "${%s_IP}"; // publish export groups if any - Map replaceTokens = - providerUtils.filterSiteOptions( - appConf.getComponent(roleGroup).options, - providerUtils.getStandardTokenMap(appConf, internalsConf, roleName, - roleGroup, containerId, getClusterName())); + Map standardTokens = providerUtils.getStandardTokenMap( + appConf, internalsConf, roleName, roleGroup, containerId, + getClusterName()); + Map replaceTokens = providerUtils.filterSiteOptions( + appConf.getComponent(roleGroup).options, standardTokens); + replaceTokens.putAll(standardTokens); + + String rolePrefix = appConf.getComponentOpt(roleGroup, ROLE_PREFIX, ""); for (Map.Entry> entry : getAmState().getRoleClusterNodeMapping().entrySet()) { - String hostName = providerUtils.getHostsList( + String otherRolePrefix = appConf.getComponentOpt(entry.getKey(), + ROLE_PREFIX, ""); + if (!otherRolePrefix.equals(rolePrefix)) { + // hostname replacements are only made within role prefix groups + continue; + } + String key = entry.getKey(); + if (!rolePrefix.isEmpty()) { + if (!key.startsWith(rolePrefix)) { + log.warn("Something went wrong, {} doesn't start with {}", key, + rolePrefix); + continue; + } + key = key.substring(rolePrefix.length()); + } + key = key.toUpperCase(Locale.ENGLISH); + String host = providerUtils.getHostsList( entry.getValue().values(), true).iterator().next(); - replaceTokens.put(String.format(hostKeyFormat, - entry.getKey().toUpperCase(Locale.ENGLISH)), hostName); + replaceTokens.put(String.format(hostKeyFormat, key), host); + String hostName = providerUtils.getHostNamesList( + entry.getValue().values()).iterator().next(); + replaceTokens.put(String.format(hostNameKeyFormat, key), hostName); + String ip = providerUtils.getIPsList( + entry.getValue().values()).iterator().next(); + replaceTokens.put(String.format(ipKeyFormat, key), ip); } replaceTokens.put("${THIS_HOST}", thisHost); @@ -338,7 +371,7 @@ public class DockerProviderService extends AbstractProviderService implements // replace host names and site properties for (String token : replaceTokens.keySet()) { if (value.contains(token)) { - value = value.replace(token, replaceTokens.get(token)); + value = value.replaceAll(Pattern.quote(token), replaceTokens.get(token)); } } ExportEntry entry = new ExportEntry(); @@ -350,6 +383,24 @@ public class DockerProviderService extends AbstractProviderService implements log.info("Preparing to publish. Key {} and Value {}", export.getKey(), value); } - providerUtils.publishExportGroup(entries, getAmState(), EXPORT_GROUP); + if (!entries.isEmpty()) { + providerUtils.publishExportGroup(entries, getAmState(), EXPORT_GROUP); + } + } + + @Override + public Map buildMonitorDetails(ClusterDescription clusterDesc) { + Map details = super.buildMonitorDetails(clusterDesc); + buildRoleHostDetails(details); + return details; + } + + private void buildRoleHostDetails(Map details) { + for (Map.Entry> entry : + getAmState().getRoleClusterNodeMapping().entrySet()) { + details.put(entry.getKey() + " Host(s)/Container(s)", + new MonitorDetail(providerUtils.getHostsList( + entry.getValue().values(), false).toString(), false)); + } } } --------------------------------------------------------------------- To unsubscribe, e-mail: common-commits-unsubscribe@hadoop.apache.org For additional commands, e-mail: common-commits-help@hadoop.apache.org