diff --git a/.gitignore b/.gitignore
index a5d69d0..848b256 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,6 +26,19 @@ hadoop-hdfs-project/hadoop-hdfs-httpfs/downloads
hadoop-common-project/hadoop-common/src/test/resources/contract-test-options.xml
hadoop-tools/hadoop-openstack/src/test/resources/contract-test-options.xml
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/main/tla/yarnregistry.toolbox
+hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/dist
+hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tmp
+hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/node
+hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/node_modules
+hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/bower_components
+hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/.sass-cache
+hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/connect.lock
+hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/coverage/*
+hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/libpeerconnection.log
+hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/npm-debug.log
+hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/testem.log
+hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/dist
+hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/tmp
yarnregistry.pdf
hadoop-tools/hadoop-aws/src/test/resources/auth-keys.xml
hadoop-tools/hadoop-aws/src/test/resources/contract-test-options.xml
diff --git a/BUILDING.txt b/BUILDING.txt
index 9d297f7..908c366 100644
--- a/BUILDING.txt
+++ b/BUILDING.txt
@@ -15,6 +15,7 @@ Requirements:
* Internet connection for first build (to fetch all Maven and Hadoop dependencies)
* python (for releasedocs)
* bats (for shell code testing)
+* Node.js / bower / Ember-cli (for YARN UI v2 building)
----------------------------------------------------------------------------------
The easiest way to get an environment with all the appropriate tools is by means
@@ -119,7 +120,7 @@ Maven build goals:
* Run clover : mvn test -Pclover [-DcloverLicenseLocation=${user.name}/.clover.license]
* Run Rat : mvn apache-rat:check
* Build javadocs : mvn javadoc:javadoc
- * Build distribution : mvn package [-Pdist][-Pdocs][-Psrc][-Pnative][-Dtar][-Preleasedocs]
+ * Build distribution : mvn package [-Pdist][-Pdocs][-Psrc][-Pnative][-Dtar][-Preleasedocs][-Pyarn-ui]
* Change Hadoop version : mvn versions:set -DnewVersion=NEWVERSION
Build options:
@@ -129,6 +130,7 @@ Maven build goals:
* Use -Psrc to create a project source TAR.GZ
* Use -Dtar to create a TAR with the distribution (using -Pdist)
* Use -Preleasedocs to include the changelog and release docs (requires Internet connectivity)
+ * Use -Pyarn-ui to build YARN UI v2. (Requires Internet connectivity)
Snappy build options:
diff --git a/LICENSE.txt b/LICENSE.txt
index 6910a09..05743fe 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1868,3 +1868,103 @@ representations with respect to the Work not specified here. Licensor shall not
be bound by any additional provisions that may appear in any communication from
You. This License may not be modified without the mutual written agreement of
the Licensor and You.
+
+The binary distribution of this product bundles these dependencies under the
+following license:
+bootstrap v3.3.6
+broccoli-asset-rev v2.4.2
+broccoli-funnel v1.0.1
+datatables v1.10.8
+em-helpers v0.5.13
+em-table v0.1.6
+ember v2.2.0
+ember-array-contains-helper v1.0.2
+ember-bootstrap v0.5.1
+ember-cli v1.13.13
+ember-cli-app-version v1.0.0
+ember-cli-babel v5.1.6
+ember-cli-content-security-policy v0.4.0
+ember-cli-dependency-checker v1.2.0
+ember-cli-htmlbars v1.0.2
+ember-cli-htmlbars-inline-precompile v0.3.1
+ember-cli-ic-ajax v0.2.1
+ember-cli-inject-live-reload v1.4.0
+ember-cli-jquery-ui v0.0.20
+ember-cli-qunit v1.2.1
+ember-cli-release v0.2.8
+ember-cli-shims v0.0.6
+ember-cli-sri v1.2.1
+ember-cli-test-loader v0.2.1
+ember-cli-uglify v1.2.0
+ember-d3 v0.1.0
+ember-data v2.1.0
+ember-disable-proxy-controllers v1.0.1
+ember-export-application-global v1.0.5
+ember-load-initializers v0.1.7
+ember-qunit v0.4.16
+ember-qunit-notifications v0.1.0
+ember-resolver v2.0.3
+ember-spin-spinner v0.2.3
+ember-truth-helpers v1.2.0
+jquery v2.1.4
+jquery-ui v1.11.4
+loader.js v3.3.0
+momentjs v2.10.6
+qunit v1.19.0
+select2 v4.0.0
+snippet-ss v1.11.0
+spin.js v2.3.2
+-------------------------------------------------------------------------------
+The MIT License (MIT)
+
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and assocated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+The binary distribution of this product bundles these dependencies under the
+following license:
+D3 v3.5.6
+--------------------------------------------------------------------------------
+(3-clause BSD license)
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this list
+ of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice, this
+ list of conditions and the following disclaimer in the documentation and/or
+ other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/dev-support/bin/create-release b/dev-support/bin/create-release
index 0e0ab86..d40fffa 100755
--- a/dev-support/bin/create-release
+++ b/dev-support/bin/create-release
@@ -527,7 +527,7 @@ function makearelease
# shellcheck disable=SC2046
run_and_redirect "${LOGDIR}/mvn_install.log" \
"${MVN}" "${MVN_ARGS[@]}" install \
- -Pdist,src \
+ -Pdist,src,yarn-ui \
"${signflags[@]}" \
-DskipTests -Dtar $(hadoop_native_flags)
diff --git a/dev-support/docker/Dockerfile b/dev-support/docker/Dockerfile
index 5a7f85a..b64e537 100644
--- a/dev-support/docker/Dockerfile
+++ b/dev-support/docker/Dockerfile
@@ -133,6 +133,15 @@ RUN pip install python-dateutil
ENV MAVEN_OPTS -Xms256m -Xmx512m
###
+# Install node js tools for web UI frameowkr
+###
+RUN apt-get -y install nodejs && \
+ ln -s /usr/bin/nodejs /usr/bin/node && \
+ apt-get -y install npm && \
+ npm install -g bower && \
+ npm install -g ember-cli
+
+###
# Everything past this point is either not needed for testing or breaks Yetus.
# So tell Yetus not to read the rest of the file:
# YETUS CUT HERE
diff --git a/hadoop-assemblies/src/main/resources/assemblies/hadoop-yarn-dist.xml b/hadoop-assemblies/src/main/resources/assemblies/hadoop-yarn-dist.xml
index 219ed81..c3f459c 100644
--- a/hadoop-assemblies/src/main/resources/assemblies/hadoop-yarn-dist.xml
+++ b/hadoop-assemblies/src/main/resources/assemblies/hadoop-yarn-dist.xml
@@ -192,6 +192,13 @@
${project.build.directory}/site/share/doc/hadoop/${hadoop.component}
+
+ hadoop-yarn/hadoop-yarn-ui/target/hadoop-yarn-ui-${project.version}
+ /share/hadoop/${hadoop.component}/webapps/rm
+
+ **/*
+
+
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java
index 86e8a95..cdfc989 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java
@@ -262,7 +262,30 @@ private static void addDeprecatedKeys() {
public static final int DEFAULT_RM_WEBAPP_HTTPS_PORT = 8090;
public static final String DEFAULT_RM_WEBAPP_HTTPS_ADDRESS = "0.0.0.0:"
+ DEFAULT_RM_WEBAPP_HTTPS_PORT;
+
+ /**
+ * Enable YARN WebApp V2.
+ */
+ public static final String RM_WEBAPP_UI2_ENABLE = RM_PREFIX
+ + "webapp.ui2.enable";
+ public static final boolean DEFAULT_RM_WEBAPP_UI2_ENABLE = false;
+
+ /** The address of the RM web ui2 application. */
+ public static final String RM_WEBAPP_UI2_ADDRESS = RM_PREFIX
+ + "webapp.ui2.address";
+
+ public static final int DEFAULT_RM_WEBAPP_UI2_PORT = 8288;
+ public static final String DEFAULT_RM_WEBAPP_UI2_ADDRESS = "0.0.0.0:" +
+ DEFAULT_RM_WEBAPP_UI2_PORT;
+ /** The https address of the RM web ui2 application.*/
+ public static final String RM_WEBAPP_UI2_HTTPS_ADDRESS =
+ RM_PREFIX + "webapp.ui2.https.address";
+
+ public static final int DEFAULT_RM_WEBAPP_UI2_HTTPS_PORT = 8290;
+ public static final String DEFAULT_RM_WEBAPP_UI2_HTTPS_ADDRESS = "0.0.0.0:"
+ + DEFAULT_RM_WEBAPP_UI2_HTTPS_PORT;
+
public static final String RM_RESOURCE_TRACKER_ADDRESS =
RM_PREFIX + "resource-tracker.address";
public static final int DEFAULT_RM_RESOURCE_TRACKER_PORT = 8031;
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml
index 423b78b..c85e0e3 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml
@@ -180,6 +180,32 @@
+ To enable RM web ui2 application.
+ yarn.resourcemanager.webapp.ui2.enable
+ false
+
+
+
+
+ The http address of the RM web ui2 application.
+ If only a host is provided as the value,
+ the webapp will be served on a random port.
+
+ yarn.resourcemanager.webapp.ui2.address
+ ${yarn.resourcemanager.hostname}:8288
+
+
+
+
+ The https address of the RM web ui2 application.
+ If only a host is provided as the value,
+ the webapp will be served on a random port.
+
+ yarn.resourcemanager.webapp.ui2.https.address
+ ${yarn.resourcemanager.hostname}:8290
+
+
+ yarn.resourcemanager.resource-tracker.address${yarn.resourcemanager.hostname}:8031
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java
index bf72fc1..10582b2 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java
@@ -18,16 +18,6 @@
package org.apache.hadoop.yarn.server.resourcemanager;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PrintStream;
-import java.net.InetSocketAddress;
-import java.nio.charset.Charset;
-import java.security.PrivilegedExceptionAction;
-import java.security.SecureRandom;
-import java.util.ArrayList;
-import java.util.List;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.curator.framework.AuthInfo;
@@ -38,10 +28,12 @@
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ha.HAServiceProtocol;
import org.apache.hadoop.ha.HAServiceProtocol.HAServiceState;
+import org.apache.hadoop.http.HttpServer2;
import org.apache.hadoop.http.lib.StaticUserWebFilter;
import org.apache.hadoop.metrics2.MetricsSystem;
import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem;
import org.apache.hadoop.metrics2.source.JvmMetrics;
+import org.apache.hadoop.net.NetUtils;
import org.apache.hadoop.security.AuthenticationFilterInitializer;
import org.apache.hadoop.security.Groups;
import org.apache.hadoop.security.HttpCrossOriginFilterInitializer;
@@ -123,6 +115,16 @@
import org.apache.zookeeper.server.auth.DigestAuthenticationProvider;
import com.google.common.annotations.VisibleForTesting;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.nio.charset.Charset;
+import java.security.PrivilegedExceptionAction;
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.List;
/**
* The ResourceManager is the main class that is a set of components.
@@ -904,7 +906,55 @@ public void handle(RMNodeEvent event) {
}
}
}
-
+
+ /**
+ * Return a HttpServer.Builder that the journalnode / namenode / secondary
+ * namenode can use to initialize their HTTP / HTTPS server.
+ *
+ * @param conf configuration object
+ * @param httpAddr HTTP address
+ * @param httpsAddr HTTPS address
+ * @param name Name of the server
+ * @throws IOException from Builder
+ * @return builder object
+ */
+ public static HttpServer2.Builder httpServerTemplateForRM(Configuration conf,
+ final InetSocketAddress httpAddr, final InetSocketAddress httpsAddr,
+ String name) throws IOException {
+ HttpServer2.Builder builder = new HttpServer2.Builder().setName(name)
+ .setConf(conf).setSecurityEnabled(false);
+
+ if (httpAddr.getPort() == 0) {
+ builder.setFindPort(true);
+ }
+
+ URI uri = URI.create("http://" + NetUtils.getHostPortString(httpAddr));
+ builder.addEndpoint(uri);
+ LOG.info("Starting Web-server for " + name + " at: " + uri);
+
+ return builder;
+ }
+
+ protected void startWebAppV2() throws IOException {
+ Configuration config = getConfig();
+ final InetSocketAddress httpAddr = config.getSocketAddr(
+ YarnConfiguration.RM_WEBAPP_UI2_ADDRESS,
+ YarnConfiguration.DEFAULT_RM_WEBAPP_UI2_ADDRESS,
+ YarnConfiguration.DEFAULT_RM_WEBAPP_UI2_PORT);
+ final InetSocketAddress httpsAddr = config.getSocketAddr(
+ YarnConfiguration.RM_WEBAPP_UI2_HTTPS_ADDRESS,
+ YarnConfiguration.DEFAULT_RM_WEBAPP_UI2_HTTPS_ADDRESS,
+ YarnConfiguration.DEFAULT_RM_WEBAPP_UI2_HTTPS_PORT);
+
+ HttpServer2.Builder builder = httpServerTemplateForRM(config, httpAddr,
+ httpsAddr, "rm");
+
+ HttpServer2 infoServer = builder.build();
+ infoServer.start();
+
+ LOG.info("Web server init done");
+ }
+
protected void startWepApp() {
// Use the customized yarn filter instead of the standard kerberos filter to
@@ -1123,6 +1173,16 @@ protected void serviceStart() throws Exception {
transitionToActive();
}
+ if (getConfig().getBoolean(YarnConfiguration.RM_WEBAPP_UI2_ENABLE,
+ YarnConfiguration.DEFAULT_RM_WEBAPP_UI2_ENABLE)) {
+ try {
+ startWebAppV2();
+ LOG.info("Yarn WebApp UI 2 is started");
+ } catch (Exception e) {
+ LOG.error("Failed to start Yarn web app v2:" + e.getMessage());
+ }
+ }
+
startWepApp();
if (getConfig().getBoolean(YarnConfiguration.IS_MINI_YARN_CLUSTER,
false)) {
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/YarnUI2.md b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/YarnUI2.md
new file mode 100644
index 0000000..ff48183
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/YarnUI2.md
@@ -0,0 +1,47 @@
+
+
+Hadoop: YARN-UI V2
+=================
+
+Prerequisites
+-------------
+
+If you run RM locally in your computer for test purpose, you need the following things properly installed.
+
+- Install Node.js with NPM: https://nodejs.org/download
+- After Node.js installed, install `corsproxy`: `npm install -g corsproxy`.
+
+
+Configurations
+-------------
+
+*In yarn-site.xml*
+
+| Configuration Property | Description |
+|:---- |:---- |
+| `yarn.resourcemanager.webapp.ui2.enable` | In the server side it indicates whether the new YARN-UI v2 is enabled or not. Defaults to `false`. |
+| `yarn.resourcemanager.webapp.ui2.address` | Specify the address of ResourceManager and port which host YARN-UI v2, defaults to `localhost:8288`. |
+
+*In $HADOOP_PREFIX/share/hadoop/yarn/webapps/rm/config/configs.env*
+
+- Update timelineWebAddress and rmWebAddress to the actual addresses run resource manager and timeline server
+- If you run RM locally in you computer just for test purpose, you need to keep `corsproxy` running. Otherwise, you need to set `localBaseAddress` to empty.
+
+Use it
+-------------
+Open your browser, go to `rm-address:8288` and try it!
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/pom.xml b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/pom.xml
new file mode 100644
index 0000000..b750a73
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/pom.xml
@@ -0,0 +1,195 @@
+
+
+
+
+ hadoop-yarn
+ org.apache.hadoop
+ 3.0.0-alpha2-SNAPSHOT
+
+ 4.0.0
+ org.apache.hadoop
+ hadoop-yarn-ui
+ 3.0.0-alpha2-SNAPSHOT
+ Apache Hadoop YARN UI
+ ${packaging.type}
+
+
+ war
+ src/main/webapp
+ node
+ v0.12.2
+ 2.10.0
+ false
+
+
+
+
+
+
+ org.apache.rat
+ apache-rat-plugin
+
+
+ src/main/webapp/node_modules/**/*
+ src/main/webapp/bower_components/**/*
+ src/main/webapp/jsconfig.json
+ src/main/webapp/bower.json
+ src/main/webapp/package.json
+ src/main/webapp/testem.json
+
+ src/main/webapp/dist/**/*
+ src/main/webapp/tmp/**/*
+ src/main/webapp/public/assets/images/**/*
+ src/main/webapp/public/assets/images/*
+ src/main/webapp/public/robots.txt
+
+ public/assets/images/**/*
+ public/crossdomain.xml
+
+ src/main/webapp/.tmp/**/*
+ src/main/webapp/.bowerrc
+ src/main/webapp/.editorconfig
+ src/main/webapp/.ember-cli
+ src/main/webapp/.gitignore
+ src/main/webapp/.jshintrc
+ src/main/webapp/.travis.yml
+ src/main/webapp/.watchmanconfig
+ src/main/webapp/tests/.jshintrc
+ src/main/webapp/blueprints/.jshintrc
+
+
+
+
+
+ maven-clean-plugin
+ 3.0.0
+
+ ${keep-ui-build-cache}
+ false
+
+
+ ${basedir}/src/main/webapp/bower_components
+
+
+ ${basedir}/src/main/webapp/node_modules
+
+
+
+
+
+
+
+
+
+ yarn-ui
+
+
+ false
+
+
+
+ war
+
+
+
+
+
+
+ exec-maven-plugin
+ org.codehaus.mojo
+
+
+ generate-sources
+ npm install
+
+ exec
+
+
+ ${webappDir}
+ npm
+
+ install
+
+
+
+
+ generate-sources
+ bower install
+
+ exec
+
+
+ ${webappDir}
+ bower
+
+ --allow-root
+ install
+
+
+
+
+ ember build
+ generate-sources
+
+ exec
+
+
+ ${webappDir}
+ ember
+
+ build
+ -prod
+ --output-path
+ ${basedir}/target/dist
+
+
+
+
+ cleanup tmp
+ generate-sources
+
+ exec
+
+
+ ${webappDir}
+ rm
+
+ -rf
+ tmp
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+
+ ${basedir}/src/main/webapp/WEB-INF/web.xml
+ ${basedir}/target/dist
+
+
+
+
+
+
+
+
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/public/crossdomain.xml b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/public/crossdomain.xml
new file mode 100644
index 0000000..0c16a7a
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/public/crossdomain.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/.bowerrc b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/.bowerrc
new file mode 100644
index 0000000..959e169
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/.bowerrc
@@ -0,0 +1,4 @@
+{
+ "directory": "bower_components",
+ "analytics": false
+}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/.editorconfig b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/.editorconfig
new file mode 100644
index 0000000..47c5438
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/.editorconfig
@@ -0,0 +1,34 @@
+# EditorConfig helps developers define and maintain consistent
+# coding styles between different editors and IDEs
+# editorconfig.org
+
+root = true
+
+
+[*]
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+indent_style = space
+indent_size = 2
+
+[*.js]
+indent_style = space
+indent_size = 2
+
+[*.hbs]
+insert_final_newline = false
+indent_style = space
+indent_size = 2
+
+[*.css]
+indent_style = space
+indent_size = 2
+
+[*.html]
+indent_style = space
+indent_size = 2
+
+[*.{diff,md}]
+trim_trailing_whitespace = false
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/.ember-cli b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/.ember-cli
new file mode 100644
index 0000000..ee64cfe
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/.ember-cli
@@ -0,0 +1,9 @@
+{
+ /**
+ Ember CLI sends analytics information by default. The data is completely
+ anonymous, but there are times when you might want to disable this behavior.
+
+ Setting `disableAnalytics` to true will prevent any data from being sent.
+ */
+ "disableAnalytics": false
+}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/.jshintrc b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/.jshintrc
new file mode 100644
index 0000000..08096ef
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/.jshintrc
@@ -0,0 +1,32 @@
+{
+ "predef": [
+ "document",
+ "window",
+ "-Promise"
+ ],
+ "browser": true,
+ "boss": true,
+ "curly": true,
+ "debug": false,
+ "devel": true,
+ "eqeqeq": true,
+ "evil": true,
+ "forin": false,
+ "immed": false,
+ "laxbreak": false,
+ "newcap": true,
+ "noarg": true,
+ "noempty": false,
+ "nonew": false,
+ "nomen": false,
+ "onevar": false,
+ "plusplus": false,
+ "regexp": false,
+ "undef": true,
+ "sub": true,
+ "strict": false,
+ "white": false,
+ "eqnull": true,
+ "esnext": true,
+ "unused": true
+}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/.watchmanconfig b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/.watchmanconfig
new file mode 100644
index 0000000..e7834e3
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/.watchmanconfig
@@ -0,0 +1,3 @@
+{
+ "ignore_dirs": ["tmp", "dist"]
+}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/WEB-INF/web.xml b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..ddb8532
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+ YARN UI
+
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/abstract.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/abstract.js
new file mode 100644
index 0000000..c7e5c36
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/abstract.js
@@ -0,0 +1,48 @@
+/**
+ * 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.
+ */
+import Ember from 'ember';
+
+export default DS.JSONAPIAdapter.extend({
+ address: null, //Must be set by inheriting classes
+ restNameSpace: null, //Must be set by inheriting classes
+ serverName: null, //Must be set by inheriting classes
+
+ headers: {
+ Accept: 'application/json'
+ },
+
+ host: Ember.computed("address", function () {
+ var address = this.get("address");
+ return this.get(`hosts.${address}`);
+ }),
+
+ namespace: Ember.computed("restNameSpace", function () {
+ var serverName = this.get("restNameSpace");
+ return this.get(`env.app.namespaces.${serverName}`);
+ }),
+
+ ajax: function(url, method, options) {
+ options = options || {};
+ options.crossDomain = true;
+ options.xhrFields = {
+ withCredentials: true
+ };
+ options.targetServer = this.get('serverName');
+ return this._super(url, method, options);
+ }
+});
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/cluster-info.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/cluster-info.js
new file mode 100644
index 0000000..f79df92
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/cluster-info.js
@@ -0,0 +1,30 @@
+/**
+ * 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.
+ */
+
+import AbstractAdapter from './abstract';
+
+export default AbstractAdapter.extend({
+ address: "rmWebAddress",
+ restNameSpace: "cluster",
+ serverName: "RM",
+
+ // Any cluster-info specific adapter changes must be added here
+ pathForType(modelName) {
+ return ''; // move to some common place, return path by modelname.
+ },
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/cluster-metric.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/cluster-metric.js
new file mode 100644
index 0000000..8325a4c
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/cluster-metric.js
@@ -0,0 +1,30 @@
+/**
+ * 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.
+ */
+
+import AbstractAdapter from './abstract';
+
+export default AbstractAdapter.extend({
+ address: "rmWebAddress",
+ restNameSpace: "metrics",
+ serverName: "RM",
+
+ // Any cluster-metric specific adapter changes must be added here
+ pathForType(modelName) {
+ return ''; // move to some common place, return path by modelname.
+ },
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-app-attempt.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-app-attempt.js
new file mode 100644
index 0000000..78f5e02
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-app-attempt.js
@@ -0,0 +1,38 @@
+/**
+ * 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.
+ */
+
+import AbstractAdapter from './abstract';
+import Converter from 'yarn-ui/utils/converter';
+
+export default AbstractAdapter.extend({
+ address: "rmWebAddress",
+ restNameSpace: "cluster",
+ serverName: "RM",
+
+ urlForQuery(query, modelName) {
+ var url = this._buildURL();
+ return url + '/apps/' + query.appId + "/appattempts";
+ },
+
+ urlForFindRecord(id, modelName, snapshot) {
+ var url = this._buildURL();
+ return url + '/apps/' +
+ Converter.attemptIdToAppId(id) + "/appattempts/" + id;
+ }
+
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-app.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-app.js
new file mode 100644
index 0000000..67a2847b
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-app.js
@@ -0,0 +1,43 @@
+/**
+ * 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.
+ */
+
+import AbstractAdapter from './abstract';
+
+export default AbstractAdapter.extend({
+ address: "rmWebAddress",
+ restNameSpace: "cluster",
+ serverName: "RM",
+
+ urlForQuery(query, modelName) {
+ var url = this._buildURL();
+ if (query.state) {
+ url = url + '/apps/?state=' + query.state;
+ }
+ return url;
+ },
+
+ urlForFindRecord(id, modelName, snapshot) {
+ var url = this._buildURL();
+ url = url + '/apps/' + id;
+ return url;
+ },
+
+ pathForType(modelName) {
+ return 'apps'; // move to some common place, return path by modelname.
+ },
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-container-log.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-container-log.js
new file mode 100644
index 0000000..9f2d5d7
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-container-log.js
@@ -0,0 +1,80 @@
+/**
+ * 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.
+ */
+
+import DS from 'ember-data';
+import Ember from 'ember';
+import Converter from 'yarn-ui/utils/converter';
+
+/**
+ * REST URL's response when fetching container logs will be
+ * in plain text format and not JSON.
+ */
+export default DS.RESTAdapter.extend({
+ headers: {
+ Accept: 'text/plain'
+ },
+
+ host: Ember.computed("address", function () {
+ return this.get(`hosts.localBaseAddress`);
+ }),
+
+ namespace: Ember.computed("restNameSpace", function () {
+ return this.get(`env.app.namespaces.node`);
+ }),
+
+ urlForFindRecord(id, modelName, snapshot) {
+ var splits = Converter.splitForContainerLogs(id);
+ var nodeHttpAddr = splits[0];
+ var containerId = splits[1];
+ var filename = splits[2];
+ this.host = this.get('host') + nodeHttpAddr;
+ var url = this._buildURL();
+ url = url + "/containerlogs/" + containerId + "/" + filename;
+ return url;
+ },
+
+ ajax(url, method, hash) {
+ hash = hash || {};
+ hash.crossDomain = true;
+ hash.xhrFields = {withCredentials: true};
+ hash.targetServer = "NM";
+ return this._super(url, method, hash);
+ },
+
+ /**
+ * Override options so that result is not expected to be JSON
+ */
+ ajaxOptions: function (url, type, options) {
+ var hash = options || {};
+ hash.url = url;
+ hash.type = type;
+ // Make sure jQuery does not try to convert response to JSON.
+ hash.dataType = 'text';
+ hash.context = this;
+
+ var headers = Ember.get(this, 'headers');
+ if (headers != undefined) {
+ hash.beforeSend = function (xhr) {
+ Object.keys(headers).forEach(function (key) {
+ return xhr.setRequestHeader(key, headers[key]);
+ });
+ };
+ }
+ return hash;
+ },
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-container.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-container.js
new file mode 100644
index 0000000..fd6a6f8
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-container.js
@@ -0,0 +1,63 @@
+/**
+ * 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.
+ */
+
+import DS from 'ember-data';
+import Converter from 'yarn-ui/utils/converter';
+
+export default DS.JSONAPIAdapter.extend({
+ headers: {
+ Accept: 'application/json'
+ },
+
+ host: function() {
+ return undefined
+ }.property(),
+
+ namespace: function() {
+ return undefined
+ }.property(),
+
+ urlForQuery(query, modelName) {
+ var rmHosts = this.get(`hosts.rmWebAddress`);
+ var tsHosts = this.get(`hosts.timelineWebAddress`);
+ var rmNamespaces = this.get(`env.app.namespaces.cluster`);
+ var tsNamespaces = this.get(`env.app.namespaces.timeline`);
+
+ if (query.is_rm) {
+ this.set("host", rmHosts);
+ this.set("namespace", rmNamespaces);
+ } else {
+ this.set("host", tsHosts);
+ this.set("namespace", tsNamespaces);
+ }
+
+ var url = this._buildURL();
+ url = url + '/apps/' + Converter.attemptIdToAppId(query.app_attempt_id)
+ + "/appattempts/" + query.app_attempt_id + "/containers";
+ console.log(url);
+ return url;
+ },
+
+ ajax(url, method, hash) {
+ hash = {};
+ hash.crossDomain = true;
+ hash.xhrFields = {withCredentials: true};
+ hash.targetServer = "RM";
+ return this._super(url, method, hash);
+ }
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-node-app.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-node-app.js
new file mode 100644
index 0000000..eaddfcb
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-node-app.js
@@ -0,0 +1,61 @@
+/**
+ * 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.
+ */
+
+import AbstractAdapter from './abstract';
+
+export default AbstractAdapter.extend({
+
+ address: "localBaseAddress",
+ restNameSpace: "node",
+ serverName: "NM",
+
+ urlForQuery(query) {
+ var extension = this.get("host").split('/').pop();
+ if (extension != query.nodeAddr) {
+ this.host = this.get("host") + query.nodeAddr;
+ }
+ var url = this._buildURL();
+ url = url + "/apps";
+ return url;
+ },
+
+ urlForQueryRecord: function (query) {
+ var extension = this.get("host").split('/').pop();
+ if (extension != query.nodeAddr) {
+ this.host = this.get("host") + query.nodeAddr;
+ }
+ var url = this._buildURL();
+ url = url + "/apps/" + query.appId;
+ return url;
+ },
+
+ query: function (store, type, query) {
+ var url = this.urlForQuery(query);
+ // Query params not required.
+ query = null;
+ return this.ajax(url, 'GET', { data: query });
+ },
+
+ queryRecord: function (store, type, query) {
+ var url = this.urlForQueryRecord(query);
+ // Query params not required.
+ query = null;
+ return this.ajax(url, 'GET', { data: query });
+ },
+
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-node-container.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-node-container.js
new file mode 100644
index 0000000..56c4bcd
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-node-container.js
@@ -0,0 +1,62 @@
+/**
+ * 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.
+ */
+
+import AbstractAdapter from './abstract';
+
+export default AbstractAdapter.extend({
+
+ address: "localBaseAddress",
+ restNameSpace: "node",
+ serverName: "NM",
+
+ urlForQuery(query) {
+ var extension = this.get("host").split('/').pop();
+ if (extension != query.nodeHttpAddr) {
+ this.host = this.get("host") + query.nodeHttpAddr;
+ }
+ var url = this._buildURL();
+ url = url + "/containers";
+ return url;
+ },
+
+ urlForQueryRecord(query) {
+ var extension = this.get("host").split('/').pop();
+ if (extension != query.nodeHttpAddr) {
+ this.host = this.get("host") + query.nodeHttpAddr;
+ }
+ var url = this._buildURL();
+ url = url + "/containers/" + query.containerId;
+ return url;
+ },
+
+ query: function (store, type, query) {
+ var url = this.urlForQuery(query);
+ // Query params not required.
+ query = null;
+ return this.ajax(url, 'GET', { data: query });
+ },
+
+ queryRecord: function (store, type, query) {
+ var url = this.urlForQueryRecord(query);
+ // Query params not required.
+ query = null;
+ console.log(url);
+ return this.ajax(url, 'GET', { data: query });
+ },
+
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-node.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-node.js
new file mode 100644
index 0000000..7a0fc4a
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-node.js
@@ -0,0 +1,36 @@
+/**
+ * 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.
+ */
+
+import AbstractAdapter from './abstract';
+
+export default AbstractAdapter.extend({
+
+ address: "localBaseAddress",
+ restNameSpace: "node",
+ serverName: "NM",
+
+ urlForFindRecord(id, modelName, snapshot) {
+ var extension = this.get("host").split('/').pop();
+ if (extension != id) {
+ this.host = this.get("host") + id;
+ }
+ var url = this._buildURL();
+ return url;
+ },
+
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-queue.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-queue.js
new file mode 100644
index 0000000..41cd442
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-queue.js
@@ -0,0 +1,30 @@
+/**
+ * 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.
+ */
+
+import AbstractAdapter from './abstract';
+
+export default AbstractAdapter.extend({
+ address: "rmWebAddress",
+ restNameSpace: "cluster",
+ serverName: "RM",
+
+ pathForType(modelName) {
+ return 'scheduler'; // move to some common place, return path by modelname.
+ },
+
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-rm-node.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-rm-node.js
new file mode 100644
index 0000000..a24c399
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-rm-node.js
@@ -0,0 +1,36 @@
+/**
+ * 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.
+ */
+
+import AbstractAdapter from './abstract';
+
+export default AbstractAdapter.extend({
+ address: "rmWebAddress",
+ restNameSpace: "cluster",
+ serverName: "RM",
+
+ pathForType(modelName) {
+ return 'nodes';
+ },
+
+ urlForFindRecord(id, modelName, snapshot) {
+ var url = this._buildURL();
+ url = url + "/nodes/" + id;
+ return url;
+ },
+
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/app.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/app.js
new file mode 100644
index 0000000..8c1025a
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/app.js
@@ -0,0 +1,38 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+import Resolver from 'ember-resolver';
+import loadInitializers from 'ember/load-initializers';
+import config from './config/environment';
+import Sorter from 'yarn-ui/utils/sorter';
+
+var App;
+
+Ember.MODEL_FACTORY_INJECTIONS = true;
+
+App = Ember.Application.extend({
+ modulePrefix: config.modulePrefix,
+ podModulePrefix: config.podModulePrefix,
+ Resolver
+});
+
+loadInitializers(App, config.modulePrefix);
+Sorter.initDataTableSorter();
+
+export default App;
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-attempt-table.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-attempt-table.js
new file mode 100644
index 0000000..4b741b8
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-attempt-table.js
@@ -0,0 +1,22 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+});
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-table.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-table.js
new file mode 100644
index 0000000..4b741b8
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-table.js
@@ -0,0 +1,22 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+});
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-usage-donut-chart.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-usage-donut-chart.js
new file mode 100644
index 0000000..90f41fc
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-usage-donut-chart.js
@@ -0,0 +1,62 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+import DonutChart from 'yarn-ui/components/donut-chart';
+import BaseUsageDonutChart from 'yarn-ui/components/base-usage-donut-chart';
+import ColorUtils from 'yarn-ui/utils/color-utils';
+import HrefAddressUtils from 'yarn-ui/utils/href-address-utils';
+
+export default BaseUsageDonutChart.extend({
+ colors: d3.scale.category20().range(),
+
+ draw: function() {
+ var usageByApps = [];
+ var avail = 100;
+
+ this.get("data").forEach(function (app) {
+ var v = app.get("clusterUsagePercentage");
+ if (v > 1e-2) {
+ usageByApps.push({
+ label: app.get("id"),
+ link: HrefAddressUtils.getApplicationLink(app.get("id")),
+ value: v.toFixed(2)
+ });
+
+ console.log(v);
+ avail = avail - v;
+ }
+ }.bind(this));
+
+ usageByApps.sort(function(a,b) {
+ return b.value - a.value;
+ });
+
+ usageByApps = this.mergeLongTails(usageByApps, 8);
+
+ usageByApps.push({
+ label: "Available",
+ value: avail.toFixed(4)
+ })
+
+ this.colors = ColorUtils.getColors(usageByApps.length, ["others", "good"], true);
+
+ this.renderDonutChart(usageByApps, this.get("title"), this.get("showLabels"),
+ this.get("middleLabel"), "100%", "%");
+ },
+})
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/bar-chart.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/bar-chart.js
new file mode 100644
index 0000000..a5c49a9
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/bar-chart.js
@@ -0,0 +1,127 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+import BaseChartComponent from 'yarn-ui/components/base-chart-component';
+
+export default BaseChartComponent.extend({
+ // data:
+ // [{label=label1, value=value1}, ...]
+ // ...
+ renderBarChart: function(data, title, textWidth = 50) {
+ var g = this.chart.g;
+ var layout = this.getLayout();
+ this.renderTitleAndBG(g, title, layout);
+
+ var maxValue = -1;
+ for (var i = 0; i < data.length; i++) {
+ if (data[i] instanceof Array) {
+ if (data[i][0].value > maxValue) {
+ maxValue = data[i][0].value;
+ }
+ } else {
+ if (data[i].value > maxValue) {
+ maxValue = data[i].value;
+ }
+ }
+ }
+
+ var singleBarHeight = 30;
+
+ // 50 is for text
+ var maxBarWidth = layout.x2 - layout.x1 - 2 * layout.margin - textWidth - 50;
+
+ // 30 is for title
+ var maxBarsHeight = layout.y2 - layout.y1 - 2 * layout.margin - 30;
+ var gap = (maxBarsHeight - data.length * singleBarHeight) / (data.length -
+ 1);
+
+ var xScaler = d3.scale.linear()
+ .domain([0, maxValue])
+ .range([0, maxBarWidth]);
+
+ // show bar text
+ for (var i = 0; i < data.length; i++) {
+ g.append("text")
+ .text(
+ function() {
+ return data[i].label;
+ })
+ .attr("y", function() {
+ return layout.y1 + singleBarHeight / 2 + layout.margin + (gap +
+ singleBarHeight) * i + 30;
+ })
+ .attr("x", layout.x1 + layout.margin);
+ }
+
+ // show bar
+ var bar = g.selectAll("bars")
+ .data(data)
+ .enter()
+ .append("rect")
+ .attr("y", function(d, i) {
+ return layout.y1 + 30 + layout.margin + (gap + singleBarHeight) * i;
+ })
+ .attr("x", layout.x1 + layout.margin + textWidth)
+ .attr("height", singleBarHeight)
+ .attr("fill", function(d, i) {
+ return this.colors[i];
+ }.bind(this))
+ .attr("width", 0);
+
+ this.bindTooltip(bar);
+
+ bar.transition()
+ .duration(500)
+ .attr("width", function(d) {
+ var w;
+ w = xScaler(d.value);
+ // At least each item has 3 px
+ w = Math.max(w, 3);
+ return w;
+ });
+
+ // show bar value
+ for (var i = 0; i < data.length; i++) {
+ g.append("text")
+ .text(
+ function() {
+ return data[i].value;
+ })
+ .attr("y", function() {
+ return layout.y1 + singleBarHeight / 2 + layout.margin + (gap +
+ singleBarHeight) * i + 30;
+ })
+ .attr("x", layout.x1 + layout.margin + textWidth + 15 + xScaler(data[i].value));
+ }
+ },
+
+ draw: function() {
+ this.renderBarChart(this.get("data"), this.get("title"), this.get("textWidth"));
+ },
+
+ _dataChange: Ember.observer("data", function() {
+ this.chart.g.selectAll("*").remove();
+ this.draw();
+ }),
+
+ didInsertElement: function() {
+ this.initChart();
+ this.draw();
+ },
+})
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/base-chart-component.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/base-chart-component.js
new file mode 100644
index 0000000..d221488
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/base-chart-component.js
@@ -0,0 +1,144 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+import Converter from 'yarn-ui/utils/converter';
+
+export default Ember.Component.extend({
+ tooltip : undefined,
+ colors: d3.scale.category10().range(),
+
+ init: function () {
+ this._super();
+ this.set("chart", {
+ svg: undefined,
+ g: undefined,
+ h: 0,
+ w: 0,
+ tooltip: undefined
+ });
+ },
+
+ initChart: function(removeLast = false) {
+ // Init tooltip if it is not initialized
+ // this.tooltip = d3.select("#chart-tooltip");
+ if (!this.tooltip) {
+ this.tooltip = d3.select("body")
+ .append("div")
+ .attr("class", "tooltip")
+ .attr("id", "chart-tooltip")
+ .style("opacity", 0);
+ }
+
+ var parentId = this.get("parentId");
+
+ if (removeLast) {
+ // Init svg
+ var svg = d3.select("#" + parentId + "-svg");
+ if (svg) {
+ svg.remove();
+ }
+ }
+
+ var parent = d3.select("#" + parentId);
+ var bbox = parent.node().getBoundingClientRect();
+ this.chart.w = bbox.width - 30;
+
+ var ratio = 0.75; // 4:3 by default
+ if (this.get("ratio")) {
+ ratio = this.get("ratio");
+ }
+ this.chart.h = bbox.width * ratio;
+
+ if (this.get("maxHeight")) {
+ this.chart.h = Math.min(this.get("maxHeight"), this.chart.h);
+ }
+
+ this.chart.svg = parent.append("svg")
+ .attr("width", this.chart.w)
+ .attr("height", this.chart.h)
+ .attr("id", parentId + "-svg");
+
+ this.chart.g = this.chart.svg.append("g");
+ },
+
+ renderTitleAndBG: function(g, title, layout, background=true) {
+ var bg = g.append("g");
+ bg.append("text")
+ .text(title)
+ .attr("x", (layout.x1 + layout.x2) / 2)
+ .attr("y", layout.y1 + layout.margin + 20)
+ .attr("class", "chart-title");
+
+ if (background) {
+ bg.append("rect")
+ .attr("x", layout.x1)
+ .attr("y", layout.y1)
+ .attr("width", layout.x2 - layout.x1)
+ .attr("height", layout.y2 - layout.y1)
+ .attr("class", "chart-frame");
+ }
+ },
+
+ bindTooltip: function(d) {
+ d.on("mouseover", function(d) {
+ this.tooltip
+ .style("left", (d3.event.pageX) + "px")
+ .style("top", (d3.event.pageY - 28) + "px");
+ }.bind(this))
+ .on("mousemove", function(d) {
+ // Handle pie chart case
+ var data = d;
+ if (d.data) {
+ data = d.data;
+ }
+
+ this.tooltip.style("opacity", .9);
+ var value = data.value;
+ if (this.get("type") == "memory") {
+ value = Converter.memoryToSimpliedUnit(value);
+ }
+ this.tooltip.html(data.label + " = " + value)
+ .style("left", (d3.event.pageX) + "px")
+ .style("top", (d3.event.pageY - 28) + "px");
+ }.bind(this))
+ .on("mouseout", function(d) {
+ this.tooltip.style("opacity", 0);
+ }.bind(this));
+ },
+
+ adjustMaxHeight: function(h) {
+ this.chart.svg.attr("height", h);
+ },
+
+ getLayout: function() {
+ var x1 = 0;
+ var y1 = 0;
+ var x2 = this.chart.w;
+ var y2 = this.chart.h;
+
+ var layout = {
+ x1: x1,
+ y1: y1,
+ x2: x2 - 10,
+ y2: y2 - 10,
+ margin: 10
+ };
+ return layout;
+ },
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/base-usage-donut-chart.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/base-usage-donut-chart.js
new file mode 100644
index 0000000..bec06c9
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/base-usage-donut-chart.js
@@ -0,0 +1,43 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+import DonutChart from 'yarn-ui/components/donut-chart';
+
+export default DonutChart.extend({
+ mergeLongTails: function(usages, nItemsKept) {
+ var arr = [];
+ for (var i = 0; i < Math.min(usages.length, nItemsKept); i++) {
+ arr.push(usages[i]);
+ }
+
+ var others = {
+ label: "Used by others",
+ value: 0
+ }
+
+ for (var i = nItemsKept; i < usages.length; i++) {
+ others.value += Number(usages[i].value);
+ }
+ others.value = others.value.toFixed(2);
+
+ arr.push(others)
+
+ return arr;
+ },
+})
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/breadcrumb-bar.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/breadcrumb-bar.js
new file mode 100644
index 0000000..44edb8e
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/breadcrumb-bar.js
@@ -0,0 +1,31 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+
+ breadcrumbs: null,
+
+ actions:{
+ refresh: function () {
+ this.get("targetObject").send("refresh");
+ }
+ }
+
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/container-table.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/container-table.js
new file mode 100644
index 0000000..4b741b8
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/container-table.js
@@ -0,0 +1,22 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+});
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/donut-chart.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/donut-chart.js
new file mode 100644
index 0000000..a2a21b3
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/donut-chart.js
@@ -0,0 +1,193 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+import BaseChartComponent from 'yarn-ui/components/base-chart-component';
+import ColorUtils from 'yarn-ui/utils/color-utils';
+import Converter from 'yarn-ui/utils/converter';
+
+export default BaseChartComponent.extend({
+ /*
+ * data = [{label="xx", value=},{...}]
+ */
+ renderDonutChart: function(data, title, showLabels = false,
+ middleLabel = "Total", middleValue = undefined, suffix = "") {
+ var g = this.chart.g;
+ var layout = this.getLayout();
+ this.renderTitleAndBG(g, title, layout);
+
+ var total = 0;
+ var allZero = true;
+ for (var i = 0; i < data.length; i++) {
+ total += data[i].value;
+ if (data[i].value > 1e-6) {
+ allZero = false;
+ }
+ }
+
+ if (!middleValue) {
+ if (this.get("type") == "memory") {
+ middleValue = Converter.memoryToSimpliedUnit(total);
+ } else {
+ middleValue = total;
+ }
+ }
+
+ //Width and height
+ var h = layout.y2 - layout.y1;
+
+ // 50 is for title
+ var outerRadius = (h - 50 - 2 * layout.margin) / 2;
+ var innerRadius = outerRadius * 0.618;
+ console.log("inner:" + innerRadius + " outer:" + outerRadius);
+
+ var arc = d3.svg.arc()
+ .innerRadius(innerRadius)
+ .outerRadius(outerRadius);
+
+ var cx;
+ var cy = layout.y1 + 50 + layout.margin + outerRadius;
+ if (showLabels) {
+ cx = layout.x1 + layout.margin + outerRadius;
+ } else {
+ cx = (layout.x1 + layout.x2) / 2;
+ }
+
+ var pie = d3.layout.pie();
+ pie.sort(null);
+ pie.value(function(d) {
+ var v = d.value;
+ // make sure it > 0
+ v = Math.max(v, 1e-6);
+ return v;
+ });
+
+ //Set up groups
+ var arcs = g
+ .selectAll("g.arc")
+ .data(pie(data))
+ .enter()
+ .append("g")
+ .attr("class", "arc")
+ .attr("transform", "translate(" + cx + "," + cy + ")");
+
+ function tweenPie(finish) {
+ var start = {
+ startAngle: 0,
+ endAngle: 0
+ };
+ var i = d3.interpolate(start, finish);
+ return function(d) {
+ return arc(i(d));
+ };
+ }
+
+ //Draw arc paths
+ var path = arcs.append("path")
+ .attr("fill", function(d, i) {
+ if (d.value > 1e-6) {
+ return this.colors[i];
+ } else {
+ return "white";
+ }
+ }.bind(this))
+ .attr("d", arc)
+ .attr("stroke", function(d, i) {
+ if (allZero) {
+ return this.colors[i];
+ }
+ }.bind(this))
+ this.bindTooltip(path);
+ path.on("click", function (d) {
+ var data = d.data;
+ if (data.link) {
+ this.tooltip.remove();
+ document.location.href = data.link;
+ }
+ }.bind(this))
+
+ // Show labels
+ if (showLabels) {
+ var lx = layout.x1 + layout.margin + outerRadius * 2 + 30;
+ var squareW = 15;
+ var margin = 10;
+
+ var select = g.selectAll(".rect")
+ .data(data)
+ .enter();
+ select.append("rect")
+ .attr("fill", function(d, i) {
+ return this.colors[i];
+ }.bind(this))
+ .attr("x", lx)
+ .attr("y", function(d, i) {
+ return layout.y1 + 75 + (squareW + margin) * i + layout.margin;
+ })
+ .attr("width", squareW)
+ .attr("height", squareW);
+ select.append("text")
+ .attr("x", lx + squareW + margin)
+ .attr("y", function(d, i) {
+ return layout.y1 + 80 + (squareW + margin) * i + layout.margin + squareW / 2;
+ })
+ .text(function(d) {
+ var value = d.value;
+ if (this.get("type") == "memory") {
+ value = Converter.memoryToSimpliedUnit(value);
+ }
+ return d.label + ' = ' + value + suffix;
+ }.bind(this));
+ }
+
+ if (middleLabel) {
+ var highLightColor = this.colors[0];
+ g.append("text").text(middleLabel).attr("x", cx).attr("y", cy - 10).
+ attr("class", "donut-highlight-text").attr("fill", highLightColor);
+ g.append("text").text(middleValue).attr("x", cx).attr("y", cy + 15).
+ attr("class", "donut-highlight-sub").attr("fill", highLightColor);
+ }
+
+ path.transition()
+ .duration(500)
+ .attrTween('d', tweenPie);
+ },
+
+ _dataChange: Ember.observer("data", function() {
+ this.chart.g.selectAll("*").remove();
+ if(this.get("data")) {
+ this.draw();
+ }
+ }),
+
+ draw: function() {
+ var colorTargets = this.get("colorTargets");
+ if (colorTargets) {
+ var colorTargetReverse = Boolean(this.get("colorTargetReverse"));
+ var targets = colorTargets.split(" ");
+ this.colors = ColorUtils.getColors(this.get("data").length, targets, colorTargetReverse);
+ }
+
+ this.renderDonutChart(this.get("data"), this.get("title"), this.get("showLabels"),
+ this.get("middleLabel"), this.get("middleValue"));
+ },
+
+ didInsertElement: function() {
+ this.initChart();
+ this.draw();
+ },
+})
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/item-selector.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/item-selector.js
new file mode 100644
index 0000000..235e438
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/item-selector.js
@@ -0,0 +1,39 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+ didInsertElement: function() {
+ $(".js-example-basic-single").select2(
+ {
+ width: '100%',
+ placeholder: "Select a queue"
+ });
+ var elementId = this.get("element-id");
+ var prefix = this.get("prefix");
+
+ var element = d3.select("#" + elementId);
+
+ if (element) {
+ this.get("model").forEach(function(o) {
+ element.append("option").attr("value", o.get("name")).text(prefix + o.get("name"));
+ });
+ }
+ }
+});
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/nodes-heatmap.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/nodes-heatmap.js
new file mode 100644
index 0000000..af8ceb3
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/nodes-heatmap.js
@@ -0,0 +1,209 @@
+/**
+ * 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.
+ */
+
+import BaseChartComponent from 'yarn-ui/components/base-chart-component';
+import Mock from 'yarn-ui/utils/mock';
+
+export default BaseChartComponent.extend({
+ CELL_WIDTH: 250,
+ SAMPLE_CELL_WIDTH: 100,
+ SAMPLE_HEIGHT: 30,
+ CELL_HEIGHT: 30,
+ CELL_MARGIN: 2,
+ RACK_MARGIN: 20,
+ filter: "",
+
+ bindTP: function(element) {
+ element.on("mouseover", function() {
+ this.tooltip
+ .style("left", (d3.event.pageX) + "px")
+ .style("top", (d3.event.pageY - 28) + "px");
+ element.style("opacity", 1.0);
+ }.bind(this))
+ .on("mousemove", function() {
+ // Handle pie chart case
+ var text = element.attr("tooltiptext");
+
+ this.tooltip.style("opacity", .9);
+ this.tooltip.html(text)
+ .style("left", (d3.event.pageX) + "px")
+ .style("top", (d3.event.pageY - 28) + "px");
+ }.bind(this))
+ .on("mouseout", function() {
+ this.tooltip.style("opacity", 0);
+ element.style("opacity", 0.8);
+ }.bind(this));
+ },
+
+ // data:
+ // [{label=label1, value=value1}, ...]
+ // ...
+ renderCells: function (model, title) {
+ var data = [];
+ model.forEach(function (o) {
+ data.push(o);
+ });
+
+ this.chart.g.remove();
+ this.chart.g = this.chart.svg.append("g");
+ var g = this.chart.g;
+ var layout = this.getLayout();
+ layout.margin = 50;
+
+ let racks = new Set();
+ for (var i = 0; i < data.length; i++) {
+ racks.add(data[i].get("rack"));
+ }
+
+ let racksArray = [];
+ racks.forEach(v => racksArray.push(v));
+
+ var xOffset = layout.margin;
+ var yOffset = layout.margin * 3;
+
+ var colorFunc = d3.interpolate(d3.rgb("#bdddf5"), d3.rgb("#0f3957"));
+
+ var sampleXOffset = (layout.x2 - layout.x1) / 2 - 2.5 * this.SAMPLE_CELL_WIDTH -
+ 2 * this.CELL_MARGIN;
+ var sampleYOffset = layout.margin * 2;
+
+ for (var i = 1; i <= 5; i++) {
+ var ratio = i * 0.2 - 0.1;
+
+ var rect = g.append("rect")
+ .attr("x", sampleXOffset)
+ .attr("y", sampleYOffset)
+ .attr("fill", colorFunc(ratio))
+ .attr("width", this.SAMPLE_CELL_WIDTH)
+ .attr("height", this.SAMPLE_HEIGHT);
+ g.append("text")
+ .text("" + (ratio * 100).toFixed(1) + "% Used")
+ .attr("y", sampleYOffset + this.SAMPLE_HEIGHT / 2 + 5)
+ .attr("x", sampleXOffset + this.SAMPLE_CELL_WIDTH / 2)
+ .attr("class", "heatmap-cell");
+ sampleXOffset += this.CELL_MARGIN + this.SAMPLE_CELL_WIDTH;
+ }
+
+ var chartXOffset = -1;
+
+ for (var i = 0; i < racksArray.length; i++) {
+ var text = g.append("text")
+ .text(racksArray[i])
+ .attr("y", yOffset + this.CELL_HEIGHT / 2 + 5)
+ .attr("x", layout.margin)
+ .attr("class", "heatmap-rack");
+
+ if (-1 == chartXOffset) {
+ chartXOffset = layout.margin + text.node().getComputedTextLength() + 30;
+ }
+
+ xOffset = chartXOffset;
+
+ for (var j = 0; j < data.length; j++) {
+ var rack = data[j].get("rack");
+ var host = data[j].get("nodeHostName");
+
+ if (rack == racksArray[i]) {
+ if (!rack.includes(this.filter) && !host.includes(this.filter)) {
+ this.addNode(g, xOffset, yOffset, colorFunc, data[j], false);
+ var text = g.append("text")
+ .text(host)
+ .attr("y", yOffset + this.CELL_HEIGHT / 2 + 5)
+ .attr("x", xOffset + this.CELL_WIDTH / 2)
+ .attr("class", "heatmap-cell-notselected");
+ } else {
+ this.addNode(g, xOffset, yOffset, colorFunc, data[j], true);
+ g.append("text")
+ .text(host)
+ .attr("y", yOffset + this.CELL_HEIGHT / 2 + 5)
+ .attr("x", xOffset + this.CELL_WIDTH / 2)
+ .attr("class", "heatmap-cell");
+ }
+
+ xOffset += this.CELL_MARGIN + this.CELL_WIDTH;
+ if (xOffset + this.CELL_MARGIN + this.CELL_WIDTH >= layout.x2 -
+ layout.margin) {
+ xOffset = chartXOffset;
+ yOffset = yOffset + this.CELL_MARGIN + this.CELL_HEIGHT;
+ }
+
+ }
+ }
+
+ while (xOffset > chartXOffset && xOffset + this.CELL_MARGIN +
+ this.CELL_WIDTH < layout.x2 - layout.margin) {
+ this.addPlaceholderNode(g, xOffset, yOffset);
+ xOffset += this.CELL_MARGIN + this.CELL_WIDTH;
+ }
+
+ if (xOffset != chartXOffset) {
+ xOffset = chartXOffset;
+ yOffset += this.CELL_MARGIN + this.CELL_HEIGHT;
+ }
+ yOffset += this.RACK_MARGIN;
+ }
+
+ layout.y2 = yOffset + layout.margin;
+ this.adjustMaxHeight(layout.y2);
+ this.renderTitleAndBG(g, title, layout, false);
+ },
+
+ addNode: function (g, xOffset, yOffset, colorFunc, data, selected) {
+ var rect = g.append("rect")
+ .attr("y", yOffset)
+ .attr("x", xOffset)
+ .attr("height", this.CELL_HEIGHT)
+ .attr("fill", colorFunc(data.get("usedMemoryMB") /
+ (data.get("usedMemoryMB") + data.get("availMemoryMB"))))
+ .attr("width", this.CELL_WIDTH)
+ .attr("tooltiptext", data.get("toolTipText"));
+ if (selected) {
+ rect.style("opacity", 0.8);
+ this.bindTP(rect);
+ } else {
+ rect.style("opacity", 0.8);
+ rect.attr("fill", "DimGray");
+ }
+ },
+
+ addPlaceholderNode: function(g, xOffset, yOffset) {
+ var rect = g.append("rect")
+ .attr("y", yOffset)
+ .attr("x", xOffset)
+ .attr("height", this.CELL_HEIGHT)
+ .attr("fill", "grey")
+ .attr("width", this.CELL_WIDTH)
+ .style("opacity", 0.20);
+ },
+
+ draw: function() {
+ this.initChart(true);
+ this.renderCells(this.get("model"), this.get("title"), this.get("textWidth"));
+ },
+
+ didInsertElement: function () {
+ this.draw();
+ },
+
+ actions: {
+ applyFilter: function(event) {
+ this.filter = event.srcElement.value;
+ this.didInsertElement();
+ }
+ }
+})
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/per-app-memusage-by-nodes-stacked-barchart.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/per-app-memusage-by-nodes-stacked-barchart.js
new file mode 100644
index 0000000..7feb7bb
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/per-app-memusage-by-nodes-stacked-barchart.js
@@ -0,0 +1,88 @@
+/**
+ * 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.
+ */
+
+import StackedBarchart from 'yarn-ui/components/stacked-barchart';
+import Converter from 'yarn-ui/utils/converter';
+
+export default StackedBarchart.extend({
+ getDataForRender: function(containers, nodes) {
+ var arr = [];
+ var nodeToResources = {};
+ nodes.forEach(function(n) {
+ nodeToResources[n.id] =
+ {
+ used: Number(n.get("usedMemoryMB")),
+ avail: Number(n.get("availMemoryMB"))
+ }
+ });
+
+ containers.forEach(function(c) {
+ res = nodeToResources[c.get("assignedNodeId")];
+ if (res) {
+ if (!res.usedByTheApp) {
+ res.usedByTheApp = 0;
+ }
+ res.usedByTheApp += Number(c.get("allocatedMB"));
+ }
+ });
+
+ for (var nodeId in nodeToResources) {
+ var res = nodeToResources[nodeId];
+
+ var subArr = [];
+ var value = res.usedByTheApp ? res.usedByTheApp : 0;
+ subArr.push({
+ value: value,
+ bindText: "This app uses " + Converter.memoryToSimpliedUnit(value) + ". On node=" + nodeId,
+ });
+
+ value = res.used - value;
+ value = Math.max(value, 0);
+ subArr.push({
+ value: value,
+ bindText: "Other applications uses " + Converter.memoryToSimpliedUnit(value) + ". On node=" + nodeId,
+ });
+
+ subArr.push({
+ value: res.avail,
+ bindText: "Free resource " + Converter.memoryToSimpliedUnit(res.avail) + " . On node=" + nodeId
+ });
+
+ arr.push(subArr);
+ }
+
+ console.log(arr);
+
+ return arr;
+ },
+
+ didInsertElement: function() {
+ this.initChart(true);
+
+ this.colors = ["Orange", "Grey", "LimeGreen"];
+
+ var containers = this.get("rmContainers");
+ var nodes = this.get("nodes");
+
+ var data = this.getDataForRender(containers, nodes);
+
+ this.show(
+ data, this.get("title"), ["Used by this app", "Used by other apps",
+ "Available"]);
+ },
+})
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/per-app-ncontainers-by-nodes-stacked-barchart.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/per-app-ncontainers-by-nodes-stacked-barchart.js
new file mode 100644
index 0000000..251f557
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/per-app-ncontainers-by-nodes-stacked-barchart.js
@@ -0,0 +1,67 @@
+/**
+ * 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.
+ */
+
+import StackedBarchart from 'yarn-ui/components/stacked-barchart';
+
+export default StackedBarchart.extend({
+ getDataForRender: function(containers, nodes) {
+ var arr = [];
+ var nodeToContainers = {};
+ nodes.forEach(function(n) {
+ nodeToContainers[n.id] = 0;
+ });
+
+ containers.forEach(function(c) {
+ var nodeId = c.get("assignedNodeId");
+ var n = nodeToContainers[nodeId];
+ if (undefined != n) {
+ nodeToContainers[nodeId] += 1;
+ }
+ });
+
+ for (var nodeId in nodeToContainers) {
+ var n = nodeToContainers[nodeId];
+
+ var subArr = [];
+ subArr.push({
+ value: n,
+ bindText: "This app has " + n + " containers running on node=" + nodeId
+ });
+
+ arr.push(subArr);
+ }
+
+ console.log(arr);
+
+ return arr;
+ },
+
+ didInsertElement: function() {
+ this.initChart(true);
+
+ this.colors = ["Orange", "Grey", "Gainsboro"];
+
+ var containers = this.get("rmContainers");
+ var nodes = this.get("nodes");
+
+ var data = this.getDataForRender(containers, nodes);
+
+ this.show(
+ data, this.get("title"), ["Running containers from this app"]);
+ },
+})
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-configuration-table.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-configuration-table.js
new file mode 100644
index 0000000..4b741b8
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-configuration-table.js
@@ -0,0 +1,22 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+});
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-navigator.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-navigator.js
new file mode 100644
index 0000000..4b741b8
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-navigator.js
@@ -0,0 +1,22 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+});
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-usage-donut-chart.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-usage-donut-chart.js
new file mode 100644
index 0000000..f5e7574
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-usage-donut-chart.js
@@ -0,0 +1,69 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+import DonutChart from 'yarn-ui/components/donut-chart';
+import BaseUsageDonutChart from 'yarn-ui/components/base-usage-donut-chart';
+import ColorUtils from 'yarn-ui/utils/color-utils';
+import HrefAddressUtils from 'yarn-ui/utils/href-address-utils';
+
+export default BaseUsageDonutChart.extend({
+ colors: d3.scale.category20().range(),
+
+ draw: function() {
+ var usageByQueues = [];
+ var avail = 100;
+
+ this.get("data").forEach(function (queue) {
+ var v = queue.get("absUsedCapacity");
+
+ if (queue.get("isLeafQueue")) {
+ if (v > 1e-2) {
+ usageByQueues.push({
+ label: queue.get("id"),
+ link: HrefAddressUtils.getQueueLink(queue.get("id")),
+ value: v.toFixed(2)
+ });
+
+ avail = avail - v;
+ }
+ }
+ });
+
+ usageByQueues.sort(function(a, b) {
+ return b.value - a.value;
+ });
+
+ usageByQueues = this.mergeLongTails(usageByQueues, 8);
+
+ usageByQueues.push({
+ label: "Available",
+ value: avail.toFixed(4)
+ });
+
+ this.colors = ColorUtils.getColors(usageByQueues.length, ["others", "good"], true);
+
+ this.renderDonutChart(usageByQueues, this.get("title"), this.get("showLabels"),
+ this.get("middleLabel"), "100%", "%");
+ },
+
+ didInsertElement: function() {
+ this.initChart();
+ this.draw();
+ },
+})
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-view.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-view.js
new file mode 100644
index 0000000..adedf9a
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-view.js
@@ -0,0 +1,289 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+import ChartUtilsMixin from 'yarn-ui/mixins/charts-utils';
+
+export default Ember.Component.extend(ChartUtilsMixin, {
+ queues: {
+ data: undefined,
+ foldedQueues: {},
+ selectedQueueCircle: undefined,
+ maxDepth: -1,
+ },
+
+ queueColors: d3.scale.category20().range(),
+
+ renderQueue: function (now, depth, sequence) {
+ if (depth > this.queues.maxDepth) {
+ this.queues.maxDepth = depth;
+ }
+
+ var cx = 20 + depth * 30;
+ var cy = 20 + sequence * 30;
+ var name = now.get("name");
+
+ var g = this.queues.dataGroup.append("g")
+ .attr("id", "queue-" + name + "-g");
+
+ var folded = this.queues.foldedQueues[name];
+ var isParentQueue = false;
+
+ // render its children
+ var children = [];
+ var childrenNames = now.get("children");
+ if (childrenNames) {
+ childrenNames.forEach(function (name) {
+ isParentQueue = true;
+ var child = this.queues.data[name];
+ if (child) {
+ children.push(child);
+ }
+ }.bind(this));
+ }
+ if (folded) {
+ children = [];
+ }
+ var linefunction = d3.svg.line()
+ .interpolate("basis")
+ .x(function (d) {
+ return d.x;
+ })
+ .y(function (d) {
+ return d.y;
+ });
+
+ for (var i = 0; i < children.length; i++) {
+ sequence = sequence + 1;
+ // Get center of children queue
+ var cc = this.renderQueue(children[i],
+ depth + 1, sequence);
+ g.append("path")
+ .attr("class", "queue")
+ .attr("d", linefunction([{
+ x: cx,
+ y: cy
+ }, {
+ x: cc.x - 20,
+ y: cc.y
+ }, cc]));
+ }
+
+ var circle = g.append("circle")
+ .attr("cx", cx)
+ .attr("cy", cy)
+ .attr("class", "queue");
+
+ circle.on('mouseover', function () {
+ }.bind(this));
+ circle.on('mouseout', function () {
+ if (circle != this.queues.selectedQueueCircle) {
+ circle.style("fill", this.queueColors[0]);
+ }
+ }.bind(this));
+ circle.on('click', function () {
+ circle.style("fill", this.queueColors[2]);
+ var pre = this.queues.selectedQueueCircle;
+ this.queues.selectedQueueCircle = circle;
+ if (pre) {
+ pre.on('mouseout')();
+ }
+ this.renderCharts(name);
+ }.bind(this));
+ circle.on('dblclick', function () {
+ if (!isParentQueue) {
+ return;
+ }
+
+ if (this.queues.foldedQueues[name]) {
+ delete this.queues.foldedQueues[name];
+ } else {
+ this.queues.foldedQueues[name] = now;
+ }
+ this.renderQueues();
+ }.bind(this));
+
+ var text = name;
+ if (folded) {
+ text = name + " (+)";
+ }
+
+ // print queue's name
+ g.append("text")
+ .attr("x", cx + 30)
+ .attr("y", cy + 5)
+ .text(text)
+ .attr("class", "queue");
+
+ return {
+ x: cx,
+ y: cy
+ };
+ },
+
+ renderQueues: function () {
+ if (this.queues.dataGroup) {
+ this.queues.dataGroup.remove();
+ }
+ // render queues
+ this.queues.dataGroup = this.canvas.svg.append("g")
+ .attr("id", "queues-g");
+ var rootQueue = undefined;
+
+ if (this.queues.data) {
+ this.renderQueue(this.queues.data['root'], 0, 0);
+
+ }
+ },
+
+ draw: function () {
+ this.queues.data = {};
+ this.get("model")
+ .forEach(function (o) {
+ this.queues.data[o.id] = o;
+ }.bind(this));
+
+ // get w/h of the svg
+ var bbox = d3.select("#main-container")
+ .node()
+ .getBoundingClientRect();
+ this.canvas.w = bbox.width;
+ this.canvas.h = Math.max(Object.keys(this.queues.data)
+ .length * 35, 1500);
+
+ this.canvas.svg = d3.select("#main-container")
+ .append("svg")
+ .attr("width", this.canvas.w)
+ .attr("height", this.canvas.h)
+ .attr("id", "main-svg");
+
+ this.renderBackground();
+
+ this.renderQueues();
+ this.renderCharts("root");
+ },
+
+ didInsertElement: function () {
+ this.draw();
+ },
+
+ /*
+ * data = [{label="xx", value=},{...}]
+ */
+ renderTable: function (data, title, layout) {
+ d3.select("#main-svg")
+ .append('table')
+ .selectAll('tr')
+ .data(data)
+ .enter()
+ .append('tr')
+ .selectAll('td')
+ .data(function (d) {
+ return d;
+ })
+ .enter()
+ .append('td')
+ .text(function (d) {
+ return d;
+ });
+ },
+
+ renderQueueCapacities: function (queue, layout) {
+ // Render bar chart
+ this.renderCells(this.charts.g, [{
+ label: "Cap",
+ value: queue.get("capacity")
+ }, {
+ label: "MaxCap",
+ value: queue.get("maxCapacity")
+ }, {
+ label: "UsedCap",
+ value: queue.get("usedCapacity")
+ }], "Queue Capacities", layout, 60);
+ },
+
+ renderChildrenCapacities: function (queue, layout) {
+ var data = [];
+ var children = queue.get("children");
+ if (children) {
+ for (var i = 0; i < children.length; i++) {
+ var child = this.queues.data[children[i]];
+ data.push({
+ label: child.get("name"),
+ value: child.get("capacity")
+ });
+ }
+ }
+
+ this.renderDonutChart(this.charts.g, data, "Children Capacities", layout, true);
+ },
+
+ renderChildrenUsedCapacities: function (queue, layout) {
+ var data = [];
+ var children = queue.get("children");
+ if (children) {
+ for (var i = 0; i < children.length; i++) {
+ var child = this.queues.data[children[i]];
+ data.push({
+ label: child.get("name"),
+ value: child.get("usedCapacity")
+ });
+ }
+ }
+
+ this.renderDonutChart(this.charts.g, data, "Children Used Capacities", layout, true);
+ },
+
+ renderLeafQueueUsedCapacities: function (layout) {
+ var leafQueueUsedCaps = [];
+ for (var queueName in this.queues.data) {
+ var q = this.queues.data[queueName];
+ if ((!q.get("children")) || q.get("children")
+ .length == 0) {
+ // it's a leafqueue
+ leafQueueUsedCaps.push({
+ label: q.get("name"),
+ value: q.get("usedCapacity")
+ });
+ }
+ }
+
+ this.renderDonutChart(this.charts.g, leafQueueUsedCaps, "LeafQueues Used Capacities",
+ layout, true);
+ },
+
+ renderCharts: function (queueName) {
+ this.charts.leftBannerLen = this.queues.maxDepth * 30 + 100;
+ this.initCharts();
+
+ var queue = this.queues.data[queueName];
+ var idx = 0;
+
+ if (queue.get("name") == "root") {
+ this.renderLeafQueueUsedCapacities(this.getLayout(idx++));
+ }
+ if (queue.get("name") != "root") {
+ this.renderQueueCapacities(queue, this.getLayout(idx++));
+ }
+ if (queue.get("children") && queue.get("children")
+ .length > 0) {
+ this.renderChildrenCapacities(queue, this.getLayout(idx++));
+ this.renderChildrenUsedCapacities(queue, this.getLayout(idx++));
+ }
+ },
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/simple-table.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/simple-table.js
new file mode 100644
index 0000000..359583d
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/simple-table.js
@@ -0,0 +1,81 @@
+
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+ didInsertElement: function() {
+ var paging = this.get("paging") ? true : this.get("paging");
+ var ordering = this.get("ordering") ? true : this.get("ordering");
+ var info = this.get("info") ? true : this.get("info");
+ var bFilter = this.get("bFilter") ? true : this.get("bFilter");
+ var defaultSearch = this.get("defaultSearch") ? this.get("defaultSearch") : "";
+
+ // Defines sorter for the columns if not default.
+ // Can also specify a custom sorter.
+ var i;
+ var colDefs = [];
+ if (this.get("colTypes")) {
+ var typesArr = this.get("colTypes").split(' ');
+ var targetsArr = this.get("colTargets").split(' ');
+ for (i = 0; i < typesArr.length; i++) {
+ console.log(typesArr[i] + " " + targetsArr[i]);
+ colDefs.push({
+ type: typesArr[i],
+ targets: parseInt(targetsArr[i])
+ });
+ }
+ }
+ // Defines initial column and sort order.
+ var orderArr = [];
+ if (this.get("colsOrder")) {
+ var cols = this.get("colsOrder").split(' ');
+ for (i = 0; i < cols.length; i++) {
+ var col = cols[i].split(',');
+ if (col.length != 2) {
+ continue;
+ }
+ var order = col[1].trim();
+ if (order != 'asc' && order != 'desc') {
+ continue;
+ }
+ var colOrder = [];
+ colOrder.push(parseInt(col[0]));
+ colOrder.push(order);
+ orderArr.push(colOrder);
+ }
+ }
+ if (orderArr.length == 0) {
+ var defaultOrder = [0, 'asc'];
+ orderArr.push(defaultOrder);
+ }
+ console.log(orderArr[0]);
+ Ember.$('#' + this.get('table-id')).DataTable({
+ "paging": paging,
+ "ordering": ordering,
+ "info": info,
+ "bFilter": bFilter,
+ "order": orderArr,
+ "columnDefs": colDefs,
+ "oSearch": {
+ "sSearch": defaultSearch
+ }
+ });
+ }
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/stacked-barchart.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/stacked-barchart.js
new file mode 100644
index 0000000..4a121fe
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/stacked-barchart.js
@@ -0,0 +1,198 @@
+/**
+ * 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.
+ */
+
+import BaseChartComponent from 'yarn-ui/components/base-chart-component';
+import Mock from 'yarn-ui/utils/mock';
+
+export default BaseChartComponent.extend({
+ MAX_BAR_HEIGHT: 120,
+ MAX_BAR_WIDTH: 30,
+ GAP: 5,
+ filter: "",
+ WIDTH_OF_SAMPLE: 200,
+
+ bindTP: function(element) {
+ element.on("mouseover", function() {
+ this.tooltip
+ .style("left", (d3.event.pageX) + "px")
+ .style("top", (d3.event.pageY - 28) + "px");
+ element.style("opacity", 1.0);
+ }.bind(this))
+ .on("mousemove", function() {
+ // Handle pie chart case
+ var text = element.attr("tooltiptext");
+
+ this.tooltip.style("opacity", .9);
+ this.tooltip.html(text)
+ .style("left", (d3.event.pageX) + "px")
+ .style("top", (d3.event.pageY - 28) + "px");
+ }.bind(this))
+ .on("mouseout", function() {
+ this.tooltip.style("opacity", 0);
+ element.style("opacity", 0.8);
+ }.bind(this));
+
+ element.on("click", function() {
+ if (element.attr("link")) {
+ this.tooltip.remove();
+ document.location.href = element.attr("link");
+ }
+ }.bind(this));
+ },
+
+ printSamples: function(n, layout, g, colorTitles) {
+ var yOffset = layout.margin * 3;
+
+ for (var i = 0; i < n; i++) {
+ var xOffset = layout.x2 - this.WIDTH_OF_SAMPLE - layout.margin;
+ g.append("rect").
+ attr("fill", this.colors[i]).
+ attr("x", xOffset).
+ attr("y", yOffset).
+ attr("width", 20).
+ attr("height", 20);
+
+ g.append("text").
+ attr("x", xOffset + 30).
+ attr("y", yOffset + 10).
+ text(colorTitles[i]);
+
+ yOffset = yOffset + 30;
+ }
+ },
+
+ // data:
+ // [[{value=xx, bindText=xx}, {value=yy, bindText=yy}], [ ... ]]
+ // __________________________________________________ ___________
+ // bar-1 bar-2
+ show: function (data, title, colorTitles) {
+ var width = this.MAX_BAR_WIDTH;
+ var height = this.MAX_BAR_HEIGHT;
+
+ this.chart.g.remove();
+ this.chart.g = this.chart.svg.append("g");
+ var g = this.chart.g;
+ var layout = this.getLayout();
+ layout.margin = 50;
+
+ var nBarPerRow = Math.floor((layout.x2 - layout.x1 - 3 * layout.margin -
+ this.WIDTH_OF_SAMPLE) /
+ (width + this.GAP));
+
+ var xOffset;
+ var yOffset = layout.margin * 2;
+
+ var maxValue = 0;
+ var maxN = 0;
+ for (var i = 0; i < data.length; i++) {
+ var total = 0;
+ for (var j = 0; j < data[i].length; j++) {
+ total += data[i][j].value;
+ }
+
+ if (total > maxValue) {
+ maxValue = total;
+ }
+ if (data[i].length > maxN) {
+ maxN = data[i].length;
+ }
+ }
+
+ // print samples
+ this.printSamples(maxN, layout, g, colorTitles);
+
+ // print data
+ data.sort(function(a, b) {
+ return b[0].value - a[0].value;
+ });
+
+ for (var i = 0; i < data.length; i++) {
+ if (i % nBarPerRow == 0) {
+ xOffset = layout.margin;
+ yOffset += layout.margin + height;
+ }
+
+ var leftTopY = yOffset;
+ for (var j = 0; j < data[i].length; j++) {
+ var dy = data[i][j].value * height / maxValue;
+ if (dy > 0) {
+ leftTopY = leftTopY - dy;
+
+ var node = g.append("rect").
+ attr("fill", this.colors[j]).
+ attr("x", xOffset).
+ attr("y", leftTopY).
+ attr("width", width).
+ attr("height", dy).
+ attr("tooltiptext",
+ (data[i][j].bindText) ? data[i][j].bindText : data[i][j].value).
+ attr("link", data[i][j].link)
+ .style("opacity", 0.8);
+
+ this.bindTP(node);
+ }
+ }
+
+ if (data[i].length == 1) {
+ g.append("text")
+ .text(data[i][0].value)
+ .attr("y", leftTopY - 10)
+ .attr("x", xOffset + width / 2)
+ .attr("class", "heatmap-cell")
+ .style("fill", "black");
+ }
+
+ xOffset += width + this.GAP;
+ }
+
+ layout.y2 = yOffset + layout.margin;
+ this.adjustMaxHeight(layout.y2);
+ this.renderTitleAndBG(g, title, layout, false);
+ },
+
+ draw: function(data, title, textWidth) {
+ this.initChart(true);
+ //Mock.initMockNodesData(this);
+
+ // mock data
+ var arr = [];
+ for (var i = 0; i < 5; i++) {
+ var subArr = [];
+ for (var j = 0; j < Math.random() * 4 + 1; j++) {
+ subArr.push({
+ value : Math.abs(Math.random())
+ });
+ }
+ arr.push(subArr);
+ }
+
+ this.show(
+ arr, this.get("title"));
+ },
+
+ didInsertElement: function () {
+ this.draw();
+ },
+
+ actions: {
+ applyFilter: function(event) {
+ this.filter = event.srcElement.value;
+ this.didInsertElement();
+ }
+ }
+})
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/timeline-view.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/timeline-view.js
new file mode 100644
index 0000000..516b114
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/timeline-view.js
@@ -0,0 +1,277 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+import Converter from 'yarn-ui/utils/converter';
+
+export default Ember.Component.extend({
+ canvas: {
+ svg: undefined,
+ h: 0,
+ w: 0,
+ tooltip: undefined
+ },
+
+ clusterMetrics: undefined,
+ modelArr: [],
+ colors: d3.scale.category10().range(),
+ _selected: undefined,
+
+ selected: function() {
+ return this._selected;
+ }.property(),
+
+ tableComponentName: function() {
+ return "app-attempt-table";
+ }.property(),
+
+ setSelected: function(d) {
+ if (this._selected == d) {
+ return;
+ }
+
+ // restore color
+ if (this._selected) {
+ var dom = d3.select("#timeline-bar-" + this._selected.get("id"));
+ dom.attr("fill", this.colors[0]);
+ }
+
+ this._selected = d;
+ this.set("selected", d);
+ dom = d3.select("#timeline-bar-" + d.get("id"));
+ dom.attr("fill", this.colors[1]);
+ },
+
+ getPerItemHeight: function() {
+ var arrSize = this.modelArr.length;
+
+ if (arrSize < 20) {
+ return 30;
+ } else if (arrSize < 100) {
+ return 10;
+ } else {
+ return 2;
+ }
+ },
+
+ getPerItemGap: function() {
+ var arrSize = this.modelArr.length;
+
+ if (arrSize < 20) {
+ return 5;
+ } else if (arrSize < 100) {
+ return 1;
+ } else {
+ return 1;
+ }
+ },
+
+ getCanvasHeight: function() {
+ return (this.getPerItemHeight() + this.getPerItemGap()) * this.modelArr.length + 200;
+ },
+
+ draw: function(start, end) {
+ // get w/h of the svg
+ var bbox = d3.select("#" + this.get("parent-id"))
+ .node()
+ .getBoundingClientRect();
+ this.canvas.w = bbox.width;
+ this.canvas.h = this.getCanvasHeight();
+
+ this.canvas.svg = d3.select("#" + this.get("parent-id"))
+ .append("svg")
+ .attr("width", this.canvas.w)
+ .attr("height", this.canvas.h)
+ .attr("id", this.get("my-id"));
+ this.renderTimeline(start, end);
+ },
+
+ renderTimeline: function(start, end) {
+ var border = 30;
+ var singleBarHeight = this.getPerItemHeight();
+ var gap = this.getPerItemGap();
+ var textWidth = 200;
+ /*
+ start-time end-time
+ |--------------------------------------|
+ ==============
+ ==============
+ ==============
+ ===============
+ */
+ var xScaler = d3.scale.linear()
+ .domain([start, end])
+ .range([0, this.canvas.w - 2 * border - textWidth]);
+
+ /*
+ * Render frame of timeline view
+ */
+ this.canvas.svg.append("line")
+ .attr("x1", border + textWidth)
+ .attr("y1", border - 5)
+ .attr("x2", this.canvas.w - border)
+ .attr("y2", border - 5)
+ .attr("class", "chart");
+
+ this.canvas.svg.append("line")
+ .attr("x1", border + textWidth)
+ .attr("y1", border - 10)
+ .attr("x2", border + textWidth)
+ .attr("y2", border - 5)
+ .attr("class", "chart");
+
+ this.canvas.svg.append("line")
+ .attr("x1", this.canvas.w - border)
+ .attr("y1", border - 10)
+ .attr("x2", this.canvas.w - border)
+ .attr("y2", border - 5)
+ .attr("class", "chart");
+
+ this.canvas.svg.append("text")
+ .text(Converter.timeStampToDate(start))
+ .attr("y", border - 15)
+ .attr("x", border + textWidth)
+ .attr("class", "bar-chart-text")
+ .attr("text-anchor", "left");
+
+ this.canvas.svg.append("text")
+ .text(Converter.timeStampToDate(end))
+ .attr("y", border - 15)
+ .attr("x", this.canvas.w - border)
+ .attr("class", "bar-chart-text")
+ .attr("text-anchor", "end");
+
+ // show bar
+ var bar = this.canvas.svg.selectAll("bars")
+ .data(this.modelArr)
+ .enter()
+ .append("rect")
+ .attr("y", function(d, i) {
+ return border + (gap + singleBarHeight) * i;
+ })
+ .attr("x", function(d, i) {
+ return border + textWidth + xScaler(d.get("startTs"));
+ })
+ .attr("height", singleBarHeight)
+ .attr("fill", function(d, i) {
+ return this.colors[0];
+ }.bind(this))
+ .attr("width", function(d, i) {
+ var finishedTs = xScaler(d.get("finishedTs"));
+ finishedTs = finishedTs > 0 ? finishedTs : xScaler(end);
+ return finishedTs - xScaler(d.get("startTs"));
+ })
+ .attr("id", function(d, i) {
+ return "timeline-bar-" + d.get("id");
+ });
+ bar.on("click", function(d) {
+ this.setSelected(d);
+ }.bind(this));
+
+ this.bindTooltip(bar);
+
+ if (this.modelArr.length <= 20) {
+ // show bar texts
+ for (var i = 0; i < this.modelArr.length; i++) {
+ this.canvas.svg.append("text")
+ .text(this.modelArr[i].get(this.get("label")))
+ .attr("y", border + (gap + singleBarHeight) * i + singleBarHeight / 2)
+ .attr("x", border)
+ .attr("class", "bar-chart-text");
+ }
+ }
+ },
+
+ bindTooltip: function(d) {
+ d.on("mouseover", function(d) {
+ this.tooltip
+ .style("left", (d3.event.pageX) + "px")
+ .style("top", (d3.event.pageY - 28) + "px");
+ }.bind(this))
+ .on("mousemove", function(d) {
+ this.tooltip.style("opacity", .9);
+ this.tooltip.html(d.get("tooltipLabel"))
+ .style("left", (d3.event.pageX) + "px")
+ .style("top", (d3.event.pageY - 28) + "px");
+ }.bind(this))
+ .on("mouseout", function(d) {
+ this.tooltip.style("opacity", 0);
+ }.bind(this));
+ },
+
+ initTooltip: function() {
+ this.tooltip = d3.select("body")
+ .append("div")
+ .attr("class", "tooltip")
+ .attr("id", "chart-tooltip")
+ .style("opacity", 0);
+ },
+
+ didInsertElement: function() {
+ // init tooltip
+ this.initTooltip();
+ this.modelArr = [];
+
+ // init model
+ if (this.get("rmModel")) {
+ this.get("rmModel").forEach(function(o) {
+ if(!this.modelArr.contains(o)) {
+ this.modelArr.push(o);
+ }
+ }.bind(this));
+ }
+
+ if (this.get("tsModel")) {
+ this.get("tsModel").forEach(function(o) {
+ if(!this.modelArr.contains(o)) {
+ this.modelArr.push(o);
+ }
+ }.bind(this));
+ }
+
+ if(this.modelArr.length == 0) {
+ return;
+ }
+
+ this.modelArr.sort(function(a, b) {
+ var tsA = a.get("startTs");
+ var tsB = b.get("startTs");
+
+ return tsA - tsB;
+ });
+ if (this.modelArr.length > 0) {
+ var begin = this.modelArr[0].get("startTs");
+ }
+ var end = 0;
+ for (var i = 0; i < this.modelArr.length; i++) {
+ var ts = this.modelArr[i].get("finishedTs");
+ if (ts > end) {
+ end = ts;
+ }
+ }
+ if (end < begin) {
+ end = Date.now();
+ }
+
+ this.draw(begin, end);
+
+ if (this.modelArr.length > 0) {
+ this.setSelected(this.modelArr[0]);
+ }
+ },
+});
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/tree-selector.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/tree-selector.js
new file mode 100644
index 0000000..5e7cfa0
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/tree-selector.js
@@ -0,0 +1,298 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+const INBETWEEN_HEIGHT = 130;
+
+export default Ember.Component.extend({
+ // Map:
+ map : undefined,
+
+ // Normalized data for d3
+ treeData: undefined,
+
+ // folded queues, folded[] == true means is folded
+ foldedQueues: { },
+
+ // maxDepth
+ maxDepth: 0,
+
+ // num of leaf queue, folded queue is treated as leaf queue
+ numOfLeafQueue: 0,
+
+ // mainSvg
+ mainSvg: undefined,
+
+ // Init data
+ initData: function() {
+ this.map = { };
+ this.treeData = { };
+ this.maxDepth = 0;
+ this.numOfLeafQueue = 0;
+
+ this.get("model")
+ .forEach(function(o) {
+ this.map[o.id] = o;
+ }.bind(this));
+
+ var selected = this.get("selected");
+
+ this.initQueue("root", 1, this.treeData);
+ },
+
+ // get Children array of given queue
+ getChildrenNamesArray: function(q) {
+ var namesArr = [];
+
+ // Folded queue's children is empty
+ if (this.foldedQueues[q.get("name")]) {
+ return namesArr;
+ }
+
+ var names = q.get("children");
+ if (names) {
+ names.forEach(function(name) {
+ namesArr.push(name);
+ });
+ }
+
+ return namesArr;
+ },
+
+ // Init queues
+ initQueue: function(queueName, depth, node) {
+ if ((!queueName) || (!this.map[queueName])) {
+ // Queue is not existed
+ return;
+ }
+
+ if (depth > this.maxDepth) {
+ this.maxDepth = this.maxDepth + 1;
+ }
+
+ var queue = this.map[queueName];
+
+ var names = this.getChildrenNamesArray(queue);
+
+ node.name = queueName;
+ node.parent = queue.get("parent");
+ node.queueData = queue;
+
+ if (names.length > 0) {
+ node.children = [];
+
+ names.forEach(function(name) {
+ var childQueueData = {};
+ node.children.push(childQueueData);
+ this.initQueue(name, depth + 1, childQueueData);
+ }.bind(this));
+ } else {
+ this.numOfLeafQueue = this.numOfLeafQueue + 1;
+ }
+ },
+
+ update: function(source, root, tree, diagonal) {
+ var duration = 300;
+ var i = 0;
+
+ // Compute the new tree layout.
+ var nodes = tree.nodes(root).reverse();
+ var links = tree.links(nodes);
+
+ // Normalize for fixed-depth.
+ nodes.forEach(function(d) { d.y = d.depth * 200; });
+
+ // Update the nodes…
+ var node = this.mainSvg.selectAll("g.node")
+ .data(nodes, function(d) { return d.id || (d.id = ++i); });
+
+ // Enter any new nodes at the parent's previous position.
+ var nodeEnter = node.enter().append("g")
+ .attr("class", "node")
+ .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
+ .on("mouseover", function(d,i){
+ if (d.queueData.get("name") != this.get("selected")) {
+ document.location.href = "#/yarn-queues/" + d.queueData.get("name");
+ }
+
+ Ember.run.later(this, function () {
+ var treeWidth = this.maxDepth * 200;
+ var treeHeight = this.numOfLeafQueue * INBETWEEN_HEIGHT;
+ var tree = d3.layout.tree().size([treeHeight, treeWidth]);
+ var diagonal = d3.svg.diagonal()
+ .projection(function(d) { return [d.y, d.x]; });
+
+ this.update(this.treeData, this.treeData, tree, diagonal);
+ }, 100);
+
+ }.bind(this))
+ .on("click", function (d) {
+ document.location.href = "#/yarn-queue/" + d.queueData.get("name");
+ });
+
+ nodeEnter.append("circle")
+ .attr("r", 1e-6)
+ .style("fill", function(d) {
+ var usedCap = d.queueData.get("usedCapacity");
+ if (usedCap <= 60.0) {
+ return "LimeGreen";
+ } else if (usedCap <= 100.0) {
+ return "DarkOrange";
+ } else {
+ return "LightCoral";
+ }
+ });
+
+ // append percentage
+ nodeEnter.append("text")
+ .attr("x", function(d) { return 0; })
+ .attr("dy", ".35em")
+ .attr("fill", "white")
+ .attr("text-anchor", function(d) { return "middle"; })
+ .text(function(d) {
+ var usedCap = d.queueData.get("usedCapacity");
+ if (usedCap >= 100.0) {
+ return usedCap.toFixed(0) + "%";
+ } else {
+ return usedCap.toFixed(1) + "%";
+ }
+ })
+ .style("fill-opacity", 1e-6);
+
+ // append queue name
+ nodeEnter.append("text")
+ .attr("x", "0px")
+ .attr("dy", "45px")
+ .attr("text-anchor", "middle")
+ .text(function(d) { return d.name; })
+ .style("fill-opacity", 1e-6);
+
+ // Transition nodes to their new position.
+ var nodeUpdate = node.transition()
+ .duration(duration)
+ .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });
+
+ nodeUpdate.select("circle")
+ .attr("r", 30)
+ .attr("href",
+ function(d) {
+ return "#/yarn-queues/" + d.queueData.get("name");
+ })
+ .style("stroke-width", function(d) {
+ if (d.queueData.get("name") == this.get("selected")) {
+ return 7;
+ } else {
+ return 2;
+ }
+ }.bind(this))
+ .style("stroke", function(d) {
+ if (d.queueData.get("name") == this.get("selected")) {
+ return "gray";
+ } else {
+ return "gray";
+ }
+ }.bind(this));
+
+ nodeUpdate.selectAll("text")
+ .style("fill-opacity", 1);
+
+ // Transition exiting nodes to the parent's new position.
+ var nodeExit = node.exit().transition()
+ .duration(duration)
+ .attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; })
+ .remove();
+
+ nodeExit.select("circle")
+ .attr("r", 1e-6);
+
+ nodeExit.select("text")
+ .style("fill-opacity", 1e-6);
+
+ // Update the links…
+ var link = this.mainSvg.selectAll("path.link")
+ .data(links, function(d) { return d.target.id; });
+
+ // Enter any new links at the parent's previous position.
+ link.enter().insert("path", "g")
+ .attr("class", "link")
+ .attr("d", function(d) {
+ var o = {x: source.x0, y: source.y0};
+ return diagonal({source: o, target: o});
+ });
+
+ // Transition links to their new position.
+ link.transition()
+ .duration(duration)
+ .attr("d", diagonal);
+
+ // Transition exiting nodes to the parent's new position.
+ link.exit().transition()
+ .duration(duration)
+ .attr("d", function(d) {
+ var o = {x: source.x, y: source.y};
+ return diagonal({source: o, target: o});
+ })
+ .remove();
+
+ // Stash the old positions for transition.
+ nodes.forEach(function(d) {
+ d.x0 = d.x;
+ d.y0 = d.y;
+ });
+ },
+
+ reDraw: function() {
+ this.initData();
+
+ var margin = {top: 20, right: 120, bottom: 20, left: 120};
+ var treeWidth = this.maxDepth * 200;
+ var treeHeight = this.numOfLeafQueue * INBETWEEN_HEIGHT;
+ var width = treeWidth + margin.left + margin.right;
+ var height = treeHeight + margin.top + margin.bottom;
+ var layout = { };
+
+ if (this.mainSvg) {
+ this.mainSvg.remove();
+ }
+
+ this.mainSvg = d3.select("#" + this.get("parentId")).append("svg")
+ .attr("width", width)
+ .attr("height", height)
+ .attr("class", "tree-selector")
+ .append("g")
+ .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
+
+ var tree = d3.layout.tree().size([treeHeight, treeWidth]);
+
+ var diagonal = d3.svg.diagonal()
+ .projection(function(d) { return [d.y, d.x]; });
+
+ var root = this.treeData;
+ root.x0 = height / 2;
+ root.y0 = 0;
+
+ d3.select(self.frameElement).style("height", height);
+
+ this.update(root, root, tree, diagonal);
+ },
+
+ didInsertElement: function() {
+ this.reDraw();
+ }
+});
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/config.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/config.js
new file mode 100644
index 0000000..157d48b
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/config.js
@@ -0,0 +1,24 @@
+/**
+ * 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.
+ */
+
+/**
+ * Host and port configurations
+ */
+
+export default {
+};
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/constants.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/constants.js
new file mode 100644
index 0000000..d2937a0
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/constants.js
@@ -0,0 +1,24 @@
+/**
+ * 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.
+ */
+
+/**
+ * Application level global constants go here.
+ */
+export default {
+ PARAM_SEPARATOR: '!',
+};
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/application.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/application.js
new file mode 100644
index 0000000..2effb13
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/application.js
@@ -0,0 +1,55 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+/**
+ * Base controller for application.
+ */
+export default Ember.Controller.extend({
+ /**
+ * Output main top UI menu which is common across all pages.
+ * Menu item will be made active based on current path.
+ */
+ outputMainMenu: function(){
+ var path = this.get('currentPath');
+ var html = '
';
+ return Ember.String.htmlSafe(html);
+ }.property('currentPath')
+});
+
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/cluster-overview.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/cluster-overview.js
new file mode 100644
index 0000000..22e6267
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/cluster-overview.js
@@ -0,0 +1,32 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Controller.extend({
+ loading: true,
+
+ breadcrumbs: [{
+ text: "Home",
+ routeName: 'application'
+ }, {
+ text: "Cluster Overview",
+ routeName: 'cluster-overview',
+ }]
+
+});
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app-attempt.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app-attempt.js
new file mode 100644
index 0000000..a458842
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app-attempt.js
@@ -0,0 +1,40 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Controller.extend({
+
+ breadcrumbs: Ember.computed("model.attempt.appId", function () {
+ var appId = this.get("model.attempt.appId");
+ return [{
+ text: "Home",
+ routeName: 'application'
+ },{
+ text: "Applications",
+ routeName: 'yarn-apps'
+ }, {
+ text: `App [${appId}]`,
+ routeName: 'yarn-app',
+ model: appId
+ }, {
+ text: "Attempt",
+ }];
+ })
+
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app-attempts.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app-attempts.js
new file mode 100644
index 0000000..9ebc2a6
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app-attempts.js
@@ -0,0 +1,40 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Controller.extend({
+
+ breadcrumbs: Ember.computed("model.appId", function () {
+ var appId = this.get("model.appId");
+ return [{
+ text: "Home",
+ routeName: 'application'
+ },{
+ text: "Applications",
+ routeName: 'yarn-apps'
+ }, {
+ text: `App [${appId}]`,
+ routeName: 'yarn-app',
+ model: appId
+ }, {
+ text: "Attempts",
+ }];
+ })
+
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app.js
new file mode 100644
index 0000000..f6b9404
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app.js
@@ -0,0 +1,38 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Controller.extend({
+
+ breadcrumbs: Ember.computed("model.app.id", function () {
+ var appId = this.get("model.app.id");
+ return [{
+ text: "Home",
+ routeName: 'application'
+ },{
+ text: "Applications",
+ routeName: 'yarn-apps'
+ }, {
+ text: `App [${appId}]`,
+ routeName: 'yarn-app',
+ model: appId
+ }];
+ })
+
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-apps.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-apps.js
new file mode 100644
index 0000000..396f83b
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-apps.js
@@ -0,0 +1,31 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Controller.extend({
+
+ breadcrumbs: [{
+ text: "Home",
+ routeName: 'application'
+ }, {
+ text: "Applications",
+ routeName: 'yarn-apps',
+ }]
+
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-container-log.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-container-log.js
new file mode 100644
index 0000000..3352eaf
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-container-log.js
@@ -0,0 +1,40 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Controller.extend({
+
+ breadcrumbs: Ember.computed('model.nodeInfo', 'model.containerInfo', function () {
+ var nodeInfo = this.get('model.nodeInfo'),
+ containerInfo = this.get('model.containerInfo');
+ return [{
+ text: "Home",
+ routeName: 'application'
+ }, {
+ text: `Node [ ${nodeInfo.id} ]`,
+ href: `/#/yarn-node/${nodeInfo.id}/${nodeInfo.addr}`,
+ }, {
+ text: `Container [ ${containerInfo.id} ]`,
+ href: `/#/yarn-node-container/${nodeInfo.id}/${nodeInfo.addr}/${containerInfo.id}`,
+ }, {
+ text: "Log",
+ }];
+ })
+
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node-app.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node-app.js
new file mode 100644
index 0000000..76da281
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node-app.js
@@ -0,0 +1,36 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Controller.extend({
+
+ breadcrumbs: Ember.computed('model.nodeInfo', function () {
+ var nodeInfo = this.get('model.nodeInfo');
+ return [{
+ text: "Home",
+ routeName: 'application'
+ }, {
+ text: `Node [ ${nodeInfo.id} ]`,
+ href: `/#/yarn-node/${nodeInfo.id}/${nodeInfo.addr}`,
+ }, {
+ text: "Application",
+ }];
+ })
+
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node-apps.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node-apps.js
new file mode 100644
index 0000000..4bfe9d0
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node-apps.js
@@ -0,0 +1,39 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Controller.extend({
+
+ breadcrumbs: Ember.computed("model.attempt.appId", function () {
+ var nodeInfo = this.get("model.nodeInfo");
+ return [{
+ text: "Home",
+ routeName: 'application'
+ },{
+ text: "Nodes",
+ routeName: 'yarn-nodes'
+ }, {
+ text: `Node [ ${nodeInfo.id} ]`,
+ href: `/#/yarn-node/${nodeInfo.id}/${nodeInfo.addr}`,
+ }, {
+ text: "Applications",
+ }];
+ })
+
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node-containers.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node-containers.js
new file mode 100644
index 0000000..59c8591
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node-containers.js
@@ -0,0 +1,39 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Controller.extend({
+
+ breadcrumbs: Ember.computed("model.nodeInfo", function () {
+ var nodeInfo = this.get("model.nodeInfo");
+ return [{
+ text: "Home",
+ routeName: 'application'
+ },{
+ text: "Nodes",
+ routeName: 'yarn-nodes'
+ }, {
+ text: `Node [ ${nodeInfo.id} ]`,
+ href: `/#/yarn-node/${nodeInfo.id}/${nodeInfo.addr}`,
+ }, {
+ text: "Containers",
+ }];
+ })
+
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node.js
new file mode 100644
index 0000000..e505022
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node.js
@@ -0,0 +1,37 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Controller.extend({
+
+ breadcrumbs: Ember.computed("model.attempt.appId", function () {
+ var nodeInfo = this.get("model.nodeInfo");
+ return [{
+ text: "Home",
+ routeName: 'application'
+ },{
+ text: "Nodes",
+ routeName: 'yarn-nodes'
+ }, {
+ text: `Node [ ${nodeInfo.id} ]`,
+ href: `/#/yarn-node/${nodeInfo.id}/${nodeInfo.addr}`,
+ }];
+ })
+
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-nodes-heatmap.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-nodes-heatmap.js
new file mode 100644
index 0000000..fbe77fa
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-nodes-heatmap.js
@@ -0,0 +1,36 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Controller.extend({
+ needReload: true,
+ selectedQueue: undefined,
+
+ breadcrumbs: [{
+ text: "Home",
+ routeName: 'application'
+ }, {
+ text: "Nodes",
+ routeName: 'yarn-nodes',
+ }, {
+ text: "Heatmap",
+ routeName: 'yarn-nodes-heatmap',
+ }]
+
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-nodes.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-nodes.js
new file mode 100644
index 0000000..b4bf0f0
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-nodes.js
@@ -0,0 +1,33 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Controller.extend({
+ needReload: true,
+ selectedQueue: undefined,
+
+ breadcrumbs: [{
+ text: "Home",
+ routeName: 'application'
+ }, {
+ text: "Nodes",
+ routeName: 'yarn-nodes',
+ }]
+
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queue-apps.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queue-apps.js
new file mode 100644
index 0000000..e7bedd6
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queue-apps.js
@@ -0,0 +1,46 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Controller.extend({
+ needReload: true,
+ selectedQueue: undefined,
+
+ breadcrumbs: Ember.computed("model.selected", function () {
+ var queueName = this.get("model.selected");
+
+ return [{
+ text: "Home",
+ routeName: 'application'
+ }, {
+ text: "Queues",
+ routeName: 'yarn-queues',
+ model: 'root'
+ }, {
+ text: `Queue [ ${queueName} ]`,
+ routeName: 'yarn-queue',
+ model: queueName
+ }, {
+ text: "Applications",
+ }];
+
+ }),
+
+
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queue.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queue.js
new file mode 100644
index 0000000..0b4150f
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queue.js
@@ -0,0 +1,44 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Controller.extend({
+ needReload: true,
+ selectedQueue: undefined,
+
+ breadcrumbs: Ember.computed("model.selected", function () {
+ var queueName = this.get("model.selected");
+
+ return [{
+ text: "Home",
+ routeName: 'application'
+ }, {
+ text: "Queues",
+ routeName: 'yarn-queues',
+ model: 'root'
+ }, {
+ text: `Queue [ ${queueName} ]`,
+ routeName: 'yarn-queue',
+ model: queueName
+ }];
+
+ }),
+
+
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queues.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queues.js
new file mode 100644
index 0000000..941e150
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queues.js
@@ -0,0 +1,34 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Controller.extend({
+ needReload: true,
+ selectedQueue: undefined,
+
+ breadcrumbs: [{
+ text: "Home",
+ routeName: 'application'
+ }, {
+ text: "Queues",
+ routeName: 'yarn-queues',
+ model: 'root'
+ }]
+
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-services.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-services.js
new file mode 100644
index 0000000..597962a
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-services.js
@@ -0,0 +1,34 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Controller.extend({
+
+ breadcrumbs: [{
+ text: "Home",
+ routeName: 'application'
+ }, {
+ text: "Applications",
+ routeName: 'yarn-apps',
+ }, {
+ text: "Long Running Services",
+ routeName: 'yarn-services',
+ }]
+
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/helpers/divide.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/helpers/divide.js
new file mode 100644
index 0000000..fcf64dd
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/helpers/divide.js
@@ -0,0 +1,31 @@
+/**
+ * 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.
+ */
+import Ember from 'ember';
+
+/**
+ * Helper assumes values are numeric. num means numerator and
+ * den means denominator.
+ */
+export default Ember.Helper.helper(function(params,hash) {
+ var num = hash.num;
+ var den = hash.den;
+ if (den == 0) {
+ return 0;
+ }
+ return Math.floor(num/den);
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/helpers/log-files-comma.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/helpers/log-files-comma.js
new file mode 100644
index 0000000..192e1ed
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/helpers/log-files-comma.js
@@ -0,0 +1,48 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+/**
+ * Represent log files as comma separated list.
+ */
+export default Ember.Helper.helper(function(params,hash) {
+ var logFiles = hash.logFiles;
+ if (logFiles == null) {
+ return "";
+ }
+ var logFilesLen = logFiles.length;
+ if (logFilesLen == 0) {
+ return "";
+ }
+ var nodeId = hash.nodeId;
+ var nodeAddr = hash.nodeAddr;
+ var containerId = hash.containerId;
+ var html = '
';
+ var logFilesCommaSeparated = "";
+ for (var i = 0; i < logFilesLen; i++) {
+ html = html + '' + logFiles[i] +
+ '';
+ if (i != logFilesLen - 1) {
+ html = html + ",";
+ }
+ }
+ html = html + '
';
+ return Ember.String.htmlSafe(html);
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/helpers/node-link.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/helpers/node-link.js
new file mode 100644
index 0000000..e524f08
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/helpers/node-link.js
@@ -0,0 +1,37 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+/**
+ * Generate link to node page if its not SHUTDOWN or LOST.
+ */
+export default Ember.Helper.helper(function(params,hash) {
+ var nodeState = hash.nodeState;
+ var nodeHTTPAddress = hash.nodeHTTPAddress;
+ var nodeId = hash.nodeId;
+ var html = '
';
+ if (nodeState == "SHUTDOWN" || nodeState == "LOST") {
+ html = html + nodeHTTPAddress;
+ } else {
+ html = html + '' +
+ nodeHTTPAddress + '';
+ }
+ html = html + '
';
+ return Ember.String.htmlSafe(html);
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/helpers/node-menu.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/helpers/node-menu.js
new file mode 100644
index 0000000..d4a73a4
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/helpers/node-menu.js
@@ -0,0 +1,66 @@
+/**
+ * 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.
+ */
+import Ember from 'ember';
+
+/**
+ * Create left hand side node manager menu with menu item activated based
+ * on page being accessed.
+ */
+export default Ember.Helper.helper(function(params,hash) {
+ // Place a menu within a panel inside col-md-2 container.
+ var nodeIdSplitAtPort = hash.nodeId;
+ var portIndex = nodeIdSplitAtPort.indexOf(':');
+ if (portIndex != -1) {
+ nodeIdSplitAtPort = nodeIdSplitAtPort.substring(0, portIndex) +
+ ':' + nodeIdSplitAtPort.substring(portIndex + 1);
+ }
+ var normalizedNodeId = '';
+ var splitsAlongDots = nodeIdSplitAtPort.split('.');
+ if (splitsAlongDots) {
+ var len = splitsAlongDots.length;
+ for (var i = 0; i < len; i++) {
+ normalizedNodeId = normalizedNodeId + splitsAlongDots[i];
+ if (i != len - 1) {
+ normalizedNodeId = normalizedNodeId + '.';
+ }
+ }
+ } else {
+ normalizedNodeId = nodeIdSplitAtPort;
+ }
+
+ var html = '
';
+ return Ember.String.htmlSafe(html);
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/helpers/node-name.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/helpers/node-name.js
new file mode 100644
index 0000000..56ce373
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/helpers/node-name.js
@@ -0,0 +1,46 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export function nodeName(params/*, hash*/) {
+ // Place a menu within a panel inside col-md-2 container.
+ console.log('nodes-uid', params[0]);
+ var nodeIdSplitAtPort = params[0];
+ var portIndex = nodeIdSplitAtPort.indexOf(':');
+ if (portIndex != -1) {
+ nodeIdSplitAtPort = nodeIdSplitAtPort.substring(0, portIndex) +
+ ':' + nodeIdSplitAtPort.substring(portIndex + 1);
+ }
+ var normalizedNodeId = '';
+ var splitsAlongDots = nodeIdSplitAtPort.split('.');
+ if (splitsAlongDots) {
+ var len = splitsAlongDots.length;
+ for (var i = 0; i < len; i++) {
+ normalizedNodeId = normalizedNodeId + splitsAlongDots[i];
+ if (i != len - 1) {
+ normalizedNodeId = normalizedNodeId + '.';
+ }
+ }
+ } else {
+ normalizedNodeId = nodeIdSplitAtPort;
+ }
+ return Ember.String.htmlSafe(normalizedNodeId);
+}
+
+export default Ember.Helper.helper(nodeName);
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/index.html b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/index.html
new file mode 100644
index 0000000..f727454
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/index.html
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+ YarnUi
+
+
+
+ {{content-for 'head'}}
+
+
+
+
+ {{content-for 'head-footer'}}
+
+
+ {{content-for 'body'}}
+
+
+
+
+
+ {{content-for 'body-footer'}}
+
+
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/initializers/env.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/initializers/env.js
new file mode 100644
index 0000000..c613593
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/initializers/env.js
@@ -0,0 +1,29 @@
+/**
+ * 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.
+ */
+
+
+export function initialize( application ) {
+ application.inject('controller', 'env', 'service:env');
+ application.inject('route', 'env', 'service:env');
+ application.inject('adapter', 'env', 'service:env');
+}
+
+export default {
+ name: 'env',
+ initialize
+};
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/initializers/hosts.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/initializers/hosts.js
new file mode 100644
index 0000000..6e3aa96
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/initializers/hosts.js
@@ -0,0 +1,28 @@
+/**
+ * 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.
+ */
+
+export function initialize( application ) {
+ application.inject('controller', 'hosts', 'service:hosts');
+ application.inject('route', 'hosts', 'service:hosts');
+ application.inject('adapter', 'hosts', 'service:hosts');
+}
+
+export default {
+ name: 'hosts',
+ initialize
+};
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/cluster-info.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/cluster-info.js
new file mode 100644
index 0000000..332fdf3
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/cluster-info.js
@@ -0,0 +1,31 @@
+/**
+ * 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.
+ */
+
+import DS from 'ember-data';
+
+export default DS.Model.extend({
+ startedOn: DS.attr('string'),
+ state: DS.attr('string'),
+ haState: DS.attr('string'),
+ rmStateStoreName: DS.attr('string'),
+ resourceManagerVersion: DS.attr('string'),
+ resourceManagerBuildVersion: DS.attr('string'),
+ hadoopVersion: DS.attr('string'),
+ hadoopBuildVersion: DS.attr('string'),
+ hadoopVersionBuiltOn: DS.attr('string')
+});
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/cluster-metric.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/cluster-metric.js
new file mode 100644
index 0000000..bc6e27a
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/cluster-metric.js
@@ -0,0 +1,133 @@
+/**
+ * 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.
+ */
+
+import DS from 'ember-data';
+
+export default DS.Model.extend({
+ appsSubmitted: DS.attr('number'),
+ appsCompleted: DS.attr('number'),
+ appsPending: DS.attr('number'),
+ appsRunning: DS.attr('number'),
+ appsFailed: DS.attr('number'),
+ appsKilled: DS.attr('number'),
+ reservedMB: DS.attr('number'),
+ availableMB: DS.attr('number'),
+ allocatedMB: DS.attr('number'),
+ reservedVirtualCores: DS.attr('number'),
+ availableVirtualCores: DS.attr('number'),
+ allocatedVirtualCores: DS.attr('number'),
+ containersAllocated: DS.attr('number'),
+ containersReserved: DS.attr('number'),
+ containersPending: DS.attr('number'),
+ totalMB: DS.attr('number'),
+ totalVirtualCores: DS.attr('number'),
+ totalNodes: DS.attr('number'),
+ lostNodes: DS.attr('number'),
+ unhealthyNodes: DS.attr('number'),
+ decommissionedNodes: DS.attr('number'),
+ rebootedNodes: DS.attr('number'),
+ activeNodes: DS.attr('number'),
+
+ getFinishedAppsDataForDonutChart: function() {
+ var arr = [];
+ arr.push({
+ label: "Completed",
+ value: this.get("appsCompleted")
+ });
+ arr.push({
+ label: "Killed",
+ value: this.get("appsKilled")
+ });
+ arr.push({
+ label: "Failed",
+ value: this.get("appsFailed")
+ });
+
+ return arr;
+ }.property("appsCompleted", "appsKilled", "appsFailed"),
+
+ getRunningAppsDataForDonutChart: function() {
+ var arr = [];
+
+ arr.push({
+ label: "Pending",
+ value: this.get("appsPending")
+ });
+ arr.push({
+ label: "Running",
+ value: this.get("appsRunning")
+ });
+
+ return arr;
+ }.property("appsPending", "appsRunning"),
+
+ getNodesDataForDonutChart: function() {
+ var arr = [];
+ arr.push({
+ label: "Active",
+ value: this.get("activeNodes")
+ });
+ arr.push({
+ label: "Unhealthy",
+ value: this.get("unhealthyNodes")
+ });
+ arr.push({
+ label: "Decomissioned",
+ value: this.get("decommissionedNodes")
+ });
+ return arr;
+ }.property("activeNodes", "unhealthyNodes", "decommissionedNodes"),
+
+ getMemoryDataForDonutChart: function() {
+ var type = "MB";
+ var arr = [];
+ arr.push({
+ label: "Allocated",
+ value: this.get("allocated" + type)
+ });
+ arr.push({
+ label: "Reserved",
+ value: this.get("reserved" + type)
+ });
+ arr.push({
+ label: "Available",
+ value: this.get("available" + type)
+ });
+
+ return arr;
+ }.property("allocatedMB", "reservedMB", "availableMB"),
+
+ getVCoreDataForDonutChart: function() {
+ var type = "VirtualCores";
+ var arr = [];
+ arr.push({
+ label: "Allocated",
+ value: this.get("allocated" + type)
+ });
+ arr.push({
+ label: "Reserved",
+ value: this.get("reserved" + type)
+ });
+ arr.push({
+ label: "Available",
+ value: Math.max(this.get("available" + type), 0)
+ });
+
+ return arr;
+ }.property("allocatedVirtualCores", "reservedVirtualCores", "availableVirtualCores"),
+});
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-app-attempt.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-app-attempt.js
new file mode 100644
index 0000000..f30d143
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-app-attempt.js
@@ -0,0 +1,143 @@
+/**
+ * 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.
+ */
+
+import DS from 'ember-data';
+import Converter from 'yarn-ui/utils/converter';
+
+export default DS.Model.extend({
+ startTime: DS.attr('string'),
+ startedTime: DS.attr('string'),
+ finishedTime: DS.attr('string'),
+ containerId: DS.attr('string'),
+ amContainerId: DS.attr('string'),
+ nodeHttpAddress: DS.attr('string'),
+ nodeId: DS.attr('string'),
+ hosts: DS.attr('string'),
+ logsLink: DS.attr('string'),
+ state: DS.attr('string'),
+ appAttemptId: DS.attr('string'),
+
+ appId: Ember.computed("id",function () {
+ var id = this.get("id");
+ id = id.split("_");
+
+ id[0] = "application";
+ id.pop();
+
+ return id.join("_");
+ }),
+
+ attemptStartedTime: function() {
+ var startTime = this.get("startTime");
+ // If startTime variable is not present, get from startedTime
+ if (startTime == undefined ||
+ startTime == "Invalid date") {
+ startTime = this.get("startedTime");
+ }
+
+ return startTime;
+ }.property("startedTime"),
+
+ startTs: function() {
+ return Converter.dateToTimeStamp(this.get('attemptStartedTime'));
+ }.property("startTime"),
+
+ finishedTs: function() {
+ var ts = Converter.dateToTimeStamp(this.get("finishedTime"));
+ return ts;
+ }.property("finishedTime"),
+
+ validatedFinishedTs: function() {
+ if (this.get("finishedTs") < this.get("startTs")) {
+ return "";
+ }
+ return this.get("finishedTime");
+ }.property("finishedTime"),
+
+ shortAppAttemptId: function() {
+ if (!this.get("containerId")) {
+ return this.get("id");
+ }
+ return "attempt_" +
+ parseInt(Converter.containerIdToAttemptId(this.get("containerId")).split("_")[3]);
+ }.property("containerId"),
+
+ appMasterContainerId: function() {
+ var id = this.get("containerId");
+ // If containerId variable is not present, get from amContainerId
+ if (id == undefined) {
+ id = this.get("amContainerId");
+ }
+ return id;
+ }.property("amContainerId"),
+
+ IsAmNodeUrl: function() {
+ var url = this.get("nodeHttpAddress");
+ // If nodeHttpAddress variable is not present, hardcode it.
+ if (url == undefined) {
+ url = "Not Available";
+ }
+ return url != "Not Available";
+ }.property("nodeHttpAddress"),
+
+ amNodeId : function() {
+ var id = this.get("nodeId");
+ // If nodeId variable is not present, get from host
+ if (id == undefined) {
+ id = this.get("hosts");
+ }
+ return id;
+ }.property("nodeId"),
+
+ IsLinkAvailable: function() {
+ var url = this.get("logsLink");
+ // If logsLink variable is not present, hardcode its.
+ if (url == undefined) {
+ url = "Not Available";
+ }
+ return url != "Not Available";
+ }.property("logsLink"),
+
+ elapsedTime: function() {
+ var elapsedMs = this.get("finishedTs") - this.get("startTs");
+ if (elapsedMs <= 0) {
+ elapsedMs = Date.now() - this.get("startTs");
+ }
+
+ return Converter.msToElapsedTime(elapsedMs);
+ }.property(),
+
+ tooltipLabel: function() {
+ return "
";
+ }.property(),
+
+ link: function() {
+ return "/yarn-app-attempt/" + this.get("id");
+ }.property(),
+
+ linkname: function() {
+ return "yarn-app-attempt";
+ }.property(),
+
+ attemptState: function() {
+ return this.get("state");
+ }.property(),
+
+});
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-app.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-app.js
new file mode 100644
index 0000000..0a5df87
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-app.js
@@ -0,0 +1,101 @@
+/**
+ * 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.
+ */
+
+import Converter from 'yarn-ui/utils/converter';
+import DS from 'ember-data';
+
+export default DS.Model.extend({
+ appName: DS.attr('string'),
+ user: DS.attr('string'),
+ queue: DS.attr('string'),
+ state: DS.attr('string'),
+ startTime: DS.attr('string'),
+ elapsedTime: DS.attr('string'),
+ finalStatus: DS.attr('string'),
+ finishedTime: DS.attr('finishedTime'),
+ progress: DS.attr('number'),
+ diagnostics: DS.attr('string'),
+ amContainerLogs: DS.attr('string'),
+ amHostHttpAddress: DS.attr('string'),
+ logAggregationStatus: DS.attr('string'),
+ unmanagedApplication: DS.attr('string'),
+ amNodeLabelExpression: DS.attr('string'),
+ applicationTags: DS.attr('string'),
+ applicationType: DS.attr('string'),
+ priority: DS.attr('number'),
+ allocatedMB: DS.attr('number'),
+ allocatedVCores: DS.attr('number'),
+ runningContainers: DS.attr('number'),
+ memorySeconds: DS.attr('number'),
+ vcoreSeconds: DS.attr('number'),
+ preemptedResourceMB: DS.attr('number'),
+ preemptedResourceVCores: DS.attr('number'),
+ numNonAMContainerPreempted: DS.attr('number'),
+ numAMContainerPreempted: DS.attr('number'),
+ clusterUsagePercentage: DS.attr('number'),
+ queueUsagePercentage: DS.attr('number'),
+ currentAppAttemptId: DS.attr('string'),
+
+ isFailed: function() {
+ return this.get('finalStatus') == "FAILED"
+ }.property("finalStatus"),
+
+ validatedFinishedTs: function() {
+ if (this.get("finishedTime") < this.get("startTime")) {
+ return "";
+ }
+ return this.get("finishedTime");
+ }.property("finishedTime"),
+
+ allocatedResource: function() {
+ return Converter.resourceToString(this.get("allocatedMB"), this.get("allocatedVCores"));
+ }.property("allocatedMB", "allocatedVCores"),
+
+ preemptedResource: function() {
+ return Converter.resourceToString(this.get("preemptedResourceMB"), this.get("preemptedResourceVCores"));
+ }.property("preemptedResourceMB", "preemptedResourceVCores"),
+
+ aggregatedResourceUsage: function() {
+ return Converter.resourceToString(this.get("memorySeconds"), this.get("vcoreSeconds")) + " (× Secs)";
+ }.property("memorySeconds", "vcoreSeconds"),
+
+ progressStyle: function() {
+ return "width: " + this.get("progress") + "%";
+ }.property("progress"),
+
+ runningContainersNumber: function() {
+ if(this.get("runningContainers") < 0) {
+ return 0;
+ }
+ return this.get("runningContainers");
+ }.property("progress"),
+
+ finalStatusStyle: function() {
+ var style = "default";
+ var finalStatus = this.get("finalStatus");
+ if (finalStatus == "KILLED") {
+ style = "warning";
+ } else if (finalStatus == "FAILED") {
+ style = "danger";
+ } else {
+ style = "success";
+ }
+
+ return "label label-" + style;
+ }.property("finalStatus")
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-container-log.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-container-log.js
new file mode 100644
index 0000000..31cf61e
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-container-log.js
@@ -0,0 +1,25 @@
+/**
+ * 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.
+ */
+
+import DS from 'ember-data';
+
+export default DS.Model.extend({
+ logs: DS.attr('string'),
+ containerID: DS.attr('string'),
+ logFileName: DS.attr('string')
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-container.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-container.js
new file mode 100644
index 0000000..bd9cea7
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-container.js
@@ -0,0 +1,64 @@
+/**
+ * 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.
+ */
+
+import DS from 'ember-data';
+import Converter from 'yarn-ui/utils/converter';
+
+export default DS.Model.extend({
+ allocatedMB: DS.attr('number'),
+ allocatedVCores: DS.attr('number'),
+ assignedNodeId: DS.attr('string'),
+ priority: DS.attr('number'),
+ startedTime: DS.attr('number'),
+ finishedTime: DS.attr('number'),
+ logUrl: DS.attr('string'),
+ containerExitStatus: DS.attr('number'),
+ containerState: DS.attr('string'),
+ nodeHttpAddress: DS.attr('string'),
+
+ startTs: function() {
+ return Converter.dateToTimeStamp(this.get("startedTime"));
+ }.property("startedTime"),
+
+ finishedTs: function() {
+ var ts = Converter.dateToTimeStamp(this.get("finishedTime"));
+ return ts;
+ }.property("finishedTime"),
+
+ validatedFinishedTs: function() {
+ if (this.get("finishedTs") < this.get("startTs")) {
+ return "";
+ }
+ return this.get("finishedTime");
+ }.property("finishedTime"),
+
+ elapsedTime: function() {
+ var elapsedMs = this.get("finishedTs") - this.get("startTs");
+ if (elapsedMs <= 0) {
+ elapsedMs = Date.now() - this.get("startTs");
+ }
+
+ return Converter.msToElapsedTime(elapsedMs);
+ }.property(),
+
+ tooltipLabel: function() {
+ return "
";
+ }.property(),
+});
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-node-app.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-node-app.js
new file mode 100644
index 0000000..6dc69ae
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-node-app.js
@@ -0,0 +1,44 @@
+/**
+ * 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.
+ */
+
+import DS from 'ember-data';
+
+export default DS.Model.extend({
+ appId: DS.attr('string'),
+ state: DS.attr('string'),
+ user: DS.attr('string'),
+ containers: DS.attr('array'),
+ /**
+ * Indicates no rows were retrieved from backend
+ */
+ isDummyApp: function() {
+ return this.get('id') == "dummy";
+ }.property("id"),
+
+ appStateStyle: function() {
+ var style = "default";
+ var appState = this.get("state");
+ if (appState == "RUNNING" || appState == "FINISHING_CONTAINERS_WAIT" ||
+ appState == "APPLICATION_RESOURCES_CLEANINGUP") {
+ style = "primary";
+ } else if (appState == "FINISHED") {
+ style = "success";
+ }
+ return "label label-" + style;
+ }.property("state")
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-node-container.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-node-container.js
new file mode 100644
index 0000000..3ba3216
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-node-container.js
@@ -0,0 +1,57 @@
+/**
+ * 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.
+ */
+
+import DS from 'ember-data';
+
+export default DS.Model.extend({
+ containerId: DS.attr('string'),
+ state: DS.attr('string'),
+ user: DS.attr('string'),
+ exitCode: DS.attr('string'),
+ diagnostics: DS.attr('string'),
+ totalMemoryNeeded: DS.attr('number'),
+ totalVCoresNeeded: DS.attr('number'),
+ containerLogFiles: DS.attr('array'),
+
+ /**
+ * Indicates that there was no container retrieved from backend.
+ */
+ isDummyContainer: function() {
+ return this.get('id') == "dummy";
+ }.property("id"),
+
+ containerStateStyle: function() {
+ var style = "primary";
+ var containerState = this.get('state');
+ var containerExitCode = this.get('exitCode');
+ if (containerState == "DONE") {
+ if (containerExitCode == "0") {
+ style = "success";
+ } else if (containerExitCode != "N/A") {
+ style = "danger";
+ }
+ }
+ if (containerState == "EXITED_WITH_SUCCESS") {
+ style = "success";
+ }
+ if (containerState == "EXITED_WITH_FAILURE") {
+ style = "danger";
+ }
+ return "label label-" + style;
+ }.property("state", "exitCode")
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-node.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-node.js
new file mode 100644
index 0000000..4753983
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-node.js
@@ -0,0 +1,33 @@
+/**
+ * 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.
+ */
+
+import DS from 'ember-data';
+
+export default DS.Model.extend({
+ totalVmemAllocatedContainersMB: DS.attr('number'),
+ totalPmemAllocatedContainersMB: DS.attr('number'),
+ totalVCoresAllocatedContainers: DS.attr('number'),
+ vmemCheckEnabled: DS.attr('boolean'),
+ pmemCheckEnabled: DS.attr('boolean'),
+ nodeHealthy: DS.attr('boolean'),
+ lastNodeUpdateTime: DS.attr('string'),
+ healthReport: DS.attr('string'),
+ nmStartupTime: DS.attr('string'),
+ nodeManagerBuildVersion: DS.attr('string'),
+ hadoopBuildVersion: DS.attr('string'),
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-queue.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-queue.js
new file mode 100644
index 0000000..7de4ccc
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-queue.js
@@ -0,0 +1,94 @@
+/**
+ * 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.
+ */
+
+import DS from 'ember-data';
+
+export default DS.Model.extend({
+ name: DS.attr('string'),
+ children: DS.attr('array'),
+ parent: DS.attr('string'),
+ capacity: DS.attr('number'),
+ maxCapacity: DS.attr('number'),
+ usedCapacity: DS.attr('number'),
+ absCapacity: DS.attr('number'),
+ absMaxCapacity: DS.attr('number'),
+ absUsedCapacity: DS.attr('number'),
+ state: DS.attr('string'),
+ userLimit: DS.attr('number'),
+ userLimitFactor: DS.attr('number'),
+ preemptionDisabled: DS.attr('number'),
+ numPendingApplications: DS.attr('number'),
+ numActiveApplications: DS.attr('number'),
+ users: DS.hasMany('YarnUser'),
+
+ isLeafQueue: function() {
+ var len = this.get("children.length");
+ if (!len) {
+ return true;
+ }
+ return len <= 0;
+ }.property("children"),
+
+ capacitiesBarChartData: function() {
+ return [
+ {
+ label: "Absolute Capacity",
+ value: this.get("name") == "root" ? 100 : this.get("absCapacity")
+ },
+ {
+ label: "Absolute Used",
+ value: this.get("name") == "root" ? this.get("usedCapacity") : this.get("absUsedCapacity")
+ },
+ {
+ label: "Absolute Max Capacity",
+ value: this.get("name") == "root" ? 100 : this.get("absMaxCapacity")
+ }
+ ]
+ }.property("absCapacity", "absUsedCapacity", "absMaxCapacity"),
+
+ userUsagesDonutChartData: function() {
+ var data = [];
+ if (this.get("users")) {
+ this.get("users").forEach(function(o) {
+ data.push({
+ label: o.get("name"),
+ value: o.get("usedMemoryMB")
+ })
+ });
+ }
+
+ return data;
+ }.property("users"),
+
+ hasUserUsages: function() {
+ return this.get("userUsagesDonutChartData").length > 0;
+ }.property(),
+
+ numOfApplicationsDonutChartData: function() {
+ return [
+ {
+ label: "Pending Apps",
+ value: this.get("numPendingApplications") || 0 // TODO, fix the REST API so root will return #applications as well.
+ },
+ {
+ label: "Active Apps",
+ value: this.get("numActiveApplications") || 0
+ }
+ ]
+ }.property(),
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-rm-node.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-rm-node.js
new file mode 100644
index 0000000..a15a20f
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-rm-node.js
@@ -0,0 +1,99 @@
+/**
+ * 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.
+ */
+
+import DS from 'ember-data';
+
+export default DS.Model.extend({
+ rack: DS.attr('string'),
+ state: DS.attr('string'),
+ nodeHostName: DS.attr('string'),
+ nodeHTTPAddress: DS.attr('string'),
+ lastHealthUpdate: DS.attr('string'),
+ healthReport: DS.attr('string'),
+ numContainers: DS.attr('number'),
+ usedMemoryMB: DS.attr('number'),
+ availMemoryMB: DS.attr('number'),
+ usedVirtualCores: DS.attr('number'),
+ availableVirtualCores: DS.attr('number'),
+ version: DS.attr('string'),
+ nodeLabels: DS.attr('array'),
+
+ nodeLabelsAsString: function() {
+ var labels = this.get("nodeLabels");
+ var labelToReturn = "";
+ // Only one label per node supported.
+ if (labels && labels.length > 0) {
+ labelToReturn = labels[0];
+ }
+ return labelToReturn;
+ }.property("nodeLabels"),
+
+ /**
+ * Indicates no rows were retrieved from backend
+ */
+ isDummyNode: function() {
+ return this.get('id') == "dummy";
+ }.property("id"),
+
+ nodeStateStyle: function() {
+ var style = "default";
+ var nodeState = this.get("state");
+ if (nodeState == "REBOOTED") {
+ style = "warning";
+ } else if (nodeState == "UNHEALTHY" || nodeState == "DECOMMISSIONED" ||
+ nodeState == "LOST" || nodeState == "SHUTDOWN") {
+ style = "danger";
+ } else if (nodeState == "RUNNING") {
+ style = "success";
+ }
+ return "label label-" + style;
+ }.property("state"),
+
+ getMemoryDataForDonutChart: function() {
+ var arr = [];
+ arr.push({
+ label: "Used",
+ value: this.get("usedMemoryMB")
+ });
+ arr.push({
+ label: "Available",
+ value: this.get("availMemoryMB")
+ });
+ return arr;
+ }.property("availMemoryMB", "usedMemoryMB"),
+
+ getVCoreDataForDonutChart: function() {
+ var arr = [];
+ arr.push({
+ label: "Used",
+ value: this.get("usedVirtualCores")
+ });
+ arr.push({
+ label: "Available",
+ value: this.get("availableVirtualCores")
+ });
+ return arr;
+ }.property("availableVirtualCores", "usedVirtualCores"),
+
+ toolTipText: function() {
+ return "
Rack: " + this.get("rack") + '
' +
+ "
Host: " + this.get("nodeHostName") + '
' +
+ "
Used Memory: " + Math.round(this.get("usedMemoryMB")) + ' MB
' +
+ "
Available Memory: " + Math.round(this.get("availMemoryMB")) + ' MB
';
+ }.property(),
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-user.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-user.js
new file mode 100644
index 0000000..7cfd182
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-user.js
@@ -0,0 +1,26 @@
+/**
+ * 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.
+ */
+
+import DS from 'ember-data';
+
+export default DS.Model.extend({
+ name: DS.attr('string'),
+ queueName: DS.attr('string'),
+ usedMemoryMB: DS.attr('number'),
+ usedVCore: DS.attr('number')
+})
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/router.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/router.js
new file mode 100644
index 0000000..87a018d
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/router.js
@@ -0,0 +1,58 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+import config from './config/environment';
+
+var Router = Ember.Router.extend({
+ location: config.locationType
+});
+
+Router.map(function() {
+ this.route('yarn-apps', function () {
+ this.route('apps');
+ this.route('services');
+ });
+ this.route('yarn-nodes', function(){
+ this.route('table');
+ this.route('heatmap');
+ });
+ this.route('yarn-nodes-heatmap');
+ this.route('yarn-node', { path: '/yarn-node/:node_id/:node_addr' });
+ this.route('yarn-node-apps', { path: '/yarn-node-apps/:node_id/:node_addr' });
+ this.route('yarn-node-app',
+ { path: '/yarn-node-app/:node_id/:node_addr/:app_id' });
+ this.route('yarn-node-containers',
+ { path: '/yarn-node-containers/:node_id/:node_addr' });
+ this.route('yarn-node-container',
+ { path: '/yarn-node-container/:node_id/:node_addr/:container_id' });
+ this.route('yarn-container-log', { path:
+ '/yarn-container-log/:node_id/:node_addr/:container_id/:filename' });
+ this.route('yarn-queue', { path: '/yarn-queue/:queue_name' });
+
+ this.route('cluster-overview');
+ this.route('yarn-app', { path: '/yarn-app/:app_id' });
+ this.route('yarn-app-attempt', { path: '/yarn-app-attempt/:app_attempt_id'});
+ this.route('error');
+ this.route('notfound', { path: '*:' });
+ this.route('yarn-app-attempts', { path: '/yarn-app-attempts/:app_id' });
+ this.route('yarn-queues', { path: '/yarn-queues/:queue_name' });
+ this.route('yarn-queue-apps', { path: '/yarn-queue-apps/:queue_name' });
+});
+
+export default Router;
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/abstract.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/abstract.js
new file mode 100644
index 0000000..3163237
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/abstract.js
@@ -0,0 +1,32 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Route.extend({
+ unloadAll() {
+ // Must be implemented by inheriting classes
+ },
+
+ actions: {
+ refresh: function () {
+ this.unloadAll();
+ this.refresh();
+ }
+ }
+});
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/application.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/application.js
new file mode 100644
index 0000000..07b3792
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/application.js
@@ -0,0 +1,40 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Route.extend({
+ actions: {
+ /**
+ * Base error handler for the application.
+ * If specific routes do not handle the error, it will bubble up to
+ * this handler. Here we redirect to either 404 page or a generic
+ * error handler page.
+ */
+ error: function (error) {
+ Ember.Logger.log(error.stack);
+
+ if (error && error.errors[0] &&
+ error.errors[0].status == 404) {
+ this.intermediateTransitionTo('/notfound');
+ } else {
+ this.intermediateTransitionTo('/error');
+ }
+ }
+ }
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/cluster-overview.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/cluster-overview.js
new file mode 100644
index 0000000..1068126
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/cluster-overview.js
@@ -0,0 +1,44 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+ model() {
+ return Ember.RSVP.hash({
+ clusterMetrics: this.store.findAll('ClusterMetric'),
+ apps: this.store.query('yarn-app',
+ {
+ state: "RUNNING"
+ }),
+ queues: this.store.query('yarn-queue', {}),
+ });
+ },
+
+ afterModel() {
+ this.controllerFor("ClusterOverview").set("loading", false);
+ },
+
+ unloadAll() {
+ this.store.unloadAll('ClusterMetric');
+ this.store.unloadAll('yarn-app');
+ this.store.unloadAll('yarn-queue');
+ }
+});
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/index.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/index.js
new file mode 100644
index 0000000..af26670
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/index.js
@@ -0,0 +1,29 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Route.extend({
+ /**
+ * Redirect root URL to cluster overview page.
+ */
+ beforeModel: function() {
+ this.replaceWith('cluster-overview');
+ }
+});
+
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app-attempt.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app-attempt.js
new file mode 100644
index 0000000..762fb29
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app-attempt.js
@@ -0,0 +1,50 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+ model(param) {
+ return Ember.RSVP.hash({
+ attempt: this.store.findRecord('yarn-app-attempt', param.app_attempt_id),
+
+ rmContainers: this.store.query('yarn-container',
+ {
+ app_attempt_id: param.app_attempt_id,
+ is_rm: true
+ }),
+
+ tsContainers: this.store.query('yarn-container',
+ {
+ app_attempt_id: param.app_attempt_id,
+ is_rm: false
+ }).catch (function() {
+ // Promise rejected, fulfill with some default value to
+ // use as the route's model and continue on with the transition
+ return [];
+ })
+ });
+ },
+
+ unloadAll() {
+ this.store.unloadAll('yarn-app-attempt');
+ this.store.unloadAll('yarn-container');
+ }
+});
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app-attempts.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app-attempts.js
new file mode 100644
index 0000000..121debf
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app-attempts.js
@@ -0,0 +1,36 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+ model(param) {
+ return this.store.query('yarn-app-attempt', { appId: param.app_id}).then(function (attempts) {
+ return {
+ appId: param.app_id,
+ attempts: attempts
+ };
+ });
+ },
+
+ unloadAll() {
+ this.store.unloadAll('yarn-app-attempt');
+ }
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app.js
new file mode 100644
index 0000000..000b02f
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app.js
@@ -0,0 +1,52 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+ model(param) {
+ return Ember.RSVP.hash({
+ app: this.store.find('yarn-app', param.app_id),
+
+ rmContainers: this.store.find('yarn-app', param.app_id).then(function(app) {
+ return this.store.query('yarn-app-attempt', {appId: param.app_id}).then(function (attempts) {
+ if (attempts && attempts.get('firstObject')) {
+ var appAttemptId = attempts.get('firstObject').get('appAttemptId');
+ var rmContainers = this.store.query('yarn-container',
+ {
+ app_attempt_id: appAttemptId,
+ is_rm: true
+ });
+ return rmContainers;
+ }
+ }.bind(this));
+ }.bind(this)),
+
+ nodes: this.store.findAll('yarn-rm-node'),
+ });
+ },
+
+ unloadAll() {
+ this.store.unloadAll('yarn-app');
+ this.store.unloadAll('yarn-app-attempt');
+ this.store.unloadAll('yarn-container');
+ this.store.unloadAll('yarn-rm-node');
+ }
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-apps.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-apps.js
new file mode 100644
index 0000000..0ac503c
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-apps.js
@@ -0,0 +1,35 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+ model() {
+ return Ember.RSVP.hash({
+ apps: this.store.findAll('yarn-app'),
+ clusterMetrics: this.store.findAll('ClusterMetric'),
+ });
+ },
+
+ unloadAll() {
+ this.store.unloadAll('yarn-app');
+ this.store.unloadAll('ClusterMetric');
+ }
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-apps/apps.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-apps/apps.js
new file mode 100644
index 0000000..8719170
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-apps/apps.js
@@ -0,0 +1,22 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Route.extend({
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-apps/services.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-apps/services.js
new file mode 100644
index 0000000..8719170
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-apps/services.js
@@ -0,0 +1,22 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Route.extend({
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-container-log.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-container-log.js
new file mode 100644
index 0000000..9e4c7d3
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-container-log.js
@@ -0,0 +1,63 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+import Constants from 'yarn-ui/constants';
+
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+ model(param) {
+ var id = param.node_addr + Constants.PARAM_SEPARATOR + param.container_id +
+ Constants.PARAM_SEPARATOR + param.filename;
+ return Ember.RSVP.hash({
+ containerLog: this.store.findRecord('yarn-container-log', id),
+ containerInfo: { id: param.container_id },
+ nodeInfo: { id: param.node_id, addr: param.node_addr }
+ }).then(function(hash) {
+ // Just return as its success.
+ return hash;
+ }, function(reason) {
+ if (reason.errors && reason.errors[0]) {
+ // This means HTTP error response was sent by adapter.
+ return reason;
+ } else {
+ // Assume empty response received from server.
+ return { nodeInfo: { id: param.node_id, addr: param.node_addr },
+ containerInfo: { id: param.container_id },
+ containerLog: { logs: "", containerID: param.container_id,
+ logFileName: param.filename}};
+ }
+ });
+ },
+
+ afterModel(model) {
+ // Handle errors and redirect if promise is rejected.
+ if (model.errors && model.errors[0]) {
+ if (model.errors[0].status == 404) {
+ this.replaceWith('/notfound');
+ } else {
+ this.replaceWith('/error');
+ }
+ }
+ },
+
+ unloadAll() {
+ this.store.unloadAll('yarn-container-log');
+ }
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-node-app.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-node-app.js
new file mode 100644
index 0000000..0a11930
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-node-app.js
@@ -0,0 +1,35 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+ model(param) {
+ return Ember.RSVP.hash({
+ nodeApp: this.store.queryRecord('yarn-node-app',
+ { nodeAddr : param.node_addr, appId: param.app_id }),
+ nodeInfo: { id: param.node_id, addr: param.node_addr }
+ });
+ },
+
+ unloadAll() {
+ this.store.unloadAll('yarn-node-app');
+ }
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-node-apps.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-node-apps.js
new file mode 100644
index 0000000..6044076
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-node-apps.js
@@ -0,0 +1,35 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+ model(param) {
+ // Get all apps running on a specific node. Node is contacted by using node_addr.
+ return Ember.RSVP.hash({
+ apps: this.store.query('yarn-node-app', { nodeAddr: param.node_addr }),
+ nodeInfo: { id: param.node_id, addr: param.node_addr }
+ });
+ },
+
+ unloadAll() {
+ this.store.unloadAll('yarn-node-app');
+ }
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-node-container.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-node-container.js
new file mode 100644
index 0000000..b7a79de
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-node-container.js
@@ -0,0 +1,36 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+ model(param) {
+ // Get a specific container running on a specific node.
+ return Ember.RSVP.hash({
+ nodeContainer: this.store.queryRecord('yarn-node-container',
+ { nodeHttpAddr: param.node_addr, containerId: param.container_id }),
+ nodeInfo: { id: param.node_id, addr: param.node_addr }
+ });
+ },
+
+ unloadAll() {
+ this.store.unloadAll('yarn-node-container');
+ }
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-node-containers.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-node-containers.js
new file mode 100644
index 0000000..3c709f7
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-node-containers.js
@@ -0,0 +1,34 @@
+/**
+ * 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.
+ */
+import Ember from 'ember';
+
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+ model(param) {
+ // Get all containers running on specific node.
+ return Ember.RSVP.hash({
+ containers: this.store.query('yarn-node-container', { nodeHttpAddr: param.node_addr }),
+ nodeInfo: { id: param.node_id, addr: param.node_addr }
+ });
+ },
+
+ unloadAll() {
+ this.store.unloadAll('yarn-node-container');
+ }
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-node.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-node.js
new file mode 100644
index 0000000..967d007
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-node.js
@@ -0,0 +1,37 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+ model(param) {
+ // Fetches data from both NM and RM. RM is queried to get node usage info.
+ return Ember.RSVP.hash({
+ nodeInfo: { id: param.node_id, addr: param.node_addr },
+ node: this.store.findRecord('yarn-node', param.node_addr),
+ rmNode: this.store.findRecord('yarn-rm-node', param.node_id)
+ });
+ },
+
+ unloadAll() {
+ this.store.unloadAll('yarn-node');
+ this.store.unloadAll('yarn-rm-node');
+ }
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-nodes.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-nodes.js
new file mode 100644
index 0000000..4439569
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-nodes.js
@@ -0,0 +1,35 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+ model() {
+ return Ember.RSVP.hash({
+ nodes: this.store.findAll('yarn-rm-node'),
+ clusterMetrics: this.store.findAll('ClusterMetric'),
+ });
+ },
+
+ unloadAll() {
+ this.store.unloadAll('yarn-rm-node');
+ this.store.unloadAll('ClusterMetric');
+ }
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-nodes/heatmap.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-nodes/heatmap.js
new file mode 100644
index 0000000..8719170
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-nodes/heatmap.js
@@ -0,0 +1,22 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Route.extend({
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-nodes/table.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-nodes/table.js
new file mode 100644
index 0000000..38ae5d1
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-nodes/table.js
@@ -0,0 +1,22 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Route.extend({
+});
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-queue-apps.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-queue-apps.js
new file mode 100644
index 0000000..373e1be
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-queue-apps.js
@@ -0,0 +1,42 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+ model(param) {
+ return Ember.RSVP.hash({
+ selected : param.queue_name,
+ queues: this.store.findAll('yarn-queue'),
+ selectedQueue : undefined,
+ apps: undefined, // apps of selected queue
+ });
+ },
+
+ afterModel(model) {
+ model.selectedQueue = this.store.peekRecord('yarn-queue', model.selected);
+ model.apps = this.store.findAll('yarn-app');
+ },
+
+ unloadAll() {
+ this.store.unloadAll('yarn-queue');
+ this.store.unloadAll('yarn-app');
+ }
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-queue.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-queue.js
new file mode 100644
index 0000000..5342913
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-queue.js
@@ -0,0 +1,42 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+ model(param) {
+ return Ember.RSVP.hash({
+ selected : param.queue_name,
+ queues: this.store.query('yarn-queue', {}),
+ selectedQueue : undefined,
+ apps: undefined, // apps of selected queue
+ });
+ },
+
+ afterModel(model) {
+ model.selectedQueue = this.store.peekRecord('yarn-queue', model.selected);
+ model.apps = this.store.findAll('yarn-app');
+ },
+
+ unloadAll() {
+ this.store.unloadAll('yarn-queue');
+ this.store.unloadAll('yarn-app');
+ }
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-queues.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-queues.js
new file mode 100644
index 0000000..5342913
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-queues.js
@@ -0,0 +1,42 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+ model(param) {
+ return Ember.RSVP.hash({
+ selected : param.queue_name,
+ queues: this.store.query('yarn-queue', {}),
+ selectedQueue : undefined,
+ apps: undefined, // apps of selected queue
+ });
+ },
+
+ afterModel(model) {
+ model.selectedQueue = this.store.peekRecord('yarn-queue', model.selected);
+ model.apps = this.store.findAll('yarn-app');
+ },
+
+ unloadAll() {
+ this.store.unloadAll('yarn-queue');
+ this.store.unloadAll('yarn-app');
+ }
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-queues/index.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-queues/index.js
new file mode 100644
index 0000000..4ab5716
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-queues/index.js
@@ -0,0 +1,23 @@
+/**
+ * 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.
+ */
+
+export default Ember.Route.extend({
+ beforeModel() {
+ this.transitionTo('yarn-queues.root');
+ }
+});
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-queues/queues-selector.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-queues/queues-selector.js
new file mode 100644
index 0000000..5d14c6f
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-queues/queues-selector.js
@@ -0,0 +1,25 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Route.extend({
+ model() {
+ return this.store.findAll('yarn-queue');
+ },
+});
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/cluster-info.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/cluster-info.js
new file mode 100644
index 0000000..fad321a
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/cluster-info.js
@@ -0,0 +1,47 @@
+/**
+ * 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.
+ */
+
+import DS from 'ember-data';
+
+export default DS.JSONAPISerializer.extend({
+ normalizeSingleResponse(store, primaryModelClass, payload, id,
+ requestType) {
+ var fixedPayload = {
+ id: id,
+ type: primaryModelClass.modelName,
+ attributes: payload
+ };
+
+ return this._super(store, primaryModelClass, fixedPayload, id,
+ requestType);
+ },
+
+ normalizeArrayResponse(store, primaryModelClass, payload, id,
+ requestType) {
+ // return expected is { data: [ {}, {} ] }
+ var normalizedArrayResponse = {};
+
+ // payload has apps : { app: [ {},{},{} ] }
+ // need some error handling for ex apps or app may not be defined.
+ normalizedArrayResponse.data = [
+ this.normalizeSingleResponse(store, primaryModelClass,
+ payload.clusterInfo, payload.clusterInfo.id, requestType)
+ ];
+ return normalizedArrayResponse;
+ }
+});
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/cluster-metric.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/cluster-metric.js
new file mode 100644
index 0000000..73c4bc5
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/cluster-metric.js
@@ -0,0 +1,47 @@
+/**
+ * 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.
+ */
+
+import DS from 'ember-data';
+
+export default DS.JSONAPISerializer.extend({
+ normalizeSingleResponse(store, primaryModelClass, payload, id,
+ requestType) {
+ var fixedPayload = {
+ id: id,
+ type: primaryModelClass.modelName,
+ attributes: payload
+ };
+
+ return this._super(store, primaryModelClass, fixedPayload, id,
+ requestType);
+ },
+
+ normalizeArrayResponse(store, primaryModelClass, payload, id,
+ requestType) {
+ // return expected is { data: [ {}, {} ] }
+ var normalizedArrayResponse = {};
+
+ // payload has apps : { app: [ {},{},{} ] }
+ // need some error handling for ex apps or app may not be defined.
+ normalizedArrayResponse.data = [
+ this.normalizeSingleResponse(store, primaryModelClass,
+ payload.clusterMetrics, 1, requestType)
+ ];
+ return normalizedArrayResponse;
+ }
+});
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-app-attempt.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-app-attempt.js
new file mode 100644
index 0000000..3de377a
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-app-attempt.js
@@ -0,0 +1,75 @@
+/**
+ * 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.
+ */
+
+import DS from 'ember-data';
+import Converter from 'yarn-ui/utils/converter';
+
+export default DS.JSONAPISerializer.extend({
+ internalNormalizeSingleResponse(store, primaryModelClass, payload, id,
+ requestType) {
+
+ if (payload.appAttempt) {
+ payload = payload.appAttempt;
+ }
+
+ var fixedPayload = {
+ id: payload.appAttemptId,
+ type: primaryModelClass.modelName, // yarn-app
+ attributes: {
+ startTime: Converter.timeStampToDate(payload.startTime),
+ startedTime: Converter.timeStampToDate(payload.startedTime),
+ finishedTime: Converter.timeStampToDate(payload.finishedTime),
+ containerId: payload.containerId,
+ amContainerId: payload.amContainerId,
+ nodeHttpAddress: payload.nodeHttpAddress,
+ nodeId: payload.nodeId,
+ hosts: payload.host,
+ state: payload.appAttemptState,
+ logsLink: payload.logsLink,
+ appAttemptId: payload.appAttemptId
+ }
+ };
+
+ return fixedPayload;
+ },
+
+ normalizeSingleResponse(store, primaryModelClass, payload, id,
+ requestType) {
+ var p = this.internalNormalizeSingleResponse(store,
+ primaryModelClass, payload, id, requestType);
+ return { data: p };
+ },
+
+ normalizeArrayResponse(store, primaryModelClass, payload, id,
+ requestType) {
+ // return expected is { data: [ {}, {} ] }
+ var normalizedArrayResponse = {};
+
+ if (payload.appAttempts && payload.appAttempts.appAttempt) {
+ // payload has apps : { app: [ {},{},{} ] }
+ // need some error handling for ex apps or app may not be defined.
+ normalizedArrayResponse.data = payload.appAttempts.appAttempt.map(singleApp => {
+ return this.internalNormalizeSingleResponse(store, primaryModelClass,
+ singleApp, singleApp.id, requestType);
+ }, this);
+ } else {
+ normalizedArrayResponse.data = [];
+ }
+ return normalizedArrayResponse;
+ }
+});
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-app.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-app.js
new file mode 100644
index 0000000..427c3d8
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-app.js
@@ -0,0 +1,93 @@
+/**
+ * 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.
+ */
+
+import DS from 'ember-data';
+import Converter from 'yarn-ui/utils/converter';
+
+export default DS.JSONAPISerializer.extend({
+ internalNormalizeSingleResponse(store, primaryModelClass, payload, id,
+ requestType) {
+ if (payload.app) {
+ payload = payload.app;
+ }
+
+ var fixedPayload = {
+ id: id,
+ type: primaryModelClass.modelName, // yarn-app
+ attributes: {
+ appName: payload.name,
+ user: payload.user,
+ queue: payload.queue,
+ state: payload.state,
+ startTime: Converter.timeStampToDate(payload.startedTime),
+ elapsedTime: Converter.msToElapsedTime(payload.elapsedTime),
+ finishedTime: Converter.timeStampToDate(payload.finishedTime),
+ finalStatus: payload.finalStatus,
+ progress: payload.progress,
+ applicationType: payload.applicationType,
+ diagnostics: payload.diagnostics,
+ amContainerLogs: payload.amContainerLogs,
+ amHostHttpAddress: payload.amHostHttpAddress,
+ logAggregationStatus: payload.logAggregationStatus,
+ unmanagedApplication: payload.unmanagedApplication,
+ amNodeLabelExpression: payload.amNodeLabelExpression,
+ priority: payload.priority,
+ allocatedMB: payload.allocatedMB,
+ allocatedVCores: payload.allocatedVCores,
+ runningContainers: payload.runningContainers,
+ memorySeconds: payload.memorySeconds,
+ vcoreSeconds: payload.vcoreSeconds,
+ preemptedResourceMB: payload.preemptedResourceMB,
+ preemptedResourceVCores: payload.preemptedResourceVCores,
+ numNonAMContainerPreempted: payload.numNonAMContainerPreempted,
+ numAMContainerPreempted: payload.numAMContainerPreempted,
+ clusterUsagePercentage: payload.clusterUsagePercentage,
+ queueUsagePercentage: payload.queueUsagePercentage,
+ currentAppAttemptId: payload.currentAppAttemptId
+ }
+ };
+
+ return fixedPayload;
+ },
+
+ normalizeSingleResponse(store, primaryModelClass, payload, id,
+ requestType) {
+ var p = this.internalNormalizeSingleResponse(store,
+ primaryModelClass, payload, id, requestType);
+ return { data: p };
+ },
+
+ normalizeArrayResponse(store, primaryModelClass, payload, id,
+ requestType) {
+ // return expected is { data: [ {}, {} ] }
+ var normalizedArrayResponse = {};
+
+ // payload has apps : { app: [ {},{},{} ] }
+ // need some error handling for ex apps or app may not be defined.
+ if(payload.apps && payload.apps.app) {
+ normalizedArrayResponse.data = payload.apps.app.map(singleApp => {
+ return this.internalNormalizeSingleResponse(store, primaryModelClass,
+ singleApp, singleApp.id, requestType);
+ }, this);
+ } else {
+ normalizedArrayResponse.data = [];
+ }
+
+ return normalizedArrayResponse;
+ }
+});
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-container-log.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-container-log.js
new file mode 100644
index 0000000..9e10615
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-container-log.js
@@ -0,0 +1,39 @@
+/**
+ * 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.
+ */
+
+import DS from 'ember-data';
+import Converter from 'yarn-ui/utils/converter';
+
+export default DS.JSONAPISerializer.extend({
+ normalizeSingleResponse(store, primaryModelClass, payload, id,
+ requestType) {
+ // Convert plain text response into JSON.
+ // ID is of the form nodeAddress!containerId!fileName
+ var splits = Converter.splitForContainerLogs(id);
+ var convertedPayload = {
+ id: id,
+ type: primaryModelClass.modelName,
+ attributes: {
+ logs: payload,
+ containerID: splits[1],
+ logFileName: splits[2]
+ }
+ };
+ return { data: convertedPayload };
+ },
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-container.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-container.js
new file mode 100644
index 0000000..b9b923d
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-container.js
@@ -0,0 +1,79 @@
+/**
+ * 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.
+ */
+
+import DS from 'ember-data';
+import Converter from 'yarn-ui/utils/converter';
+
+export default DS.JSONAPISerializer.extend({
+ internalNormalizeSingleResponse(store, primaryModelClass, payload, id,
+ requestType) {
+
+ var fixedPayload = {
+ id: payload.containerId,
+ type: primaryModelClass.modelName, // yarn-app
+ attributes: {
+ allocatedMB: payload.allocatedMB,
+ allocatedVCores: payload.allocatedVCores,
+ assignedNodeId: payload.assignedNodeId,
+ priority: payload.priority,
+ startedTime: Converter.timeStampToDate(payload.startedTime),
+ finishedTime: Converter.timeStampToDate(payload.finishedTime),
+ elapsedTime: payload.elapsedTime,
+ logUrl: payload.logUrl,
+ containerExitStatus: payload.containerExitStatus,
+ containerState: payload.containerState,
+ nodeHttpAddress: payload.nodeHttpAddress
+ }
+ };
+
+ return fixedPayload;
+ },
+
+ normalizeSingleResponse(store, primaryModelClass, payload, id,
+ requestType) {
+ var p = this.internalNormalizeSingleResponse(store,
+ primaryModelClass, payload, id, requestType);
+ return { data: p };
+ },
+
+ normalizeArrayResponse(store, primaryModelClass, payload, id,
+ requestType) {
+ // return expected is { data: [ {}, {} ] }
+ var normalizedArrayResponse = {};
+
+ if (payload && payload.container) {
+ if (Array.isArray(payload.container)) {
+ // payload has apps : { app: [ {},{},{} ] }
+ // need some error handling for ex apps or app may not be defined.
+ normalizedArrayResponse.data = payload.container.map(singleContainer => {
+ return this.internalNormalizeSingleResponse(store, primaryModelClass,
+ singleContainer, singleContainer.id, requestType);
+ }, this);
+ } else {
+ normalizedArrayResponse.data = [this.internalNormalizeSingleResponse(
+ store, primaryModelClass, payload.container, payload.container.id,
+ requestType)];
+ }
+ return normalizedArrayResponse;
+ } else {
+ normalizedArrayResponse.data = [];
+ }
+
+ return normalizedArrayResponse;
+ }
+});
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-node-app.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-node-app.js
new file mode 100644
index 0000000..5945813
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-node-app.js
@@ -0,0 +1,83 @@
+/**
+ * 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.
+ */
+/**
+ * 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.
+ */
+
+import DS from 'ember-data';
+import Ember from 'ember';
+
+export default DS.JSONAPISerializer.extend({
+ internalNormalizeSingleResponse(store, primaryModelClass, payload) {
+ if (payload.app) {
+ payload = payload.app;
+ }
+
+ var fixedPayload = {
+ id: payload.id,
+ type: primaryModelClass.modelName,
+ attributes: {
+ appId: payload.id,
+ state: payload.state,
+ user: payload.user,
+ containers: payload.containerids
+ }
+ };
+ return fixedPayload;
+ },
+
+ normalizeSingleResponse(store, primaryModelClass, payload, id,
+ requestType) {
+ // payload is of the form {"app":{}}
+ var p = this.internalNormalizeSingleResponse(store,
+ primaryModelClass, payload);
+ return { data: p };
+ },
+
+ normalizeArrayResponse(store, primaryModelClass, payload, id,
+ requestType) {
+ // expected return response is of the form { data: [ {}, {} ] }
+ var normalizedArrayResponse = {};
+ // payload is of the form { "apps" : { "app": [ {},{},{} ] } }
+ if (payload.apps) {
+ normalizedArrayResponse.data = payload.apps.app.map(singleApp => {
+ return this.internalNormalizeSingleResponse(store, primaryModelClass,
+ singleApp);
+ }, this);
+ } else {
+ // No container reported inside containers.
+ // Response of the form { "apps": null }
+ normalizedArrayResponse.data = [];
+ }
+ return normalizedArrayResponse;
+ }
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-node-container.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-node-container.js
new file mode 100644
index 0000000..a104f1e
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-node-container.js
@@ -0,0 +1,71 @@
+/**
+ * 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.
+ */
+
+import DS from 'ember-data';
+import Ember from 'ember';
+
+export default DS.JSONAPISerializer.extend({
+ internalNormalizeSingleResponse(store, primaryModelClass, payload) {
+ if (payload.container) {
+ payload = payload.container;
+ }
+ var fixedPayload = {
+ id: payload.id,
+ type: primaryModelClass.modelName,
+ attributes: {
+ containerId: payload.id,
+ state: payload.state,
+ user: payload.user,
+ diagnostics: payload.diagnostics,
+ exitCode: payload.exitCode,
+ totalMemoryNeeded: payload.totalMemoryNeededMB,
+ totalVCoresNeeded: payload.totalVCoresNeeded,
+ containerLogFiles: payload.containerLogFiles
+ }
+ };
+
+ return fixedPayload;
+ },
+
+ normalizeSingleResponse(store, primaryModelClass, payload, id,
+ requestType) {
+ // payload is of the form {"container":{}}
+ var p = this.internalNormalizeSingleResponse(store,
+ primaryModelClass, payload);
+ return { data: p };
+ },
+
+ normalizeArrayResponse(store, primaryModelClass, payload, id,
+ requestType) {
+ // expected return response is of the form { data: [ {}, {} ] }
+ var normalizedArrayResponse = {};
+ if (payload.containers) {
+ // payload is of the form { "containers" : { "container": [ {},{},{} ] } }
+ normalizedArrayResponse.data =
+ payload.containers.container.map(singleContainer => {
+ return this.internalNormalizeSingleResponse(store, primaryModelClass,
+ singleContainer);
+ }, this);
+ } else {
+ // No container reported inside containers.
+ // Response of the form { "containers": null }
+ normalizedArrayResponse.data = [];
+ }
+ return normalizedArrayResponse;
+ }
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-node.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-node.js
new file mode 100644
index 0000000..19308e2
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-node.js
@@ -0,0 +1,56 @@
+/**
+ * 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.
+ */
+
+import DS from 'ember-data';
+import Converter from 'yarn-ui/utils/converter';
+
+export default DS.JSONAPISerializer.extend({
+ internalNormalizeSingleResponse(store, primaryModelClass, payload, id,
+ requestType) {
+ if (payload.nodeInfo) {
+ payload = payload.nodeInfo;
+ }
+
+ var fixedPayload = {
+ id: id,
+ type: primaryModelClass.modelName,
+ attributes: {
+ totalVmemAllocatedContainersMB: payload.totalVmemAllocatedContainersMB,
+ totalPmemAllocatedContainersMB: payload.totalPmemAllocatedContainersMB,
+ totalVCoresAllocatedContainers: payload.totalVCoresAllocatedContainers,
+ vmemCheckEnabled: payload.vmemCheckEnabled,
+ pmemCheckEnabled: payload.pmemCheckEnabled,
+ nodeHealthy: payload.nodeHealthy,
+ lastNodeUpdateTime: Converter.timeStampToDate(payload.lastNodeUpdateTime),
+ healthReport: payload.healthReport,
+ nmStartupTime: Converter.timeStampToDate(payload.nmStartupTime),
+ nodeManagerBuildVersion: payload.nodeManagerBuildVersion,
+ hadoopBuildVersion: payload.hadoopBuildVersion
+ }
+ };
+ return fixedPayload;
+ },
+
+ normalizeSingleResponse(store, primaryModelClass, payload, id,
+ requestType) {
+ // payload is of the form {"nodeInfo":{}}
+ var p = this.internalNormalizeSingleResponse(store,
+ primaryModelClass, payload, id, requestType);
+ return { data: p };
+ },
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-queue.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-queue.js
new file mode 100644
index 0000000..1c5b7b3
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-queue.js
@@ -0,0 +1,145 @@
+/**
+ * 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.
+ */
+
+import DS from 'ember-data';
+
+export default DS.JSONAPISerializer.extend({
+
+ normalizeSingleResponse(store, primaryModelClass, payload, id,
+ requestType) {
+ var children = [];
+ if (payload.queues) {
+ payload.queues.queue.forEach(function(queue) {
+ children.push(queue.queueName);
+ });
+ }
+
+ var includedData = [];
+ var relationshipUserData = [];
+
+ // update user models
+ if (payload.users && payload.users.user) {
+ payload.users.user.forEach(function(u) {
+ includedData.push({
+ type: "YarnUser",
+ id: u.username + "_" + payload.queueName,
+ attributes: {
+ name: u.username,
+ queueName: payload.queueName,
+ usedMemoryMB: u.resourcesUsed.memory || 0,
+ usedVCore: u.resourcesUsed.vCores || 0,
+ }
+ });
+
+ relationshipUserData.push({
+ type: "YarnUser",
+ id: u.username + "_" + payload.queueName,
+ })
+ });
+ }
+
+
+ var fixedPayload = {
+ id: id,
+ type: primaryModelClass.modelName, // yarn-queue
+ attributes: {
+ name: payload.queueName,
+ parent: payload.myParent,
+ children: children,
+ capacity: payload.capacity,
+ usedCapacity: payload.usedCapacity,
+ maxCapacity: payload.maxCapacity,
+ absCapacity: payload.absoluteCapacity,
+ absMaxCapacity: payload.absoluteMaxCapacity,
+ absUsedCapacity: payload.absoluteUsedCapacity,
+ state: payload.state,
+ userLimit: payload.userLimit,
+ userLimitFactor: payload.userLimitFactor,
+ preemptionDisabled: payload.preemptionDisabled,
+ numPendingApplications: payload.numPendingApplications,
+ numActiveApplications: payload.numActiveApplications,
+ },
+ // Relationships
+ relationships: {
+ users: {
+ data: relationshipUserData
+ }
+ }
+ };
+
+ return {
+ queue: this._super(store, primaryModelClass, fixedPayload, id, requestType),
+ includedData: includedData
+ }
+ },
+
+ handleQueue(store, primaryModelClass, payload, id, requestType) {
+ var data = [];
+ var includedData = []
+ var result = this.normalizeSingleResponse(store, primaryModelClass,
+ payload, id, requestType);
+
+ data.push(result.queue);
+ includedData = includedData.concat(result.includedData);
+
+ if (payload.queues) {
+ for (var i = 0; i < payload.queues.queue.length; i++) {
+ var queue = payload.queues.queue[i];
+ queue.myParent = payload.queueName;
+ var childResult = this.handleQueue(store, primaryModelClass, queue,
+ queue.queueName,
+ requestType);
+
+ data = data.concat(childResult.data);
+ includedData = includedData.concat(childResult.includedData);
+ }
+ }
+
+ return {
+ data: data,
+ includedData, includedData
+ }
+ },
+
+ normalizeArrayResponse(store, primaryModelClass, payload, id,
+ requestType) {
+ var normalizedArrayResponse = {};
+ var result = this.handleQueue(store,
+ primaryModelClass,
+ payload.scheduler.schedulerInfo, "root", requestType);
+
+ normalizedArrayResponse.data = result.data;
+ normalizedArrayResponse.included = result.includedData;
+
+ console.log(normalizedArrayResponse);
+
+ return normalizedArrayResponse;
+
+ /*
+ // return expected is { data: [ {}, {} ] }
+ var normalizedArrayResponse = {};
+
+ // payload has apps : { app: [ {},{},{} ] }
+ // need some error handling for ex apps or app may not be defined.
+ normalizedArrayResponse.data = payload.apps.app.map(singleApp => {
+ return this.normalizeSingleResponse(store, primaryModelClass, singleApp, singleApp.id, requestType);
+ }, this);
+ return normalizedArrayResponse;
+ */
+ }
+});
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-rm-node.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-rm-node.js
new file mode 100644
index 0000000..6feab36
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-rm-node.js
@@ -0,0 +1,74 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+import DS from 'ember-data';
+import Converter from 'yarn-ui/utils/converter';
+
+export default DS.JSONAPISerializer.extend({
+ internalNormalizeSingleResponse(store, primaryModelClass, payload, id) {
+ if (payload.node) {
+ payload = payload.node;
+ }
+
+ var fixedPayload = {
+ id: id,
+ type: primaryModelClass.modelName,
+ attributes: {
+ rack: payload.rack,
+ state: payload.state,
+ nodeHostName: payload.nodeHostName,
+ nodeHTTPAddress: payload.nodeHTTPAddress,
+ lastHealthUpdate: Converter.timeStampToDate(payload.lastHealthUpdate),
+ healthReport: payload.healthReport,
+ numContainers: payload.numContainers,
+ usedMemoryMB: payload.usedMemoryMB,
+ availMemoryMB: payload.availMemoryMB,
+ usedVirtualCores: payload.usedVirtualCores,
+ availableVirtualCores: payload.availableVirtualCores,
+ version: payload.version,
+ nodeLabels: payload.nodeLabels
+ }
+ };
+ return fixedPayload;
+ },
+
+ normalizeSingleResponse(store, primaryModelClass, payload, id,
+ requestType) {
+ // payload is of the form {"nodeInfo":{}}
+ var p = this.internalNormalizeSingleResponse(store,
+ primaryModelClass, payload, id);
+ return { data: p };
+ },
+
+ normalizeArrayResponse(store, primaryModelClass, payload, id,
+ requestType) {
+ // expected response is of the form { data: [ {}, {} ] }
+ var normalizedArrayResponse = {};
+ if (payload.nodes) {
+ // payload is of the form { "nodes": { "node": [ {},{},{} ] } }
+ normalizedArrayResponse.data = payload.nodes.node.map(singleNode => {
+ return this.internalNormalizeSingleResponse(store, primaryModelClass,
+ singleNode, singleNode.id);
+ }, this);
+ } else {
+ normalizedArrayResponse.data = [];
+ }
+ return normalizedArrayResponse;
+ }
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/services/env.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/services/env.js
new file mode 100644
index 0000000..208499c
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/services/env.js
@@ -0,0 +1,59 @@
+/*global more*/
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+import environment from '../config/environment';
+
+var MoreObject = more.Object;
+
+export default Ember.Service.extend({
+ ENV: null,
+
+ init: function () {
+ this.collateConfigs();
+ },
+
+ collateConfigs: function () {
+ var collatedENV = {
+ APP: {}
+ },
+ ENV = window.ENV;
+
+ MoreObject.merge(collatedENV, environment);
+
+ if(ENV) {
+ MoreObject.merge(collatedENV.APP, ENV);
+ }
+
+ this.setComputedENVs(collatedENV);
+
+ this.set("ENV", collatedENV);
+ },
+
+ setComputedENVs: function (env) {
+ var navigator = window.navigator;
+ env.isIE = navigator.userAgent.indexOf('MSIE') !== -1 || navigator.appVersion.indexOf('Trident/') > 0;
+ console.log('In setComputedENVs', env.isIE);
+ },
+
+ app: Ember.computed("ENV.APP", function () {
+ return this.get("ENV.APP");
+ })
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/services/hosts.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/services/hosts.js
new file mode 100644
index 0000000..19863e1
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/services/hosts.js
@@ -0,0 +1,74 @@
+/**
+ * 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.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Service.extend({
+
+ env: Ember.inject.service("env"),
+
+ attachProtocolScheme: function (url) {
+ var localProto = this.get("env.app.hosts.protocolScheme");
+
+ if(localProto === "") {
+ localProto = "http:";
+ }
+
+ if(url.match("://")) {
+ url = url.substr(url.indexOf("://") + 3);
+ }
+
+ return localProto + "//" + url;
+ },
+
+ normalizeURL: function (url) {
+ var address;
+
+ // If localBaseAddress is configured, then normalized URL has to
+ // start with this address. For eg: when used with CORS proxy.
+ // In any case, this fn will return with correct proto scheme.
+ address = this.localAddress() + url;
+
+ // Remove trailing slash
+ if(address && address.charAt(address.length - 1) === '/') {
+ address = address.slice(0, -1);
+ }
+ return address;
+ },
+
+ localAddress: function () {
+ var localBaseAddressProto = "";
+
+ if (this.get("env.app.hosts.localBaseAddress").length > 0) {
+ localBaseAddressProto = this.get("env.app.hosts.localBaseAddress") + '/';
+ }
+ return this.attachProtocolScheme(localBaseAddressProto);
+ },
+
+ localBaseAddress: Ember.computed(function () {
+ return this.localAddress();
+ }),
+
+ timelineWebAddress: Ember.computed(function () {
+ return this.normalizeURL(this.get("env.app.hosts.timelineWebAddress"));
+ }),
+
+ rmWebAddress: Ember.computed(function () {
+ return this.normalizeURL(this.get("env.app.hosts.rmWebAddress"));
+ }),
+});
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/styles/app.css b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/styles/app.css
new file mode 100644
index 0000000..da5b4bf
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/styles/app.css
@@ -0,0 +1,279 @@
+/**
+ * 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.
+ */
+
+body, html, body > .ember-view {
+ height: 100%;
+ overflow: visible;
+ color: @text-color;
+}
+body, html {
+ min-width: 1024px;
+}
+
+/*
+ Over all style
+ */
+text {
+ font: 16px sans-serif;
+}
+
+text.small {
+ font: 8px sans-serif;
+}
+
+html, body
+{
+ margin: 0px;
+ padding: 0px;
+ height: 100%;
+ width: 100%;
+}
+
+
+/*
+ queue's style (left banner of queues)
+ */
+
+text.queue {
+ font-family : sans-serif;
+ font-size : 15px;
+ fill : gray;
+}
+
+text.heatmap-cell {
+ font: 14px sans-serif;
+ font-weight: bold;
+ text-anchor: middle;
+ fill: Azure;
+ text-align: center;
+}
+
+text.heatmap-cell-notselected {
+ font: 14px sans-serif;
+ font-weight: bold;
+ text-anchor: middle;
+ fill: Silver;
+ text-align: center;
+}
+
+text.heatmap-rack {
+ font: 20px sans-serif;
+ fill: DimGray;
+}
+
+path.queue {
+ stroke: "red";
+ fill: none;
+}
+
+/*
+ background style
+ */
+line.grid {
+ stroke: WhiteSmoke;
+}
+
+line.chart {
+ stroke: Gray;
+}
+
+/*
+ charts styles
+ */
+text.chart-title {
+ font-size: 30px;
+ font-family: sans-serif;
+ text-anchor: middle;
+ fill: Gray;
+}
+
+text.donut-highlight-text, text.donut-highlight-sub {
+ font-size: 15px;
+ font-family: sans-serif;
+ text-anchor: middle;
+ fill: Gray;
+ vertical-align: middle;
+}
+
+text.donut-highlight-sub {
+ font-size: 23px;
+ margin-top: 10px;
+}
+
+rect.chart-frame {
+ fill: none;
+}
+
+text.bar-chart-text {
+ font-size: 8px;
+ font-family: sans-serif;
+ vertical-align: middle;
+ fill: Gray;;
+}
+
+div.tooltip {
+ position: absolute;
+ text-align: center;
+ padding: 2px;
+ font: 24px sans-serif;
+ background: lightsteelblue;
+ border: 0px;
+ border-radius: 8px;
+ pointer-events: none;
+}
+
+/*
+ * Data table
+ */
+
+table.dataTable thead .sorting {
+ background-image: url("/assets/images/datatables/sort_both.png");
+}
+table.dataTable thead .sorting_asc {
+ background-image: url("/assets/images/datatables/sort_asc.png");
+}
+table.dataTable thead .sorting_desc {
+ background-image: url("/assets/images/datatables/sort_desc.png");
+}
+table.dataTable thead .sorting_asc_disabled {
+ background-image: url("/assets/images/datatables/sort_asc_disabled.png");
+}
+table.dataTable thead .sorting_desc_disabled {
+ background-image: url("/assets/images/datatables/sort_desc_disabled.png");
+}
+
+.add-ellipsis {
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.breadcrumb {
+ padding-bottom: 3px;
+}
+
+.navbar-default .navbar-nav > li > a {
+ color: #337ab7;
+}
+
+/*
+ * Queue selector
+ */
+.node {
+ cursor: pointer;
+}
+
+.node circle {
+ fill: #fff;
+ stroke: steelblue;
+ stroke-width: 3px;
+}
+
+.node text {
+ font: 12px sans-serif;
+}
+
+.link {
+ fill: none;
+ stroke: #ccc;
+ stroke-width: 2px;
+}
+
+.lr-margin {
+ margin: 0px 30px;
+}
+
+.footer {
+ background-color: @white;
+ color: @text-color;
+
+ padding: 10px 0px;
+ margin: 0px;
+
+ border-top: 1px lightgrey solid;
+
+ font-size: .9em;
+}
+
+.table {
+ margin-bottom: 0px;
+ border: none;
+
+ overflow: hidden;
+}
+
+.table-bordered > thead > tr > th, .table-bordered > tbody > tr > th, .table-bordered > tfoot > tr > th, .table-bordered > thead > tr > td, .table-bordered > tbody > tr > td, .table-bordered > tfoot > tr > td {
+ border: none !important;
+}
+
+.dataTables_wrapper .table {
+ border: 1px solid lightgrey;
+ border-bottom: 1px solid lightgrey !important;
+ border-radious: 5px;
+}
+
+.dataTables_wrapper .table-bordered > thead > tr > th, .table-bordered > tbody > tr > th, .table-bordered > tfoot > tr > th, .table-bordered > thead > tr > td, .table-bordered > tbody > tr > td, .table-bordered > tfoot > tr > td {
+ border: 1px solid lightgrey;
+}
+
+td {
+ padding: 8px 15px 8px 15px !important;
+}
+
+.footer-frame {
+ height: 60px;
+}
+.footer {
+ height: 40px;
+}
+
+.footer-pusher {
+ min-height: 100%;
+ height: auto !important;
+ height: 100%;
+ margin: 0 auto -40px; // Must be same as footer & footer-frame
+}
+
+.panel-default .container-fluid {
+ margin-top: -45px !important;
+ margin-bottom: -10px !important;
+}
+
+.panel-heading {
+ font-weight: bold;
+}
+
+.hadoop-brand-image {
+ margin-top: -10px;
+ width: auto;
+ height: 45px;
+}
+
+li a.navigation-link.ember-view {
+ color: #2196f3;
+ font-weight: bold;
+}
+
+.breadcrumb-bar .refresh {
+ position: absolute;
+ right: 20px;
+ top: 3px;
+}
+
+.x-scroll {
+ overflow-x: scroll;
+}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/application.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/application.hbs
new file mode 100644
index 0000000..7783db4
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/application.hbs
@@ -0,0 +1,85 @@
+{{!
+ * 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.
+}}
+
+
+
+
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/cluster-overview.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/cluster-overview.hbs
new file mode 100644
index 0000000..3bf0f37
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/cluster-overview.hbs
@@ -0,0 +1,150 @@
+{{!
+ * 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.
+}}
+
+{{breadcrumb-bar breadcrumbs=breadcrumbs}}
+
+{{#if model}}
+
+
+
+{{/if}}
+
+
+{{outlet}}
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/app-attempt-table.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/app-attempt-table.hbs
new file mode 100644
index 0000000..2b16f86
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/app-attempt-table.hbs
@@ -0,0 +1,62 @@
+{{!
+ * 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.
+}}
+
+
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/app-table.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/app-table.hbs
new file mode 100644
index 0000000..a036a0c
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/app-table.hbs
@@ -0,0 +1,86 @@
+{{!
+ * 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.
+}}
+
+
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/breadcrumb-bar.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/breadcrumb-bar.hbs
new file mode 100644
index 0000000..24acbd9
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/breadcrumb-bar.hbs
@@ -0,0 +1,22 @@
+{{!
+ * 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.
+}}
+
+
+ {{em-breadcrumbs items=breadcrumbs}}
+
+
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/container-table.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/container-table.hbs
new file mode 100644
index 0000000..0736a69
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/container-table.hbs
@@ -0,0 +1,54 @@
+{{!
+ * 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.
+}}
+
+
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/node-menu-panel.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/node-menu-panel.hbs
new file mode 100644
index 0000000..d2486c9
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/node-menu-panel.hbs
@@ -0,0 +1,44 @@
+{{!
+ * 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.
+}}
+
+
+{{outlet}}
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/nodes-heatmap.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/nodes-heatmap.hbs
new file mode 100644
index 0000000..e9e6261
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/nodes-heatmap.hbs
@@ -0,0 +1,27 @@
+{{!
+ * 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.
+}}
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/queue-configuration-table.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/queue-configuration-table.hbs
new file mode 100644
index 0000000..17a1e1a
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/queue-configuration-table.hbs
@@ -0,0 +1,54 @@
+{{!
+ * 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.
+}}
+
+
+
+
+
Configurations
+
Value
+
+
+
+
+
Configured Capacity
+
{{queue.capacity}}
+
+
+
Configured Max Capacity
+
{{queue.maxCapacity}}
+
+
+
State
+
{{queue.state}}
+
+ {{#if queue.isLeafQueue}}
+
+
User Limit Percent
+
{{queue.userLimit}}
+
+
+
User Limit Factor
+
{{queue.userLimitFactor}}
+
+
+
Preemption Disabled
+
{{queue.preemptionDisabled}}
+
+ {{/if}}
+
+
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/queue-navigator.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/queue-navigator.hbs
new file mode 100644
index 0000000..d8dd236
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/queue-navigator.hbs
@@ -0,0 +1,28 @@
+{{!
+ * 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.
+}}
+
+
+
+
+{{outlet}}
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/timeline-view.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/timeline-view.hbs
new file mode 100644
index 0000000..b110268
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/timeline-view.hbs
@@ -0,0 +1,54 @@
+{{!
+ * 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.
+}}
+
+
+
+{{outlet}}
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/error.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/error.hbs
new file mode 100644
index 0000000..2e2a6e5
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/error.hbs
@@ -0,0 +1,19 @@
+{{!--
+ 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.
+--}}
+
+
Sorry, Error Occurred.
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/notfound.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/notfound.hbs
new file mode 100644
index 0000000..588ea44
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/notfound.hbs
@@ -0,0 +1,20 @@
+{{!--
+ 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.
+--}}
+
+
404, Not Found
+
Please Check your URL
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-app-attempt.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-app-attempt.hbs
new file mode 100644
index 0000000..1dbae9a
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-app-attempt.hbs
@@ -0,0 +1,43 @@
+{{!
+ * 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.
+}}
+
+{{breadcrumb-bar breadcrumbs=breadcrumbs}}
+
+
+{{outlet}}
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-app-attempts.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-app-attempts.hbs
new file mode 100644
index 0000000..c0fa7e1
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-app-attempts.hbs
@@ -0,0 +1,55 @@
+{{!
+ * 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.
+}}
+
+{{breadcrumb-bar breadcrumbs=breadcrumbs}}
+
+
+{{outlet}}
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-app.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-app.hbs
new file mode 100644
index 0000000..9e92fc1
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-app.hbs
@@ -0,0 +1,253 @@
+{{!
+ * 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.
+}}
+
+{{breadcrumb-bar breadcrumbs=breadcrumbs}}
+
+{{#if model.app}}
+
+{{/if}}
+{{outlet}}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps.hbs
new file mode 100644
index 0000000..d5f6347
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps.hbs
@@ -0,0 +1,90 @@
+{{!
+ * 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.
+}}
+
+{{breadcrumb-bar breadcrumbs=breadcrumbs}}
+
+
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps/apps.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps/apps.hbs
new file mode 100644
index 0000000..a2ba163
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps/apps.hbs
@@ -0,0 +1,24 @@
+{{!--
+ 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.
+--}}
+
+{{#if model.apps}}
+ {{app-table table-id="apps-table" arr=model.apps}}
+ {{simple-table table-id="apps-table" bFilter=true colsOrder="0,desc" colTypes="natural elapsed-time" colTargets="0 7"}}
+{{else}}
+
Could not find any applications from this cluster
+{{/if}}
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps/services.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps/services.hbs
new file mode 100644
index 0000000..e472e8e
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps/services.hbs
@@ -0,0 +1,27 @@
+{{!--
+ 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.
+--}}
+
+{{#if model.apps}}
+ {{app-table table-id="apps-table" arr=model.apps}}
+ {{simple-table table-id="apps-table" bFilter=true colsOrder="0,desc"
+ colTypes="natural elapsed-time" colTargets="0 7" defaultSearch="slider"}}
+{{else}}
+
Could not find any applications from this cluster
+{{/if}}
+
+{{outlet}}
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-container-log.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-container-log.hbs
new file mode 100644
index 0000000..67629d2
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-container-log.hbs
@@ -0,0 +1,38 @@
+{{!--
+ 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.
+--}}
+
+{{breadcrumb-bar breadcrumbs=breadcrumbs}}
+
+
{{model.containerLog.logFileName}} for {{model.containerLog.containerID}}
+
+
+ {{#if model.containerLog.logs}}
+
{{model.containerLog.logs}}
+ {{else}}
+
No logs were written in {{model.containerLog.logFileName}}.
+ {{/if}}
+
+
+
+
+{{outlet}}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-node-app.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-node-app.hbs
new file mode 100644
index 0000000..99d99cc
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-node-app.hbs
@@ -0,0 +1,62 @@
+{{!--
+ 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.
+--}}
+
+{{breadcrumb-bar breadcrumbs=breadcrumbs}}
+
+
+{{outlet}}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-node-apps.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-node-apps.hbs
new file mode 100644
index 0000000..52f0c86
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-node-apps.hbs
@@ -0,0 +1,53 @@
+{{!--
+ 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.
+--}}
+
+{{breadcrumb-bar breadcrumbs=breadcrumbs}}
+
+
+{{outlet}}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-node-container.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-node-container.hbs
new file mode 100644
index 0000000..45abee8
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-node-container.hbs
@@ -0,0 +1,72 @@
+{{!--
+ 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.
+--}}
+
+{{breadcrumb-bar breadcrumbs=breadcrumbs}}
+
+
+{{outlet}}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-node-containers.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-node-containers.hbs
new file mode 100644
index 0000000..f520c46
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-node-containers.hbs
@@ -0,0 +1,60 @@
+{{!--
+ 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.
+--}}
+
+{{breadcrumb-bar breadcrumbs=breadcrumbs}}
+
+
+{{outlet}}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-node.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-node.hbs
new file mode 100644
index 0000000..2d6b3a3
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-node.hbs
@@ -0,0 +1,118 @@
+{{!--
+ 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.
+--}}
+
+{{breadcrumb-bar breadcrumbs=breadcrumbs}}
+
+
+{{outlet}}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-nodes.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-nodes.hbs
new file mode 100644
index 0000000..ed5522e
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-nodes.hbs
@@ -0,0 +1,70 @@
+{{!--
+ 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.
+--}}
+
+{{breadcrumb-bar breadcrumbs=breadcrumbs}}
+
+
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-nodes/heatmap.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-nodes/heatmap.hbs
new file mode 100644
index 0000000..e06249f
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-nodes/heatmap.hbs
@@ -0,0 +1,30 @@
+{{!--
+ 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.
+--}}
+
+{{#if model.nodes}}
+
+
+
+{{/if}}
+
+{{outlet}}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-nodes/table.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-nodes/table.hbs
new file mode 100644
index 0000000..d9fae3a
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-nodes/table.hbs
@@ -0,0 +1,67 @@
+{{!--
+ 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.
+--}}
+
+
+{{outlet}}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-queue-apps.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-queue-apps.hbs
new file mode 100644
index 0000000..d5329f2
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-queue-apps.hbs
@@ -0,0 +1,64 @@
+{{!
+ * 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.
+}}
+
+{{breadcrumb-bar breadcrumbs=breadcrumbs}}
+
+
+{{outlet}}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-queue.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-queue.hbs
new file mode 100644
index 0000000..11c527c
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-queue.hbs
@@ -0,0 +1,108 @@
+{{!
+ * 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.
+}}
+
+{{breadcrumb-bar breadcrumbs=breadcrumbs}}
+
+
+{{outlet}}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-queues.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-queues.hbs
new file mode 100644
index 0000000..ea9338c
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-queues.hbs
@@ -0,0 +1,70 @@
+{{!
+ * 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.
+}}
+
+{{breadcrumb-bar breadcrumbs=breadcrumbs}}
+
+
+
+{{outlet}}
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/utils/color-utils.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/utils/color-utils.js
new file mode 100644
index 0000000..b96ec16
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/utils/color-utils.js
@@ -0,0 +1,67 @@
+/**
+ * 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.
+ */
+
+import Constants from 'yarn-ui/constants';
+
+export default {
+ preDefinedColors : ["#1f77b4", "#aec7e8", "#ffbb78",
+ "#98df8a", "#ff9896", "#9467bd", "#c5b0d5", "#8c564b",
+ "#c49c94", "#e377c2", "#f7b6d2", "#c7c7c7", "#bcbd22",
+ "#dbdb8d", "#17becf", "#9edae5"],
+
+ colorMap: {
+ "warn": "#ff7f0e",
+ "good": "#2ca02c",
+ "error": "#d62728",
+ "others": "#7f7f7f",
+ },
+
+ getColors: function(nColors, colorsTarget, reverse = false) {
+ var colors = [];
+ for (var i = 0; i < nColors; i++) {
+ colors.push(undefined);
+ }
+
+ var startIdx = 0;
+
+ if (reverse) {
+ startIdx = Math.max(nColors - colorsTarget.length, 0);
+ }
+
+ for (var i = 0; i < colorsTarget.length; i++) {
+ if (i + startIdx < nColors) {
+ colors[i + startIdx] = this.getColorByTarget(colorsTarget[i]);
+ }
+ }
+
+ var idx = 0;
+ for (var i = 0; i < nColors; i++) {
+ if (!colors[i]) {
+ colors[i] = this.preDefinedColors[i % this.preDefinedColors.length];
+ idx ++;
+ }
+ }
+
+ console.log(colors);
+ return colors;
+ },
+
+ getColorByTarget: function(target) {
+ return this.colorMap[target];
+ }
+};
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/utils/converter.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/utils/converter.js
new file mode 100644
index 0000000..6fd9d30
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/utils/converter.js
@@ -0,0 +1,126 @@
+/**
+ * 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.
+ */
+
+import Constants from 'yarn-ui/constants';
+
+export default {
+ containerIdToAttemptId: function(containerId) {
+ if (containerId) {
+ var arr = containerId.split('_');
+ var attemptId = ["appattempt", arr[1],
+ arr[2], this.padding(arr[3], 6)];
+ return attemptId.join('_');
+ }
+ },
+ attemptIdToAppId: function(attemptId) {
+ if (attemptId) {
+ var arr = attemptId.split('_');
+ var appId = ["application", arr[1],
+ arr[2]].join('_');
+ return appId;
+ }
+ },
+ padding: function(str, toLen=2) {
+ str = str.toString();
+ if (str.length >= toLen) {
+ return str;
+ }
+ return '0'.repeat(toLen - str.length) + str;
+ },
+ resourceToString: function(mem, cpu) {
+ mem = Math.max(0, mem);
+ cpu = Math.max(0, cpu);
+ return mem + " MBs, " + cpu + " VCores";
+ },
+ msToElapsedTime: function(timeInMs) {
+ var sec_num = timeInMs / 1000; // don't forget the second param
+ var hours = Math.floor(sec_num / 3600);
+ var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
+ var seconds = sec_num - (hours * 3600) - (minutes * 60);
+
+ var timeStrArr = [];
+
+ if (hours > 0) {
+ timeStrArr.push(hours + ' Hrs');
+ }
+ if (minutes > 0) {
+ timeStrArr.push(minutes + ' Mins');
+ }
+ if (seconds > 0) {
+ timeStrArr.push(Math.round(seconds) + " Secs");
+ }
+ return timeStrArr.join(' : ');
+ },
+ elapsedTimeToMs: function(elapsedTime) {
+ elapsedTime = elapsedTime.toLowerCase();
+ var arr = elapsedTime.split(' : ');
+ var total = 0;
+ for (var i = 0; i < arr.length; i++) {
+ if (arr[i].indexOf('hr') > 0) {
+ total += parseInt(arr[i].substring(0, arr[i].indexOf(' '))) * 3600;
+ } else if (arr[i].indexOf('min') > 0) {
+ total += parseInt(arr[i].substring(0, arr[i].indexOf(' '))) * 60;
+ } else if (arr[i].indexOf('sec') > 0) {
+ total += parseInt(arr[i].substring(0, arr[i].indexOf(' ')));
+ }
+ }
+ return total * 1000;
+ },
+ timeStampToDate: function(timeStamp) {
+ var dateTimeString = moment(parseInt(timeStamp)).format("YYYY/MM/DD HH:mm:ss");
+ return dateTimeString;
+ },
+ dateToTimeStamp: function(date) {
+ if (date) {
+ var ts = moment(date, "YYYY/MM/DD HH:mm:ss").valueOf();
+ return ts;
+ }
+ },
+ splitForContainerLogs: function(id) {
+ if (id) {
+ var splits = id.split(Constants.PARAM_SEPARATOR);
+ var splitLen = splits.length;
+ if (splitLen < 3) {
+ return null;
+ }
+ var fileName = splits[2];
+ var index;
+ for (index = 3; index < splitLen; index++) {
+ fileName = fileName + Constants.PARAM_SEPARATOR + splits[index];
+ }
+ return [splits[0], splits[1], fileName];
+ }
+ },
+ memoryToSimpliedUnit: function(mb) {
+ var unit = "MB"
+ var value = mb;
+ if (value / 1024 >= 0.9) {
+ value = value / 1024;
+ unit = "GB";
+ }
+ if (value / 1024 >= 0.9) {
+ value = value / 1024;
+ unit = "TB";
+ }
+ if (value / 1024 >= 0.9) {
+ value = value / 1024;
+ unit = "PB";
+ }
+ return value.toFixed(1) + " " + unit;
+ }
+};
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/utils/href-address-utils.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/utils/href-address-utils.js
new file mode 100644
index 0000000..fd940a2
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/utils/href-address-utils.js
@@ -0,0 +1,29 @@
+/**
+ * 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.
+ */
+
+import Constants from 'yarn-ui/constants';
+
+export default {
+ getApplicationLink: function(applicationId) {
+ return "#/yarn-app/" + applicationId;
+ },
+
+ getQueueLink: function(queueName) {
+ return '#/yarn-queue/' + queueName;
+ }
+};
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/utils/mock.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/utils/mock.js
new file mode 100644
index 0000000..62eebc1
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/utils/mock.js
@@ -0,0 +1,36 @@
+/**
+ * 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.
+ */
+
+export default {
+ initMockNodesData: function(ref) {
+ var data = [];
+ for (var i = 0; i < 3; i++) {
+ for (var j = 0; j < 38; j++) {
+ var node = ref.get('targetObject.store').createRecord('YarnRmNode', {
+ rack: "/rack-" + i,
+ nodeHostName: "hadoop-" + ["centos6", "ubuntu7", "win"][i % 3] + "-" + ["web", "etl", "dm"][j % 3] + "-" + j,
+ usedMemoryMB: Math.abs(Math.random() * 10000),
+ availMemoryMB: Math.abs(Math.random() * 10000)
+ });
+ data.push(node);
+ }
+ }
+
+ ref.set("model", data);
+ },
+}
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/utils/sorter.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/utils/sorter.js
new file mode 100644
index 0000000..febef6f
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/utils/sorter.js
@@ -0,0 +1,73 @@
+/**
+ * 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.
+ */
+
+import Converter from 'yarn-ui/utils/converter';
+import Ember from 'ember';
+
+export default {
+ _initElapsedTimeSorter: function() {
+ Ember.$.extend(Ember.$.fn.dataTableExt.oSort, {
+ "elapsed-time-pre": function (a) {
+ return Converter.padding(Converter.elapsedTimeToMs(a), 20);
+ },
+ });
+ },
+
+ _initNaturalSorter: function() {
+ Ember.$.extend(Ember.$.fn.dataTableExt.oSort, {
+ "natural-asc": function (a, b) {
+ return naturalSort(a,b);
+ },
+ "natural-desc": function (a, b) {
+ return naturalSort(a,b) * -1;
+ },
+ });
+ },
+
+ initDataTableSorter: function() {
+ this._initElapsedTimeSorter();
+ this._initNaturalSorter();
+ },
+};
+
+/**
+ * Natural sort implementation.
+ * Typically used to sort application Ids'.
+ */
+function naturalSort(a, b) {
+ var diff = a.length - b.length;
+ if (diff != 0) {
+ var splitA = a.split("_");
+ var splitB = b.split("_");
+ if (splitA.length != splitB.length) {
+ return a.localeCompare(b);
+ }
+ for (var i = 1; i < splitA.length; i++) {
+ var splitdiff = splitA[i].length - splitB[i].length;
+ if (splitdiff != 0) {
+ return splitdiff;
+ }
+ var splitCompare = splitA[i].localeCompare(splitB[i]);
+ if (splitCompare != 0) {
+ return splitCompare;
+ }
+ }
+ return diff;
+ }
+ return a.localeCompare(b);
+}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/bower.json b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/bower.json
new file mode 100644
index 0000000..fe5f289
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/bower.json
@@ -0,0 +1,24 @@
+{
+ "name": "yarn-ui",
+ "dependencies": {
+ "ember": "2.2.0",
+ "ember-cli-shims": "0.0.6",
+ "ember-cli-test-loader": "0.2.1",
+ "ember-data": "2.1.0",
+ "ember-load-initializers": "0.1.7",
+ "ember-qunit": "0.4.16",
+ "ember-qunit-notifications": "0.1.0",
+ "jquery": "2.1.4",
+ "loader.js": "3.3.0",
+ "qunit": "1.19.0",
+ "jquery-ui": "1.11.4",
+ "more-js": "0.8.2",
+ "bootstrap": "3.3.6",
+ "d3": "~3.5.6",
+ "datatables": "~1.10.8",
+ "spin.js": "~2.3.2",
+ "momentjs": "~2.10.6",
+ "select2": "4.0.0",
+ "snippet-ss": "~1.11.0"
+ }
+}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/configs.env b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/configs.env
new file mode 100644
index 0000000..04577c9
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/configs.env
@@ -0,0 +1,48 @@
+/**
+ * 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.
+ */
+
+ENV = {
+ hosts: {
+ /*
+ * Local URL. This is empty by default. In case when ResourceManager
+ * and Timeline Server (ATS) are running on same node, cross domain
+ * requests has to be supported. In such cases, proxy URL can be configured
+ * here to handle requests (CORS). For eg:"localhost:1337"
+ */
+ //localBaseAddress: "localhost:1337",
+
+ /*
+ * Timeline web interface can be configured below.
+ * By default timeline server is set as localhost:8188, uncomment and change
+ * the following value for pointing to a different address.
+ */
+ //timelineWebAddress: "localhost:8188",
+
+ /*
+ * RM web interface can be configured below.
+ * By default RM web address is set as localhost:8088, uncomment and change
+ * the following value for pointing to a different address.
+ */
+ //rmWebAddress: "localhost:8088",
+
+ /*
+ * Protocol scheme. It can be "http:" or "https:". By default, http is used.
+ */
+ //protocolScheme: "http:"
+ },
+};
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/default-config.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/default-config.js
new file mode 100644
index 0000000..92d0721
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/default-config.js
@@ -0,0 +1,32 @@
+/**
+ * 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.
+ */
+
+module.exports = { // Yarn UI App configurations
+ hosts: {
+ localBaseAddress: "localhost:1337",
+ timelineWebAddress: "localhost:8188",
+ rmWebAddress: "localhost:8088",
+ protocolScheme: "http:"
+ },
+ namespaces: {
+ timeline: 'ws/v1/applicationhistory',
+ cluster: 'ws/v1/cluster',
+ metrics: 'ws/v1/cluster/metrics',
+ node: 'ws/v1/node'
+ },
+};
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/environment.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/environment.js
new file mode 100644
index 0000000..3c478be
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/environment.js
@@ -0,0 +1,70 @@
+/**
+ * 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.
+ */
+
+/* jshint node: true */
+
+const DEFAULT_CONFIG = require('./default-config');
+
+module.exports = function(environment) {
+ var ENV = {
+ modulePrefix: 'yarn-ui',
+ environment: environment,
+ baseURL: '/',
+ locationType: 'hash',
+ EmberENV: {
+ FEATURES: {
+ // Here you can enable experimental features on an ember canary build
+ // e.g. 'with-controller': true
+ }
+ },
+
+ APP: DEFAULT_CONFIG,
+ contentSecurityPolicy: {
+ 'connect-src': "* 'self'",
+ 'child-src': "'self' 'unsafe-inline'",
+ 'style-src': "'self' 'unsafe-inline'",
+ 'script-src': "'self' 'unsafe-inline'"
+ }
+ };
+
+ if (environment === 'development') {
+ // ENV.APP.LOG_RESOLVER = true;
+ // ENV.APP.LOG_ACTIVE_GENERATION = true;
+ // ENV.APP.LOG_TRANSITIONS = true;
+ // ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
+ // ENV.APP.LOG_VIEW_LOOKUPS = true;
+ }
+
+ if (environment === 'test') {
+ // Testem prefers this...
+ ENV.baseURL = '/';
+ ENV.locationType = 'none';
+
+ // keep test console output quieter
+ ENV.APP.LOG_ACTIVE_GENERATION = false;
+ ENV.APP.LOG_VIEW_LOOKUPS = false;
+
+ ENV.APP.rootElement = '#ember-testing';
+ }
+
+ if (environment === 'production') {
+
+ }
+
+ return ENV;
+};
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/ember-cli-build.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/ember-cli-build.js
new file mode 100644
index 0000000..7736c75
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/ember-cli-build.js
@@ -0,0 +1,58 @@
+/**
+ * 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.
+ */
+
+/* global require, module */
+var Funnel = require("broccoli-funnel");
+var EmberApp = require('ember-cli/lib/broccoli/ember-app');
+
+module.exports = function(defaults) {
+ var app = new EmberApp(defaults, {
+ hinting: false
+ });
+
+ app.import("bower_components/datatables/media/css/jquery.dataTables.min.css");
+ app.import("bower_components/datatables/media/js/jquery.dataTables.min.js");
+ app.import("bower_components/momentjs/min/moment.min.js");
+ app.import("bower_components/select2/dist/css/select2.min.css");
+ app.import("bower_components/select2/dist/js/select2.min.js");
+ app.import('bower_components/jquery-ui/jquery-ui.js');
+ app.import('bower_components/more-js/dist/more.js');
+ app.import('bower_components/bootstrap/dist/css/bootstrap.css');
+ app.import('bower_components/bootstrap/dist/css/bootstrap-theme.css');
+ app.import('bower_components/bootstrap/dist/js/bootstrap.min.js');
+
+ // Use `app.import` to add additional libraries to the generated
+ // output files.
+ //
+ // If you need to use different assets in different
+ // environments, specify an object as the first parameter. That
+ // object's keys should be the environment name and the values
+ // should be the asset to use in that environment.
+ //
+ // If the library that you are including contains AMD or ES6
+ // modules that you would like to import into your application
+ // please specify an object with the list of modules as keys
+ // along with the exports of each module as its value.
+ var extraAssets = new Funnel('config', {
+ srcDir: '/',
+ include: ['*.env'],
+ destDir: '/config'
+ });
+
+ return app.toTree(extraAssets);
+};
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/jsconfig.json b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/jsconfig.json
new file mode 100644
index 0000000..875bb90c
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/jsconfig.json
@@ -0,0 +1,6 @@
+{
+ "compilerOptions": {
+ "target": "ES6",
+ "module": "commonjs"
+ }
+}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/package.json b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/package.json
new file mode 100644
index 0000000..6a4eb16
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/package.json
@@ -0,0 +1,52 @@
+{
+ "name": "yarn-ui",
+ "version": "0.0.1",
+ "description": "New UI framework of Apache Hadoop YARN",
+ "private": true,
+ "directories": {
+ "doc": "doc",
+ "test": "tests"
+ },
+ "scripts": {
+ "build": "ember build",
+ "start": "ember server"
+ },
+ "repository": "",
+ "engines": {
+ "node": ">= 0.10.0"
+ },
+ "author": "",
+ "license": "Apache",
+ "devDependencies": {
+ "broccoli-asset-rev": "2.4.2",
+ "broccoli-funnel": "1.0.1",
+ "em-table": "0.1.6",
+ "ember-bootstrap": "0.5.1",
+ "ember-array-contains-helper": "1.0.2",
+ "ember-cli": "1.13.13",
+ "ember-cli-app-version": "1.0.0",
+ "ember-cli-babel": "5.1.6",
+ "ember-cli-content-security-policy": "0.4.0",
+ "ember-cli-dependency-checker": "1.2.0",
+ "ember-cli-htmlbars": "1.0.2",
+ "ember-cli-htmlbars-inline-precompile": "0.3.1",
+ "ember-cli-ic-ajax": "0.2.1",
+ "ember-cli-inject-live-reload": "1.4.0",
+ "ember-cli-jquery-ui": "0.0.20",
+ "ember-cli-qunit": "1.2.1",
+ "ember-cli-release": "0.2.8",
+ "ember-cli-sri": "1.2.1",
+ "ember-cli-uglify": "1.2.0",
+ "ember-d3": "0.1.0",
+ "ember-data": "2.1.0",
+ "ember-disable-proxy-controllers": "1.0.1",
+ "ember-export-application-global": "1.0.5",
+ "ember-resolver": "2.0.3",
+ "ember-spin-spinner": "0.2.3",
+ "ember-truth-helpers": "1.2.0",
+ "select2": "4.0.0"
+ },
+ "dependencies": {
+ "em-helpers": "^0.5.13"
+ }
+}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/public/assets/images/datatables/Sorting icons.psd b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/public/assets/images/datatables/Sorting icons.psd
new file mode 100644
index 0000000000000000000000000000000000000000..53b2e06850767cb57c52b316f0b845b1a8e0ca0e
GIT binary patch
literal 27490
zcmeG^33yY*)^oGAX}T}$5K3uTx@2jaq_m}N($WHj(w42FkS4cnARAd|!3_{mfhUTH
zY|1K#_&`w>abZmhao`qBLJ(pzsNq?Pf|62BSCWcgaLqBHCE&EOUv}>Xi$*(!wu`FiTD>VJ
z{+AE7#EbO0ocN&`rQ%YHimuZaPq5Mz69!ajCydc5b@9D(1=$T*4MvNRwrfNUMuW+g
z)sPdf(V461EPydOEnY-e>|=7`WvP->Ns2@wjn5T`M51h~t|qHoUF4F4R8D-I-EPTB
zORKN1Ppy}wnys~I5~Wg^CYGj2r76IXVjFL=YZ_8awl0hkw;nZZ(^~ZwyWVUPVZEAa
zv%{VfACEKgTuc#lT2DR}ht)uG(P`6Y18t;Dc3T=0GR>nLWV3bJtQxb`sIlj2EEa=a
ztHHUXjWg*|NmWxVb!NNSR%fGR{uJrSU2qsXEr$0{>^FZqQgf#WvYoIcv?v
zG$25c#lA%bWR}WGYwTugrP*xA&BtvbDsvZ9q^gjLhU!f^bGI#2
zx!pT4Hfx|&50)W)DOZx6b{o#C;)FJ=oVJ+_4&3*0B$)~
zF$4*~fLF+prOM1?nOKr6lPDl4lQX0cWKzI^9=R9-@XB#I1LzQB=`v}rf^>;GQ!SAw
z)Y8n1LTRB?kzbUNAum)aRbsg$-)&)^lDUfgmyJ<$gZ?glfGM~80mf#P=^JRnFtr}~
zi4C`{M46p-M}n7;o9V;vCg??IDX20V%+?Bc+R@nYh%PTwOKu;F$ubq0>B;G0Wu}JT!^AScXGj>H^kgh0Co!}rv=(3>228plLrh|5O@N^-A%@nM%fL5q4Ezu)
zajXDNh;d#r@Dv>5Tx8%uI0jjWi7fa}x+EQ_IEK@OP-$z
z*2q+*H+%AKvYtw%9JQGGgG9g;Kq04yQ7|By$z-Xl#URGqDo{%8e~E?WP!UC(Ew}Fc$bb}2q$QFIthf3
zj$(9lAZdI~lu3tr(ha0sZ9M6Yqz;!zI+(-|xwHsK8cv;Jo+Rc}slamzl|>{k6P{v}
zR#O8M1H?R+6oXkZZ@vd3C910+cJpKqOiD9`=)4AL1T}_w-RWYV#pF9toX&rThVv#S
zL(qzBl49YU5Mu`d60DejTnb-|eQ^zNt?&umFv1f=FxX~*W92cy)f%{M5o&Iowm8YU
z0uh#S$zYtxVKBfApYaW<*4XF)8Y5jOPZp!{+B!EKr+GFw4olmH82Z~FMfv2z
zB{V=sLEw`_iP}pyzt(DYSbR`CvsDjgk7<*`2r|OL3alN@2?7q%p&EzX+=n*NRyc~P
z0|crZZ=qex0)`o5Fr~y;D}vjDu0I>j54#NSGA?c!Ured3*4;P^4^LyTS88f~xWcqF
z$k7e<5?gU)Y5!_Cvx}L7+-M)>;5xH)LcT#?>$X%lQ~6>y8YKBTx<=zL*Z~Y4M_cW8
zU?1W}`?7~r*OK!|UdD}N^cVE;5I_VCFq^QggY9O^K!@E%yB!151O{-V+pxlFvmG4j
zHhc&)aa{{`(p$P=T}TLl>V1*GOuq^z=wcuh_t%@uEa)3Xlii9>MGYHXCF1Xco*E4O
z4*XoBwOL9lig4dRaAHb?k4`a~NDNlKa+K*AU#1k7i9}ws`vD`h7AqK;Dg$Pj4i2FM
zJOyAwz1@QGxYRM#V=&CZJub!y1q8S?hHDu(neZ@h9)@*B6Zkg^m)W8->M*<$;Ah7<
zu-~)$13Yz{o~{S@Fu(~0hfxnO9v@?jvNSje{dzx|0lFc~tQW#s|S;T&!8CN|Ip^Z-?)cTudT*6|6
z!lxj#VZT>>;;_GXeUU&uJ^8qT-sE%e&`ZO=DCVUBgN$DT
z5WV~siW!-TBKF51_Ro6|CprYNN4y3U%F}NBgNGp8^M-ah!}vYGKqs+J#F`07mQ7Ed
z3P@F6DbhNu;}{kWzH#Ac9*$yA8`KeXLETUak|H_kh4N4#>Wc=#jB7Z01m;+E$OzBY
zdh{5Ygr=hD=mqpLnvWKtPbl{1(iz`QvIoNYB)8Ds-;YngL;g5ikeQ%qUKXes8!TE)ce#nYBzO|
z`kFdHouhuEZm`%aAuEQ}ftAQgV<}kqtbVLY*2An?)>zgA))dzBthubEthZPjSld`%
zu#T`ASwFEZvk^Ol9mnp>PGKw9D)vBj6}yIQWk125#-77o%3j0X%-+TRlHJHY&%Vy#
zaiTdQP70?NrL)6<_+hK<~_=r!F!drmbaC6kavoAna}69;rHa{
z@CWiWd^>+Ce;)rW{ucfr{%QWTppc+WLDHb2psFBK(Bz;wL2m|q9CRq?Owi5Xh~Tcl
zS-}H?b;09m|v
zT3B>gYFJ5_F6_y$1z{V)4uxF^4-W4do*({5_=NB|;qQj;4?iCf9FZ8IiqJ$n5wRfR
z{fJ``mm{MiC6NOojgd1V-;CTHc{Yk4l^9hRrHh&pwJd5!)TwB8beCvVv^M&w=;hI$
zM4yh~#U#a)#Eg!a9`pB@eK8kfqhixzhr~9-E{OdowlR(!ml#(PXNa2_w=V8z+>KTp
zTIIK*TRqomO{+t#uC{L1IwmsSoYFpp-
zwYHzMJ>M>-U9Wc9cGKFeYxhliR{I|9%iBNNep&lH?Jsxe*r87cONV(Kc62!3F|K1?
z$I%^Ucl@~HxlYlYay#ie&F-|N(~qK9QNG9^nk(8Vy4bmW=i<(e&PzJ)>wGglDSmML
zbysvB)BV-%2YRr2Wb~-(v7pEPo~)jkJ@q|b
z?RhYn3&+Jx$xD-ur3h2xaze#&YwbBLB!?I9Wk?cv?CfTp)J=5v**V4brh|Va@cqU_e#vhsTOl#(v
z%yaSt`6&59`7uR|qD(PE@tKmVEKokF{7`v4D>KWUwJz(IUMaoC^m?<`+3cijI(vEc
zshs#6P0o^>##~YEsNBW5jlDbf*7RQ5`($31JYC+3yfgXT^GD~um4Bf?TwpC&UvO2G
zrFvYoRn1oSQBPCvD~u`}TsXh*`=a=w+M?A(7yD%Nd9=^gVs3H2;unjLm2@c4maHnd
z*jL{7@xD9z3Hw#_o8Rwb{~rCV{Wq7gO8b_+RC;_s*8!#h8wa9+B?Dg?_+432+1RoV
z2Jr@!4O%ehhjK~zW97RlqANyLyjgLjvY>Ki<+p>o4R#FPJ|uj|h#{+nTpg+&I%{a-
zu(V;15Bp+x+u{1*o2vL#L#kF(U4E$Wp_d;zJtAYo)DcG?PI|cE;oXn4eZ=s{M&sbAKm^~=f@^JcH;5;$Co@oJyHF{_9weMIpxXI6Z=ejW0GLfm`Qsl
zizm;T{QFZwpV~a7!<30rPCeb{>D5!irdp>Sd#2Yji=O2?tABRibF$~=J$GxGZrbP5
z#nb0ZZzc}?@{<{w#5uwd=N_6wg|c=c7?tA}38
zdu`344vVHQy0KWl_^Ty-mTXv>xOC1k-m-Daepo(a`L5R$udiCscE$7+f2=gEY<#2q
zjh(CHt5&_){>_=IS*snZ&%HI`tpk5o|9#V%lr>A%#;u+HHhSCf_K)w3dgti6e(Scs
zt9WOyMABhz76~3`!^j>9@u;^`{2iidLP>MrTWWH50@PN
z;>ds_2agUu`qi-!#~Q!VeRcM0!`HulGwz$4-%dQvJwENbi0|fn-~Rih|LFdYwT+pL
zADvL2*mJVtBn>iliSr8bvV{+|B(_RD3LzrSLz3LFJ6o2mN4AYC^l4%!{zaVf(0Q|OCqdn
zvE9T7L~$rKi^Jmbc|lyZPzJyH2TPGh>
z@w?8dxOn1Mtt}&N>AI&9)h|`*3b!w_XSO;t_$2+?yHj?2={R+%C~5Zcr{8;d=iz_;
z{`&e)j-0+cq-NaIIV(1Ndh~}Y@;*ar>z{dL<;Gpd&RmT|EEbfOL(0VGaWhB}I!mHB
zP=c}X(Ol`I7h`Y%Z;t1XrYhP2s
ztdj1|1D6NKJ>K#7qGh{!p0>}bxLn@vbmgoH=hwssJA=<4SkZwt!L1RF@{taiQ8g^^
zh+yJd2e2K2jX)OQi2f4}5mKQFnA&2eCOO0dh^W-kQq%*0AjGGl$hs0VG~nC9ycn}0
zR86(>z@w>dE*@}tN&@fN2(^b`rKAMLJ?Z&p^kjtz%Pxm-012ADK?qh0UH5x@kqqI_
zjAe->SrWNO?D|d^s6gz+RCC!Dvpo8v7qgpT%m^2cf+;WDDOd&Yst47vxgJ!acRg5?
zTL+cOYSvAZK?FUU*n!-!<-!+ZQqU-)8Nb`R^1>)sdw~Gzyf04*13GUCz=Vj`Eis$2{(pe4OO#ZG{aQtsSpL<1{L@+f}|gm=A3Ya%k{~hDTdeU=X?Y
z6Ub=R$7=FPm+O4#l~$9@z1SV1(dkNEpK)~K1bEHAoYpzCw7VRUcrDCYiAxTvQg*A^
z;8Uo`=8Cz