Repository: ambari Updated Branches: refs/heads/branch-1.6.0.slider 9789595a2 -> 71aa9236d
AMBARI-5925. Provide HDFS and YARN urls in slider apps table page. (srimanth) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/71aa9236 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/71aa9236 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/71aa9236 Branch: refs/heads/branch-1.6.0.slider Commit: 71aa9236d9b3d7599fb03b51ac503dcb15539184 Parents: 9789595 Author: Srimanth Gunturi <[email protected]> Authored: Thu May 29 01:09:30 2014 -0700 Committer: Srimanth Gunturi <[email protected]> Committed: Thu May 29 01:09:30 2014 -0700 ---------------------------------------------------------------------- .../slider/SliderAppsViewControllerImpl.java | 181 +++++++++++-------- .../apache/ambari/view/slider/ViewStatus.java | 64 ++++--- .../app/assets/data/resource/status_false.json | 6 +- .../app/assets/data/resource/status_true.json | 6 +- .../src/main/resources/ui/app/initialize.js | 7 +- .../ui/app/mappers/application_status.js | 1 + .../resources/ui/app/templates/slider_apps.hbs | 22 +++ .../resources/ui/app/views/slider_apps_view.js | 14 +- 8 files changed, 195 insertions(+), 106 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/71aa9236/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 adfa68f..7ff7b82 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,13 +18,22 @@ package org.apache.ambari.view.slider; -import com.google.gson.Gson; -import com.google.gson.JsonArray; -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.FileOutputStream; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Field; +import java.security.PrivilegedExceptionAction; +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 org.apache.ambari.view.ViewContext; import org.apache.ambari.view.slider.clients.AmbariClient; import org.apache.ambari.view.slider.clients.AmbariCluster; @@ -66,21 +75,13 @@ import org.apache.tools.zip.ZipFile; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.type.TypeReference; -import java.io.File; -import java.io.FileOutputStream; -import java.io.FilenameFilter; -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.Field; -import java.security.PrivilegedExceptionAction; -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.Gson; +import com.google.gson.JsonArray; +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; @Singleton public class SliderAppsViewControllerImpl implements SliderAppsViewController { @@ -96,8 +97,8 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { private String getAppsFolderPath() { return viewContext - .getAmbariProperty(org.apache.ambari.server.configuration.Configuration.RESOURCES_DIR_KEY) - + "/apps"; + .getAmbariProperty(org.apache.ambari.server.configuration.Configuration.RESOURCES_DIR_KEY) + + "/apps"; } private String getAppsCreateFolderPath() { @@ -108,6 +109,7 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { public ViewStatus getViewStatus() { ViewStatus status = new ViewStatus(); List<String> viewErrors = new ArrayList<String>(); + Map<String, String> viewUrls = new HashMap<String, String>(); AmbariClusterInfo clusterInfo = ambariClient.getClusterInfo(); if (clusterInfo != null) { @@ -172,12 +174,37 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { viewErrors .add("Slider applications view is unable to determine the security status of the cluster"); } + // HDFS URL + if (cluster.getDesiredConfigs() != null + && cluster.getDesiredConfigs().containsKey("hdfs-site")) { + Map<String, String> hdfsConfig = ambariClient.getConfiguration( + clusterInfo, "hdfs-site", + cluster.getDesiredConfigs().get("hdfs-site")); + if (hdfsConfig != null + && hdfsConfig.containsKey("dfs.namenode.http-address")) { + viewUrls.put("dfs.namenode.http-address", + "http://" + hdfsConfig.get("dfs.namenode.http-address")); + } + } + // YARN URL + if (cluster.getDesiredConfigs() != null + && cluster.getDesiredConfigs().containsKey("yarn-site")) { + Map<String, String> yarnConfig = ambariClient.getConfiguration( + clusterInfo, "yarn-site", + cluster.getDesiredConfigs().get("yarn-site")); + if (yarnConfig != null + && yarnConfig.containsKey("yarn.resourcemanager.webapp.address")) { + viewUrls.put("yarn.resourcemanager.webapp.address", "http://" + + yarnConfig.get("yarn.resourcemanager.webapp.address")); + } + } } else { viewErrors.add("Slider applications view requires a cluster"); } status.setVersion(SliderAppsConfiguration.INSTANCE.getVersion()); status.setViewEnabled(viewErrors.size() < 1); status.setViewErrors(viewErrors); + status.setViewUrls(viewUrls); return status; } @@ -191,7 +218,7 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { private String getApplicationIdString(ApplicationId appId) { return Long.toString(appId.getClusterTimestamp()) + "_" - + Integer.toString(appId.getId()); + + Integer.toString(appId.getId()); } private ApplicationId getApplicationId(String appIdString) { @@ -227,7 +254,7 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { } private SliderApp createSliderAppObject(ApplicationReport yarnApp, - Set<String> properties, SliderClient sliderClient) { + Set<String> properties, SliderClient sliderClient) { if (yarnApp == null) { return null; } @@ -310,13 +337,17 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { List<SliderAppType> appTypes = getSliderAppTypes(null); if (appTypes != null && appTypes.size() > 0) { for (SliderAppType appType : appTypes) { - logger.info("TYPE: " + appType.getTypeName() + " " + app.getType()); - logger.info("VERSION: " + appType.getTypeVersion() + " " + app.getAppVersion()); - if ((appType.getTypeName() != null && appType.getTypeName().equalsIgnoreCase(app.getType())) && - (appType.getTypeVersion() != null - && appType.getTypeVersion().equalsIgnoreCase(app.getAppVersion()))) { + logger.info("TYPE: " + appType.getTypeName() + " " + + app.getType()); + logger.info("VERSION: " + appType.getTypeVersion() + " " + + app.getAppVersion()); + if ((appType.getTypeName() != null && appType.getTypeName() + .equalsIgnoreCase(app.getType())) + && (appType.getTypeVersion() != null && appType + .getTypeVersion().equalsIgnoreCase( + app.getAppVersion()))) { app.setJmx(sliderAppClient.getJmx(jmxUrl, viewContext, - appType)); + appType)); break; } } @@ -335,10 +366,8 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { 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(); + 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()) { @@ -352,7 +381,7 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { appComponent .setCompletedContainers(new HashMap<String, Map<String, String>>()); componentTypeMap.put(componentEntry.getKey(), - appComponent); + appComponent); } for (Entry<String, Map<String, Object>> containerEntry : componentEntry .getValue().entrySet()) { @@ -365,19 +394,19 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { Object containerPropertyValue = containerValues .get(containerProperty); containerDataMap.put(containerProperty, - containerPropertyValue.toString()); + containerPropertyValue.toString()); } if (isLive) { appComponent.getActiveContainers().put(containerId, - containerDataMap); + containerDataMap); } else { appComponent.getCompletedContainers().put( containerId, containerDataMap); } } appComponent.setInstanceCount(appComponent - .getActiveContainers().size() - + appComponent.getCompletedContainers().size()); + .getActiveContainers().size() + + appComponent.getCompletedContainers().size()); } } app.setComponents(componentTypeMap); @@ -385,16 +414,16 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { } catch (UnknownApplicationInstanceException e) { logger.warn( "Unable to determine app components for " - + yarnApp.getName(), e); + + yarnApp.getName(), e); } catch (YarnException e) { logger.warn( "Unable to determine app components for " - + yarnApp.getName(), e); + + yarnApp.getName(), e); throw new RuntimeException(e.getMessage(), e); } catch (IOException e) { logger.warn( "Unable to determine app components for " - + yarnApp.getName(), e); + + yarnApp.getName(), e); throw new RuntimeException(e.getMessage(), e); } } @@ -406,9 +435,10 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { } /** - * Creates a new {@link SliderClient} initialized with appropriate configuration. If configuration was not determined, - * <code>null</code> is returned. - * + * Creates a new {@link SliderClient} initialized with appropriate + * configuration. If configuration was not determined, <code>null</code> is + * returned. + * * @return */ protected SliderClient getSliderClient() { @@ -425,7 +455,7 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { super.serviceInit(conf); // Override the default FS client to set the super user. FileSystem fs = FileSystem.get(FileSystem.getDefaultUri(getConfig()), - getConfig(), "yarn"); + getConfig(), "yarn"); SliderFileSystem fileSystem = new SliderFileSystem(fs, getConfig()); Field fsField = SliderClient.class .getDeclaredField("sliderFileSystem"); @@ -435,7 +465,7 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { }; try { sliderClientConfiguration = client.bindArgs(sliderClientConfiguration, - new String[]{"usage"}); + new String[] { "usage" }); } catch (Exception e) { logger.warn("Unable to set SliderClient configs", e); throw new RuntimeException(e.getMessage(), e); @@ -448,15 +478,16 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { } /** - * Dynamically determines Slider client configuration. If unable to determine, <code>null</code> is returned. - * + * 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"); + "ZOOKEEPER"); if (zkService != null && ambariCluster.getDesiredConfigs() != null && ambariCluster.getDesiredConfigs().containsKey("global") && ambariCluster.getDesiredConfigs().containsKey("yarn-site") @@ -491,7 +522,7 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { yarnConfig.set("yarn.log-aggregation-enable", "true"); yarnConfig.set("yarn.resourcemanager.address", rmAddress); yarnConfig.set("yarn.resourcemanager.scheduler.address", - rmSchedulerAddress); + rmSchedulerAddress); yarnConfig.set("fs.defaultFS", hdfsPath); yarnConfig.set("slider.zookeeper.quorum", zkQuorum.toString()); yarnConfig @@ -517,7 +548,7 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { List<ApplicationReport> yarnApps = sliderClient.listSliderInstances(null); for (ApplicationReport yarnApp : yarnApps) { SliderApp sliderAppObject = createSliderAppObject(yarnApp, properties, - sliderClient); + sliderClient); if (sliderAppObject != null) { if (sliderAppsMap.containsKey(sliderAppObject.getName())) { if (sliderAppsMap.get(sliderAppObject.getName()).getId() @@ -593,7 +624,7 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { try { ZipFile zipFile = new ZipFile(appZip); Metainfo metainfo = new MetainfoParser().parse(zipFile - .getInputStream(zipFile.getEntry("metainfo.xml"))); + .getInputStream(zipFile.getEntry("metainfo.xml"))); // Create app type object if (metainfo.getServices() != null && metainfo.getServices().size() > 0) { @@ -637,11 +668,11 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { // appTypeComponent.setPriority(component.); if (component.getMinInstanceCount() != null) { appTypeComponent.setInstanceCount(Integer.parseInt(component - .getMinInstanceCount())); + .getMinInstanceCount())); } if (component.getMaxInstanceCount() != null) { appTypeComponent.setMaxInstanceCount(Integer - .parseInt(component.getMaxInstanceCount())); + .parseInt(component.getMaxInstanceCount())); } if (resourcesJson != null) { JsonElement componentJson = resourcesJson.getAsJsonObject() @@ -649,10 +680,10 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { .get(component.getName()); if (componentJson != null && componentJson.getAsJsonObject().has( - "yarn.role.priority")) { + "yarn.role.priority")) { appTypeComponent.setPriority(Integer.parseInt(componentJson - .getAsJsonObject().get("yarn.role.priority") - .getAsString())); + .getAsJsonObject().get("yarn.role.priority") + .getAsString())); } } appTypeComponent.setCategory(component.getCategory()); @@ -661,7 +692,7 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { appType.setJmxMetrics(readMetrics(zipFile, "jmx_metrics.json")); appType.setGangliaMetrics(readMetrics(zipFile, - "ganglia_metrics.json")); + "ganglia_metrics.json")); appType.setTypeComponents(appTypeComponentList); appTypes.add(appType); @@ -678,16 +709,16 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { } Map<String, Map<String, Map<String, Metric>>> readMetrics(ZipFile zipFile, - String fileName) { + String fileName) { Map<String, Map<String, Map<String, Metric>>> metrics = null; try { InputStream inputStream = zipFile.getInputStream(zipFile - .getEntry("jmx_metrics.json")); + .getEntry("jmx_metrics.json")); ObjectMapper mapper = new ObjectMapper(); metrics = mapper.readValue(inputStream, - new TypeReference<Map<String, Map<String, Map<String, Metric>>>>() { - }); + new TypeReference<Map<String, Map<String, Map<String, Metric>>>>() { + }); } catch (IOException e) { logger.info("Error reading metrics. " + e.getMessage()); } @@ -727,7 +758,7 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { appCount = ++createAppCounter; } File appCreateFolder = new File(appsCreateFolder, - Integer.toString(appCount)); + Integer.toString(appCount)); appCreateFolder.mkdirs(); File appConfigJsonFile = new File(appCreateFolder, "appConfig.json"); File resourcesJsonFile = new File(appCreateFolder, "resources.json"); @@ -738,20 +769,20 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { AmbariCluster cluster = ambariClient.getCluster(clusterInfo); Map<String, String> coreSiteConfigs = ambariClient.getConfiguration( clusterInfo, "core-site", cluster.getDesiredConfigs() - .get("core-site")); + .get("core-site")); String hdfsLocation = coreSiteConfigs.get("fs.defaultFS"); final ActionCreateArgs createArgs = new ActionCreateArgs(); createArgs.template = appConfigJsonFile; createArgs.resources = resourcesJsonFile; createArgs.image = new Path(hdfsLocation - + "/slider/agent/slider-agent.tar.gz"); + + "/slider/agent/slider-agent.tar.gz"); ClassLoader currentClassLoader = Thread.currentThread() .getContextClassLoader(); Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); try { ApplicationId applicationId = UserGroupInformation.getBestUGI(null, - "yarn").doAs(new PrivilegedExceptionAction<ApplicationId>() { + "yarn").doAs(new PrivilegedExceptionAction<ApplicationId>() { public ApplicationId run() throws IOException, YarnException { SliderClient sliderClient = getSliderClient(); sliderClient.actionCreate(appName, createArgs); @@ -769,10 +800,10 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { } private void saveAppResources(JsonArray componentsArray, - File resourcesJsonFile) throws IOException { + File resourcesJsonFile) throws IOException { JsonObject resourcesObj = new JsonObject(); resourcesObj.addProperty("schema", - "http://example.org/specification/v2.0.0"); + "http://example.org/specification/v2.0.0"); resourcesObj.add("metadata", new JsonObject()); resourcesObj.add("global", new JsonObject()); JsonObject componentsObj = new JsonObject(); @@ -782,11 +813,11 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { if (inputComponent.has("id")) { JsonObject componentValue = new JsonObject(); componentValue.addProperty("yarn.role.priority", - inputComponent.get("priority").getAsString()); + inputComponent.get("priority").getAsString()); componentValue.addProperty("yarn.component.instances", inputComponent .get("instanceCount").getAsString()); componentsObj.add(inputComponent.get("id").getAsString(), - componentValue); + componentValue); } } } @@ -804,7 +835,7 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { } private void saveAppConfigs(JsonObject configs, JsonArray componentsArray, - File appConfigJsonFile) throws IOException { + File appConfigJsonFile) throws IOException { JsonObject appConfigs = new JsonObject(); appConfigs.addProperty("schema", "http://example.org/specification/v2.0.0"); appConfigs.add("metadata", new JsonObject()); @@ -815,7 +846,7 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController { JsonObject inputComponent = componentsArray.get(i).getAsJsonObject(); if (inputComponent.has("id")) { componentsObj.add(inputComponent.get("id").getAsString(), - new JsonObject()); + new JsonObject()); } } } http://git-wip-us.apache.org/repos/asf/ambari/blob/71aa9236/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 134f400..4146ab8 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 @@ -19,33 +19,43 @@ package org.apache.ambari.view.slider; import java.util.List; +import java.util.Map; public class ViewStatus { - private String version; - private boolean viewEnabled; - private List<String> viewErrors; - - public String getVersion() { - return version; - } - - public void setVersion(String version) { - this.version = version; - } - - public boolean isViewEnabled() { - return viewEnabled; - } - - public void setViewEnabled(boolean viewEnabled) { - this.viewEnabled = viewEnabled; - } - - public List<String> getViewErrors() { - return viewErrors; - } - - public void setViewErrors(List<String> viewErrors) { - this.viewErrors = viewErrors; - } + private String version; + private boolean viewEnabled; + private List<String> viewErrors; + private Map<String, String> viewUrls; + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public boolean isViewEnabled() { + return viewEnabled; + } + + public void setViewEnabled(boolean viewEnabled) { + this.viewEnabled = viewEnabled; + } + + public List<String> getViewErrors() { + return viewErrors; + } + + public void setViewErrors(List<String> viewErrors) { + this.viewErrors = viewErrors; + } + + public Map<String, String> getViewUrls() { + return viewUrls; + } + + public void setViewUrls(Map<String, String> urls) { + this.viewUrls = urls; + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/71aa9236/contrib/views/slider/src/main/resources/ui/app/assets/data/resource/status_false.json ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/app/assets/data/resource/status_false.json b/contrib/views/slider/src/main/resources/ui/app/assets/data/resource/status_false.json index 62a4354..de26144 100644 --- a/contrib/views/slider/src/main/resources/ui/app/assets/data/resource/status_false.json +++ b/contrib/views/slider/src/main/resources/ui/app/assets/data/resource/status_false.json @@ -4,5 +4,9 @@ "viewErrors": [ "Slider applications view requires HDFS service to be started", "Slider applications view requires YARN, HDFS and ZooKeeper services to bestarted." - ] + ], + "viewUrls": { + "dfs.namenode.http-address": "http://c6401.ambari.apache.org:50070", + "yarn.resourcemanager.webapp.address": "http://c6401.ambari.apache.org:8088" + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/71aa9236/contrib/views/slider/src/main/resources/ui/app/assets/data/resource/status_true.json ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/app/assets/data/resource/status_true.json b/contrib/views/slider/src/main/resources/ui/app/assets/data/resource/status_true.json index 409bb2f..454ca0e 100644 --- a/contrib/views/slider/src/main/resources/ui/app/assets/data/resource/status_true.json +++ b/contrib/views/slider/src/main/resources/ui/app/assets/data/resource/status_true.json @@ -1,5 +1,9 @@ { "version": "0.0.1-SNAPSHOT", "viewEnabled": true, - "viewErrors": [] + "viewErrors": [], + "viewUrls": { + "dfs.namenode.http-address": "http://c6401.ambari.apache.org:50070", + "yarn.resourcemanager.webapp.address": "http://c6401.ambari.apache.org:8088" + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/71aa9236/contrib/views/slider/src/main/resources/ui/app/initialize.js ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/app/initialize.js b/contrib/views/slider/src/main/resources/ui/app/initialize.js index cc22ba2..6387df9 100755 --- a/contrib/views/slider/src/main/resources/ui/app/initialize.js +++ b/contrib/views/slider/src/main/resources/ui/app/initialize.js @@ -79,8 +79,13 @@ App.initializer({ * List of errors * @type {string[]} */ - viewErrors: [] + viewErrors: [], + /** + * Map of URL id to URL. + * @type {object} + */ + viewUrls: {} }); application.ApplicationStatusMapper.loop('load'); application.ApplicationTypeMapper.loop('load'); http://git-wip-us.apache.org/repos/asf/ambari/blob/71aa9236/contrib/views/slider/src/main/resources/ui/app/mappers/application_status.js ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/app/mappers/application_status.js b/contrib/views/slider/src/main/resources/ui/app/mappers/application_status.js index 40a6edf..b70673d 100644 --- a/contrib/views/slider/src/main/resources/ui/app/mappers/application_status.js +++ b/contrib/views/slider/src/main/resources/ui/app/mappers/application_status.js @@ -40,6 +40,7 @@ App.ApplicationStatusMapper = App.Mapper.createWithMixins(App.RunPeriodically, { map: { viewEnabled: 'viewEnabled', viewErrors: 'viewErrors', + viewUrls: 'viewUrls', resourcesVersion: 'version' }, http://git-wip-us.apache.org/repos/asf/ambari/blob/71aa9236/contrib/views/slider/src/main/resources/ui/app/templates/slider_apps.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/app/templates/slider_apps.hbs b/contrib/views/slider/src/main/resources/ui/app/templates/slider_apps.hbs index 024e638..bcc4254 100644 --- a/contrib/views/slider/src/main/resources/ui/app/templates/slider_apps.hbs +++ b/contrib/views/slider/src/main/resources/ui/app/templates/slider_apps.hbs @@ -19,9 +19,31 @@ <div id="slider-apps-table"> <div class="box-header"> <div class="pull-right create-app"> + <div class="btn-toolbar"> + <div class="btn-group"> <a href="#" class="btn btn-primary" {{action createApp}}> <i class="icon-plus"></i><span> {{t slider.apps.create}}</span> </a> + </div> + <div class="btn-group"> + <button class="btn dropdown-toggle" data-toggle="dropdown" href="#"> + <i class="icon-cog"></i><span> </span> + <span class="caret"></span> + </button> + <ul class="dropdown-menu"> + {{#if view.yarnUi}} + <li> + <a {{bind-attr href="view.yarnUi"}} target="_blank">YARN UI</a> + </li> + {{/if}} + {{#if view.hdfsUi}} + <li> + <a {{bind-attr href="view.hdfsUi"}} href="" target="_blank">HDFS UI</a> + </li> + {{/if}} + </ul> + </div> + </div> </div> </div> http://git-wip-us.apache.org/repos/asf/ambari/blob/71aa9236/contrib/views/slider/src/main/resources/ui/app/views/slider_apps_view.js ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/app/views/slider_apps_view.js b/contrib/views/slider/src/main/resources/ui/app/views/slider_apps_view.js index 53252b7..3b50950 100644 --- a/contrib/views/slider/src/main/resources/ui/app/views/slider_apps_view.js +++ b/contrib/views/slider/src/main/resources/ui/app/views/slider_apps_view.js @@ -150,6 +150,18 @@ App.SliderAppsView = App.TableView.extend({ associations[4] = 'started'; associations[5] = 'ended'; return associations; - }.property() + }.property(), + + hdfsUi: function() { + if (App.viewUrls) { + return App.viewUrls['dfs.namenode.http-address']; + } + }.property('App.viewUrls'), + + yarnUi: function() { + if (App.viewUrls) { + return App.viewUrls['yarn.resourcemanager.webapp.address']; + } + }.property('App.viewUrls') });
