AMBARI-7625. Slider View: Reduce view parameter count and provide /status API (srimanth)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/8cc65e39 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/8cc65e39 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/8cc65e39 Branch: refs/heads/branch-alerts-dev Commit: 8cc65e396f948591f22a9fa68d0e72401c155f4f Parents: 9299f92 Author: Srimanth Gunturi <[email protected]> Authored: Thu Oct 2 21:55:25 2014 -0700 Committer: Srimanth Gunturi <[email protected]> Committed: Thu Oct 2 23:39:13 2014 -0700 ---------------------------------------------------------------------- .../view/slider/SliderAppsViewController.java | 25 +- .../slider/SliderAppsViewControllerImpl.java | 270 +++++++++++++------ .../apache/ambari/view/slider/ViewStatus.java | 40 +++ .../slider/rest/client/AmbariHttpClient.java | 72 ++++- .../views/slider/src/main/resources/view.xml | 117 +++----- 5 files changed, 340 insertions(+), 184 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/8cc65e39/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewController.java ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewController.java b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewController.java index 9174e22..ea11bf9 100644 --- a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewController.java +++ b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewController.java @@ -31,25 +31,18 @@ import com.google.inject.ImplementedBy; @ImplementedBy(SliderAppsViewControllerImpl.class) public interface SliderAppsViewController { - public static final String PROPERTY_HDFS_ADDRESS = "hdfs.url"; - public static final String PROPERTY_YARN_RM_ADDRESS = "yarn.rm.url"; - public static final String PROPERTY_YARN_RM_WEBAPP_ADDRESS = "yarn.rm.webapp.url"; - public static final String PROPERTY_YARN_RM_SCHEDULER_ADDRESS = "yarn.rm.scheduler.url"; - public static final String PROPERTY_ZK_QUOROM = "zookeeper.quorum"; - // Ganglia + public static final String PARAM_AMBARI_CLUSTER_API = "ambari.server.url"; + public static final String PARAM_AMBARI_USERNAME = "ambari.server.username"; + public static final String PARAM_AMBARI_PASSWORD = "ambari.server.password"; + public static final String PARAM_SLIDER_USER = "slider.user"; + public static final String PARAM_VIEW_PRINCIPAL = "view.kerberos.principal"; + public static final String PARAM_VIEW_PRINCIPAL_KEYTAB= "view.kerberos.principal.keytab"; + + public static final String PROPERTY_SLIDER_ZK_QUORUM = "slider.zookeeper.quorum"; public static final String PROPERTY_GANGLIA_SERVER_HOSTNAME = "ganglia.server.hostname"; public static final String PROPERTY_GANGLIA_CUSTOM_CLUSTERS = "ganglia.additional.clusters"; - // Security - public static final String PROPERTY_SLIDER_USER = "slider.user"; + public static final String PROPERTY_YARN_RM_WEBAPP_URL = "yarn.rm.webapp.url"; public static final String PROPERTY_SLIDER_SECURITY_ENABLED = "slider.security.enabled"; - public static final String PROPERTY_YARN_RM_PRINCIPAL = "yarn.rm.kerberos.principal"; - public static final String PROPERTY_HDFS_NN_PRINCIPAL = "dfs.namenode.kerberos.principal"; - public static final String PROPERTY_VIEW_PRINCIPAL = "view.kerberos.principal"; - public static final String PROPERTY_VIEW_PRINCIPAL_KEYTAB= "view.kerberos.principal.keytab"; - // HA - public static final String PROPERTY_YARN_RM_HA_HOSTS = "yarm.rm.ha.hosts"; - public static final String PROPERTY_YARN_RM_STORE_CLASS = "yarn.rm.store.class"; - public static final String PROPERTY_YARN_RM_HA_AUTO_FAILOVER_ZKPATH = "yarn.rm.ha.automatic-failover.zk-base-path"; public ViewStatus getViewStatus(); http://git-wip-us.apache.org/repos/asf/ambari/blob/8cc65e39/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 3829155..e23fdd6 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 @@ -36,6 +36,12 @@ import java.util.Set; import java.util.zip.ZipException; import org.apache.ambari.view.ViewContext; +import org.apache.ambari.view.slider.clients.AmbariCluster; +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.AmbariHttpClient; 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; @@ -85,6 +91,7 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { @Inject private ViewContext viewContext; private List<SliderAppType> appTypes; + private Map<String, String> hadoopConfigs; private Integer createAppCounter = -1; @Inject private SliderAppsAlerts sliderAlerts; @@ -101,7 +108,154 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { @Override public ViewStatus getViewStatus() { ViewStatus status = new ViewStatus(); + Map<String, String> newHadoopConfigs = new HashMap<String, String>(); status.setVersion(SliderAppsConfiguration.INSTANCE.getVersion()); + String ambariCluster = getViewParameterValue(PARAM_AMBARI_CLUSTER_API); + String ambariUsername = getViewParameterValue(PARAM_AMBARI_USERNAME); + String ambariPassword = getViewParameterValue(PARAM_AMBARI_PASSWORD); + if (ambariCluster != null && ambariUsername != null + && ambariPassword != null && ambariCluster.trim().length() > 0 + && ambariUsername.trim().length() > 0 + && ambariPassword.trim().length() > 0) { + String APIPREFIX = "/api/v1/clusters/"; + int index = ambariCluster.indexOf(APIPREFIX); + if (index > 0) { + String ambariUrl = ambariCluster.substring(0, index); + String clusterName = ambariCluster + .substring(index + APIPREFIX.length()); + if (clusterName.endsWith("/")) { + clusterName = clusterName.substring(0, clusterName.length() - 1); + } + AmbariHttpClient ambariClient = new AmbariHttpClient(ambariUrl, + ambariUsername, ambariPassword); + AmbariClusterInfo clusterInfo = ambariClient.getClusterInfo(); + if (clusterName.equals(clusterInfo.getName())) { + AmbariCluster cluster = ambariClient.getCluster(clusterInfo); + AmbariServiceInfo hdfsServiceInfo = null; + AmbariServiceInfo yarnServiceInfo = null; + for (AmbariServiceInfo svc : cluster.getServices()) { + if ("HDFS".equals(svc.getId())) { + hdfsServiceInfo = svc; + } else if ("YARN".equals(svc.getId())) { + yarnServiceInfo = svc; + } + } + // HDFS + if (hdfsServiceInfo != null) { + if (!hdfsServiceInfo.isStarted()) { + status.getValidations().add( + new ViewStatus.Validation("HDFS service is not started")); + } + } else { + status.getValidations().add( + new ViewStatus.Validation("HDFS service is not installed")); + } + // YARN + if (yarnServiceInfo != null) { + if (!yarnServiceInfo.isStarted()) { + status.getValidations().add( + new ViewStatus.Validation("YARN service is not started")); + } + } else { + status.getValidations().add( + new ViewStatus.Validation("YARN service is not installed")); + } + // Configs + if (cluster.getDesiredConfigs().containsKey("core-site")) { + Map<String, String> coreSiteConfigs = ambariClient + .getConfiguration(cluster, "core-site", cluster + .getDesiredConfigs().get("core-site")); + newHadoopConfigs.putAll(coreSiteConfigs); + } + if (cluster.getDesiredConfigs().containsKey("cluster-env")) { + Map<String, String> clusterEnvConfigs = ambariClient + .getConfiguration(cluster, "cluster-env", cluster + .getDesiredConfigs().get("cluster-env")); + newHadoopConfigs.put("security_enabled", + clusterEnvConfigs.get("security_enabled")); + } + if (cluster.getDesiredConfigs().containsKey("yarn-site")) { + Map<String, String> yarnSiteConfigs = ambariClient + .getConfiguration(cluster, "yarn-site", cluster + .getDesiredConfigs().get("yarn-site")); + newHadoopConfigs.putAll(yarnSiteConfigs); + status.getParameters().put(PROPERTY_YARN_RM_WEBAPP_URL, + newHadoopConfigs.get("yarn.resourcemanager.webapp.address")); + } + if (cluster.getDesiredConfigs().containsKey("zookeeper-env")) { + Map<String, String> zkEnvConfigs = ambariClient.getConfiguration( + cluster, "zookeeper-env", + cluster.getDesiredConfigs().get("zookeeper-env")); + StringBuilder zkQuorumBuilder = new StringBuilder(); + String port = zkEnvConfigs.get("clientPort"); + AmbariService zkService = ambariClient.getService(cluster, + "ZOOKEEPER"); + if (zkService != null) { + List<AmbariHostComponent> hostsList = zkService + .getComponentsToHostComponentsMap().get("ZOOKEEPER_SERVER"); + int count = 1; + for (AmbariHostComponent host : hostsList) { + zkQuorumBuilder.append(host.getHostName() + ":" + port); + if (count++ < hostsList.size()) { + zkQuorumBuilder.append(","); + } + } + newHadoopConfigs.put(PROPERTY_SLIDER_ZK_QUORUM, + zkQuorumBuilder.toString()); + } else { + status.getValidations().add( + new ViewStatus.Validation( + "ZooKeeper service is not installed")); + } + } else { + status.getValidations() + .add( + new ViewStatus.Validation( + "ZooKeeper service is not installed")); + } + if (cluster.getDesiredConfigs().containsKey("ganglia-env")) { + Map<String, String> gangliaConfigs = ambariClient.getConfiguration( + cluster, "ganglia-env", + cluster.getDesiredConfigs().get("ganglia-env")); + String clustersCsv = gangliaConfigs.get("additional_clusters"); + AmbariService gangliaService = ambariClient.getService(cluster, + "GANGLIA"); + List<AmbariHostComponent> hostsList = gangliaService + .getComponentsToHostComponentsMap().get("GANGLIA_SERVER"); + if (hostsList != null && hostsList.size() > 0) { + String gangliaHostName = hostsList + .get(0).getHostName(); + newHadoopConfigs.put(PROPERTY_GANGLIA_SERVER_HOSTNAME, gangliaHostName); + status.getParameters().put(PROPERTY_GANGLIA_SERVER_HOSTNAME, gangliaHostName); + } + newHadoopConfigs.put(PROPERTY_GANGLIA_CUSTOM_CLUSTERS, clustersCsv); + status.getParameters().put(PROPERTY_GANGLIA_CUSTOM_CLUSTERS, clustersCsv); + } + } else { + status.getValidations().add( + new ViewStatus.Validation("Ambari cluster with ID [" + + clusterName + "] was not found on Ambari server")); + } + } else { + status + .getValidations() + .add( + new ViewStatus.Validation( + "Ambari server cluster API URL should include cluster name, for example http://ambari.server:8080/api/v1/clusters/c1")); + } + } else { + status.getValidations().add( + new ViewStatus.Validation( + "View parameters specifying Ambari details required")); + } + Set<String> removeKeys = new HashSet<String>(viewContext.getInstanceData().keySet()); + for (Entry<String, String> e : newHadoopConfigs.entrySet()) { + viewContext.putInstanceData(e.getKey(), e.getValue()); + removeKeys.remove(e.getKey()); + } + for (String key : removeKeys) { + viewContext.removeInstanceData(key); + } return status; } @@ -128,7 +282,7 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { } private String getUserToRunAs() { - String user = getViewParameterValue(PROPERTY_SLIDER_USER); + String user = getViewParameterValue(PARAM_SLIDER_USER); if (user == null || user.trim().length() < 1) { return "yarn"; } else if ("${username}".equals(user)) { @@ -145,26 +299,25 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { boolean securityEnabled = Boolean.valueOf(getViewParameterValue(PROPERTY_SLIDER_SECURITY_ENABLED)); UserGroupInformation sliderUser; if (securityEnabled) { - String viewPrincipal = getViewParameterValue(PROPERTY_VIEW_PRINCIPAL); - String viewPrincipalKeytab = getViewParameterValue(PROPERTY_VIEW_PRINCIPAL_KEYTAB); + String viewPrincipal = getViewParameterValue(PARAM_VIEW_PRINCIPAL); + String viewPrincipalKeytab = getViewParameterValue(PARAM_VIEW_PRINCIPAL_KEYTAB); UserGroupInformation ambariUser = UserGroupInformation.loginUserFromKeytabAndReturnUGI(viewPrincipal, viewPrincipalKeytab); sliderUser = UserGroupInformation.createProxyUser(getUserToRunAs(), ambariUser); } else { sliderUser = UserGroupInformation.getBestUGI(null, getUserToRunAs()); } - try{ - T value = sliderUser.doAs( - new PrivilegedExceptionAction<T>() { - @Override - public T run() throws Exception { - final SliderClient sliderClient = createSliderClient(); - try{ - return runnable.run(sliderClient); - }finally{ - destroySliderClient(sliderClient); - } - } - }); + try { + T value = sliderUser.doAs(new PrivilegedExceptionAction<T>() { + @Override + public T run() throws Exception { + final SliderClient sliderClient = createSliderClient(); + try { + return runnable.run(sliderClient); + } finally { + destroySliderClient(sliderClient); + } + } + }); return value; } catch (UndeclaredThrowableException e) { Throwable cause = e.getCause(); @@ -178,7 +331,7 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { Thread.currentThread().setContextClassLoader(currentClassLoader); } } - + @Override public SliderApp getSliderApp(final String applicationId, final Set<String> properties) throws YarnException, IOException, InterruptedException { @@ -463,6 +616,13 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { return value; } + protected Map<String, String> getHadoopConfigs() { + if(hadoopConfigs==null) { + hadoopConfigs = viewContext.getInstanceData(); + } + return hadoopConfigs; + } + /** * Dynamically determines Slider client configuration. If unable to determine, * <code>null</code> is returned. @@ -470,79 +630,27 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { * @return */ private Configuration getSliderClientConfiguration() { - String hdfsPath = getViewParameterValue(PROPERTY_HDFS_ADDRESS); - String rmAddress = getViewParameterValue(PROPERTY_YARN_RM_ADDRESS); - String rmSchedulerAddress = getViewParameterValue(PROPERTY_YARN_RM_SCHEDULER_ADDRESS); - String zkQuorum = getViewParameterValue(PROPERTY_ZK_QUOROM); - boolean securedCluster = Boolean.valueOf(getViewParameterValue(PROPERTY_SLIDER_SECURITY_ENABLED)); - String rmHAHosts = getViewParameterValue(PROPERTY_YARN_RM_HA_HOSTS); - String rmStoreClass = getViewParameterValue(PROPERTY_YARN_RM_STORE_CLASS); - String rmHAAutoFailoverPath = getViewParameterValue(PROPERTY_YARN_RM_HA_AUTO_FAILOVER_ZKPATH); - HdfsConfiguration hdfsConfig = new HdfsConfiguration(); YarnConfiguration yarnConfig = new YarnConfiguration(hdfsConfig); - 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()); - yarnConfig.set("yarn.application.classpath", - "/etc/hadoop/conf,/usr/hdp/current/hadoop/*,/usr/hdp/current/hadoop/lib/*,/usr/hdp/current/hadoop-hdfs/*,/usr/hdp/current/hadoop-hdfs/lib/*,/usr/hdp/current/hadoop-yarn/*,/usr/hdp/current/hadoop-yarn/lib/*,/usr/hdp/current/hadoop-mapreduce/*,/usr/hdp/current/hadoop-mapreduce/lib/*"); - - if (securedCluster) { - String rmPrincipal = getViewParameterValue(PROPERTY_YARN_RM_PRINCIPAL); - String nnPrincipal = getViewParameterValue(PROPERTY_HDFS_NN_PRINCIPAL); - yarnConfig.set("yarn.resourcemanager.principal", rmPrincipal); - yarnConfig.set("dfs.namenode.kerberos.principal", nnPrincipal); - yarnConfig.set("hadoop.security.authorization", "true"); - yarnConfig.set("hadoop.security.authentication", "kerberos"); - yarnConfig.set("slider.security.enabled", "true"); + Map<String, String> hadoopConfigs = getHadoopConfigs(); + for(Entry<String, String> entry: hadoopConfigs.entrySet()) { + yarnConfig.set(entry.getKey(), entry.getValue()); } - - if (rmHAHosts != null && rmHAHosts.trim().length() > 0 && rmStoreClass!=null && rmHAAutoFailoverPath!=null) { - yarnConfig.set("yarn.resourcemanager.ha.enabled", "true"); - yarnConfig.set("yarn.resourcemanager.cluster-id", "yarn-cluster"); - yarnConfig.set("yarn.resourcemanager.recovery.enabled", "true"); - yarnConfig.set("yarn.resourcemanager.store.class", rmStoreClass); - yarnConfig.set("yarn.resourcemanager.ha.automatic-failover.zk-base-path", - rmHAAutoFailoverPath); - // ZK - int count = 1; - String[] zkHostPorts = zkQuorum.split(","); - StringBuffer zkHosts = new StringBuffer(); - for (String zkHostPort : zkHostPorts) { - String host = zkHostPort.split(":")[0]; - zkHosts.append(host); - if (count++ < zkHostPorts.length) { - zkHosts.append(","); - } - } - yarnConfig.set("yarn.resourcemanager.zk-address", zkHosts.toString()); - // HA Ids - StringBuffer rmIds = new StringBuffer(); - String[] hosts = rmHAHosts.trim().split(","); - count = 1; - for (String host : hosts) { - String rmId = "rm" + Integer.toString(count++); - rmIds.append(rmId); - if (count <= hosts.length) { - rmIds.append(","); - } - yarnConfig.set("yarn.resourcemanager.hostname." + rmId, host.trim()); - } - yarnConfig.set("yarn.resourcemanager.ha.rm-ids", rmIds.toString()); + yarnConfig.set("slider.security.enabled", hadoopConfigs.get("security_enabled")); + yarnConfig.set("slider.yarn.queue", "default"); //TODO Remove? + if (hadoopConfigs.containsKey(PROPERTY_SLIDER_ZK_QUORUM)) { + yarnConfig.set(PROPERTY_SLIDER_ZK_QUORUM, hadoopConfigs.get(PROPERTY_SLIDER_ZK_QUORUM)); } return yarnConfig; } private boolean areViewParametersSet() { - String hdfsPath = getViewParameterValue(PROPERTY_HDFS_ADDRESS); - String rmAddress = getViewParameterValue(PROPERTY_YARN_RM_ADDRESS); - String rmSchedulerAddress = getViewParameterValue(PROPERTY_YARN_RM_SCHEDULER_ADDRESS); - String zkQuorum = getViewParameterValue(PROPERTY_ZK_QUOROM); - return hdfsPath!=null && rmAddress!=null && rmSchedulerAddress!=null && zkQuorum!=null; + Map<String, String> hadoopConfigs = getHadoopConfigs(); + return hadoopConfigs.containsKey("fs.defaultFS") + && hadoopConfigs.containsKey("yarn.resourcemanager.address") + && hadoopConfigs.containsKey("yarn.resourcemanager.webapp.address") + && hadoopConfigs.containsKey(PROPERTY_SLIDER_ZK_QUORUM); } @Override http://git-wip-us.apache.org/repos/asf/ambari/blob/8cc65e39/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/ViewStatus.java ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/ViewStatus.java b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/ViewStatus.java index b9dbbbd..49761dc 100644 --- a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/ViewStatus.java +++ b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/ViewStatus.java @@ -18,9 +18,33 @@ package org.apache.ambari.view.slider; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; public class ViewStatus { + public static class Validation { + public static enum TYPE { + ERROR, WARN + } + + public String message; + public String type; + + public Validation(String message, String type) { + this.message = message; + this.type = type; + } + public Validation(String message) { + this.message = message; + this.type = TYPE.ERROR.name(); + } + } + private String version; + private Map<String, String> parameters = new HashMap<String, String>(); + private List<Validation> validations = new ArrayList<ViewStatus.Validation>(); public String getVersion() { return version; @@ -29,4 +53,20 @@ public class ViewStatus { public void setVersion(String version) { this.version = version; } + + public Map<String, String> getParameters() { + return parameters; + } + + public void setParameters(Map<String, String> parameters) { + this.parameters = parameters; + } + + public List<Validation> getValidations() { + return validations; + } + + public void setValidations(List<Validation> validations) { + this.validations = validations; + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/8cc65e39/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/AmbariHttpClient.java ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/AmbariHttpClient.java b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/AmbariHttpClient.java index 1480237..6229f0d 100644 --- a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/AmbariHttpClient.java +++ b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/AmbariHttpClient.java @@ -27,6 +27,7 @@ import java.util.Map; import org.apache.ambari.view.slider.clients.AmbariClient; import org.apache.ambari.view.slider.clients.AmbariCluster; import org.apache.ambari.view.slider.clients.AmbariClusterInfo; +import org.apache.ambari.view.slider.clients.AmbariHostComponent; import org.apache.ambari.view.slider.clients.AmbariHostInfo; import org.apache.ambari.view.slider.clients.AmbariService; import org.apache.ambari.view.slider.clients.AmbariServiceInfo; @@ -77,13 +78,14 @@ public class AmbariHttpClient extends BaseHttpClient implements AmbariClient { if (clusterInfo != null) { try { JsonElement jsonElement = doGetJson("/api/v1/clusters/" - + clusterInfo.getName()); + + clusterInfo.getName() + "?fields=services/ServiceInfo,hosts,Clusters"); if (jsonElement != null) { AmbariCluster cluster = new AmbariCluster(); // desired configs Map<String, String> desiredConfigs = new HashMap<String, String>(); - JsonObject desiredConfigsObj = jsonElement.getAsJsonObject() - .get("Clusters").getAsJsonObject().get("desired_configs") + JsonObject jsonObject = jsonElement.getAsJsonObject(); + JsonObject clustersJsonObject = jsonObject.get("Clusters").getAsJsonObject(); + JsonObject desiredConfigsObj = clustersJsonObject.get("desired_configs") .getAsJsonObject(); for (Map.Entry<String, JsonElement> entry : desiredConfigsObj .entrySet()) { @@ -91,11 +93,30 @@ public class AmbariHttpClient extends BaseHttpClient implements AmbariClient { .getAsJsonObject().get("tag").getAsString()); } cluster.setDesiredConfigs(desiredConfigs); + cluster.setName(clustersJsonObject.get("cluster_name").getAsString()); + cluster.setVersion(clustersJsonObject.get("version").getAsString()); // services - List<AmbariServiceInfo> services = new ArrayList<AmbariServiceInfo>(); + List<AmbariServiceInfo> services = new ArrayList<AmbariServiceInfo>(); + for (JsonElement svcJson : jsonObject.get("services") + .getAsJsonArray()) { + AmbariServiceInfo si = new AmbariServiceInfo(); + si.setId(svcJson.getAsJsonObject().get("ServiceInfo") + .getAsJsonObject().get("service_name").getAsString()); + si.setStarted("STARTED".equals(svcJson.getAsJsonObject() + .get("ServiceInfo").getAsJsonObject().get("state") + .getAsString())); + services.add(si); + } cluster.setServices(services); // hosts List<AmbariHostInfo> hosts = new ArrayList<AmbariHostInfo>(); + for (JsonElement hostJson : jsonObject.get("hosts") + .getAsJsonArray()) { + AmbariHostInfo hi = new AmbariHostInfo(); + hi.setHostName(hostJson.getAsJsonObject().get("Hosts") + .getAsJsonObject().get("host_name").getAsString()); + hosts.add(hi); + } cluster.setHosts(hosts); return cluster; } @@ -143,8 +164,45 @@ public class AmbariHttpClient extends BaseHttpClient implements AmbariClient { @Override public AmbariService getService(AmbariClusterInfo cluster, String serviceId) { - // TODO Auto-generated method stub - return null; - } + if (cluster != null && serviceId != null) { + try { + JsonElement jsonElement = doGetJson("/api/v1/clusters/" + + cluster.getName() + "/services/" + serviceId + "?fields=ServiceInfo,components/host_components/HostRoles"); + JsonObject jsonObject = jsonElement.getAsJsonObject(); + if (jsonObject.has("status") && "404".equals(jsonObject.get("status").getAsString())) { + return null; + } + AmbariService svc = new AmbariService(); + JsonObject serviceInfoJsonObject = jsonObject.get("ServiceInfo").getAsJsonObject(); + svc.setId(serviceInfoJsonObject.get("service_name").getAsString()); + svc.setStarted("STARTED".equals(serviceInfoJsonObject.get("state").getAsString())); + svc.setMaintenanceMode(!"OFF".equals(serviceInfoJsonObject.get("maintenance_state").getAsString())); + Map<String, List<AmbariHostComponent>> componentsToHostComponentsMap = new HashMap<String, List<AmbariHostComponent>>(); + for(JsonElement ce: jsonObject.get("components").getAsJsonArray()){ + String componentName = ce.getAsJsonObject().get("ServiceComponentInfo").getAsJsonObject().get("component_name").getAsString(); + List<AmbariHostComponent> hcList = new ArrayList<AmbariHostComponent>(); + componentsToHostComponentsMap.put(componentName, hcList); + JsonArray hcJsonArray = ce.getAsJsonObject().get("host_components").getAsJsonArray(); + for(JsonElement hce: hcJsonArray) { + AmbariHostComponent hc = new AmbariHostComponent(); + JsonObject hcJsonObject = hce.getAsJsonObject().get("HostRoles").getAsJsonObject(); + hc.setHostName(hcJsonObject.get("host_name").getAsString()); + hc.setStarted("STARTED".equals(hcJsonObject.get("state").getAsString())); + hc.setName(hcJsonObject.get("component_name").getAsString()); + hcList.add(hc); + } + } + svc.setComponentsToHostComponentsMap(componentsToHostComponentsMap); + return svc; + } 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; +} } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/8cc65e39/contrib/views/slider/src/main/resources/view.xml ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/view.xml b/contrib/views/slider/src/main/resources/view.xml index 2c6ca0f..8f8b78b 100644 --- a/contrib/views/slider/src/main/resources/view.xml +++ b/contrib/views/slider/src/main/resources/view.xml @@ -18,86 +18,43 @@ limitations under the License. Kerberos, LDAP, Custom. Binary/Htt <name>SLIDER</name> <label>Slider Apps View</label> <version>1.0.0</version> - <parameter> - <name>hdfs.url</name> - <description>The URL to access HDFS service via its protocol. Typically this is the fs.defaultFS property in the core-site.xml configuration file. For example: hdfs://hdfs.namenode.host:8020.</description> - <required>true</required> - </parameter> - <parameter> - <name>yarn.rm.url</name> - <description>The URL to the YARN ResourceManager, used to provide YARN Application data. For example: http://yarn.resourcemanager.host:8050</description> - <required>true</required> - </parameter> - <parameter> - <name>yarn.rm.webapp.url</name> - <description>The URL to the YARN ResourceManager Web Application, used to provide YARN UI. Typically this is the yarn.resourcemanager.webapp.address config from yarn-site.xml configuration file. For example: http://yarn.resourcemanager.host:8088</description> - <required>true</required> - </parameter> - <parameter> - <name>yarn.rm.scheduler.url</name> - <description>The URL to the YARN ResourceManager Scheduler, which schedules YARN Applications. For example: http://yarn.resourcemanager.host:8030</description> - <required>true</required> - </parameter> - <parameter> - <name>zookeeper.quorum</name> - <description>ZooKeeper quorum location. Typically this is a comma separated list of ZooKeeper hostnames and port numbers (clientPort property in the zookeeper-env). For example: zookeeper.host1:2181,zookeeper.host2:2181.</description> - <required>true</required> - </parameter> - <parameter> - <name>ganglia.server.hostname</name> - <description>Hostname where Ganglia Server is located</description> - <required>false</required> - </parameter> - <parameter> - <name>ganglia.additional.clusters</name> - <description>Ganglia clusters which can be used by applications created in Slider Apps view. Value is comma separated list of cluster-name and port pairs. Typically this is the additional_clusters in the ganglia-env configuration. For example: Application1:8881,Application2:8882</description> - <required>false</required> - </parameter> - <parameter> - <name>slider.user</name> - <description>Slider user</description> - <required>false</required> - </parameter> - <parameter> - <name>slider.security.enabled</name> - <description>Indicates whether cluster has been secured or not.</description> - <required>true</required> - </parameter> - <parameter> - <name>yarn.rm.kerberos.principal</name> - <description>Kerberos principal used to access YARN ResourceManager. For example: rm/[email protected]</description> - <required>optional</required> - </parameter> - <parameter> - <name>dfs.namenode.kerberos.principal</name> - <description>Kerberos principal used to access HDFS NameNode. For example: nn/[email protected]</description> - <required>optional</required> - </parameter> - <parameter> - <name>view.kerberos.principal</name> - <description>Kerberos principal associated with this view. For example: ambari/[email protected]</description> - <required>optional</required> - </parameter> - <parameter> - <name>view.kerberos.principal.keytab</name> - <description>Path to the Kerberos principal keytab used for view's user. For example: /etc/security/keytabs/ambari.headless.keytab</description> - <required>optional</required> - </parameter> - <parameter> - <name>yarm.rm.ha.hosts</name> - <description>Hostnames where YARN ResourceManagers are available when High Availability is enabled. Value should be a comma separated list of host names</description> - <required>optional</required> - </parameter> - <parameter> - <name>yarn.rm.store.class</name> - <description>Name of class used by YARN ResourceManager to persist its state. For example some of the classes are 'org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore', or 'org.apache.hadoop.yarn.server.resourcemanager.recovery.FileSystemRMStateStore'</description> - <required>optional</required> - </parameter> - <parameter> - <name>yarn.rm.ha.automatic-failover.zk-base-path</name> - <description>The base path in ZooKeeper used for storing leader information. This is used when ZooKeeper based leader election is performed. For example: '/yarn-leader-election'</description> - <required>optional</required> - </parameter> + <parameter> + <name>ambari.server.url</name> + <description>Ambari Server Cluster REST API URL (for example: + http://ambari.server:8080/api/v1/clusters/c1)</description> + <required>true</required> + </parameter> + <parameter> + <name>ambari.server.username</name> + <description>Ambari administrator username (for example: admin) + </description> + <required>true</required> + </parameter> + <parameter> + <name>ambari.server.password</name> + <description>Ambari administrator password (for example: admin) + </description> + <required>true</required> + </parameter> + <parameter> + <name>slider.user</name> + <description>Slider user</description> + <required>false</required> + </parameter> + <parameter> + <name>view.kerberos.principal</name> + <description>Kerberos principal associated with this view. For + example: ambari/[email protected] + </description> + <required>optional</required> + </parameter> + <parameter> + <name>view.kerberos.principal.keytab</name> + <description>Path to the Kerberos principal keytab used for view's + user. For example: /etc/security/keytabs/ambari.headless.keytab + </description> + <required>optional</required> + </parameter> <resource> <name>status</name> <service-class>org.apache.ambari.view.slider.rest.ViewStatusResource</service-class>
