You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by sm...@apache.org on 2014/05/27 07:27:12 UTC
git commit: AMBARI-5896. Provide JMX values in Slider Apps /apps/id
endpoint
Repository: ambari
Updated Branches:
refs/heads/trunk 7d5fc0242 -> 52806bd7f
AMBARI-5896. Provide JMX values in Slider Apps /apps/id endpoint
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/52806bd7
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/52806bd7
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/52806bd7
Branch: refs/heads/trunk
Commit: 52806bd7fdb392f6e84645ec9e62238a6bffaa05
Parents: 7d5fc02
Author: Sumit Mohanty <sm...@hortonworks.com>
Authored: Mon May 26 17:42:24 2014 -0700
Committer: Sumit Mohanty <sm...@hortonworks.com>
Committed: Mon May 26 17:42:24 2014 -0700
----------------------------------------------------------------------
.../ambari/view/slider/SliderAppType.java | 153 +--
.../slider/SliderAppsViewControllerImpl.java | 1060 +++++++++---------
.../ambari/view/slider/rest/client/Metric.java | 120 ++
.../rest/client/SliderAppMasterClient.java | 385 ++++---
.../rest/client/SliderAppMasterClientTest.java | 96 ++
5 files changed, 1113 insertions(+), 701 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/52806bd7/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppType.java
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppType.java b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppType.java
index 7c52190..528c1fe 100644
--- a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppType.java
+++ b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppType.java
@@ -18,72 +18,99 @@
package org.apache.ambari.view.slider;
+import org.apache.ambari.view.slider.rest.client.Metric;
+import org.codehaus.jackson.annotate.JsonIgnore;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+
import java.util.List;
import java.util.Map;
+@JsonIgnoreProperties({ "jmxMetrics", "gangliaMetrics" })
public class SliderAppType {
- private String id;
- private String typeName;
- private String typeVersion;
- private String typeDescription;
- private Map<String, String> typeConfigs;
- private List<SliderAppTypeComponent> typeComponents;
- private String typePackageFileName;
-
- public String getId() {
- return id;
- }
-
- public void setId(String id) {
- this.id = id;
- }
-
- public String getTypeName() {
- return typeName;
- }
-
- public void setTypeName(String name) {
- this.typeName = name;
- }
-
- public String getTypeDescription() {
- return typeDescription;
- }
-
- public void setTypeDescription(String description) {
- this.typeDescription = description;
- }
-
- public Map<String, String> getTypeConfigs() {
- return typeConfigs;
- }
-
- public void setTypeConfigs(Map<String, String> configs) {
- this.typeConfigs = configs;
- }
-
- public List<SliderAppTypeComponent> getTypeComponents() {
- return typeComponents;
- }
-
- public void setTypeComponents(List<SliderAppTypeComponent> components) {
- this.typeComponents = components;
- }
-
- public String getTypeVersion() {
- return typeVersion;
- }
-
- public void setTypeVersion(String version) {
- this.typeVersion = version;
- }
-
- public String getTypePackageFileName() {
- return typePackageFileName;
- }
-
- public void setTypePackageFileName(String typePackageFileName) {
- this.typePackageFileName = typePackageFileName;
- }
+ private String id;
+ private String typeName;
+ private String typeVersion;
+ private String typeDescription;
+ private Map<String, String> typeConfigs;
+ private List<SliderAppTypeComponent> typeComponents;
+ private String typePackageFileName;
+ @JsonIgnore
+ private Map<String, Map<String, Map<String, Metric>>> jmxMetrics;
+ @JsonIgnore
+ private Map<String, Map<String, Map<String, Metric>>> gangliaMetrics;
+
+ @JsonIgnore
+ public Map<String, Map<String, Map<String, Metric>>> getJmxMetrics() {
+ return jmxMetrics;
+ }
+
+ public void setJmxMetrics(Map<String, Map<String, Map<String, Metric>>> jmxMetrics) {
+ this.jmxMetrics = jmxMetrics;
+ }
+
+ @JsonIgnore
+ public Map<String, Map<String, Map<String, Metric>>> getGangliaMetrics() {
+ return gangliaMetrics;
+ }
+
+ public void setGangliaMetrics(Map<String, Map<String, Map<String, Metric>>> gangliaMetrics) {
+ this.gangliaMetrics = gangliaMetrics;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getTypeName() {
+ return typeName;
+ }
+
+ public void setTypeName(String name) {
+ this.typeName = name;
+ }
+
+ public String getTypeDescription() {
+ return typeDescription;
+ }
+
+ public void setTypeDescription(String description) {
+ this.typeDescription = description;
+ }
+
+ public Map<String, String> getTypeConfigs() {
+ return typeConfigs;
+ }
+
+ public void setTypeConfigs(Map<String, String> configs) {
+ this.typeConfigs = configs;
+ }
+
+ public List<SliderAppTypeComponent> getTypeComponents() {
+ return typeComponents;
+ }
+
+ public void setTypeComponents(List<SliderAppTypeComponent> components) {
+ this.typeComponents = components;
+ }
+
+ public String getTypeVersion() {
+ return typeVersion;
+ }
+
+ public void setTypeVersion(String version) {
+ this.typeVersion = version;
+ }
+
+ public String getTypePackageFileName() {
+ return typePackageFileName;
+ }
+
+ public void setTypePackageFileName(String typePackageFileName) {
+ this.typePackageFileName = typePackageFileName;
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/52806bd7/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewControllerImpl.java
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewControllerImpl.java b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewControllerImpl.java
index 774bf76..c67e9ce 100644
--- a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewControllerImpl.java
+++ b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewControllerImpl.java
@@ -18,19 +18,11 @@
package org.apache.ambari.view.slider;
-import java.io.File;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.zip.ZipException;
-
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
import org.apache.ambari.view.ViewContext;
import org.apache.ambari.view.slider.clients.AmbariClient;
import org.apache.ambari.view.slider.clients.AmbariCluster;
@@ -38,6 +30,7 @@ import org.apache.ambari.view.slider.clients.AmbariClusterInfo;
import org.apache.ambari.view.slider.clients.AmbariHostComponent;
import org.apache.ambari.view.slider.clients.AmbariService;
import org.apache.ambari.view.slider.clients.AmbariServiceInfo;
+import org.apache.ambari.view.slider.rest.client.Metric;
import org.apache.ambari.view.slider.rest.client.SliderAppMasterClient;
import org.apache.ambari.view.slider.rest.client.SliderAppMasterClient.SliderAppMasterData;
import org.apache.commons.io.IOUtils;
@@ -63,522 +56,575 @@ import org.apache.slider.providers.agent.application.metadata.Metainfo;
import org.apache.slider.providers.agent.application.metadata.MetainfoParser;
import org.apache.slider.providers.agent.application.metadata.Service;
import org.apache.tools.zip.ZipFile;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.type.TypeReference;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.zip.ZipException;
@Singleton
public class SliderAppsViewControllerImpl implements SliderAppsViewController {
- private static final Logger logger = Logger
- .getLogger(SliderAppsViewControllerImpl.class);
- @Inject
- private ViewContext viewContext;
- @Inject
- private AmbariClient ambariClient;
- private List<SliderAppType> appTypes;
+ private static final Logger logger = Logger
+ .getLogger(SliderAppsViewControllerImpl.class);
+ @Inject
+ private ViewContext viewContext;
+ @Inject
+ private AmbariClient ambariClient;
+ private List<SliderAppType> appTypes;
+
+ private String getAppsFolderPath() {
+ return viewContext
+ .getAmbariProperty(org.apache.ambari.server.configuration.Configuration.RESOURCES_DIR_KEY)
+ + "/apps";
+ }
+
+ @Override
+ public ViewStatus getViewStatus() {
+ ViewStatus status = new ViewStatus();
+ List<String> viewErrors = new ArrayList<String>();
+
+ AmbariClusterInfo clusterInfo = ambariClient.getClusterInfo();
+ if (clusterInfo != null) {
+ AmbariCluster cluster = ambariClient.getCluster(clusterInfo);
+ List<AmbariServiceInfo> services = cluster.getServices();
+ if (services != null && !services.isEmpty()) {
+ AmbariServiceInfo hdfsService = null, yarnService = null, zkService = null;
+ for (AmbariServiceInfo service : services) {
+ if ("HDFS".equals(service.getId())) {
+ hdfsService = service;
+ } else if ("YARN".equals(service.getId())) {
+ yarnService = service;
+ } else if ("ZOOKEEPER".equals(service.getId())) {
+ zkService = service;
+ }
+ }
+ if (hdfsService == null) {
+ viewErrors.add("Slider applications view requires HDFS service");
+ } else {
+ if (!hdfsService.isStarted()) {
+ viewErrors
+ .add("Slider applications view requires HDFS service to be started");
+ }
+ }
+ if (yarnService == null) {
+ viewErrors.add("Slider applications view requires YARN service");
+ } else {
+ if (!yarnService.isStarted()) {
+ viewErrors
+ .add("Slider applications view requires YARN service to be started");
+ }
+ }
+ if (zkService == null) {
+ viewErrors.add("Slider applications view requires ZooKeeper service");
+ } else {
+ if (!zkService.isStarted()) {
+ viewErrors
+ .add("Slider applications view requires ZooKeeper service to be started");
+ }
+ }
+ } else {
+ viewErrors
+ .add("Slider applications view is unable to locate any services");
+ }
+ // Check security
+ if (cluster.getDesiredConfigs() != null
+ && cluster.getDesiredConfigs().containsKey("global")) {
+ Map<String, String> globalConfig = ambariClient.getConfiguration(
+ clusterInfo, "global", cluster.getDesiredConfigs().get("global"));
+ if (globalConfig != null
+ && globalConfig.containsKey("security_enabled")) {
+ String securityValue = globalConfig.get("security_enabled");
+ if (Boolean.valueOf(securityValue)) {
+ viewErrors
+ .add("Slider applications view cannot be rendered in secure mode");
+ }
+ } else {
+ viewErrors
+ .add("Slider applications view is unable to determine the security status of the cluster");
+ }
+ } else {
+ viewErrors
+ .add("Slider applications view is unable to determine the security status of the cluster");
+ }
+ } else {
+ viewErrors.add("Slider applications view requires a cluster");
+ }
+ status.setVersion(SliderAppsConfiguration.INSTANCE.getVersion());
+ status.setViewEnabled(viewErrors.size() < 1);
+ status.setViewErrors(viewErrors);
+ return status;
+ }
+
+ private AmbariCluster getAmbariCluster() {
+ AmbariClusterInfo clusterInfo = ambariClient.getClusterInfo();
+ if (clusterInfo != null) {
+ return ambariClient.getCluster(clusterInfo);
+ }
+ return null;
+ }
+
+ @Override
+ public SliderApp getSliderApp(String applicationId, Set<String> properties)
+ throws YarnException, IOException {
+ if (applicationId != null) {
+ int index = applicationId.indexOf('_');
+ if (index > -1 && index < applicationId.length() - 1) {
+ ApplicationId appId = ApplicationId.newInstance(
+ Long.parseLong(applicationId.substring(0, index)),
+ Integer.parseInt(applicationId.substring(index + 1)));
+ ClassLoader currentClassLoader = Thread.currentThread()
+ .getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(
+ getClass().getClassLoader());
+ try {
+ SliderClient sliderClient = getSliderClient();
+ ApplicationReport yarnApp = sliderClient.getApplicationReport(appId);
+ return createSliderAppObject(yarnApp, properties, sliderClient);
+ } finally {
+ Thread.currentThread().setContextClassLoader(currentClassLoader);
+ }
+ }
+ }
+ return null;
+ }
- private String getAppsFolderPath() {
- return viewContext
- .getAmbariProperty(org.apache.ambari.server.configuration.Configuration.RESOURCES_DIR_KEY)
- + "/apps";
- }
+ private SliderApp createSliderAppObject(ApplicationReport yarnApp,
+ Set<String> properties, SliderClient sliderClient) {
+ if (yarnApp == null) {
+ return null;
+ }
- @Override
- public ViewStatus getViewStatus() {
- ViewStatus status = new ViewStatus();
- List<String> viewErrors = new ArrayList<String>();
+ SliderApp app = new SliderApp();
+ app.setState(yarnApp.getYarnApplicationState().name());
- AmbariClusterInfo clusterInfo = ambariClient.getClusterInfo();
- if (clusterInfo != null) {
- AmbariCluster cluster = ambariClient.getCluster(clusterInfo);
- List<AmbariServiceInfo> services = cluster.getServices();
- if (services != null && !services.isEmpty()) {
- AmbariServiceInfo hdfsService = null, yarnService = null, zkService = null;
- for (AmbariServiceInfo service : services) {
- if ("HDFS".equals(service.getId())) {
- hdfsService = service;
- } else if ("YARN".equals(service.getId())) {
- yarnService = service;
- } else if ("ZOOKEEPER".equals(service.getId())) {
- zkService = service;
- }
- }
- if (hdfsService == null) {
- viewErrors.add("Slider applications view requires HDFS service");
- } else {
- if (!hdfsService.isStarted()) {
- viewErrors
- .add("Slider applications view requires HDFS service to be started");
- }
- }
- if (yarnService == null) {
- viewErrors.add("Slider applications view requires YARN service");
- } else {
- if (!yarnService.isStarted()) {
- viewErrors
- .add("Slider applications view requires YARN service to be started");
- }
- }
- if (zkService == null) {
- viewErrors.add("Slider applications view requires ZooKeeper service");
- } else {
- if (!zkService.isStarted()) {
- viewErrors
- .add("Slider applications view requires ZooKeeper service to be started");
- }
- }
- } else {
- viewErrors
- .add("Slider applications view is unable to locate any services");
- }
- // Check security
- if (cluster.getDesiredConfigs() != null
- && cluster.getDesiredConfigs().containsKey("global")) {
- Map<String, String> globalConfig = ambariClient.getConfiguration(
- clusterInfo, "global", cluster.getDesiredConfigs().get("global"));
- if (globalConfig != null
- && globalConfig.containsKey("security_enabled")) {
- String securityValue = globalConfig.get("security_enabled");
- if (Boolean.valueOf(securityValue)) {
- viewErrors
- .add("Slider applications view cannot be rendered in secure mode");
- }
- } else {
- viewErrors
- .add("Slider applications view is unable to determine the security status of the cluster");
- }
- } else {
- viewErrors
- .add("Slider applications view is unable to determine the security status of the cluster");
- }
- } else {
- viewErrors.add("Slider applications view requires a cluster");
- }
- status.setVersion(SliderAppsConfiguration.INSTANCE.getVersion());
- status.setViewEnabled(viewErrors.size() < 1);
- status.setViewErrors(viewErrors);
- return status;
- }
+ // Valid Slider App?
+ // We want all Slider apps except the ones which properly finished.
+ if (YarnApplicationState.FINISHED.equals(yarnApp.getYarnApplicationState())) {
+ try {
+ if (sliderClient.actionExists(yarnApp.getName(), false) == LauncherExitCodes.EXIT_SUCCESS) {
+ app.setState(SliderApp.STATE_FROZEN);
+ }
+ } catch (UnknownApplicationInstanceException e) {
+ return null; // Application not in HDFS - means it is not frozen
+ } catch (YarnException e) {
+ logger.warn(
+ "Unable to determine frozen state for " + yarnApp.getName(), e);
+ return null;
+ } catch (IOException e) {
+ logger.warn(
+ "Unable to determine frozen state for " + yarnApp.getName(), e);
+ return null;
+ }
+ }
- private AmbariCluster getAmbariCluster() {
- AmbariClusterInfo clusterInfo = ambariClient.getClusterInfo();
- if (clusterInfo != null)
- return ambariClient.getCluster(clusterInfo);
- return null;
- }
+ app.setId(Long.toString(yarnApp.getApplicationId().getClusterTimestamp())
+ + "_" + Integer.toString(yarnApp.getApplicationId().getId()));
+ app.setName(yarnApp.getName());
+ app.setUser(yarnApp.getUser());
+ app.setDiagnostics(yarnApp.getDiagnostics());
+ app.setYarnId(yarnApp.getApplicationId().toString());
+ app.setType(yarnApp.getApplicationType());
+ app.setStartTime(yarnApp.getStartTime());
+ app.setEndTime(yarnApp.getFinishTime());
+ if (properties != null && !properties.isEmpty()) {
+ SliderAppMasterClient sliderAppClient = yarnApp.getTrackingUrl() == null ? null
+ : new SliderAppMasterClient(yarnApp.getTrackingUrl());
+ SliderAppMasterData appMasterData = null;
+ Map<String, String> quickLinks = new HashMap<String, String>();
+ for (String property : properties) {
+ if ("RUNNING".equals(app.getState())) {
+ if (sliderAppClient != null) {
+ if (appMasterData == null) {
+ appMasterData = sliderAppClient.getAppMasterData();
+ }
+ if ("urls".equals(property.toLowerCase())) {
+ if (quickLinks.isEmpty()) {
+ quickLinks = sliderAppClient
+ .getQuickLinks(appMasterData.publisherUrl);
+ }
+ app.setUrls(quickLinks);
+ } else if ("configs".equals(property.toLowerCase())) {
+ Map<String, Map<String, String>> configs = sliderAppClient
+ .getConfigs(appMasterData.publisherUrl);
+ app.setConfigs(configs);
+ } else if ("jmx".equals(property.toLowerCase())) {
+ if (quickLinks.isEmpty()) {
+ quickLinks = sliderAppClient
+ .getQuickLinks(appMasterData.publisherUrl);
+ }
+ if (quickLinks != null && quickLinks.containsKey("JMX")) {
+ String jmxUrl = quickLinks.get("JMX");
+ List<SliderAppType> appTypes = getSliderAppTypes(null);
+ if(appTypes != null && appTypes.size() > 0) {
+ // TODO: Get the correct app type based on name and version
+ SliderAppType appType = appTypes.get(0);
+ app.setJmx(sliderAppClient.getJmx(jmxUrl, viewContext, appType));
+ }
+ }
+ Map<String, Map<String, String>> configs = sliderAppClient
+ .getConfigs(appMasterData.publisherUrl);
+ app.setConfigs(configs);
+ } else if ("components".equals(property.toLowerCase())) {
+ try {
+ System.setProperty(SliderKeys.HADOOP_USER_NAME, "yarn");
+ ClusterDescription description = sliderClient
+ .getClusterDescription(yarnApp.getName());
+ if (description != null && description.status != null
+ && !description.status.isEmpty()) {
+ Map<String, SliderAppComponent> componentTypeMap = new HashMap<String, SliderAppComponent>();
+ for (Entry<String, Object> e : description.status.entrySet()) {
+ @SuppressWarnings("unchecked")
+ Map<String, Map<String, Map<String, Object>>>
+ componentsObj =
+ (Map<String, Map<String, Map<String, Object>>>) e
+ .getValue();
+ boolean isLive = "live".equals(e.getKey());
+ for (Entry<String, Map<String, Map<String, Object>>> componentEntry : componentsObj
+ .entrySet()) {
+ SliderAppComponent appComponent = componentTypeMap
+ .get(componentEntry.getKey());
+ if (appComponent == null) {
+ appComponent = new SliderAppComponent();
+ appComponent.setComponentName(componentEntry.getKey());
+ appComponent
+ .setActiveContainers(new HashMap<String, Map<String, String>>());
+ appComponent
+ .setCompletedContainers(new HashMap<String, Map<String, String>>());
+ componentTypeMap.put(componentEntry.getKey(),
+ appComponent);
+ }
+ for (Entry<String, Map<String, Object>> containerEntry : componentEntry
+ .getValue().entrySet()) {
+ Map<String, String> containerDataMap = new HashMap<String, String>();
+ String containerId = containerEntry.getKey();
+ Map<String, Object> containerValues = containerEntry
+ .getValue();
+ for (String containerProperty : containerValues
+ .keySet()) {
+ Object containerPropertyValue = containerValues
+ .get(containerProperty);
+ containerDataMap.put(containerProperty,
+ containerPropertyValue.toString());
+ }
+ if (isLive) {
+ appComponent.getActiveContainers().put(containerId,
+ containerDataMap);
+ } else {
+ appComponent.getCompletedContainers().put(
+ containerId, containerDataMap);
+ }
+ }
+ appComponent.setInstanceCount(appComponent
+ .getActiveContainers().size()
+ + appComponent.getCompletedContainers().size());
+ }
+ }
+ app.setComponents(componentTypeMap);
+ }
+ } catch (UnknownApplicationInstanceException e) {
+ logger.warn(
+ "Unable to determine app components for "
+ + yarnApp.getName(), e);
+ } catch (YarnException e) {
+ logger.warn(
+ "Unable to determine app components for "
+ + yarnApp.getName(), e);
+ throw new RuntimeException(e.getMessage(), e);
+ } catch (IOException e) {
+ logger.warn(
+ "Unable to determine app components for "
+ + yarnApp.getName(), e);
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ }
+ }
+ }
+ }
+ }
+ return app;
+ }
- @Override
- public SliderApp getSliderApp(String applicationId, Set<String> properties)
- throws YarnException, IOException {
- if (applicationId != null) {
- int index = applicationId.indexOf('_');
- if (index > -1 && index < applicationId.length() - 1) {
- ApplicationId appId = ApplicationId.newInstance(
- Long.parseLong(applicationId.substring(0, index)),
- Integer.parseInt(applicationId.substring(index + 1)));
- ClassLoader currentClassLoader = Thread.currentThread()
- .getContextClassLoader();
- Thread.currentThread().setContextClassLoader(
- getClass().getClassLoader());
- try {
- SliderClient sliderClient = getSliderClient();
- ApplicationReport yarnApp = sliderClient.getApplicationReport(appId);
- return createSliderAppObject(yarnApp, properties, sliderClient);
- } finally {
- Thread.currentThread().setContextClassLoader(currentClassLoader);
- }
- }
- }
- return null;
- }
+ /**
+ * Creates a new {@link SliderClient} initialized with appropriate configuration. If configuration was not determined,
+ * <code>null</code> is returned.
+ *
+ * @return
+ */
+ protected SliderClient getSliderClient() {
+ Configuration sliderClientConfiguration = getSliderClientConfiguration();
+ if (sliderClientConfiguration != null) {
+ SliderClient client = new SliderClient() {
+ @Override
+ public String getUsername() throws IOException {
+ return null;
+ }
- private SliderApp createSliderAppObject(ApplicationReport yarnApp,
- Set<String> properties, SliderClient sliderClient) {
- if (yarnApp == null)
- return null;
+ @Override
+ protected void serviceInit(Configuration conf) throws Exception {
+ super.serviceInit(conf);
+ // Override the default FS client to set the super user.
+ FileSystem fs = FileSystem.get(FileSystem.getDefaultUri(getConfig()),
+ getConfig(), "yarn");
+ SliderFileSystem fileSystem = new SliderFileSystem(fs, getConfig());
+ Field fsField = SliderClient.class
+ .getDeclaredField("sliderFileSystem");
+ fsField.setAccessible(true);
+ fsField.set(this, fileSystem);
+ }
+ };
+ try {
+ sliderClientConfiguration = client.bindArgs(sliderClientConfiguration,
+ new String[]{"usage"});
+ } catch (Exception e) {
+ logger.warn("Unable to set SliderClient configs", e);
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ client.init(sliderClientConfiguration);
+ client.start();
+ return client;
+ }
+ return null;
+ }
- SliderApp app = new SliderApp();
- app.setState(yarnApp.getYarnApplicationState().name());
+ /**
+ * Dynamically determines Slider client configuration. If unable to determine, <code>null</code> is returned.
+ *
+ * @return
+ */
+ private Configuration getSliderClientConfiguration() {
+ AmbariCluster ambariCluster = getAmbariCluster();
+ if (ambariCluster != null) {
+ AmbariService zkService = ambariClient.getService(ambariCluster,
+ "ZOOKEEPER");
+ if (zkService != null && ambariCluster.getDesiredConfigs() != null
+ && ambariCluster.getDesiredConfigs().containsKey("global")
+ && ambariCluster.getDesiredConfigs().containsKey("yarn-site")
+ && ambariCluster.getDesiredConfigs().containsKey("core-site")) {
+ Map<String, String> globalConfigs = ambariClient.getConfiguration(
+ ambariCluster, "global",
+ ambariCluster.getDesiredConfigs().get("yarn-site"));
+ Map<String, String> yarnSiteConfigs = ambariClient.getConfiguration(
+ ambariCluster, "yarn-site",
+ ambariCluster.getDesiredConfigs().get("yarn-site"));
+ Map<String, String> coreSiteConfigs = ambariClient.getConfiguration(
+ ambariCluster, "core-site",
+ ambariCluster.getDesiredConfigs().get("core-site"));
+ String zkPort = globalConfigs.get("clientPort");
+ String hdfsPath = coreSiteConfigs.get("fs.defaultFS");
+ String rmAddress = yarnSiteConfigs.get("yarn.resourcemanager.address");
+ String rmSchedulerAddress = yarnSiteConfigs
+ .get("yarn.resourcemanager.scheduler.address");
+ StringBuilder zkQuorum = new StringBuilder();
+ List<AmbariHostComponent> zkHosts = zkService
+ .getComponentsToHostComponentsMap().get("ZOOKEEPER_SERVER");
+ for (AmbariHostComponent zkHost : zkHosts) {
+ if (zkQuorum.length() > 0) {
+ zkQuorum.append(',');
+ }
+ zkQuorum.append(zkHost.getHostName() + ":" + zkPort);
+ }
+ HdfsConfiguration hdfsConfig = new HdfsConfiguration();
+ YarnConfiguration yarnConfig = new YarnConfiguration(hdfsConfig);
- // Valid Slider App?
- // We want all Slider apps except the ones which properly finished.
- if (YarnApplicationState.FINISHED.equals(yarnApp.getYarnApplicationState())) {
- try {
- if (sliderClient.actionExists(yarnApp.getName(), false) == LauncherExitCodes.EXIT_SUCCESS)
- app.setState(SliderApp.STATE_FROZEN);
- } catch (UnknownApplicationInstanceException e) {
- return null; // Application not in HDFS - means it is not frozen
- } catch (YarnException e) {
- logger.warn(
- "Unable to determine frozen state for " + yarnApp.getName(), e);
- return null;
- } catch (IOException e) {
- logger.warn(
- "Unable to determine frozen state for " + yarnApp.getName(), e);
- return null;
- }
- }
+ yarnConfig.set("slider.yarn.queue", "default");
+ yarnConfig.set("yarn.log-aggregation-enable", "true");
+ yarnConfig.set("yarn.resourcemanager.address", rmAddress);
+ yarnConfig.set("yarn.resourcemanager.scheduler.address",
+ rmSchedulerAddress);
+ yarnConfig.set("fs.defaultFS", hdfsPath);
+ yarnConfig.set("slider.zookeeper.quorum", zkQuorum.toString());
+ return yarnConfig;
+ }
+ }
+ return null;
+ }
- app.setId(Long.toString(yarnApp.getApplicationId().getClusterTimestamp())
- + "_" + Integer.toString(yarnApp.getApplicationId().getId()));
- app.setName(yarnApp.getName());
- app.setUser(yarnApp.getUser());
- app.setDiagnostics(yarnApp.getDiagnostics());
- app.setYarnId(yarnApp.getApplicationId().toString());
- app.setType(yarnApp.getApplicationType());
- app.setStartTime(yarnApp.getStartTime());
- app.setEndTime(yarnApp.getFinishTime());
- if (properties != null && !properties.isEmpty()) {
- SliderAppMasterClient sliderAppClient = yarnApp.getTrackingUrl() == null ? null
- : new SliderAppMasterClient(yarnApp.getTrackingUrl());
- SliderAppMasterData appMasterData = null;
- Map<String, String> quickLinks = new HashMap<String, String>();
- for (String property : properties) {
- if ("RUNNING".equals(app.getState())) {
- if (sliderAppClient != null) {
- if (appMasterData == null)
- appMasterData = sliderAppClient.getAppMasterData();
- if ("urls".equals(property.toLowerCase())) {
- if (quickLinks.isEmpty())
- quickLinks = sliderAppClient
- .getQuickLinks(appMasterData.publisherUrl);
- app.setUrls(quickLinks);
- } else if ("configs".equals(property.toLowerCase())) {
- Map<String, Map<String, String>> configs = sliderAppClient
- .getConfigs(appMasterData.publisherUrl);
- app.setConfigs(configs);
- } else if ("jmx".equals(property.toLowerCase())) {
- if (quickLinks.isEmpty())
- quickLinks = sliderAppClient
- .getQuickLinks(appMasterData.publisherUrl);
- if (quickLinks != null && quickLinks.containsKey("JMX")) {
- String jmxUrl = quickLinks.get("JMX");
- app.setJmx(sliderAppClient.getJmx(jmxUrl));
- }
- Map<String, Map<String, String>> configs = sliderAppClient
- .getConfigs(appMasterData.publisherUrl);
- app.setConfigs(configs);
- } else if ("components".equals(property.toLowerCase())) {
- try {
- System.setProperty(SliderKeys.HADOOP_USER_NAME, "yarn");
- ClusterDescription description = sliderClient
- .getClusterDescription(yarnApp.getName());
- if (description != null && description.status != null
- && !description.status.isEmpty()) {
- Map<String, SliderAppComponent> componentTypeMap = new HashMap<String, SliderAppComponent>();
- for (Entry<String, Object> e : description.status.entrySet()) {
- @SuppressWarnings("unchecked")
- Map<String, Map<String, Map<String, Object>>> componentsObj = (Map<String, Map<String, Map<String, Object>>>) e
- .getValue();
- boolean isLive = "live".equals(e.getKey());
- for (Entry<String, Map<String, Map<String, Object>>> componentEntry : componentsObj
- .entrySet()) {
- SliderAppComponent appComponent = componentTypeMap
- .get(componentEntry.getKey());
- if (appComponent == null) {
- appComponent = new SliderAppComponent();
- appComponent.setComponentName(componentEntry.getKey());
- appComponent
- .setActiveContainers(new HashMap<String, Map<String, String>>());
- appComponent
- .setCompletedContainers(new HashMap<String, Map<String, String>>());
- componentTypeMap.put(componentEntry.getKey(),
- appComponent);
- }
- for (Entry<String, Map<String, Object>> containerEntry : componentEntry
- .getValue().entrySet()) {
- Map<String, String> containerDataMap = new HashMap<String, String>();
- String containerId = containerEntry.getKey();
- Map<String, Object> containerValues = containerEntry
- .getValue();
- for (String containerProperty : containerValues
- .keySet()) {
- Object containerPropertyValue = containerValues
- .get(containerProperty);
- containerDataMap.put(containerProperty,
- containerPropertyValue.toString());
- }
- if (isLive)
- appComponent.getActiveContainers().put(containerId,
- containerDataMap);
- else
- appComponent.getCompletedContainers().put(
- containerId, containerDataMap);
- }
- appComponent.setInstanceCount(appComponent
- .getActiveContainers().size()
- + appComponent.getCompletedContainers().size());
- }
- }
- app.setComponents(componentTypeMap);
- }
- } catch (UnknownApplicationInstanceException e) {
- logger.warn(
- "Unable to determine app components for "
- + yarnApp.getName(), e);
- } catch (YarnException e) {
- logger.warn(
- "Unable to determine app components for "
- + yarnApp.getName(), e);
- throw new RuntimeException(e.getMessage(), e);
- } catch (IOException e) {
- logger.warn(
- "Unable to determine app components for "
- + yarnApp.getName(), e);
- throw new RuntimeException(e.getMessage(), e);
- }
- }
- }
- }
- }
- }
- return app;
- }
+ @Override
+ public List<SliderApp> getSliderApps(Set<String> properties)
+ throws YarnException, IOException {
+ List<SliderApp> sliderApps = new ArrayList<SliderApp>();
+ ClassLoader currentClassLoader = Thread.currentThread()
+ .getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
+ try {
+ SliderClient sliderClient = getSliderClient();
+ List<ApplicationReport> yarnApps = sliderClient.listSliderInstances(null);
+ for (ApplicationReport yarnApp : yarnApps) {
+ SliderApp sliderAppObject = createSliderAppObject(yarnApp, properties,
+ sliderClient);
+ if (sliderAppObject != null) {
+ sliderApps.add(sliderAppObject);
+ }
+ }
+ } finally {
+ Thread.currentThread().setContextClassLoader(currentClassLoader);
+ }
+ return sliderApps;
+ }
- /**
- * Creates a new {@link SliderClient} initialized with appropriate
- * configuration. If configuration was not determined, <code>null</code> is
- * returned.
- *
- * @return
- */
- protected SliderClient getSliderClient() {
- Configuration sliderClientConfiguration = getSliderClientConfiguration();
- if (sliderClientConfiguration != null) {
- SliderClient client = new SliderClient() {
- @Override
- public String getUsername() throws IOException {
- return null;
- }
+ @Override
+ public void deleteSliderApp(String applicationId) throws YarnException,
+ IOException {
+ ClassLoader currentClassLoader = Thread.currentThread()
+ .getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
+ try {
+ Set<String> properties = new HashSet<String>();
+ properties.add("id");
+ properties.add("name");
+ SliderApp sliderApp = getSliderApp(applicationId, properties);
+ if (sliderApp == null) {
+ throw new ApplicationNotFoundException(applicationId);
+ }
- @Override
- protected void serviceInit(Configuration conf) throws Exception {
- super.serviceInit(conf);
- // Override the default FS client to set the super user.
- FileSystem fs = FileSystem.get(FileSystem.getDefaultUri(getConfig()),
- getConfig(), "yarn");
- SliderFileSystem fileSystem = new SliderFileSystem(fs, getConfig());
- Field fsField = SliderClient.class
- .getDeclaredField("sliderFileSystem");
- fsField.setAccessible(true);
- fsField.set(this, fileSystem);
- }
- };
- try {
- sliderClientConfiguration = client.bindArgs(sliderClientConfiguration,
- new String[] { "usage" });
- } catch (Exception e) {
- logger.warn("Unable to set SliderClient configs", e);
- throw new RuntimeException(e.getMessage(), e);
- }
- client.init(sliderClientConfiguration);
- client.start();
- return client;
- }
- return null;
- }
+ SliderClient sliderClient = getSliderClient();
+ sliderClient.actionDestroy(sliderApp.getName());
+ } finally {
+ Thread.currentThread().setContextClassLoader(currentClassLoader);
+ }
+ }
- /**
- * Dynamically determines Slider client configuration. If unable to determine,
- * <code>null</code> is returned.
- *
- * @return
- */
- private Configuration getSliderClientConfiguration() {
- AmbariCluster ambariCluster = getAmbariCluster();
- if (ambariCluster != null) {
- AmbariService zkService = ambariClient.getService(ambariCluster,
- "ZOOKEEPER");
- if (zkService != null && ambariCluster.getDesiredConfigs() != null
- && ambariCluster.getDesiredConfigs().containsKey("global")
- && ambariCluster.getDesiredConfigs().containsKey("yarn-site")
- && ambariCluster.getDesiredConfigs().containsKey("core-site")) {
- Map<String, String> globalConfigs = ambariClient.getConfiguration(
- ambariCluster, "global",
- ambariCluster.getDesiredConfigs().get("yarn-site"));
- Map<String, String> yarnSiteConfigs = ambariClient.getConfiguration(
- ambariCluster, "yarn-site",
- ambariCluster.getDesiredConfigs().get("yarn-site"));
- Map<String, String> coreSiteConfigs = ambariClient.getConfiguration(
- ambariCluster, "core-site",
- ambariCluster.getDesiredConfigs().get("core-site"));
- String zkPort = globalConfigs.get("clientPort");
- String hdfsPath = coreSiteConfigs.get("fs.defaultFS");
- String rmAddress = yarnSiteConfigs.get("yarn.resourcemanager.address");
- String rmSchedulerAddress = yarnSiteConfigs
- .get("yarn.resourcemanager.scheduler.address");
- StringBuilder zkQuorum = new StringBuilder();
- List<AmbariHostComponent> zkHosts = zkService
- .getComponentsToHostComponentsMap().get("ZOOKEEPER_SERVER");
- for (AmbariHostComponent zkHost : zkHosts) {
- if (zkQuorum.length() > 0)
- zkQuorum.append(',');
- zkQuorum.append(zkHost.getHostName() + ":" + zkPort);
- }
- HdfsConfiguration hdfsConfig = new HdfsConfiguration();
- YarnConfiguration yarnConfig = new YarnConfiguration(hdfsConfig);
+ @Override
+ public SliderAppType getSliderAppType(String appTypeId, Set<String> properties) {
+ List<SliderAppType> appTypes = getSliderAppTypes(properties);
+ if (appTypeId != null && appTypes != null) {
+ for (SliderAppType appType : appTypes) {
+ if (appTypeId != null && appTypeId.equals(appType.getId())) {
+ return appType;
+ }
+ }
+ }
+ return null;
+ }
- yarnConfig.set("slider.yarn.queue", "default");
- yarnConfig.set("yarn.log-aggregation-enable", "true");
- yarnConfig.set("yarn.resourcemanager.address", rmAddress);
- yarnConfig.set("yarn.resourcemanager.scheduler.address",
- rmSchedulerAddress);
- yarnConfig.set("fs.defaultFS", hdfsPath);
- yarnConfig.set("slider.zookeeper.quorum", zkQuorum.toString());
- return yarnConfig;
- }
- }
- return null;
- }
+ @Override
+ public List<SliderAppType> getSliderAppTypes(Set<String> properties) {
+ if (appTypes == null) {
+ appTypes = loadAppTypes();
+ }
+ return appTypes;
+ }
- @Override
- public List<SliderApp> getSliderApps(Set<String> properties)
- throws YarnException, IOException {
- List<SliderApp> sliderApps = new ArrayList<SliderApp>();
- ClassLoader currentClassLoader = Thread.currentThread()
- .getContextClassLoader();
- Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
- try {
- SliderClient sliderClient = getSliderClient();
- List<ApplicationReport> yarnApps = sliderClient.listSliderInstances(null);
- for (ApplicationReport yarnApp : yarnApps) {
- SliderApp sliderAppObject = createSliderAppObject(yarnApp, properties,
- sliderClient);
- if (sliderAppObject != null)
- sliderApps.add(sliderAppObject);
- }
- } finally {
- Thread.currentThread().setContextClassLoader(currentClassLoader);
- }
- return sliderApps;
- }
+ private List<SliderAppType> loadAppTypes() {
+ List<SliderAppType> appTypes = null;
+ String appsFolderPath = getAppsFolderPath();
+ File appsFolder = new File(appsFolderPath);
+ if (appsFolder.exists()) {
+ File[] appZips = appsFolder
+ .listFiles((FilenameFilter) new RegexFileFilter("^.*\\.zip$"));
+ if (appZips != null) {
+ appTypes = new ArrayList<SliderAppType>();
+ for (File appZip : appZips) {
+ try {
+ ZipFile zipFile = new ZipFile(appZip);
+ Metainfo metainfo = new MetainfoParser().parse(zipFile
+ .getInputStream(zipFile.getEntry("metainfo.xml")));
+ // Create app type object
+ if (metainfo.getServices() != null
+ && metainfo.getServices().size() > 0) {
+ Service service = metainfo.getServices().get(0);
+ String appConfigJsonString = IOUtils.toString(
+ zipFile.getInputStream(zipFile.getEntry("appConfig.json")),
+ "UTF-8");
+ String resourcesJsonString = IOUtils.toString(
+ zipFile.getInputStream(zipFile.getEntry("resources.json")),
+ "UTF-8");
+ JsonElement appConfigJson = new JsonParser()
+ .parse(appConfigJsonString);
+ JsonElement resourcesJson = new JsonParser()
+ .parse(resourcesJsonString);
+ SliderAppType appType = new SliderAppType();
+ appType.setId(service.getName());
+ appType.setTypeName(service.getName());
+ appType.setTypeDescription(service.getComment());
+ appType.setTypeVersion(service.getVersion());
+ appType.setTypePackageFileName(appZip.getName());
+ // Configs
+ Map<String, String> configsMap = new HashMap<String, String>();
+ JsonObject appTypeGlobalJson = appConfigJson.getAsJsonObject()
+ .get("global").getAsJsonObject();
+ for (Entry<String, JsonElement> e : appTypeGlobalJson.entrySet()) {
+ configsMap.put(e.getKey(), e.getValue().getAsString());
+ }
+ appType.setTypeConfigs(configsMap);
+ // Components
+ ArrayList<SliderAppTypeComponent> appTypeComponentList = new ArrayList<SliderAppTypeComponent>();
+ for (Component component : service.getComponents()) {
+ SliderAppTypeComponent appTypeComponent = new SliderAppTypeComponent();
+ appTypeComponent.setDisplayName(component.getName());
+ appTypeComponent.setId(component.getName());
+ appTypeComponent.setName(component.getName());
+ appTypeComponent.setYarnMemory(1024);
+ appTypeComponent.setYarnCpuCores(1);
+ // appTypeComponent.setPriority(component.);
+ if (component.getMinInstanceCount() != null) {
+ appTypeComponent.setInstanceCount(Integer.parseInt(component
+ .getMinInstanceCount()));
+ }
+ if (component.getMaxInstanceCount() != null) {
+ appTypeComponent.setMaxInstanceCount(Integer
+ .parseInt(component.getMaxInstanceCount()));
+ }
+ if (resourcesJson != null) {
+ JsonElement componentJson = resourcesJson.getAsJsonObject()
+ .get("components").getAsJsonObject()
+ .get(component.getName());
+ if (componentJson != null
+ && componentJson.getAsJsonObject().has(
+ "yarn.role.priority")) {
+ appTypeComponent.setPriority(Integer.parseInt(componentJson
+ .getAsJsonObject().get("yarn.role.priority")
+ .getAsString()));
+ }
+ }
+ appTypeComponent.setCategory(component.getCategory());
+ appTypeComponentList.add(appTypeComponent);
+ }
- @Override
- public void deleteSliderApp(String applicationId) throws YarnException,
- IOException {
- ClassLoader currentClassLoader = Thread.currentThread()
- .getContextClassLoader();
- Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
- try {
- Set<String> properties = new HashSet<String>();
- properties.add("id");
- properties.add("name");
- SliderApp sliderApp = getSliderApp(applicationId, properties);
- if (sliderApp == null)
- throw new ApplicationNotFoundException(applicationId);
+ appType.setJmxMetrics(readMetrics(zipFile, "jmx_metrics.json"));
+ appType.setGangliaMetrics(readMetrics(zipFile, "ganglia_metrics.json"));
- SliderClient sliderClient = getSliderClient();
- sliderClient.actionDestroy(sliderApp.getName());
- } finally {
- Thread.currentThread().setContextClassLoader(currentClassLoader);
- }
- }
+ appType.setTypeComponents(appTypeComponentList);
+ appTypes.add(appType);
+ }
+ } catch (ZipException e) {
+ logger.warn("Unable to parse app " + appZip.getAbsolutePath(), e);
+ } catch (IOException e) {
+ logger.warn("Unable to parse app " + appZip.getAbsolutePath(), e);
+ }
+ }
+ }
+ }
+ return appTypes;
+ }
- @Override
- public SliderAppType getSliderAppType(String appTypeId, Set<String> properties) {
- List<SliderAppType> appTypes = getSliderAppTypes(properties);
- if (appTypeId != null && appTypes != null) {
- for (SliderAppType appType : appTypes)
- if (appTypeId != null && appTypeId.equals(appType.getId()))
- return appType;
- }
- return null;
- }
+ Map<String, Map<String, Map<String, Metric>>> readMetrics(ZipFile zipFile, String fileName) {
+ Map<String, Map<String, Map<String, Metric>>> metrics = null;
+ try {
+ InputStream inputStream =
+ zipFile.getInputStream(zipFile.getEntry("jmx_metrics.json"));
+ ObjectMapper mapper = new ObjectMapper();
- @Override
- public List<SliderAppType> getSliderAppTypes(Set<String> properties) {
- if (appTypes == null)
- appTypes = loadAppTypes();
- return appTypes;
- }
+ metrics =
+ mapper.readValue(inputStream,
+ new TypeReference<Map<String, Map<String, Map<String, Metric>>>>() {
+ });
+ } catch (IOException e) {
+ logger.info("Error reading metrics. " + e.getMessage());
+ }
- private List<SliderAppType> loadAppTypes() {
- List<SliderAppType> appTypes = null;
- String appsFolderPath = getAppsFolderPath();
- File appsFolder = new File(appsFolderPath);
- if (appsFolder.exists()) {
- File[] appZips = appsFolder
- .listFiles((FilenameFilter) new RegexFileFilter("^.*\\.zip$"));
- if (appZips != null) {
- appTypes = new ArrayList<SliderAppType>();
- for (File appZip : appZips) {
- try {
- ZipFile zipFile = new ZipFile(appZip);
- Metainfo metainfo = new MetainfoParser().parse(zipFile
- .getInputStream(zipFile.getEntry("metainfo.xml")));
- // Create app type object
- if (metainfo.getServices() != null
- && metainfo.getServices().size() > 0) {
- Service service = metainfo.getServices().get(0);
- String appConfigJsonString = IOUtils.toString(
- zipFile.getInputStream(zipFile.getEntry("appConfig.json")),
- "UTF-8");
- String resourcesJsonString = IOUtils.toString(
- zipFile.getInputStream(zipFile.getEntry("resources.json")),
- "UTF-8");
- JsonElement appConfigJson = new JsonParser()
- .parse(appConfigJsonString);
- JsonElement resourcesJson = new JsonParser()
- .parse(resourcesJsonString);
- SliderAppType appType = new SliderAppType();
- appType.setId(service.getName());
- appType.setTypeName(service.getName());
- appType.setTypeDescription(service.getComment());
- appType.setTypeVersion(service.getVersion());
- appType.setTypePackageFileName(appZip.getName());
- // Configs
- Map<String, String> configsMap = new HashMap<String, String>();
- JsonObject appTypeGlobalJson = appConfigJson.getAsJsonObject()
- .get("global").getAsJsonObject();
- for (Entry<String, JsonElement> e : appTypeGlobalJson.entrySet())
- configsMap.put(e.getKey(), e.getValue().getAsString());
- appType.setTypeConfigs(configsMap);
- // Components
- ArrayList<SliderAppTypeComponent> appTypeComponentList = new ArrayList<SliderAppTypeComponent>();
- for (Component component : service.getComponents()) {
- SliderAppTypeComponent appTypeComponent = new SliderAppTypeComponent();
- appTypeComponent.setDisplayName(component.getName());
- appTypeComponent.setId(component.getName());
- appTypeComponent.setName(component.getName());
- appTypeComponent.setYarnMemory(1024);
- appTypeComponent.setYarnCpuCores(1);
- // appTypeComponent.setPriority(component.);
- if (component.getMinInstanceCount() != null)
- appTypeComponent.setInstanceCount(Integer.parseInt(component
- .getMinInstanceCount()));
- if (component.getMaxInstanceCount() != null)
- appTypeComponent.setMaxInstanceCount(Integer
- .parseInt(component.getMaxInstanceCount()));
- if (resourcesJson != null) {
- JsonElement componentJson = resourcesJson.getAsJsonObject()
- .get("components").getAsJsonObject()
- .get(component.getName());
- if (componentJson != null
- && componentJson.getAsJsonObject().has(
- "yarn.role.priority")) {
- appTypeComponent.setPriority(Integer.parseInt(componentJson
- .getAsJsonObject().get("yarn.role.priority")
- .getAsString()));
- }
- }
- appTypeComponent.setCategory(component.getCategory());
- appTypeComponentList.add(appTypeComponent);
- }
- appType.setTypeComponents(appTypeComponentList);
- appTypes.add(appType);
- }
- } catch (ZipException e) {
- logger.warn("Unable to parse app " + appZip.getAbsolutePath(), e);
- } catch (IOException e) {
- logger.warn("Unable to parse app " + appZip.getAbsolutePath(), e);
- }
- }
- }
- }
- return appTypes;
- }
+ return metrics;
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/52806bd7/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/Metric.java
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/Metric.java b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/Metric.java
new file mode 100644
index 0000000..a9692c0
--- /dev/null
+++ b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/Metric.java
@@ -0,0 +1,120 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.slider.rest.client;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Metric {
+ private static String SEPARATOR = ".";
+ private static char SEPARATOR_REPLACED = '#';
+ private String metric;
+ private boolean pointInTime;
+ private boolean temporal;
+ private String keyName = null;
+ private List<List<String>> matchers = null;
+
+ private Metric() {
+ }
+
+ protected Metric(String metric, boolean pointInTime, boolean temporal) {
+ this.metric = metric;
+ this.pointInTime = pointInTime;
+ this.temporal = temporal;
+ }
+
+ public String getMetric() {
+ return metric;
+ }
+
+ public void setMetric(String metric) {
+ this.metric = metric;
+ }
+
+ public boolean isPointInTime() {
+ return pointInTime;
+ }
+
+ public void setPointInTime(boolean pointInTime) {
+ this.pointInTime = pointInTime;
+ }
+
+ public boolean isTemporal() {
+ return temporal;
+ }
+
+ public void setTemporal(boolean temporal) {
+ this.temporal = temporal;
+ }
+
+ public String getKeyName() {
+ if (keyName == null) {
+ int firstIndex = metric.indexOf(SEPARATOR);
+ if (firstIndex > 0) {
+ keyName = metric.substring(0, firstIndex).replace(SEPARATOR_REPLACED, '.');
+ }
+ }
+ return keyName;
+ }
+
+ /**
+ * Matcher is of the form a.b.c... They can be matched as a -> b-> c or a.b -> c or a -> b.c etc. The matcher returns
+ * all possibilities in priority order
+ *
+ * @return
+ */
+ public List<List<String>> getMatchers() {
+ if (matchers == null) {
+ List<List<String>> tmpMatchers = new ArrayList<List<String>>();
+ int matcherStartIndex = metric.indexOf(SEPARATOR);
+ if (matcherStartIndex > 0) {
+ String allTagsStr = metric.substring(matcherStartIndex + 1);
+ String[] tags = allTagsStr.split("\\.");
+ if (tags.length > 0) {
+ extractMatchers(tags, -1, tmpMatchers, null);
+ }
+ }
+
+ matchers = tmpMatchers;
+ }
+ return matchers;
+ }
+
+ public void extractMatchers(String[] tags, int index, List<List<String>> matchers, ArrayList<String> currentSet) {
+ if (tags.length == index + 1) {
+ matchers.add(currentSet);
+ } else {
+ if (index == -1) {
+ currentSet = new ArrayList<String>();
+ currentSet.add(tags[0]);
+ extractMatchers(tags, 0, matchers, currentSet);
+ } else {
+ ArrayList<String> mergeAndProceed = new ArrayList<String>(currentSet);
+ mergeAndProceed.add(tags[index + 1]);
+ extractMatchers(tags, index + 1, matchers, mergeAndProceed);
+
+ ArrayList<String> appendAndProceed = new ArrayList<String>(currentSet);
+ int lastIndex = appendAndProceed.size() - 1;
+ appendAndProceed.set(lastIndex, appendAndProceed.get(lastIndex) + "." + tags[index + 1]);
+ extractMatchers(tags, index + 1, matchers, appendAndProceed);
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/52806bd7/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/SliderAppMasterClient.java
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/SliderAppMasterClient.java b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/SliderAppMasterClient.java
index db29035..99b22ff 100644
--- a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/SliderAppMasterClient.java
+++ b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/SliderAppMasterClient.java
@@ -18,144 +18,267 @@
package org.apache.ambari.view.slider.rest.client;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import org.apache.ambari.server.controller.jmx.JMXMetricHolder;
+import org.apache.ambari.view.URLStreamProvider;
+import org.apache.ambari.view.ViewContext;
+import org.apache.ambari.view.slider.SliderAppType;
+import org.apache.ambari.view.slider.SliderAppTypeComponent;
+import org.apache.commons.httpclient.HttpException;
+import org.apache.log4j.Logger;
+import org.codehaus.jackson.map.DeserializationConfig;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.map.ObjectReader;
+
import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import org.apache.commons.httpclient.HttpException;
-import org.apache.log4j.Logger;
+public class SliderAppMasterClient extends BaseHttpClient {
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
+ private static final Logger logger = Logger
+ .getLogger(SliderAppMasterClient.class);
+ private static final String NAME_KEY = "name";
+ private static final String PORT_KEY = "tag.port";
+ private static final String FORPORT_KEY = "ForPort";
-public class SliderAppMasterClient extends BaseHttpClient {
+ public SliderAppMasterClient(String url) {
+ super(url);
+ }
+
+ public SliderAppMasterData getAppMasterData() {
+ try {
+ String html = doGet("");
+ int from = html.lastIndexOf("<ul>");
+ int to = html.lastIndexOf("</ul>");
+ if (from < to && from > -1) {
+ SliderAppMasterData data = new SliderAppMasterData();
+ String content = html.substring(from, to);
+ content = content.replaceAll("<[^>]*>", "\r\n");
+ String[] splits = content.split("\r\n");
+ for (int i = 0; i < splits.length; i++) {
+ String split = splits[i].trim();
+ if ("Registry Web Service".equals(split)) {
+ data.registryUrl = splits[i + 1].trim();
+ } else if ("Application Master Web UI".equals(split)) {
+ data.uiUrl = splits[i + 1].trim();
+ } else if ("Management REST API".equals(split)) {
+ data.managementUrl = splits[i + 1].trim();
+ } else if ("Publisher Service".equals(split)) {
+ data.publisherUrl = splits[i + 1].trim();
+ }
+ }
+ return data;
+ }
+ } catch (HttpException e) {
+ logger.warn("Unable to determine Ambari clusters", e);
+ throw new RuntimeException(e.getMessage(), e);
+ } catch (IOException e) {
+ logger.warn("Unable to determine Ambari clusters", e);
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ return null;
+ }
+
+ public Map<String, String> getQuickLinks(String providerUrl) {
+ try {
+ JsonElement json = super.doGetJson(providerUrl, "/slider/quicklinks");
+ Map<String, String> quickLinks = new HashMap<String, String>();
+ JsonObject jsonObject = json.getAsJsonObject().get("entries")
+ .getAsJsonObject();
+ for (Entry<String, JsonElement> entry : jsonObject.entrySet()) {
+ if ("org.apache.slider.jmx".equals(entry.getKey())) {
+ quickLinks.put("JMX", entry.getValue().getAsString());
+ } else if ("org.apache.slider.monitor".equals(entry.getKey())) {
+ quickLinks.put("UI", entry.getValue().getAsString());
+ } else if ("org.apache.slider.metrics".equals(entry.getKey())) {
+ quickLinks.put("Metrics", entry.getValue().getAsString());
+ } else {
+ quickLinks.put(entry.getKey(), entry.getValue().getAsString());
+ }
+ }
+ return quickLinks;
+ } catch (HttpException e) {
+ logger.warn("Unable to determine quicklinks from " + providerUrl, e);
+ throw new RuntimeException(e.getMessage(), e);
+ } catch (IOException e) {
+ logger.warn("Unable to determine quicklinks from " + providerUrl, e);
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ }
+
+ public Map<String, Map<String, String>> getConfigs(String providerUrl) {
+ try {
+ Map<String, Map<String, String>> configsMap = new HashMap<String, Map<String, String>>();
+ JsonElement json = super.doGetJson(providerUrl, "/slider");
+ if (json != null) {
+ JsonObject configsJson = json.getAsJsonObject().get("configurations")
+ .getAsJsonObject();
+ for (Entry<String, JsonElement> entry : configsJson.entrySet()) {
+ if ("complete-config".equals(entry.getKey())
+ || "quicklinks".equals(entry.getKey())) {
+ continue;
+ }
+ JsonElement entryJson = super.doGetJson(providerUrl, "/slider/"
+ + entry.getKey());
+ if (entryJson != null) {
+ JsonObject configsObj = entryJson.getAsJsonObject().get("entries")
+ .getAsJsonObject();
+ if (configsObj != null) {
+ Map<String, String> configs = new HashMap<String, String>();
+ for (Entry<String, JsonElement> e : configsObj.entrySet()) {
+ configs.put(e.getKey(), e.getValue().getAsString());
+ }
+ configsMap.put(entry.getKey(), configs);
+ }
+ }
+ }
+ }
+ return configsMap;
+ } catch (HttpException e) {
+ logger.warn("Unable to determine quicklinks from " + providerUrl, e);
+ throw new RuntimeException(e.getMessage(), e);
+ } catch (IOException e) {
+ logger.warn("Unable to determine quicklinks from " + providerUrl, e);
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Provides only the interesting JMX metric names and values.
+ *
+ * @param jmxUrl
+ *
+ * @return
+ */
+ public Map<String, String> getJmx(String jmxUrl, ViewContext context, SliderAppType appType) {
+ Map<String, String> jmxProperties = new HashMap<String, String>();
+ if (appType == null) {
+ logger.info("AppType must be provided to extract jmx properties");
+ return jmxProperties;
+ }
+
+ try {
+ URLStreamProvider streamProvider = context.getURLStreamProvider();
+ InputStream jmxStream = null;
+ Map<String, String> headers = new HashMap<String, String>();
+ try {
+ jmxStream = streamProvider.readFrom(jmxUrl, "GET", null, headers);
+ } catch (IOException e) {
+ logger.error(String.format("Unable to access JMX endpoint at %s. Error %s", jmxUrl, e.getMessage()));
+ }
+
+ if (jmxStream != null) {
+ ObjectMapper jmxObjectMapper = new ObjectMapper();
+ jmxObjectMapper.configure(DeserializationConfig.Feature.USE_ANNOTATIONS, false);
+ ObjectReader jmxObjectReader = jmxObjectMapper.reader(JMXMetricHolder.class);
+ JMXMetricHolder metricHolder = null;
+ try {
+ metricHolder = jmxObjectReader.readValue(jmxStream);
+ } catch (IOException e) {
+ logger.error(String.format("Malformed jmx data from %s. Error %s", jmxUrl, e.getMessage()));
+ }
+
+ Map<String, Map<String, Object>> categories = new HashMap<String, Map<String, Object>>();
+
+ for (Map<String, Object> bean : metricHolder.getBeans()) {
+ String category = getCategory(bean);
+ if (category != null) {
+ categories.put(category, bean);
+ }
+ }
+
+ List<String> components = new ArrayList<String>();
+ for (SliderAppTypeComponent appTypeComponent : appType.getTypeComponents()) {
+ components.add(appTypeComponent.getName());
+ }
+
+ Map<String, Map<String, Map<String, Metric>>> metrics = appType.getJmxMetrics();
+ Map<String, Metric> relevantMetrics = getRelevantMetrics(metrics, components);
+ addJmxProperties(jmxProperties, categories, relevantMetrics);
+ }
+ } catch (Exception e) {
+ logger.info("Failed to extract jmx metrics. " + e.getMessage());
+ }
+
+ return jmxProperties;
+ }
+
+ protected void addJmxProperties(Map<String, String> jmxProperties,
+ Map<String, Map<String, Object>> categories,
+ Map<String, Metric> relevantMetrics) {
+ for (String metricName : relevantMetrics.keySet()) {
+ Metric metric = relevantMetrics.get(metricName);
+ String beanName = metric.getKeyName();
+ Object value = categories.get(beanName);
+ if (value instanceof Map) {
+ Map<?, ?> map = (Map<?, ?>) value;
+ for (List<String> matcher : metric.getMatchers()) {
+ boolean foundMetrics = false;
+ for (int matchIndex = 0; matchIndex < matcher.size(); matchIndex++) {
+ String matchKey = matcher.get(matchIndex);
+ value = map.get(matchKey);
+ if (value instanceof Map) {
+ map = (Map<?, ?>) value;
+ continue;
+ } else {
+ if (value != null && matchIndex == matcher.size() - 1) {
+ jmxProperties.put(metricName, value.toString());
+ foundMetrics = true;
+ } else {
+ break;
+ }
+ }
+ }
+ if (foundMetrics) {
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ private Map<String, Metric> getRelevantMetrics(Map<String, Map<String, Map<String, Metric>>> metrics,
+ List<String> comps) {
+ Map<String, Metric> relevantMetrics = new HashMap<String, Metric>();
+ for (String comp : comps) {
+ for (Map<String, Map<String, Metric>> m : metrics.values()) {
+ if (m.containsKey(comp)) {
+ relevantMetrics.putAll(m.get(comp));
+ }
+ }
+ }
+ return relevantMetrics;
+ }
+
+ private String getCategory(Map<String, Object> bean) {
+ if (bean.containsKey(NAME_KEY)) {
+ String name = (String) bean.get(NAME_KEY);
+
+ if (bean.containsKey(PORT_KEY)) {
+ String port = (String) bean.get(PORT_KEY);
+ name = name.replace(FORPORT_KEY + port, "");
+ }
+ return name;
+ }
+ return null;
+ }
+
+ public static class SliderAppMasterData {
+ public String registryUrl;
+ public String uiUrl;
+ public String managementUrl;
+ public String publisherUrl;
+ }
- private static final Logger logger = Logger
- .getLogger(SliderAppMasterClient.class);
-
- public static class SliderAppMasterData {
- public String registryUrl;
- public String uiUrl;
- public String managementUrl;
- public String publisherUrl;
- }
-
- public static class SliderAppContainerData {
- public String hostName;
- public String containerId;
- }
-
- public SliderAppMasterClient(String url) {
- super(url);
- }
-
- public SliderAppMasterData getAppMasterData() {
- try {
- String html = doGet("");
- int from = html.lastIndexOf("<ul>");
- int to = html.lastIndexOf("</ul>");
- if (from < to && from > -1) {
- SliderAppMasterData data = new SliderAppMasterData();
- String content = html.substring(from, to);
- content = content.replaceAll("<[^>]*>", "\r\n");
- String[] splits = content.split("\r\n");
- for (int i = 0; i < splits.length; i++) {
- String split = splits[i].trim();
- if ("Registry Web Service".equals(split))
- data.registryUrl = splits[i + 1].trim();
- else if ("Application Master Web UI".equals(split))
- data.uiUrl = splits[i + 1].trim();
- else if ("Management REST API".equals(split))
- data.managementUrl = splits[i + 1].trim();
- else if ("Publisher Service".equals(split))
- data.publisherUrl = splits[i + 1].trim();
- }
- return data;
- }
- } catch (HttpException e) {
- logger.warn("Unable to determine Ambari clusters", e);
- throw new RuntimeException(e.getMessage(), e);
- } catch (IOException e) {
- logger.warn("Unable to determine Ambari clusters", e);
- throw new RuntimeException(e.getMessage(), e);
- }
- return null;
- }
-
- public Map<String, String> getQuickLinks(String providerUrl) {
- try {
- JsonElement json = super.doGetJson(providerUrl, "/slider/quicklinks");
- Map<String, String> quickLinks = new HashMap<String, String>();
- JsonObject jsonObject = json.getAsJsonObject().get("entries")
- .getAsJsonObject();
- for (Entry<String, JsonElement> entry : jsonObject.entrySet()) {
- if ("org.apache.slider.jmx".equals(entry.getKey())) {
- quickLinks.put("JMX", entry.getValue().getAsString());
- } else if ("org.apache.slider.monitor".equals(entry.getKey())) {
- quickLinks.put("UI", entry.getValue().getAsString());
- } else if ("org.apache.slider.metrics".equals(entry.getKey())) {
- quickLinks.put("Metrics", entry.getValue().getAsString());
- } else {
- quickLinks.put(entry.getKey(), entry.getValue().getAsString());
- }
- }
- return quickLinks;
- } catch (HttpException e) {
- logger.warn("Unable to determine quicklinks from " + providerUrl, e);
- throw new RuntimeException(e.getMessage(), e);
- } catch (IOException e) {
- logger.warn("Unable to determine quicklinks from " + providerUrl, e);
- throw new RuntimeException(e.getMessage(), e);
- }
- }
-
- public Map<String, Map<String, String>> getConfigs(String providerUrl) {
- try {
- Map<String, Map<String, String>> configsMap = new HashMap<String, Map<String, String>>();
- JsonElement json = super.doGetJson(providerUrl, "/slider");
- if (json != null) {
- JsonObject configsJson = json.getAsJsonObject().get("configurations")
- .getAsJsonObject();
- for (Entry<String, JsonElement> entry : configsJson.entrySet()) {
- if ("complete-config".equals(entry.getKey())
- || "quicklinks".equals(entry.getKey()))
- continue;
- JsonElement entryJson = super.doGetJson(providerUrl, "/slider/"
- + entry.getKey());
- if (entryJson != null) {
- JsonObject configsObj = entryJson.getAsJsonObject().get("entries")
- .getAsJsonObject();
- if (configsObj != null) {
- Map<String, String> configs = new HashMap<String, String>();
- for (Entry<String, JsonElement> e : configsObj.entrySet()) {
- configs.put(e.getKey(), e.getValue().getAsString());
- }
- configsMap.put(entry.getKey(), configs);
- }
- }
- }
- }
- return configsMap;
- } catch (HttpException e) {
- logger.warn("Unable to determine quicklinks from " + providerUrl, e);
- throw new RuntimeException(e.getMessage(), e);
- } catch (IOException e) {
- logger.warn("Unable to determine quicklinks from " + providerUrl, e);
- throw new RuntimeException(e.getMessage(), e);
- }
- }
-
- /**
- * Provides only the interesting JMX metric names and values.
- *
- * @param jmxUrl
- * @return
- */
- public Map<String, String> getJmx(String jmxUrl) {
- // TODO Mechanism to filter JMX beans to get only interesting metrics is
- // needed.
- return null;
- }
+ public static class SliderAppContainerData {
+ public String hostName;
+ public String containerId;
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/52806bd7/contrib/views/slider/src/test/java/org/apache/ambari/view/slider/rest/client/SliderAppMasterClientTest.java
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/test/java/org/apache/ambari/view/slider/rest/client/SliderAppMasterClientTest.java b/contrib/views/slider/src/test/java/org/apache/ambari/view/slider/rest/client/SliderAppMasterClientTest.java
new file mode 100644
index 0000000..2c0aa1c
--- /dev/null
+++ b/contrib/views/slider/src/test/java/org/apache/ambari/view/slider/rest/client/SliderAppMasterClientTest.java
@@ -0,0 +1,96 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.slider.rest.client;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class SliderAppMasterClientTest {
+
+ @Test
+ public void testSliderClientClassAvailability() {
+ SliderAppMasterClient client = new SliderAppMasterClient("http://tmpurl.org");
+ Map<String, Metric> relevantMetric = new HashMap<String, Metric>();
+ Map<String, String> jmxProperties = new HashMap<String, String>();
+ Map<String, Map<String, Object>> categories = new HashMap<String, Map<String, Object>>();
+ relevantMetric.put("metricAverageLoad",
+ new Metric("Hadoop:service=HBase,name=Master,sub=Server.averageLoad", true, false));
+ relevantMetric.put("DeadRegionServers",
+ new Metric("Hadoop:service=HBase,name=Master,sub=Server.numDeadRegionServers", true, false));
+ relevantMetric.put("ClusterId",
+ new Metric("Hadoop:service=HBase,name=Master,sub=Server.tag.clusterId", true, false));
+ relevantMetric.put("IsActiveMaster",
+ new Metric("Hadoop:service=HBase,name=Master,sub=Server.tag.isActiveMaster", true, false));
+ relevantMetric.put("peakUsageCommitted",
+ new Metric("java#lang:type=MemoryPool,name=Code Cache.PeakUsage.committed", true, false));
+
+ Map<String, Object> masterServer = new HashMap<String, Object>();
+ masterServer.put("averageLoad", "0.1");
+ masterServer.put("numDeadRegionServers", "1");
+ masterServer.put("tag.clusterId", "11");
+ categories.put("Hadoop:service=HBase,name=Master,sub=Server", masterServer);
+ Map<String, Object> memPool = new HashMap<String, Object>();
+ Map<String, Object> peakUsage = new HashMap<String, Object>();
+ peakUsage.put("committed", 354);
+ peakUsage.put("uncommitted", 356);
+ memPool.put("PeakUsage", peakUsage);
+ memPool.put("SomeOther", "other");
+ categories.put("java.lang:type=MemoryPool,name=Code Cache", memPool);
+
+ client.addJmxProperties(jmxProperties, categories, relevantMetric);
+ Assert.assertEquals(jmxProperties.size(), 4);
+ }
+
+ @Test
+ public void testMetricMatchers() throws Exception {
+ Metric m1 = new Metric("a_b.c", true, false);
+ Assert.assertEquals(m1.getKeyName(), "a_b");
+ List<List<String>> matchers = m1.getMatchers();
+ Assert.assertEquals(matchers.size(), 1);
+ Assert.assertEquals(matchers.get(0).size(), 1);
+ Assert.assertEquals(matchers.get(0).get(0), "c");
+
+ m1 = new Metric("a_b.c.d", true, false);
+ Assert.assertEquals(m1.getKeyName(), "a_b");
+ matchers = m1.getMatchers();
+ Assert.assertEquals(matchers.size(), 2);
+ Assert.assertEquals(matchers.get(0).size(), 2);
+ Assert.assertEquals(matchers.get(0).get(0), "c");
+ Assert.assertEquals(matchers.get(0).get(1), "d");
+ Assert.assertEquals(matchers.get(1).size(), 1);
+ Assert.assertEquals(matchers.get(1).get(0), "c.d");
+
+ m1 = new Metric("a_b.c.d.e", true, false);
+ Assert.assertEquals(m1.getKeyName(), "a_b");
+ matchers = m1.getMatchers();
+ Assert.assertEquals(matchers.size(), 4);
+ Assert.assertEquals(matchers.get(0).size(), 3);
+ Assert.assertEquals(matchers.get(0).get(1), "d");
+ Assert.assertEquals(matchers.get(0).get(2), "e");
+ Assert.assertEquals(matchers.get(2).size(), 2);
+ Assert.assertEquals(matchers.get(2).get(0), "c.d");
+ Assert.assertEquals(matchers.get(2).get(1), "e");
+ Assert.assertEquals(matchers.get(3).size(), 1);
+ Assert.assertEquals(matchers.get(3).get(0), "c.d.e");
+ }
+}