diff --git .gitignore .gitignore index 3b8ef62..fb67e69 100644 --- .gitignore +++ .gitignore @@ -28,5 +28,18 @@ hadoop-common-project/hadoop-kms/downloads/ hadoop-hdfs-project/hadoop-hdfs/downloads hadoop-hdfs-project/hadoop-hdfs-httpfs/downloads 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 patchprocess/ diff --git BUILDING.txt BUILDING.txt index 0009c7d..bf6122b 100644 --- BUILDING.txt +++ BUILDING.txt @@ -4,14 +4,18 @@ Build instructions for Hadoop Requirements: * Unix System -* JDK 1.7+ +* JDK 1.8+ * Maven 3.0 or later +* Findbugs 1.3.9 (if running findbugs) * ProtocolBuffer 2.5.0 * CMake 2.6 or newer (if compiling native code), must be 3.0 or newer on Mac * Zlib devel (if compiling native code) * openssl devel (if compiling native hadoop-pipes and to get the best HDFS encryption performance) * Linux FUSE (Filesystem in Userspace) version 2.6 or above (if compiling fuse_dfs) * 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 @@ -53,12 +57,12 @@ Known issues: ---------------------------------------------------------------------------------- Installing required packages for clean install of Ubuntu 14.04 LTS Desktop: -* Oracle JDK 1.7 (preferred) +* Oracle JDK 1.8 (preferred) $ sudo apt-get purge openjdk* $ sudo apt-get install software-properties-common $ sudo add-apt-repository ppa:webupd8team/java $ sudo apt-get update - $ sudo apt-get install oracle-java7-installer + $ sudo apt-get install oracle-java8-installer * Maven $ sudo apt-get -y install maven * Native libraries @@ -70,14 +74,15 @@ Optional packages: * Snappy compression $ sudo apt-get install snappy libsnappy-dev +* Intel ISA-L library for erasure coding + Please refer to https://01.org/intel%C2%AE-storage-acceleration-library-open-source-version + (OR https://github.com/01org/isa-l) * Bzip2 $ sudo apt-get install bzip2 libbz2-dev * Jansson (C Library for JSON) $ sudo apt-get install libjansson-dev * Linux FUSE $ sudo apt-get install fuse libfuse-dev -* ZStandard compression - $ sudo apt-get install zstd ---------------------------------------------------------------------------------- Maven main modules: @@ -106,7 +111,7 @@ Maven build goals: * Clean : mvn clean [-Preleasedocs] * Compile : mvn compile [-Pnative] - * Run tests : mvn test [-Pnative] + * Run tests : mvn test [-Pnative] [-Pshelltest] * Create JAR : mvn package * Run findbugs : mvn compile findbugs:findbugs * Run checkstyle : mvn compile checkstyle:checkstyle @@ -115,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: @@ -125,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: @@ -149,28 +155,6 @@ Maven build goals: and it ignores the -Dsnappy.prefix option. If -Dsnappy.lib isn't given, the bundling and building will fail. - ZStandard build options: - - ZStandard is a compression library that can be utilized by the native code. - It is currently an optional component, meaning that Hadoop can be built with - or without this dependency. - - * Use -Drequire.zstd to fail the build if libzstd.so is not found. - If this option is not specified and the zstd library is missing. - - * Use -Dzstd.prefix to specify a nonstandard location for the libzstd - header files and library files. You do not need this option if you have - installed zstandard using a package manager. - - * Use -Dzstd.lib to specify a nonstandard location for the libzstd library - files. Similarly to zstd.prefix, you do not need this option if you have - installed using a package manager. - - * Use -Dbundle.zstd to copy the contents of the zstd.lib directory into - the final tar file. This option requires that -Dzstd.lib is also given, - and it ignores the -Dzstd.prefix option. If -Dzstd.lib isn't given, the - bundling and building will fail. - OpenSSL build options: OpenSSL includes a crypto library that can be utilized by the native code. @@ -205,6 +189,39 @@ Maven build goals: For example, to run test_bulk_crc32, you would use: mvn test -Pnative -Dtest=test_bulk_crc32 + Intel ISA-L build options: + + Intel ISA-L is an erasure coding library that can be utilized by the native code. + It is currently an optional component, meaning that Hadoop can be built with + or without this dependency. Note the library is used via dynamic module. Please + reference the official site for the library details. + https://01.org/intel%C2%AE-storage-acceleration-library-open-source-version + (OR https://github.com/01org/isa-l) + + * Use -Drequire.isal to fail the build if libisal.so is not found. + If this option is not specified and the isal library is missing, + we silently build a version of libhadoop.so that cannot make use of ISA-L and + the native raw erasure coders. + This option is recommended if you plan on making use of native raw erasure + coders and want to get more repeatable builds. + * Use -Disal.prefix to specify a nonstandard location for the libisal + library files. You do not need this option if you have installed ISA-L to the + system library path. + * Use -Disal.lib to specify a nonstandard location for the libisal library + files. + * Use -Dbundle.isal to copy the contents of the isal.lib directory into + the final tar file. This option requires that -Disal.lib is also given, + and it ignores the -Disal.prefix option. If -Disal.lib isn't given, the + bundling and building will fail. + + Special plugins: OWASP's dependency-check: + + OWASP's dependency-check plugin will scan the third party dependencies + of this project for known CVEs (security vulnerabilities against them). + It will produce a report in target/dependency-check-report.html. To + invoke, run 'mvn dependency-check:aggregate'. Note that this plugin + requires maven 3.1.1 or greater. + ---------------------------------------------------------------------------------- Building components separately @@ -299,8 +316,9 @@ Building on Windows Requirements: * Windows System -* JDK 1.7+ +* JDK 1.8+ * Maven 3.0 or later +* Findbugs 1.3.9 (if running findbugs) * ProtocolBuffer 2.5.0 * CMake 2.6 or newer * Windows SDK 7.1 or Visual Studio 2010 Professional @@ -373,14 +391,3 @@ http://www.zlib.net/ Building distributions: * Build distribution with native code : mvn package [-Pdist][-Pdocs][-Psrc][-Dtar] - ----------------------------------------------------------------------------------- -Running compatibility checks with checkcompatibility.py - -Invoke `./dev-support/bin/checkcompatibility.py` to run Java API Compliance Checker -to compare the public Java APIs of two git objects. This can be used by release -managers to compare the compatibility of a previous and current release. - -As an example, this invocation will check the compatibility of interfaces annotated as Public or LimitedPrivate: - -./dev-support/bin/checkcompatibility.py --annotation org.apache.hadoop.classification.InterfaceAudience.Public --annotation org.apache.hadoop.classification.InterfaceAudience.LimitedPrivate --include "hadoop.*" branch-2.7.2 trunk diff --git LICENSE.txt LICENSE.txt index 5c6fa9c..04d2daa 100644 --- LICENSE.txt +++ LICENSE.txt @@ -246,48 +246,11 @@ For the org.apache.hadoop.util.bloom.* classes: For portions of the native implementation of slicing-by-8 CRC calculation in src/main/native/src/org/apache/hadoop/util: -Copyright (c) 2008,2009,2010 Massachusetts Institute of Technology. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -* 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. -* Neither the name of the Massachusetts Institute of Technology 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 -OWNER 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. - - -Other portions are under the same license from Intel: -http://sourceforge.net/projects/slicing-by-8/ -/*++ - * - * Copyright (c) 2004-2006 Intel Corporation - All Rights Reserved - * - * This software program is licensed subject to the BSD License, - * available at http://www.opensource.org/licenses/bsd-license.html - * - * Abstract: The main routine - * - --*/ +/** + * Copyright 2008,2009,2010 Massachusetts Institute of Technology. + * All rights reserved. Use of this source code is governed by a + * BSD-style license that can be found in the LICENSE file. + */ For src/main/native/src/org/apache/hadoop/io/compress/lz4/{lz4.h,lz4.c,lz4hc.h,lz4hc.c}, @@ -325,6 +288,75 @@ For src/main/native/src/org/apache/hadoop/io/compress/lz4/{lz4.h,lz4.c,lz4hc.h,l - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c */ + +For hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-nativetask/src/main/native/gtest +--------------------------------------------------------------------- +Copyright 2008, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of Google Inc. 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 +OWNER 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. + +The binary distribution of this product bundles these dependencies under the +following license: +re2j 1.0 +--------------------------------------------------------------------- +This is a work derived from Russ Cox's RE2 in Go, whose license +http://golang.org/LICENSE is as follows: + +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * 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. + + * Neither the name of Google Inc. 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 +OWNER 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. + For hadoop-hdfs-project/hadoop-hdfs-native-client/src/main/native/fuse-dfs/util/tree.h --------------------------------------------------------------------- Copyright 2002 Niels Provos @@ -553,9 +585,7 @@ hadoop-tools/hadoop-sls/src/main/html/css/bootstrap-responsive.min.css And the binary distribution of this product bundles these dependencies under the following license: Mockito 1.8.5 -JUL to SLF4J bridge 1.7.25 -SLF4J API Module 1.7.25 -SLF4J LOG4J-12 Binding 1.7.25 +SLF4J 1.7.10 JCodings 1.0.8 Joni 2.1.2 -------------------------------------------------------------------------------- @@ -659,7 +689,7 @@ hadoop-tools/hadoop-sls/src/main/html/js/thirdparty/d3-LICENSE The binary distribution of this product bundles these dependencies under the following license: -HSQLDB Database 2.3.4 +HSQLDB Database 2.0.0 -------------------------------------------------------------------------------- "COPYRIGHTS AND LICENSES (based on BSD License) @@ -1613,6 +1643,12 @@ JLine 0.9.94 leveldbjni-all 1.8 Hamcrest Core 1.3 xmlenc Library 0.52 +StringTemplate 4 4.0.7 +ANTLR 3 Tool 3.5 +ANTLR 3 Runtime 3.5 +ANTLR StringTemplate 3.2.1 +ASM All 5.0.2 +sqlline 1.1.8 -------------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -1843,24 +1879,538 @@ the Licensor and You. The binary distribution of this product bundles these dependencies under the following license: -jamon-runtime 2.4.1 +jamon-runtime 2.3.1 -------------------------------------------------------------------------------- + MOZILLA PUBLIC LICENSE + Version 1.1 -For: hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs -/server/datanode/checker/AbstractFuture.java and -hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs -/server/datanode/checker/TimeoutFuture.java + --------------- -Copyright (C) 2007 The Guava Authors +1. Definitions. + + 1.0.1. "Commercial Use" means distribution or otherwise making the + Covered Code available to a third party. + + 1.1. "Contributor" means each entity that creates or contributes to + the creation of Modifications. + + 1.2. "Contributor Version" means the combination of the Original + Code, prior Modifications used by a Contributor, and the Modifications + made by that particular Contributor. + + 1.3. "Covered Code" means the Original Code or Modifications or the + combination of the Original Code and Modifications, in each case + including portions thereof. + + 1.4. "Electronic Distribution Mechanism" means a mechanism generally + accepted in the software development community for the electronic + transfer of data. + + 1.5. "Executable" means Covered Code in any form other than Source + Code. + + 1.6. "Initial Developer" means the individual or entity identified + as the Initial Developer in the Source Code notice required by Exhibit + A. + + 1.7. "Larger Work" means a work which combines Covered Code or + portions thereof with code not governed by the terms of this License. + + 1.8. "License" means this document. + + 1.8.1. "Licensable" means having the right to grant, to the maximum + extent possible, whether at the time of the initial grant or + subsequently acquired, any and all of the rights conveyed herein. + + 1.9. "Modifications" means any addition to or deletion from the + substance or structure of either the Original Code or any previous + Modifications. When Covered Code is released as a series of files, a + Modification is: + A. Any addition to or deletion from the contents of a file + containing Original Code or previous Modifications. + + B. Any new file that contains any part of the Original Code or + previous Modifications. + + 1.10. "Original Code" means Source Code of computer software code + which is described in the Source Code notice required by Exhibit A as + Original Code, and which, at the time of its release under this + License is not already Covered Code governed by this License. + + 1.10.1. "Patent Claims" means any patent claim(s), now owned or + hereafter acquired, including without limitation, method, process, + and apparatus claims, in any patent Licensable by grantor. + + 1.11. "Source Code" means the preferred form of the Covered Code for + making modifications to it, including all modules it contains, plus + any associated interface definition files, scripts used to control + compilation and installation of an Executable, or source code + differential comparisons against either the Original Code or another + well known, available Covered Code of the Contributor's choice. The + Source Code can be in a compressed or archival form, provided the + appropriate decompression or de-archiving software is widely available + for no charge. + + 1.12. "You" (or "Your") means an individual or a legal entity + exercising rights under, and complying with all of the terms of, this + License or a future version of this License issued under Section 6.1. + For legal entities, "You" includes any entity which controls, is + controlled by, or is under common control with You. For purposes of + this definition, "control" means (a) the power, direct or indirect, + to cause the direction or management of such entity, whether by + contract or otherwise, or (b) ownership of more than fifty percent + (50%) of the outstanding shares or beneficial ownership of such + entity. + +2. Source Code License. + + 2.1. The Initial Developer Grant. + The Initial Developer hereby grants You a world-wide, royalty-free, + non-exclusive license, subject to third party intellectual property + claims: + (a) under intellectual property rights (other than patent or + trademark) Licensable by Initial Developer to use, reproduce, + modify, display, perform, sublicense and distribute the Original + Code (or portions thereof) with or without Modifications, and/or + as part of a Larger Work; and + + (b) under Patents Claims infringed by the making, using or + selling of Original Code, to make, have made, use, practice, + sell, and offer for sale, and/or otherwise dispose of the + Original Code (or portions thereof). + + (c) the licenses granted in this Section 2.1(a) and (b) are + effective on the date Initial Developer first distributes + Original Code under the terms of this License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is + granted: 1) for code that You delete from the Original Code; 2) + separate from the Original Code; or 3) for infringements caused + by: i) the modification of the Original Code or ii) the + combination of the Original Code with other software or devices. + + 2.2. Contributor Grant. + Subject to third party intellectual property claims, each Contributor + hereby grants You a world-wide, royalty-free, non-exclusive license + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Contributor, to use, reproduce, modify, + display, perform, sublicense and distribute the Modifications + created by such Contributor (or portions thereof) either on an + unmodified basis, with other Modifications, as Covered Code + and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using, or + selling of Modifications made by that Contributor either alone + and/or in combination with its Contributor Version (or portions + of such combination), to make, use, sell, offer for sale, have + made, and/or otherwise dispose of: 1) Modifications made by that + Contributor (or portions thereof); and 2) the combination of + Modifications made by that Contributor with its Contributor + Version (or portions of such combination). + + (c) the licenses granted in Sections 2.2(a) and 2.2(b) are + effective on the date Contributor first makes Commercial Use of + the Covered Code. + + (d) Notwithstanding Section 2.2(b) above, no patent license is + granted: 1) for any code that Contributor has deleted from the + Contributor Version; 2) separate from the Contributor Version; + 3) for infringements caused by: i) third party modifications of + Contributor Version or ii) the combination of Modifications made + by that Contributor with other software (except as part of the + Contributor Version) or other devices; or 4) under Patent Claims + infringed by Covered Code in the absence of Modifications made by + that Contributor. + +3. Distribution Obligations. -Licensed 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 + 3.1. Application of License. + The Modifications which You create or to which You contribute are + governed by the terms of this License, including without limitation + Section 2.2. The Source Code version of Covered Code may be + distributed only under the terms of this License or a future version + of this License released under Section 6.1, and You must include a + copy of this License with every copy of the Source Code You + distribute. You may not offer or impose any terms on any Source Code + version that alters or restricts the applicable version of this + License or the recipients' rights hereunder. However, You may include + an additional document offering the additional rights described in + Section 3.5. + + 3.2. Availability of Source Code. + Any Modification which You create or to which You contribute must be + made available in Source Code form under the terms of this License + either on the same media as an Executable version or via an accepted + Electronic Distribution Mechanism to anyone to whom you made an + Executable version available; and if made available via Electronic + Distribution Mechanism, must remain available for at least twelve (12) + months after the date it initially became available, or at least six + (6) months after a subsequent version of that particular Modification + has been made available to such recipients. You are responsible for + ensuring that the Source Code version remains available even if the + Electronic Distribution Mechanism is maintained by a third party. + + 3.3. Description of Modifications. + You must cause all Covered Code to which You contribute to contain a + file documenting the changes You made to create that Covered Code and + the date of any change. You must include a prominent statement that + the Modification is derived, directly or indirectly, from Original + Code provided by the Initial Developer and including the name of the + Initial Developer in (a) the Source Code, and (b) in any notice in an + Executable version or related documentation in which You describe the + origin or ownership of the Covered Code. + + 3.4. Intellectual Property Matters + (a) Third Party Claims. + If Contributor has knowledge that a license under a third party's + intellectual property rights is required to exercise the rights + granted by such Contributor under Sections 2.1 or 2.2, + Contributor must include a text file with the Source Code + distribution titled "LEGAL" which describes the claim and the + party making the claim in sufficient detail that a recipient will + know whom to contact. If Contributor obtains such knowledge after + the Modification is made available as described in Section 3.2, + Contributor shall promptly modify the LEGAL file in all copies + Contributor makes available thereafter and shall take other steps + (such as notifying appropriate mailing lists or newsgroups) + reasonably calculated to inform those who received the Covered + Code that new knowledge has been obtained. + + (b) Contributor APIs. + If Contributor's Modifications include an application programming + interface and Contributor has knowledge of patent licenses which + are reasonably necessary to implement that API, Contributor must + also include this information in the LEGAL file. + + (c) Representations. + Contributor represents that, except as disclosed pursuant to + Section 3.4(a) above, Contributor believes that Contributor's + Modifications are Contributor's original creation(s) and/or + Contributor has sufficient rights to grant the rights conveyed by + this License. + + 3.5. Required Notices. + You must duplicate the notice in Exhibit A in each file of the Source + Code. If it is not possible to put such notice in a particular Source + Code file due to its structure, then You must include such notice in a + location (such as a relevant directory) where a user would be likely + to look for such a notice. If You created one or more Modification(s) + You may add your name as a Contributor to the notice described in + Exhibit A. You must also duplicate this License in any documentation + for the Source Code where You describe recipients' rights or ownership + rights relating to Covered Code. You may choose to offer, and to + charge a fee for, warranty, support, indemnity or liability + obligations to one or more recipients of Covered Code. However, You + may do so only on Your own behalf, and not on behalf of the Initial + Developer or any Contributor. You must make it absolutely clear than + any such warranty, support, indemnity or liability obligation is + offered by You alone, and You hereby agree to indemnify the Initial + Developer and every Contributor for any liability incurred by the + Initial Developer or such Contributor as a result of warranty, + support, indemnity or liability terms You offer. + + 3.6. Distribution of Executable Versions. + You may distribute Covered Code in Executable form only if the + requirements of Section 3.1-3.5 have been met for that Covered Code, + and if You include a notice stating that the Source Code version of + the Covered Code is available under the terms of this License, + including a description of how and where You have fulfilled the + obligations of Section 3.2. The notice must be conspicuously included + in any notice in an Executable version, related documentation or + collateral in which You describe recipients' rights relating to the + Covered Code. You may distribute the Executable version of Covered + Code or ownership rights under a license of Your choice, which may + contain terms different from this License, provided that You are in + compliance with the terms of this License and that the license for the + Executable version does not attempt to limit or alter the recipient's + rights in the Source Code version from the rights set forth in this + License. If You distribute the Executable version under a different + license You must make it absolutely clear that any terms which differ + from this License are offered by You alone, not by the Initial + Developer or any Contributor. You hereby agree to indemnify the + Initial Developer and every Contributor for any liability incurred by + the Initial Developer or such Contributor as a result of any such + terms You offer. + + 3.7. Larger Works. + You may create a Larger Work by combining Covered Code with other code + not governed by the terms of this License and distribute the Larger + Work as a single product. In such a case, You must make sure the + requirements of this License are fulfilled for the Covered Code. + +4. Inability to Comply Due to Statute or Regulation. + + If it is impossible for You to comply with any of the terms of this + License with respect to some or all of the Covered Code due to + statute, judicial order, or regulation then You must: (a) comply with + the terms of this License to the maximum extent possible; and (b) + describe the limitations and the code they affect. Such description + must be included in the LEGAL file described in Section 3.4 and must + be included with all distributions of the Source Code. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. + +5. Application of this License. + + This License applies to code to which the Initial Developer has + attached the notice in Exhibit A and to related Covered Code. + +6. Versions of the License. + + 6.1. New Versions. + Netscape Communications Corporation ("Netscape") may publish revised + and/or new versions of the License from time to time. Each version + will be given a distinguishing version number. + + 6.2. Effect of New Versions. + Once Covered Code has been published under a particular version of the + License, You may always continue to use it under the terms of that + version. You may also choose to use such Covered Code under the terms + of any subsequent version of the License published by Netscape. No one + other than Netscape has the right to modify the terms applicable to + Covered Code created under this License. + + 6.3. Derivative Works. + If You create or use a modified version of this License (which you may + only do in order to apply it to code which is not already Covered Code + governed by this License), You must (a) rename Your license so that + the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", + "MPL", "NPL" or any confusingly similar phrase do not appear in your + license (except to note that your license differs from this License) + and (b) otherwise make it clear that Your version of the license + contains terms which differ from the Mozilla Public License and + Netscape Public License. (Filling in the name of the Initial + Developer, Original Code or Contributor in the notice described in + Exhibit A shall not of themselves be deemed to be modifications of + this License.) + +7. DISCLAIMER OF WARRANTY. + + COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF + DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. + THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE + IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, + YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE + COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER + OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF + ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +8. TERMINATION. + + 8.1. This License and the rights granted hereunder will terminate + automatically if You fail to comply with terms herein and fail to cure + such breach within 30 days of becoming aware of the breach. All + sublicenses to the Covered Code which are properly granted shall + survive any termination of this License. Provisions which, by their + nature, must remain in effect beyond the termination of this License + shall survive. + + 8.2. If You initiate litigation by asserting a patent infringement + claim (excluding declatory judgment actions) against Initial Developer + or a Contributor (the Initial Developer or Contributor against whom + You file such action is referred to as "Participant") alleging that: + + (a) such Participant's Contributor Version directly or indirectly + infringes any patent, then any and all rights granted by such + Participant to You under Sections 2.1 and/or 2.2 of this License + shall, upon 60 days notice from Participant terminate prospectively, + unless if within 60 days after receipt of notice You either: (i) + agree in writing to pay Participant a mutually agreeable reasonable + royalty for Your past and future use of Modifications made by such + Participant, or (ii) withdraw Your litigation claim with respect to + the Contributor Version against such Participant. If within 60 days + of notice, a reasonable royalty and payment arrangement are not + mutually agreed upon in writing by the parties or the litigation claim + is not withdrawn, the rights granted by Participant to You under + Sections 2.1 and/or 2.2 automatically terminate at the expiration of + the 60 day notice period specified above. + + (b) any software, hardware, or device, other than such Participant's + Contributor Version, directly or indirectly infringes any patent, then + any rights granted to You by such Participant under Sections 2.1(b) + and 2.2(b) are revoked effective as of the date You first made, used, + sold, distributed, or had made, Modifications made by that + Participant. + + 8.3. If You assert a patent infringement claim against Participant + alleging that such Participant's Contributor Version directly or + indirectly infringes any patent where such claim is resolved (such as + by license or settlement) prior to the initiation of patent + infringement litigation, then the reasonable value of the licenses + granted by such Participant under Sections 2.1 or 2.2 shall be taken + into account in determining the amount or value of any payment or + license. + + 8.4. In the event of termination under Sections 8.1 or 8.2 above, + all end user license agreements (excluding distributors and resellers) + which have been validly granted by You or any distributor hereunder + prior to termination shall survive termination. + +9. LIMITATION OF LIABILITY. + + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT + (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL + DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, + OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR + ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY + CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, + WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER + COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN + INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF + LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY + RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW + PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE + EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO + THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + +10. U.S. GOVERNMENT END USERS. + + The Covered Code is a "commercial item," as that term is defined in + 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer + software" and "commercial computer software documentation," as such + terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 + C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), + all U.S. Government End Users acquire Covered Code with only those + rights set forth herein. + +11. MISCELLANEOUS. + + This License represents the complete agreement concerning subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. This License shall be governed by + California law provisions (except to the extent applicable law, if + any, provides otherwise), excluding its conflict-of-law provisions. + With respect to disputes in which at least one party is a citizen of, + or an entity chartered or registered to do business in the United + States of America, any litigation relating to this License shall be + subject to the jurisdiction of the Federal Courts of the Northern + District of California, with venue lying in Santa Clara County, + California, with the losing party responsible for costs, including + without limitation, court costs and reasonable attorneys' fees and + expenses. The application of the United Nations Convention on + Contracts for the International Sale of Goods is expressly excluded. + Any law or regulation which provides that the language of a contract + shall be construed against the drafter shall not apply to this + License. + +12. RESPONSIBILITY FOR CLAIMS. + + As between Initial Developer and the Contributors, each party is + responsible for claims and damages arising, directly or indirectly, + out of its utilization of rights under this License and You agree to + work with Initial Developer and Contributors to distribute such + responsibility on an equitable basis. Nothing herein is intended or + shall be deemed to constitute any admission of liability. + +13. MULTIPLE-LICENSED CODE. + + Initial Developer may designate portions of the Covered Code as + "Multiple-Licensed". "Multiple-Licensed" means that the Initial + Developer permits you to utilize portions of the Covered Code under + Your choice of the MPL or the alternative licenses, if any, specified + by the Initial Developer in the file described in Exhibit A. -http://www.apache.org/licenses/LICENSE-2.0 +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. -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. +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 dev-support/bin/create-release dev-support/bin/create-release index 64bd02a..b7441c0 100755 --- dev-support/bin/create-release +++ dev-support/bin/create-release @@ -530,7 +530,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 dev-support/docker/Dockerfile dev-support/docker/Dockerfile index c5bcba9..1b402ec 100644 --- dev-support/docker/Dockerfile +++ dev-support/docker/Dockerfile @@ -128,6 +128,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 hadoop-assemblies/src/main/resources/assemblies/hadoop-yarn-dist.xml hadoop-assemblies/src/main/resources/assemblies/hadoop-yarn-dist.xml index 0080112..977029b 100644 --- hadoop-assemblies/src/main/resources/assemblies/hadoop-yarn-dist.xml +++ hadoop-assemblies/src/main/resources/assemblies/hadoop-yarn-dist.xml @@ -187,6 +187,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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java index 4422f57..6c3d0be 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java @@ -288,7 +288,17 @@ 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 YARN_WEBAPP_UI2_ENABLE = "yarn." + + "webapp.ui2.enable"; + public static final boolean DEFAULT_YARN_WEBAPP_UI2_ENABLE = false; + + public static final String YARN_WEBAPP_UI2_WARFILE_PATH = "yarn." + + "webapp.ui2.war-file-path"; + 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/webapp/WebApps.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/webapp/WebApps.java index 9c96339..0dc6354 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/webapp/WebApps.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/webapp/WebApps.java @@ -44,6 +44,7 @@ import org.apache.hadoop.security.http.XFrameOptionsFilter; import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.hadoop.yarn.webapp.util.WebAppUtils; +import org.mortbay.jetty.webapp.WebAppContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -393,8 +394,15 @@ public WebApp start() { } public WebApp start(WebApp webapp) { + return start(webapp, null); + } + + public WebApp start(WebApp webapp, WebAppContext ui2Context) { WebApp webApp = build(webapp); HttpServer2 httpServer = webApp.httpServer(); + if (ui2Context != null) { + httpServer.addContext(ui2Context, true); + } try { httpServer.start(); LOG.info("Web app " + name + " started at " diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml index 8ba9ff9..baf6e99 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml @@ -198,6 +198,20 @@ + To enable RM web ui2 application. + yarn.webapp.ui2.enable + false + + + + + Explicitly provide WAR file path for ui2 if needed. + + yarn.webapp.ui2.war-file-path + + + + yarn.resourcemanager.resource-tracker.address ${yarn.resourcemanager.hostname}:8031 diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java index 2e3b3dd..b15526f 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java +++ 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; @@ -39,6 +29,10 @@ import org.apache.hadoop.metrics2.MetricsSystem; import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem; import org.apache.hadoop.metrics2.source.JvmMetrics; +import org.apache.hadoop.http.HttpServer2; +import org.apache.hadoop.http.lib.StaticUserWebFilter; +import org.apache.hadoop.net.NetUtils; +import org.apache.hadoop.security.AuthenticationFilterInitializer; import org.apache.hadoop.security.Groups; import org.apache.hadoop.security.SecurityUtil; import org.apache.hadoop.security.UserGroupInformation; @@ -52,6 +46,8 @@ import org.apache.hadoop.util.ShutdownHookManager; import org.apache.hadoop.util.StringUtils; import org.apache.hadoop.util.curator.ZKCuratorManager; +import org.apache.hadoop.util.VersionInfo; +import org.apache.hadoop.util.ZKUtil; import org.apache.hadoop.yarn.YarnUncaughtExceptionHandler; import org.apache.hadoop.yarn.api.records.ApplicationAttemptId; import org.apache.hadoop.yarn.api.records.ApplicationId; @@ -115,9 +111,22 @@ import org.apache.hadoop.yarn.webapp.WebApps.Builder; import org.apache.hadoop.yarn.webapp.util.WebAppUtils; import org.apache.zookeeper.server.auth.DigestAuthenticationProvider; +import org.mortbay.jetty.webapp.WebAppContext; import java.util.concurrent.atomic.AtomicBoolean; 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.net.URL; +import java.net.URLClassLoader; +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. @@ -140,6 +149,11 @@ private static final Log LOG = LogFactory.getLog(ResourceManager.class); private static long clusterTimeStamp = System.currentTimeMillis(); + /* + * UI2 webapp name + */ + public static final String UI2_WEBAPP_NAME = "/ui2"; + /** * "Always On" services. Services that need to run always irrespective of * the HA state of the RM. @@ -981,7 +995,35 @@ 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 startWepApp() { Configuration conf = getConfig(); @@ -1014,9 +1056,36 @@ protected void startWepApp() { builder.withAttribute(WebAppProxy.FETCHER_ATTRIBUTE, fetcher); String[] proxyParts = proxyHostAndPort.split(":"); builder.withAttribute(WebAppProxy.PROXY_HOST_ATTRIBUTE, proxyParts[0]); + } + + WebAppContext uiWebAppContext = null; + if (getConfig().getBoolean(YarnConfiguration.YARN_WEBAPP_UI2_ENABLE, + YarnConfiguration.DEFAULT_YARN_WEBAPP_UI2_ENABLE)) { + String webPath = UI2_WEBAPP_NAME; + String onDiskPath = getConfig() + .get(YarnConfiguration.YARN_WEBAPP_UI2_WARFILE_PATH); + + if (null == onDiskPath) { + String war = "hadoop-yarn-ui-" + VersionInfo.getVersion() + ".war"; + URLClassLoader cl = (URLClassLoader) ClassLoader.getSystemClassLoader(); + URL url = cl.findResource(war); + + if (null == url) { + onDiskPath = ""; + } else { + onDiskPath = url.getFile(); + } + LOG.info( + "New web UI war file name:" + war + ", and path:" + onDiskPath); + } + + uiWebAppContext = new WebAppContext(); + uiWebAppContext.setContextPath(webPath); + uiWebAppContext.setWar(onDiskPath); } - webApp = builder.start(new RMWebApp(this)); + + webApp = builder.start(new RMWebApp(this), uiWebAppContext); } /** diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/YarnUI2.md hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/YarnUI2.md new file mode 100644 index 0000000..609ebe1 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/YarnUI2.md @@ -0,0 +1,55 @@ + + +Hadoop: YARN-UI V2 +================= + +Prerequisites +------------- +Please make sure Hadoop is built by passing -Pyarn-ui to Maven (reference to BUILDING.txt for more details) + +Configurations +------------- + +*In `yarn-site.xml`* + +| Configuration Property | Description | +|:---- |:---- | +| `yarn.webapp.ui2.enable` | *(Required)* In the server side it indicates whether the new YARN-UI v2 is enabled or not. Defaults to `false`. | +| `yarn.webapp.ui2.war-file-path` | *(Optional)* WAR file path for launching yarn UI2 web application. By default this is empty and YARN will lookup required war file from classpath | + +Please note that, If you run YARN daemons locally in your machine for test purpose, +you need the following configurations added to `yarn-site.xml` to enable cross +origin (CORS) support. + +| Configuration Property | Value | Description | +|:---- |:---- |:---- | +| `yarn.timeline-service.http-cross-origin.enabled` | true | Enable CORS support for Timeline Server | +| `yarn.resourcemanager.webapp.cross-origin.enabled` | true | Enable CORS support for Resource Manager | +| `yarn.nodemanager.webapp.cross-origin.enabled` | true | Enable CORS support for Node Manager | + +Also please ensure that CORS related configurations are enabled in `core-site.xml`. +Kindly refer [here](https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/HttpAuthentication.html) + +Use it +------------- +Open your browser, go to `rm-address:8088/ui2` and try it! + +Notes +------------- + +- This UI framework is not verified under security environment, please use with caution under security environment. diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/pom.xml hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/pom.xml new file mode 100644 index 0000000..5f6eda9 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/pom.xml @@ -0,0 +1,193 @@ + + + + + hadoop-yarn + org.apache.hadoop + 2.9.0-SNAPSHOT + + 4.0.0 + org.apache.hadoop + hadoop-yarn-ui + 2.9.0-SNAPSHOT + Apache Hadoop YARN UI + ${packaging.type} + + + pom + ${basedir}/target/src/main/webapp + node + v0.12.2 + 2.10.0 + false + + + + + + + org.apache.rat + apache-rat-plugin + + + src/main/webapp/jsconfig.json + src/main/webapp/bower.json + src/main/webapp/package.json + src/main/webapp/testem.json + src/main/webapp/public/assets/images/**/* + src/main/webapp/public/assets/images/* + src/main/webapp/public/robots.txt + public/crossdomain.xml + src/main/webapp/.bowerrc + src/main/webapp/.ember-cli + src/main/webapp/.jshintrc + src/main/webapp/.watchmanconfig + + + + + + maven-clean-plugin + 3.0.0 + + ${keep-ui-build-cache} + false + + + ${webappTgtDir}/bower_components + + + ${webappTgtDir}/node_modules + + + + + + + + + + yarn-ui + + + false + + + + war + + + + + + + org.apache.maven.plugins + maven-antrun-plugin + + + prepare-source-code + generate-sources + + run + + + + + + + + + + + + + + + + + + + + exec-maven-plugin + org.codehaus.mojo + + + generate-sources + npm install + + exec + + + ${webappTgtDir} + npm + + install + + + + + generate-sources + bower install + + exec + + + ${webappTgtDir} + bower + + --allow-root + install + + + + + ember build + generate-sources + + exec + + + ${webappTgtDir} + ember + + build + -prod + --output-path + ${basedir}/target/dist + + + + + + + + + org.apache.maven.plugins + maven-war-plugin + + ${basedir}/src/main/webapp/WEB-INF/web.xml + ${basedir}/target/dist + + + + + + + + diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/public/crossdomain.xml hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/public/crossdomain.xml new file mode 100644 index 0000000..0c16a7a --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/public/crossdomain.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/.bowerrc hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/.bowerrc new file mode 100644 index 0000000..959e169 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/.bowerrc @@ -0,0 +1,4 @@ +{ + "directory": "bower_components", + "analytics": false +} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/.ember-cli hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/.ember-cli new file mode 100644 index 0000000..ee64cfe --- /dev/null +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/.jshintrc hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/.jshintrc new file mode 100644 index 0000000..08096ef --- /dev/null +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/.watchmanconfig hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/.watchmanconfig new file mode 100644 index 0000000..e7834e3 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/.watchmanconfig @@ -0,0 +1,3 @@ +{ + "ignore_dirs": ["tmp", "dist"] +} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/WEB-INF/web.xml hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..ddb8532 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,25 @@ + + + + + + YARN UI + diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/abstract.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/abstract.js new file mode 100644 index 0000000..c7e5c36 --- /dev/null +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/cluster-info.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/cluster-metric.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-app-attempt.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-app.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-app.js new file mode 100644 index 0000000..67a2847 --- /dev/null +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-container-log.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-container.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-node-app.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-node-app.js new file mode 100644 index 0000000..6d69828 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-node-app.js @@ -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. + */ + +import AbstractAdapter from './abstract'; + +export default AbstractAdapter.extend({ + + address: "localBaseAddress", + restNameSpace: "node", + serverName: "NM", + + urlForQuery(query) { + var url = this._buildURL(); + url = url.replace("{nodeAddress}", query.nodeAddr) + "/apps"; + return url; + }, + + urlForQueryRecord: function (query) { + var url = this._buildURL(); + url = url.replace("{nodeAddress}", query.nodeAddr) + "/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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-node-container.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-node-container.js new file mode 100644 index 0000000..0fff047 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-node-container.js @@ -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. + */ + +import AbstractAdapter from './abstract'; + +export default AbstractAdapter.extend({ + + address: "localBaseAddress", + restNameSpace: "node", + serverName: "NM", + + urlForQuery(query) { + var url = this._buildURL(); + url = url.replace("{nodeAddress}", query.nodeHttpAddr) + "/containers"; + return url; + }, + + urlForQueryRecord(query) { + var url = this._buildURL(); + url = url.replace("{nodeAddress}", query.nodeHttpAddr) + "/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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-node.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-node.js new file mode 100644 index 0000000..5bcfc9a --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/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 AbstractAdapter from './abstract'; + +export default AbstractAdapter.extend({ + + address: "localBaseAddress", + restNameSpace: "node", + serverName: "NM", + + urlForFindRecord(id, modelName, snapshot) { + var url = this._buildURL(); + url = url.replace("{nodeAddress}", id); + return url; + }, + +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-queue.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-rm-node.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/app.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/app.js new file mode 100644 index 0000000..8c1025a --- /dev/null +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-attempt-table.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-table.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-usage-donut-chart.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/bar-chart.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/base-chart-component.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/base-usage-donut-chart.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/breadcrumb-bar.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/container-table.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/donut-chart.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/item-selector.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/nodes-heatmap.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/per-app-memusage-by-nodes-stacked-barchart.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/per-app-ncontainers-by-nodes-stacked-barchart.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-configuration-table.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-navigator.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-usage-donut-chart.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-view.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/simple-table.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/stacked-barchart.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/timeline-view.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/tree-selector.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/config.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/config.js new file mode 100644 index 0000000..157d48b --- /dev/null +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/constants.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/constants.js new file mode 100644 index 0000000..d2937a0 --- /dev/null +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/application.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/application.js new file mode 100644 index 0000000..2effb13 --- /dev/null +++ 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 = 'Queues' + + '(current)Applications' + + '(current)Cluster Overview(current)Nodes' + + '(current)'; + return Ember.String.htmlSafe(html); + }.property('currentPath') +}); + diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/cluster-overview.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app-attempt.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app-attempts.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app.js new file mode 100644 index 0000000..309c895 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app.js @@ -0,0 +1,45 @@ +/** + * 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 + }]; + }), + + amHostHttpAddressFormatted: function() { + var amHostAddress = this.get('model.app.amHostHttpAddress'); + if (amHostAddress.indexOf('http://') < 0) { + amHostAddress = 'http://' + amHostAddress; + } + return amHostAddress; + }.property('model.app.amHostHttpAddress') +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-apps.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-container-log.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node-app.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node-apps.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node-apps.js new file mode 100644 index 0000000..6e67ab0 --- /dev/null +++ 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.table' + }, { + text: `Node [ ${nodeInfo.id} ]`, + href: `/#/yarn-node/${nodeInfo.id}/${nodeInfo.addr}`, + }, { + text: "Applications", + }]; + }) + +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node-containers.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node-containers.js new file mode 100644 index 0000000..abe4098 --- /dev/null +++ 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.table' + }, { + text: `Node [ ${nodeInfo.id} ]`, + href: `/#/yarn-node/${nodeInfo.id}/${nodeInfo.addr}`, + }, { + text: "Containers", + }]; + }) + +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node.js new file mode 100644 index 0000000..0661415 --- /dev/null +++ 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.table' + }, { + text: `Node [ ${nodeInfo.id} ]`, + href: `/#/yarn-node/${nodeInfo.id}/${nodeInfo.addr}`, + }]; + }) + +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-nodes-heatmap.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-nodes-heatmap.js new file mode 100644 index 0000000..a38d8c5 --- /dev/null +++ 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.table', + }, { + text: "Heatmap", + routeName: 'yarn-nodes-heatmap', + }] + +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-nodes.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-nodes.js new file mode 100644 index 0000000..24f9550 --- /dev/null +++ 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.table', + }] + +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queue-apps.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queue.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-queues.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-services.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/helpers/divide.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/helpers/divide.js new file mode 100644 index 0000000..fcf64dd --- /dev/null +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/helpers/log-files-comma.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/helpers/node-link.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/helpers/node-menu.js 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 +++ 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 = '
'+ + '

Node Manager
(' + normalizedNodeId + ')

'+ + ''; + return Ember.String.htmlSafe(html); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/helpers/node-name.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/index.html hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/index.html new file mode 100644 index 0000000..f727454 --- /dev/null +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/initializers/env.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/initializers/env.js new file mode 100644 index 0000000..c613593 --- /dev/null +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/initializers/hosts.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/initializers/hosts.js new file mode 100644 index 0000000..6e3aa96 --- /dev/null +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/initializers/loader.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/initializers/loader.js new file mode 100644 index 0000000..08e4dbd --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/initializers/loader.js @@ -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. + */ + + +function getTimeLineURL(parameters) { + return '/conf?name=yarn.timeline-service.webapp.address'; +} + +function updateConfigs(application) { + var hostname = window.location.hostname; + var rmhost = hostname + + (window.location.port ? ':' + window.location.port: ''); + + Ember.Logger.log("RM Address:" + rmhost); + + if(!ENV.hosts.rmWebAddress) { + ENV = { + hosts: { + rmWebAddress: rmhost, + }, + }; + } + + if(!ENV.hosts.timelineWebAddress) { + var result = []; + var timelinehost = ""; + $.ajax({ + type: 'GET', + dataType: 'json', + async: true, + context: this, + url: getTimeLineURL(), + success: function(data) { + timelinehost = data.property.value; + ENV.hosts.timelineWebAddress = timelinehost; + + var address = timelinehost.split(":")[0]; + var port = timelinehost.split(":")[1]; + + Ember.Logger.log("Timeline Address from RM:" + address + ":" + port); + + if(address == "0.0.0.0" || address == "localhost") { + var updatedAddress = hostname + ":" + port; + + /* Timeline v2 is not supporting CORS, so make as default*/ + ENV = { + hosts: { + rmWebAddress: rmhost, + timelineWebAddress: updatedAddress, + }, + }; + Ember.Logger.log("Timeline Updated Address:" + updatedAddress); + } + application.advanceReadiness(); + }, + }); + } else { + application.advanceReadiness(); + } +} + +export function initialize( application ) { + application.deferReadiness(); + updateConfigs(application); +} + +export default { + name: 'loader', + before: 'env', + initialize +}; diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/cluster-info.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/cluster-metric.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-app-attempt.js 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 +++ 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 "

Id:" + this.get("id") + + "

ElapsedTime:" + + String(this.get("elapsedTime")) + "

"; + }.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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-app.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-app.js new file mode 100644 index 0000000..8b5474f --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-app.js @@ -0,0 +1,104 @@ +/** + * 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 finalStatus = this.get("finalStatus"); + var style = ""; + + if (finalStatus == "KILLED") { + style = "warning"; + } else if (finalStatus == "FAILED") { + style = "danger"; + } else if (finalStatus == "SUCCEEDED") { + style = "success"; + } else { + style = "default"; + } + + return "label label-" + style; + }.property("finalStatus") +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-container-log.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-container.js 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 +++ 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 "

Id:" + this.get("id") + + "

ElapsedTime:" + + String(this.get("elapsedTime")) + "

"; + }.property(), +}); \ No newline at end of file diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-node-app.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-node-container.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-node.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-queue.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-rm-node.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-user.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/router.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/router.js new file mode 100644 index 0000000..87a018d --- /dev/null +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/abstract.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/abstract.js new file mode 100644 index 0000000..3163237 --- /dev/null +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/application.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/application.js new file mode 100644 index 0000000..07b3792 --- /dev/null +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/cluster-overview.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/index.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/index.js new file mode 100644 index 0000000..af26670 --- /dev/null +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app-attempt.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app-attempts.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-apps.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-apps/apps.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-apps/services.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-container-log.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-node-app.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-node-apps.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-node-container.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-node-containers.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-node.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-nodes.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-nodes/heatmap.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-nodes/table.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-queue-apps.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-queue.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-queues.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-queues/index.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-queues/queues-selector.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/cluster-info.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/cluster-metric.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-app-attempt.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-app.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-container-log.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-container.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-node-app.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-node-app.js new file mode 100644 index 0000000..3dfd776 --- /dev/null +++ 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 && payload.apps.app) { + 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-node-container.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-node-container.js new file mode 100644 index 0000000..bf19ad7 --- /dev/null +++ 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.containers.container) { + // 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-node.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-queue.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-rm-node.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/services/env.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/services/env.js new file mode 100644 index 0000000..208499c --- /dev/null +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/services/hosts.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/services/hosts.js new file mode 100644 index 0000000..19863e1 --- /dev/null +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/styles/app.css hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/styles/app.css new file mode 100644 index 0000000..da5b4bf --- /dev/null +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/application.hbs hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/application.hbs new file mode 100644 index 0000000..7783db4 --- /dev/null +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/cluster-overview.hbs 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 +++ 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}} + +
+
+
+
+
+ Cluster Resource Usage By Applications +
+
+ {{app-usage-donut-chart data=model.apps + showLabels=true + parentId="appusage-donut-chart" + ratio=0.6 + maxHeight=400}} +
+
+
+ +
+
+
+ Cluster Resource Usage By Leaf Queues +
+
+ {{queue-usage-donut-chart data=model.queues + showLabels=true + parentId="queueusage-donut-chart" + ratio=0.6 + maxHeight=400}} +
+
+
+
+
+ +
+
+
+
+ Finished Apps +
+
+ {{donut-chart data=model.clusterMetrics.firstObject.getFinishedAppsDataForDonutChart + showLabels=true + parentId="finishedapps-donut-chart" + ratio=0.6 + maxHeight=350 + colorTargets="good warn error"}} +
+
+
+ +
+
+
+ Running Apps +
+
+ {{donut-chart data=model.clusterMetrics.firstObject.getRunningAppsDataForDonutChart + showLabels=true + parentId="runningapps-donut-chart" + ratio=0.6 + maxHeight=350 + colorTargets="warn good"}} +
+
+
+ +
+
+
+ Node Managers +
+
+ {{donut-chart data=model.clusterMetrics.firstObject.getNodesDataForDonutChart + showLabels=true + parentId="nodes-donut-chart" + ratio=0.6 + maxHeight=350 + colorTargets="good error warn"}} +
+
+
+
+ +
+
+ +
+
+
+ Resource - Memory +
+
+ {{donut-chart data=model.clusterMetrics.firstObject.getMemoryDataForDonutChart + showLabels=true + parentId="mem-donut-chart" + ratio=0.6 + maxHeight=350 + colorTargets="good" + colorTargetReverse=true + type="memory"}} +
+
+
+ +
+
+
+ Resource - VCores +
+
+ {{donut-chart data=model.clusterMetrics.firstObject.getVCoreDataForDonutChart + showLabels=true + parentId="vcore-donut-chart" + ratio=0.6 + maxHeight=350 + colorTargets="good" + colorTargetReverse=true}} +
+
+
+
+
+ +{{/if}} + + +{{outlet}} \ No newline at end of file diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/app-attempt-table.hbs 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 +++ 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. +}} + + + + + + + + + + + + + + + + {{#if attempt.IsAmNodeUrl}} + + + + + {{/if}} + + + + + {{#if attempt.IsLinkAvailable}} + + + + + {{/if}} + {{#if attempt.attemptState}} + + + + + {{/if}} + {{#if attempt.elapsedTime}} + + + + + {{/if}} + +
Application Attempt Id{{attempt.id}}
Start Time{{attempt.attemptStartedTime}}
AM Container Id{{attempt.appMasterContainerId}}
AM Node Web UI{{attempt.nodeHttpAddress}}
AM Node Id{{attempt.amNodeId}}
Loglink
Attempt State{{attempt.attemptState}}
Elapsed Time{{attempt.elapsedTime}}
\ No newline at end of file diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/app-table.hbs 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 +++ 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. +}} + + + + + + + + + + + + + + + + + + + + + {{#if arr}} + {{#each arr as |app|}} + + + + + + + + + + + + + + + + {{/each}} + {{else}} + + + + + + + + + + + + + + + + {{/if}} + +
Application IDApplication TypeNameUserQueueStateFinal StatusStart TimeElapsed Time Finished TimePriorityProgress%Cluster
{{app.id}}{{app.applicationType}}{{app.appName}}{{app.user}}{{app.queue}}{{app.state}}{{app.finalStatus}}{{app.startTime}}{{app.elapsedTime}}{{app.validatedFinishedTs}}{{app.priority}} +
+
+ {{app.progress}}% +
+
+
{{app.clusterUsagePercentage}}
{{app.id}}{{app.applicationType}}{{app.appName}}{{app.user}}{{app.queue}}{{app.state}}{{app.finalStatus}}{{app.startTime}}{{app.elapsedTime}}{{app.validatedFinishedTs}}{{app.priority}} +
+
+ {{app.progress}}% +
+
+
{{app.clusterUsagePercentage}}
\ No newline at end of file diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/breadcrumb-bar.hbs 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 +++ 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. +}} + + diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/container-table.hbs 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 +++ 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. +}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Start Time{{container.startedTime}}
Finished Time{{container.validatedFinishedTs}}
Elapsed Time{{container.elapsedTime}}
Priority{{container.priority}}
Loglink
Exit Status{{container.containerExitStatus}}
State{{container.containerState}}
NodeManager UI{{container.nodeHttpAddress}}
\ No newline at end of file diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/node-menu-panel.hbs 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 +++ 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. +}} + +
+
+
+

Node Manager

+
+
+ +
+
+
+{{outlet}} \ No newline at end of file diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/nodes-heatmap.hbs 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/queue-configuration-table.hbs 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 +++ 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. +}} + + + + + + + + + + + + + + + + + + + + + + {{#if queue.isLeafQueue}} + + + + + + + + + + + + + {{/if}} + +
ConfigurationsValue
Configured Capacity{{queue.capacity}}
Configured Max Capacity{{queue.maxCapacity}}
State{{queue.state}}
User Limit Percent{{queue.userLimit}}
User Limit Factor{{queue.userLimitFactor}}
Preemption Disabled{{queue.preemptionDisabled}}
\ No newline at end of file diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/queue-navigator.hbs 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 +++ 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. +}} + + +

+
+
+ {{tree-selector model=model parentId="tree-selector-container" selected=selected}} +
+
+
+ +{{outlet}} \ No newline at end of file diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/timeline-view.hbs 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 +++ 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. +}} + +
+
+
+ {{#if attemptModel}} + Application Attempts + {{else}} + Containers + {{/if}} +
+
+

+
+
+ + +
+
+
+ {{#if selected.link}} + {{#link-to selected.linkname selected.id}}{{selected.id}}{{/link-to}} + {{else}} + {{selected.id}} + {{/if}} +
+ {{#if attemptModel}} + {{app-attempt-table attempt=selected}} + {{else}} + {{container-table container=selected}} + {{/if}} +
+
+
+
+
+ +{{outlet}} \ No newline at end of file diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/error.hbs hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/error.hbs new file mode 100644 index 0000000..2e2a6e5 --- /dev/null +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/notfound.hbs hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/notfound.hbs new file mode 100644 index 0000000..588ea44 --- /dev/null +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-app-attempt.hbs 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 +++ 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}} +


+
+
+ {{#if model.attempt}} +
+
+
+ Application attempt Information +
+ {{app-attempt-table attempt=model.attempt}} +
+
+ {{/if}} +
+ + +
+ {{#if (or model.rmContainers model.tsContainers)}} + {{timeline-view parent-id="containers-timeline-div" my-id="timeline-view" height="400" rmModel=model.rmContainers tsModel=model.tsContainers label="shortAppAttemptId" attemptModel=false}} + {{/if}} +
+
+ +{{outlet}} \ No newline at end of file diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-app-attempts.hbs 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 +++ 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}} + +
+
+ +
+
+
+

Application

+
+
+ +
+
+
+ +
+ +
+ {{timeline-view parent-id="attempt-timeline-div" my-id="timeline-view" height="100%" rmModel=model.attempts label="shortAppAttemptId" attemptModel=true}} +
+
+ +
+
+{{outlet}} \ No newline at end of file diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-app.hbs hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-app.hbs new file mode 100644 index 0000000..acf00d1 --- /dev/null +++ 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}} +
+
+ +
+
+
+

Application

+
+
+ +
+
+
+ +
+
+
+
+
Basic Info
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Application IDNameUserQueueStateFinal StatusStart TimeElapsed TimeFinished TimePriorityProgressIs Unmanaged AM
{{model.app.id}}{{model.app.appName}}{{model.app.user}}{{model.app.queue}}{{model.app.state}} + + {{model.app.finalStatus}} + + {{model.app.startTime}}{{model.app.elapsedTime}}{{model.app.validatedFinishedTs}}{{model.app.priority}} +
+
+ {{model.app.progress}}% +
+
+
{{model.app.unmanagedApplication}}
+
+
+
+
+ +
+ {{#if model.app.diagnostics}} +
+ {{#if model.app.isFailed}} +
+
+ Diagnostics +
+
{{model.app.diagnostics}}
+
+ {{else}} +
+
+ Diagnostics +
+ +
+ {{/if}} +
+ {{/if}} +
+ +
+
+
+
Scheduling Info
+ + + + + + + + + + + + + + + + + + + + + + +
Allocated ResourceRunning ContainersPreempted ResourceNum Non-AM container preemptedNum AM container preemptedAggregated Resource Usage
{{model.app.allocatedResource}}{{model.app.runningContainersNumber}}{{model.app.preemptedResource}}{{model.app.numAMContainerPreempted}}{{model.app.numAMContainerPreempted}}{{model.app.aggregatedResourceUsage}}
+
+
+ +
+
+
App Master Info
+ + + + + + + + + + + + + + + + +
Master Container LogMaster NodeMaster Node Label Expr
LinkLink{{model.app.amNodeLabelExpression}}
+
+
+
+ + {{#if model.nodes}} + {{#if model.rmContainers}} +
+ {{per-app-memusage-by-nodes-stacked-barchart + nodes=model.nodes + rmContainers=model.rmContainers + parentId="stackd-bar-chart-mem" + title=(concat 'Memory usage by nodes for: [' model.app.id ']')}} +
+ +
+ +
+ {{per-app-ncontainers-by-nodes-stacked-barchart + nodes=model.nodes + rmContainers=model.rmContainers + parentId="stackd-bar-chart-ncontainer" + title=(concat 'Running #Containers by nodes for: [' model.app.id ']')}} +
+ {{/if}} + {{/if}} + + +
+ + + + + +
+
+{{/if}} +{{outlet}} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps.hbs 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 +++ 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}} + +
+
+ +
+
+
+

Application

+
+
+ +
+
+
+ +
+ {{#if model.clusterMetrics}} +
+
+
+
+ Finished Apps +
+
+ {{donut-chart data=model.clusterMetrics.firstObject.getFinishedAppsDataForDonutChart + showLabels=true + parentId="finishedapps-donut-chart" + ratio=0.6 + maxHeight=350 + colorTargets="good warn error" + }} +
+
+
+ +
+
+
+ Running Apps +
+
+ {{donut-chart data=model.clusterMetrics.firstObject.getRunningAppsDataForDonutChart + showLabels=true + parentId="runningapps-donut-chart" + ratio=0.6 + maxHeight=350 + colorTargets="warn good" + }} +
+
+
+
+ {{/if}} + +
+ {{outlet}} +
+
+
+
\ No newline at end of file diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps/apps.hbs 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps/services.hbs 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-container-log.hbs 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 +++ 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}} + +
+ {{node-menu path="yarn-container-log" nodeAddr=model.nodeInfo.addr nodeId=model.nodeInfo.id}} +
+
+
+
{{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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-node-app.hbs 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 +++ 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}} + +
+
+ {{node-menu-panel path="yarn-node-app" nodeAddr=model.nodeInfo.addr nodeId=model.nodeInfo.id}} +
+
+
Application Information
+ + + + + + + + + + + + + + + +
Application ID{{model.nodeApp.appId}}
Application State{{model.nodeApp.state}}
User{{model.nodeApp.user}}
+
+ + + + + + + + {{#each model.nodeApp.containers as |container|}} + + + + {{/each}} + +
Containers for {{model.nodeApp.appId}}
{{container}}
+ {{simple-table table-id="node-app-table" bFilter=true colsOrder="0,desc" colTypes="natural" colTargets="0"}} +
+
+
+{{outlet}} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-node-apps.hbs 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 +++ 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}} + +
+
+ {{node-menu-panel path="yarn-node-apps" nodeAddr=model.nodeInfo.addr nodeId=model.nodeInfo.id}} + {{#if model.apps}} +
+ + + + + + + + + + {{#if model.apps}} + {{#each model.apps as |app|}} + + + + + + {{/each}} + {{/if}} + +
Application IDStateUser
{{app.appId}}{{app.state}}{{app.user}}
+ {{simple-table table-id="node-apps-table" bFilter=true colsOrder="0,desc" colTypes="natural" colTargets="0"}} +
+ {{else}} +

No apps found on this node

+ {{/if}} +
+
+{{outlet}} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-node-container.hbs 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 +++ 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}} + +
+
+ {{node-menu-panel path="yarn-node-container" nodeAddr=model.nodeInfo.addr nodeId=model.nodeInfo.id}} +
+
+
Container Information
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Container ID{{model.nodeContainer.containerId}}
Container State{{model.nodeContainer.state}}
Exit Code{{model.nodeContainer.exitCode}}
Diagnostics{{model.nodeContainer.diagnostics}}
User{{model.nodeContainer.user}}
Total Memory Needed{{model.nodeContainer.totalMemoryNeeded}} MB
Total VCores Needed{{model.nodeContainer.totalVCoresNeeded}}
Link to Logs + {{log-files-comma nodeId=model.nodeInfo.id + nodeAddr=model.nodeInfo.addr + containerId=model.nodeContainer.containerId + logFiles=model.nodeContainer.containerLogFiles}} +
+
+
+
+
+{{outlet}} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-node-containers.hbs 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 +++ 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}} + +
+
+ {{node-menu-panel path="yarn-node-containers" nodeAddr=model.nodeInfo.addr nodeId=model.nodeInfo.id}} + {{#if model.containers}} +
+ + + + + + + + + + + {{#if model.containers}} + {{#each model.containers as |container|}} + + + + + + + {{/each}} + {{/if}} + +
Container IDContainer StateUserLogs
{{container.containerId}}{{container.state}}{{container.user}} + {{log-files-comma nodeId=model.nodeInfo.id + nodeAddr=model.nodeInfo.addr + containerId=container.containerId + logFiles=container.containerLogFiles}} +
+ {{simple-table table-id="node-containers-table" bFilter=true colsOrder="0,desc" colTypes="natural" colTargets="0"}} +
+ {{else}} +

No containers found on this node

+ {{/if}} +
+
+{{outlet}} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-node.hbs hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-node.hbs new file mode 100644 index 0000000..b7f727a --- /dev/null +++ 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}} + +
+
+ + {{node-menu-panel path="yarn-node" nodeId=model.rmNode.id nodeAddr=model.node.id}} + +
+ +
+
+
+
Node Information
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Total Vmem allocated for Containers{{divide num=model.node.totalVmemAllocatedContainersMB den=1024}} GB
Vmem enforcement enabled{{model.node.vmemCheckEnabled}}
Total Pmem allocated for Containers{{divide num=model.node.totalPmemAllocatedContainersMB den=1024}} GB
Pmem enforcement enabled{{model.node.pmemCheckEnabled}}
Total VCores allocated for Containers{{model.node.totalVCoresAllocatedContainers}}
Node Healthy Status{{model.node.nodeHealthy}}
Last Node Health Report Time{{model.node.lastNodeUpdateTime}}
Node Health Report{{model.node.healthReport}}
Node Manager Start Time{{model.node.nmStartupTime}}
Node Manager Version{{model.node.nodeManagerBuildVersion}}
Hadoop Version{{model.node.hadoopBuildVersion}}
+
+
+
+ +
+
+
+
+ Resource - Memory (in MB) +
+
+ {{donut-chart data=model.rmNode.getMemoryDataForDonutChart + showLabels=true + parentId="mem-donut-chart" + ratio=0.6 + maxHeight=350}} +
+
+
+ +
+
+
+ Resource - VCores +
+
+ {{donut-chart data=model.rmNode.getVCoreDataForDonutChart + showLabels=true + parentId="vcore-donut-chart" + ratio=0.6 + maxHeight=350}} +
+
+
+
+
+
+
+{{outlet}} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-nodes.hbs hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-nodes.hbs new file mode 100644 index 0000000..874b3c4 --- /dev/null +++ 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}} + +
+
+
+
+

Nodes

+
+
+ +
+
+
+ +
+ {{#if model.clusterMetrics}} +
+
+
+
+ Node Managers +
+
+ {{donut-chart data=model.clusterMetrics.firstObject.getNodesDataForDonutChart + showLabels=true + parentId="nodes-donut-chart" + ratio=0.6 + maxHeight=350 + colorTargets="good error warn"}} +
+
+
+
+ {{/if}} + + {{outlet}} +
+
diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-nodes/heatmap.hbs 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 +++ 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}} + +
+
+ {{nodes-heatmap model=model.nodes parentId="nodes-heatmap-chart" + title="Node Heatmap Chart (Usage of Memory)"}} +
+
+ +{{/if}} + +{{outlet}} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-nodes/table.hbs 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 +++ 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. +--}} +
+ + {{#if model.nodes}} + + + + + + + + + + + + + + + + + + + + {{#each model.nodes as |node|}} + + + + + + {{node-link nodeId=node.id nodeHTTPAddress=node.nodeHTTPAddress nodeState=node.state}} + + + + + + + + + + {{/each}} + +
Node LabelsRackNode StateNode AddressNode HTTP AddressLast Health UpdateHealth-ReportContainersMem UsedMem AvailVCores UsedVCores AvailVersion
{{node.nodeLabelsAsString}}{{node.rack}}{{node.state}}{{node.id}}{{node.lastHealthUpdate}}{{node.healthReport}}{{node.numContainers}}{{divide num=node.usedMemoryMB den=1024}} GB{{divide num=node.availMemoryMB den=1024}} GB{{node.usedVirtualCores}}{{node.availableVirtualCores}}{{node.version}}
+ + {{simple-table table-id="nodes-table" bFilter=true}} + {{else}} +

No nodes found on this cluster

+ {{/if}} +
+ +{{outlet}} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-queue-apps.hbs 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 +++ 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}} + +
+
+ +
+
+
+

Application

+
+
+ +
+
+
+ +
+ +
+ +
+ {{#if model.apps}} + {{app-table table-id="apps-table" arr=model.apps}} + {{simple-table table-id="apps-table" bFilter=true colTypes="elapsed-time" colTargets="7"}} + {{else}} +

Could not find any applications from this cluster

+ {{/if}} +
+ +
+
+ +
+
+{{outlet}} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-queue.hbs 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 +++ 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}} + +
+
+ +
+
+
+

Application

+
+
+ +
+
+
+ +
+ +
+ +
+
+
+ Queue Information +
+ {{queue-configuration-table queue=model.selectedQueue}} +
+
+ +
+
+
+ Queue Capacities +
+
+
+ {{bar-chart data=model.selectedQueue.capacitiesBarChartData + title="" + parentId="capacity-bar-chart" + textWidth=170 + ratio=0.55 + maxHeight=350}} +
+
+
+ + {{#if model.selectedQueue.hasUserUsages}} +
+ {{donut-chart data=model.selectedQueue.userUsagesDonutChartData + title="User Usages" + showLabels=true + parentId="userusage-donut-chart" + type="memory" + ratio=0.6 + maxHeight=350}} +
+ {{/if}} + +
+
+
+ Running Apps +
+
+ {{donut-chart data=model.selectedQueue.numOfApplicationsDonutChartData + showLabels=true + parentId="numapplications-donut-chart" + ratio=0.6 + maxHeight=350}} +
+
+
+ +
+
+ +
+
+{{outlet}} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-queues.hbs 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 +++ 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}} + +
+ {{queue-navigator model=model.queues selected=model.selected}} + +
+ +
+
+
+ Queue Information +
+ {{queue-configuration-table queue=model.selectedQueue}} +
+
+ +
+
+
+ Queue Capacities +
+
+
+ {{bar-chart data=model.selectedQueue.capacitiesBarChartData + title="" + parentId="capacity-bar-chart" + textWidth=150 + ratio=0.55 + maxHeight=350}} +
+
+
+ +
+
+
+ Running Apps +
+
+ {{donut-chart data=model.selectedQueue.numOfApplicationsDonutChartData + showLabels=true + parentId="numapplications-donut-chart" + ratio=0.6 + maxHeight=350}} +
+
+
+ +
+
+ +{{outlet}} \ No newline at end of file diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/utils/color-utils.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/utils/converter.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/utils/converter.js new file mode 100644 index 0000000..6fd9d30 --- /dev/null +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/utils/href-address-utils.js 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 +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/utils/mock.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/utils/mock.js new file mode 100644 index 0000000..62eebc1 --- /dev/null +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/utils/sorter.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/utils/sorter.js new file mode 100644 index 0000000..febef6f --- /dev/null +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/bower.json hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/bower.json new file mode 100644 index 0000000..fe5f289 --- /dev/null +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/configs.env hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/configs.env new file mode 100644 index 0000000..04577c9 --- /dev/null +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/default-config.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/default-config.js new file mode 100644 index 0000000..70d4ebc --- /dev/null +++ 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: "", + timelineWebAddress: "localhost:8188", + rmWebAddress: "localhost:8088", + protocolScheme: "http:" + }, + namespaces: { + timeline: 'ws/v1/applicationhistory', + cluster: 'ws/v1/cluster', + metrics: 'ws/v1/cluster/metrics', + node: '{nodeAddress}/ws/v1/node' + }, +}; diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/environment.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/environment.js new file mode 100644 index 0000000..3c478be --- /dev/null +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/ember-cli-build.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/ember-cli-build.js new file mode 100644 index 0000000..7736c75 --- /dev/null +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/jsconfig.json hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/jsconfig.json new file mode 100644 index 0000000..875bb90 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/jsconfig.json @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "target": "ES6", + "module": "commonjs" + } +} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/package.json hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/package.json new file mode 100644 index 0000000..6a4eb16 --- /dev/null +++ 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 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/public/assets/images/datatables/Sorting icons.psd 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 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 Y16@Zf7?Q8!JB-NJ(KYBs*Ff|C0Zg4MIsgCw literal 0 HcmV?d00001 diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/public/assets/images/datatables/favicon.ico hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/public/assets/images/datatables/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..6eeaa2a0d393190ce748107222d9a026f992e4a7 GIT binary patch literal 894 zcmZQzU<5(|0R|u`!H~hsz#zuJz@P!dKp_SNAO?xUfG{@$0|>*weY}F;x;`B~@Mg`jC-vo5%k$%{OoKy1zkdA+(K2o3 zEDKGQQ~gcX+N!TtEj1|9e2tL(rheJva*5dKY#gZsIRxM zB;!h75Wi?9l5?>z>S-`t`=OAFp5C?(007k>qM(bnVuyja#;c*qL9N z(Q%=@`f7d2?T&^wySIHjy#MKh?rZrO7i!Bt-@f(!@WDrwB`uD&)%Eqcd3o(gVV7ri zp6ji@(BF7(+uE0x&)(R!?s#YIg_7JW1=-KHZv1@s(DSxD9<^am-%+f#!uU}z9=j>5*%b{WE2`20#tutPWS1# zz4s39d~xOMwaqJzOl{rMU%#oo=xj&xyY1WF&71o?Hs-LOkAD^4SRbV?yXz(e#efNwKXpT1J^s+yE;1`KXoe5&f?1A$tYso}un=1c3AzCL>B&D=RpqN3i1hL&lnclP!D`u*G0#bsJv!oAH) z-rc|T`^Wdkrw?7(xb)_p%`Y#WdAn`Pvz+W#0Rbo6-Ha3zp1gPgjDkZ)k6Gz!@9D0( zG^hL4?)Be4zWep#`{$>RUhUoaq@wgyfd9*oU{6tz+SXQhl3284sj;T&{L=I*bGxt4 z@4vfX%A<*$FN^a&MMa!}GOXuX|8Oj3tosHiJ3*4TN zC7>_x-r1O=t(?KoTC+`+>7&2GzdqLHBg&F)2Q?&EGZ+}|Rpsc~9`m>jw35No)z4*} HQ$iB}HK{Sd literal 0 HcmV?d00001 diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/public/assets/images/datatables/sort_asc_disabled.png hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/public/assets/images/datatables/sort_asc_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..fb11dfe24a6c564cb7ddf8bc96703ebb121df1e7 GIT binary patch literal 148 zcmeAS@N?(olHy`uVBq!ia0vp^!XV7S0wixl{&NRX(Vi}jAsXkC6BcOhI9!^3NY?Do zDX;f`c1`y6n0RgO@$!H7chZT&|Jn0dmaqO^XNm-CGtk!Ur<_=Jws3;%W$<+Mb6Mw<&;$T1GdZXL literal 0 HcmV?d00001 diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/public/assets/images/datatables/sort_both.png hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/public/assets/images/datatables/sort_both.png new file mode 100644 index 0000000000000000000000000000000000000000..af5bc7c5a10b9d6d57cb641aeec752428a07f0ca GIT binary patch literal 201 zcmeAS@N?(olHy`uVBq!ia0vp^!XV7S0wixl{&NRX6FglULp08Bycxyy87-Q;~nRxO8@-UU*I^KVWyN+&SiMHu5xDOu|HNvwzODfTdXjhVyNu1 z#7^XbGKZ7LW3XeONb$RKLeE*WhqbYpIXPIqK@r4)v+qN8um%99%MPpS9d#7Ed7SL@Bp00i_>zopr0H-Zb Aj{pDw literal 0 HcmV?d00001 diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/public/assets/images/datatables/sort_desc.png hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/public/assets/images/datatables/sort_desc.png new file mode 100644 index 0000000000000000000000000000000000000000..0e156deb5f61d18f9e2ec5da4f6a8c94a5b4fb41 GIT binary patch literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^!XV7S1|*9D%+3I*R8JSj5R22v2@yo z(czD9$NuDl3Ljm9c#_#4$vXUz=f1~&WY3aa=h!;z7fOEN>ySP9QA=6C-^Dmb&tuM= z4Z&=WZU;2WF>e%GI&mWJk^K!jrbro{W;-I>FeCfLGJl3}+Z^2)3Kw?+EoAU?^>bP0 Hl+XkKC^j|Q{b@g3TV7E(Grjn^aLC2o)_ptHrtUEoT$S@q)~)7U@V;W{6)!%@ u>N?4t-1qslpJw9!O?PJ&w0Cby)>ty0tAO(2~Kc#cMCAMySqJp=bm%F_s6a8 zzIt6#t5^3dm)^biu8vYsl0ioNga`ltkUz^xssR8HHy`+Sc-Rj}o9*NHal&_#(sEOG zv~cq@b}DJt-rI@&WE|3kyFDmqD+TUpEcxR|T^D19;Yu{Gs0 zBNq`S74+i&5MXcaW=!g3Z|C63?K<$VvZ2;$|yE{$ECEDXNf4IJ%gV zaxrr-nXb1}2vSCf?f zx2}&XA#y7>Hz$4;7Ee!4W={@gM;A*LHaC+TSF zZg1}3_E}Ph{No>HGix(`DIRf29w`oXF-cBtDQ-44K2~uFF>WpiHZe(QRta9Q|H$~C zczL)brP-u7KTZ-KnULb<6O)qSV`Y;TljP@YB75ASCOS2tq^Q}h4mwf@liZ(i>I zD=)uV@@LQtXS@@`*m2AHmm| zz~9Wx_r#uqOiJfMqKLT65bo;fS>WFqkPtn*Zq~|4oL6pKm7`B zcvv!|br2ZdKX=mQ@49Y{@m#HQUO6$&?o4z=3QyV4pmxXoOo>mJ^tn;=8|jb~^qAO; zlP-7PAl!yu5=g&g$iDlx6TT6s7|^26z|ODPLl}~8q`h4gBuM9jWDuJ0#EEFkIQBVm#onI_N*|CEY9-O z>)qLJ6b|bf4XBOVW_+L*t%8@XN436BIZAENMZFh%>nHuuxbzV}D?iExBTs%y0#Vu! zd+ybr-oYJ^ce%r%Rpi8e9Xao31SoL^Ah=Ej$dq3PqEP_^p>sF5v3crp?I9$qsB$~W z7BOV7LRX-8_qCfUx|u@#*27okn@;bmnQ4Ip&c680l~zu+la$fJ%1w$r6#=E|Map$7 zl4J@Zwd8ywH^8A*Sf5zKT2Vu1=xsG%2nlqrFtQiv&|NlmxFBu#Yn+Sr-os?#dg7qH z{kr+xZtP@Qk3D{vp96)`h92GE?bUZ*EPOt?8QK}UQM%|>&l6Al$MFVWK-wkq$X$l9 zBgahNv@EeW#Q@@pD!3!jUL{@#7*gb70N0L9oEhQNw(ZIHGLo2?rVo3k?PmL}nvL^%f0$ag;R7f8U723D$ zf%0gFBn!pxDhyfbNimr;8$!mZN{+Kt+;ge{0SXYBB)DLxiR@-iAX|77fJ{K1-X|et z4kp^srW9_P6rT`@qNUnk0(icp&Dc^8zc&GllqJDfUl3sbn&32*Z4d#v2zB>k$)O7y zQwvUVARa{P(kuG|<^FD~A3#Re%~)?G=|u3NuH9`0P!#3yeugDyK=2CocxKkVLxrp~ zVlw3J+lQjFGrWe4@*_D8UO5Biu=k*`^iDDxu}B*IFs6Te!9*O>M>V0kzk#or>-=WG z_W5m)^7~C|Cxt@`P)!LHBkTbMjKfimtpszM2h>Qz{>z{C+na+G%z_7lKX?N&U4#8T zOpE^`R%AVfG$uk^27P~+fa0U^-)##>^PnJI7b-rgy?H%(^0!L0Z*kyb+`V^j!fhq> zB7ivb-fPs5=Dph_o%%u;JXlw&nIAOX(49rRbMuagyj-45`3;x>8a#vq8;I$tSRvJT zt@6?vT<-wof&1kr;U!?WX*INoj@@b0koF%V7+hdo z(Bj*+u2u+kM8<-~iMFo!C!Pt<&55vULdD+Vba~Es@a*C*u`tN)$>RKA@4ej7D!a+s z4Zg*y1X-7GIO~o(scTQAy-7T&MbT6f+2u#MS5A>lz=eBhG|?E9;O&cwNAypiN;6U$ zgmGhKeOb)Y)`mcmQk^+|?xf9l6kn)q?-P*S9=-2VgX@YAJTZ*8IB{>ATs2tWi-5bU z@&c$wLN$>zUOTmh?fYL)243b3eT*_BpGhf9*{o+zhoOfcqJgHUmHThk6fgL~UTX2F zAqZ~9jA-id3Wzz(#!xmtI>(Ztx-OE*X$RdCQKy?K26BlhO;>3saHfQ8B$!5JURLO0 zp5@}+r8aD>2Xe_?AqwIWHqIlU9Z(ZK737c=k^kUKw}kanM_yANXYKGH`yI5~-i1U; zUTIs+ye)%<`xhpuEKb4=VcR?R_?4C-k$aD>2srU-U@{zH`-VU=Shor%>%Bx7clzxG z0(ziN>Zjv-)Yo`@v88a(-EK-9-vqNKV_hm%%}Qi!oj6))wd=l4AIM!vmsWkh7Ln#?2Gx?6N!Vhe)luYfD$Y0khxDs45p3fi zJg<<&siEei*SeDQpE(f<<}^G}svbD228#GIOalRBzebeQ^qHl-XEFh6=zdMgvJ7<9WaJ_JdU~6~xNTc&)Z;gU1#%JkZ zw3siUqXMyj2R^S%DKFpKE|iG}y@9_VH;}ORP?csV8``GQG%T@h5YuF~kzlVTDJ@Bt zg8+qa^>ufSafm6I7YbzX`)vf^#+cD4^;C+`8UlE*Xj1*!9RUdlQrAR_V;rXF8KT7^ zEu6h)yt&lS;{-;gD(u^AFO{xT!8 zNRX3BPKUC=TE&rB>dI`uwuL`m!2iKv)Wn%G7iLqJz}ksHKUON)c>{UzB7m9|Lh#Ia z@0XTVC!Tv;p;?)8AV#e5$p(#SX;eIG|I!Imcgn=Jb;^MPT*_U&F3Ixf;h+glcQ&gypgs~(`Sob;9 zrle6c3x5RGT=HBICHxfWjiS^!@J?toEgBx1D$MYX6oC3RCBx_FlxV<`D3e6J5Zd2K zC2d{1Gu+Cc7y{x;CRbvum~_K^i06-|PhfW>+)cbj;XR3NE=l|($r;Q~L5TA^I(uyS zPXYoJ#^}aR%WXSSu~a>1z&!fWl)7} zX1w3avia<7ZmrcHXL9QWyq@*!X;1*C&P`Mz#C%|c-=d6{l^samgSKv}bKL`}kIj-# zVWFnfBjGlfcZ?DtW2$FjU{H^{67PyTF9FVcw|REi(M@f4a;V2yjJv#lch$q-y{dGe zc;m%-Hb7K4T0WvJ?BOpFf250AKaT`OGu(YUzW`FRT6_^JLsuKrs&VcaXG=~kjO1!Y zY@Uc(xf{J;R2^W0IZLPB$GI?F#@neycFE9?$w>(#g&q*|X@)F!jVBHl_xlZoIKvWi z=&)TK-&I<`HMs3P!KhD z(6RS~dt3tL*B7$nJ5C6tJh8C9!OqZFq3~D`HBZ`bu=Ofw=B(?dpG{N9;2Z_CR>XsE zHZnwHpN4OV!Ip#ijC=W5O(IZCxrmb&{OHFLXBVC`R%AMMpH(ySotb}S`GnX#Ve z@TQW8jGEKA^AQ2g?rqptwdijshuY44ne{!ZKku7G?n&@Qt{n{^w|R@Y^0B?3eX!Ck zLEPKjWRRXQaa?oQJSw=ZYTxl~Csyom0GS0|v|Q>n$$eQw%i%-13IB zLl0@oxH+Ge@3Fnn+eLc}3ckSlvG@KdjdVXX77c}*lxnzP%{VS^w{XA(`hIRUe^Hs= z<)yZ|i4xlHYfHbAn206&+HnymJO>J$_Rc$O7wD9zsBj=|wWDx)$SrVWipb!uF|j1^ zRc50(RYRq|Y^j>o~?A)l#|c#O#@a}QQa@a6QZOVub^ z%dkxW_Yfz%HHJ0!;3wT9L?E}5!8kXoWiUTBak}@Z0TPuHM|S;$xfvW~VAeR>K14(N zFxsTKgFL^?S-(}*UBBS~Z}f!9M2X_nB1!M)cV41o@oweGU-z!MYJIt>H{~gLEA#H*m223 z-jLsWGj=$B=EH3Hv?l@_N(-FlCWBHuV0wV*f&2SELi+2m z8`aVFQR0v`FX=45)bK#LwLCpJ+N|h*yheW>RIr+Y!^uuKpH#h zEorvE9FHMJ=&N1=c-XXq3WP$JU`Y|Bx0gVhcM`;dT&qFd`ocXPQj74N$E+cX8h#27 z7qsi!h>t2=10}hPkEsI_bQN>2v$)D4cb#D_N`1nsMSY2K4M>`+jpsh%*|bVy zLq;X)i4OeXR7YYivwyrlSKjjWOE1@ylZ#ggMZXk-YM^X3{!I68>W^}mNeJj+yTN^) zO-eA1Q~gSC2dN6M;J2;hpX{NeI~a9%q=*Z!@!6Hj6@KvFHFWQ@DFc_9nMcT3$n$TL z8{+!tp|0VUdgQkQ#tfEdD&bvyb#1hzxZl?8Ao|xJqgDy{z5w9(sIR%@aL!lbv9I#l_M>41mAf=edF9B}D^hSMhdxa9%Mfhu; z6SV4|v8s~`3gp#9j3yvNQ>MZJ3z}fpq*SoHu0O7xR=8{Yo);$oN;61gGHvGL(0{R< zp`WW^lg;@hT8jr(#JG@9CBHw2G5WOk>t=TCl98%d&2yuPAD}8ZA~!T`PVxsyYC| z4hrJbJwP~?N_zCLr;y8pdzz%6N(mYaP>207L4YZ9ok-#npouAD6G4 zvqBdegrNPd+a}R^B;ovnUb(j13uuBvkFKQIeegxVz92_cdO9KneaywKCg5{(cswee zBy2Jf^M!v%jDF=M29V|sYv`p#_Xok`!Jb1&oB)n@j{JR2CyJ@;6jJj`J_Hfe)-5#Q zDIL|Pda#NbmcjcWjbZ(G2D&XF54Cu5R^Df|GBfDoUUf(O*9~N8gCUgIf7O%~QJLA3>T+F;$y5z@sYEE&DB*2-F?k3+m2r z-g_>s>_v1mLWLmE&nQ6#Yf>1KHEL26xAa9chFHhbPHDy_`N*)2Fs*BGLm&}^D?u_5 zt$^p}^b<`$HQ5AN%!{%Np|KJ@gcH+Mq$P0>RB`x(hqedTvtB3!*%YavoG{eNGK&}# z=RnBq(I-5(*;VSiZx&}?2Bzxpk)CFV6DI@$X(n)lBan839}2oew35z(kedE}RRw-4 zW5a=?`15%W19=k8!{DujXzp>L88^U-IIf(DgSxcqG6LES7>vm7WzhX2PwMk&ZeUXZ z2UYR6nNkH-(j5c|u#e=Sh*Yc(PQlo&7*Fxsr`EJs^DwnvW~w^bBVF~1bgw)j5(SYG6WALIec~+}dXA*f1lYoB ztq_Z^HE)EFEj9zrMEf)%_tbXsYTf6nt4LSxO(2<9(9=SI_?X$kPaAxaV%6i$;-J0U zq!h?OT!7`!EeoYVj-Md+o@zJ6%^@{ny8Rfe6ktoZ54vhq_6eblAQyF5-IY#-zV^79Fl}Cmw+I#Jfw| zvqrLuXv&U9Rqb;8r}f6 zCXqA>=A*}|z8?{SrbFqV!{`dLu0{+Hlh^i_SAfALIB$hI1o3x+DX274wqo(2z`-_)4Gn!hE;8pUDxeIMjpHwjBqj} z@z%0BB6Ie545k@M4=RtaL70Mqa&@u|kOv!E-PT!Z>U*y4Hsg)a1scWXnznXZ*=y37 zI|F+qMX|Z8zzJIDMlZq5HLZhcn8d{ZRFFg7A_hjWs0I>I=kcJo%s}pyEv&%}eMg5r zUY3xxU*k&GOHZA;r$tc&UXK6mR9`>{c0n!A#_7QJsf|!uPs0Y+l-nB0jHy>DfPd&V z1pZ)yzCP8I{Tq_Q_Vpu0y8o31s5rA_2^sAr8B_w)2q37vsacXkp%^6qhJ zM>-&ENlbXm6Dxo=CG63BNQE1`k{oBv=whg`1fl-k-T`kmg&Yr0=JZaDA?^<9tHGcC zz?sStu%Y#2GdT_v608x3w8e}Hp?d?<3A?gQVMRCORf!{Kb$BWIEbHsL;T$8s`}LGxsZ0M;UiBm8|2VRj64x zDbj}Nej=%M2{t&nPmB=evIhFUTRJL!w=@qg9>wnVzqSTDw=OG2ep4NIDBzNd2@6kd zMSyye-w_sdLX%u7W=SW~eB0jVaBUG#JPO|q_xE1PH(gnYs~D!TH60ceKy+M;ZWJ@m zc$EDnhJMgBEvaoy71CGz4besr(fH{SVMLXh9(6fDIgioKn`6`oRZG0a|Jx?2_>jY_ z3iG+ zQCF)6By5W2&28SV7MEBkM+I65s30IL558|4``S~(y!jAaY0Ni1@Y3D7>`j(}^h9p} z;lOKCL!>>vV=h((X^9uW;y1;F{A@wiceZ%nQ32vW{C6*hZPIXEb1V}#Yv3-wEx)MI zxrCk*y@K`txk0L8<6u8(*0zYare~|r(wf7?Dv^unZSuFUGvG$zNIk&WoEaBwbcn*o zz~y7k4R`i#i&IP7YjjrH>#|6(>$_0tnDcN0B{lCUsFu^ZpY}LN(Tin`H@39F$pq^v zM@h`m>ZLo%pqv^SD>n;6G-j{SLdft*%ULDxDdF?Hr9ll5<67&*D@gCjb(j=8GpAUf zdBz4Wm7BA-sYE5v5EKVm5 z^ZK9FImg%eV9;DmU`8DsZ;VOdT?Pjo_t&vm@S*7HArw2>3Vga@FPtme0mcrCCmYTe}?QcRzxm%fZ)`hl@)xjxtl0vOobaf zEx%1GNwao7vUw&BYj}XInq^w^VY~9Dc#&(TOQ6R^|45f>Ad7>(-^PL*mGrO}e1S&kWU&gIhT!1jCZ)70O>WAY@}ORf)H1oU#mMa95%V}+_ZN6)>Y z&U62riI<^2l=eCx0QO>i^m@ye=zbX%H z+isrpYg+HzssDaYV2HMQowY{LPiR-^rzihd&*M@S*7_2-41S<{^~bSS%N^xH&D>O%&)2Eme?(aZvrh|2Q~6DfQ3F(SW`YZdI+>=vm$ zmXy#*OfITi>FsQZZ3s{l?$BeEO!0b~4vFqKHDlIIuG&xBGkXbyKL={EAbAoNXXPKP zm~+Bt<0cslSlpXWICy4WbAnLL^ki0E(_=lSHd5&AwS%$`Jxn7AwP=U$hPkfok|gp@uQHd2MM)6nHnCwOzva&WWyj zJhygLsbw`B^vwSu`fz7?Qowgs>k~7#1~FzS>AR zH3zaoC@$P3dIuH6Q)J?El7L~m@?rI->6nV1t!|Beth~A&4nLj5vmKTW$n7@m^MHy` zD0UqWIJiB9Je+ILumJuR777-pmc963B+vD01;LzAV-V($7jkTGAr)(H)RGXy5)SZ$ zmCHLFFFdfvUJ!AQ>e;hb!e^UgayP!4(1CkLjArG#(DOs>(bq-h7)@*St&55%R}Q$$ z(S%e5e@=Po!t}xjgA=vVrWpm?pecD1{HRJ<#8uxX^f7ljkwY zMh=hJe*3#4{;*g+`t*!yzdCJ^&P7E{#q>2T976LHbE;;!TxF=#*O53|GE<<8WzEpT zZ7IyK=x@OL%_$vR{U`5{?xUO;$HnaGo1==?NfCZ(PJTJAad$(Puvo6piAPtLUbtKy z3*eRMi~a5ZECO>xREpjs&~`ty!@pIXyF1f$rWkq88EH7OmP3vEQWh9)sL3;mxjGy)7%z(QV((r)zgt~Y|Wcl~Nqo^pt6tz8w|XZn>|nKNC#gEIjZ`BXZS zHk__%yo7r*Ebwr!pZnqZu{cGocC|@2xEWklUrXc-XSrQ495Z{Z~eC#c^4}s=Cv`jW@!Q1*T%z+#8dRpTqYzgXO8eSZmL( z%d2kF2N&@pz3u2|yE*B3s$mffb%R(^q*fi!kVm2ux;ZujptJj?q(eUUACXq=iI$dJ z_}ENv_m{cTI0(|p9ax5sfsb0wVOfXmcw?O|5U#RigvXlrwCTa?L}9b(yY?5SM>aAM z1iZh@u&E^YepTmf=XU;~p4=u*#YmjzHFNLwSLs@gS5`*@M$l48uvuWB4z7a&-W(qnhd(|kh0XLZ_(YMPQ4h!#HT<8L6}{Yb_=$hj5MvnZwqvhpjH z1UA={>Mx!LAfw9!21H!Wk(}2%9i7TA2#5f7xBBzvMSKrCtL_EwBIpttguW^t5B7j- zkj0f_Q+Hi>w9~OrIsfo_IvPGsTyf_cKJg!zD^|ZpHvX3v`;&b=cj#d^BS;A2&hNU3 zc-ydUC=wQ>bsZjd*~b_2GbtNHzN6Qk2J3L9S-;^xS4B)0s*GO1B>@ZF$j5ap;aRASS_9-A>6dVnnvA_=Gzku(NsXxpJD>R zrEZZ~zBum}I?N8W z`|k$L!8;944cSCbOUVTooA$LuMG)z~{Ge-2!Lwr7HCpK<6Cq&^{QD!PGOX#XbkOgQ z1$LtUEzDhqc_>}e| zVL*#8RL@Abxpaam2CSZ%%3C19x+V_PX5UT19Lb*Rrxlz$?t9oL8&7Sp4j{wfr>g-L=sq?Z$E$P8 zL>XUU67hHH6Q7_rxA;-oDCtuNS;P?0j; z99E+)s7feF!_@qYjteKhz8Pq&_0!{959dEs8r0Rcu2^}l8~SWJ>~*hP{T_&mQnBK4 zNib5HRT#aJ4-i>cFrEQ>_%kopH*&memY~Lm8S$1!rYmvcOA4tsX^hBOzf|zp4A7wo zVoUD9oQU7cipf%LJ6YNESqeams8hrg2)%%=@7&Xguy2VTw_g9T`a9VKv2yD}l(3BfQ28!}L8X%vx21_GEN%~1eO zg&lFCBiD<%YV%=#P#}*Fz?C%Y5tec4g0=oq>-0$2Ue>4Oy;pa7Qp8{LwTFSg)pByk z&gV4Mw-&94T-{e%G9$oqrN^v*pnyE3>|y~j?3bcnQMxg!{c6K+iXIbV*1VWjvA^He zTz0*!y>YWMmJRhue&y=fDJ2ba9%Q8oEC;TF(H>7bONc+F?9@_)>XeU1lKTerg_rpP z*U!``lJWjqVZZk51y*K{?wOX8ew1ee4?Xb?q_XjC;iqE-DJ6}Mj_XR>D$>|&lMKcJ zjvHUbP&tFVMo;A#O* zU!mQgyrIk!*bZGWTu|rzDTW@6!T9;;ZWIRnV|%8X80jO{ESRV8jK>Uz-*-LdMCD;_bbtJ{%I>(lu*E5&rdzf|ttOUA zDMBQ&=WX)c#5Ys~oi0@Ql4GcT@--|{5cnHyMa-Q5Njhtl?Y-o$z4jDftGk=OrWb>M zPg~(si|0o;oBmSmtVK43|6DPa;+!u%0FJiOmJBpuJhEptWJE&N+@pJ`9u|vU)X4k>5Rx=oQDdTQi$JsO|^|`I>UvH9*DcYvXqP!|+G@9tjPWVkBCN z^0Hm!@wrt!oeAsP`FA6p2X>$SYtf=7!83%6yUS(oCrtX*aq#;>MF0iydR8(lqE>;j zW4uB6g>#7kwuCg@m88a~!|Ds=?o$5B4dR$J1n-^o3ISQ*c27>_%gSti?kqUsn$X_ElNBKL`@d#!u zMC${u#Ga~g5<~}t?3ot8cGueOo8F~Ev za;%SBC8VEKg!Gj@v~8~Q+(yKC?FwrFu{T=k^eb)=j}dFG&9e}{j`?)yZpr~0)MzPI z#nSWRXvL4n1Ht^(6Pt1vKn=vxSti~I-5(Ai#uX=D(N<{{l9@d9` zUi`JHgA};$u#cN`?b|M_d4Z0%uY;V5j&^vqgMWdECxhcv5Vp$%ni*6c5Yc~>za}a~ zKhDjY)-UFEYt$GG-F6%*(<|?yeJ2BWY$$qL(;CJZ0r<5R-X-;5D#FUCN$#=r9tWYv z8cjZ&WYtQTohktt;1F(&FUoOktII`;OycK^olVVad_G@mOqkwFbV# zbgTNsBMaw8s))-t4B!Fs3eUwoRr3mr?A<(zx@2-7$crmSikKd}Tj6yn_0sotv`;31 zuv!MU)>6N|?u={bfs}aH`PK61&Nu$iv^b`v_?H^ozC;l9Ohs&&?ax+UCyxH#JcokS zYLLxSaHxMnHf`<%u{V;>VZf*K@kgodjc{EEEHm`d5HJJYQZ_6rys3&s)!lvN-G&BD zflCP@oqQ1?A;l|KlY^sY{hipo;O4Sy$a9*RVv{k|V9Tj%VK}J2ub?Mp@B}$=Em^7& zzz2J4gq4^o7rka-A1Z+t_PXXTed_(4mR5{_>s11`OFEiKHdHs%sKV`l{Jus}v9cQ+ z%CR$W;`kEt*v+49MHBqTl00z`?EP#$ab_aV6%5Ik)A!fWT>sdFZ=vRP6w<1*d-*p~ ze!WYWSGHLN=CU8%K*<IX zaM$|vcYTOJVQ*iT?0)f*TaV17C54p%$kJhWhbL;_o|7hsH+*C`{!p)Gi~OF@m7`%K zPFF~0+0kD`b79^-=Xt5Ks{9+B7qjs|XyfDfF;X;>HWp4kmVZ8dYAnnRCey$hyqz_i zj+<0j-i%xRR(t|BM2X&?;q5}BN-!ONd-HthfSim5DX4OOs4d>XT75qzeb?k>eAky! z9AD&{_pOb}L{2Y{KQoKxQ)Taa(Ln(m2U6Am2TGf}d~Q`Lj=qO3r!e`{ zMXe-+^gwic`U{5&{WTH{RLjwYu~~yt9j_>Das?tT+a0D+iC~DQ(e?gXx$))qyU)n6 zg-u4h!YsU0-+Q<|R?Di6VFzxc8MTJ61F!Qt%WEd%gkK)F=2c@T9<$uvQpg>rl#cAh_v$rU#?&7cx5}4@+N@md#;|8Kgp_(npU?A0 zwCufz^5z%Jj%bg%DqE-V*?y7j;z7a+3bL6CE9?c^Tw7R%9`twA#-<)qX6xfrtw~Pr~2**L_@Lr4mZTR^oufg-Iet4$A2&Wz*Hd^`!##=cJ>2u( ziwzoi>RQfn_LoX^S(-hR?$_#1@TDajv3kcLe9R9E{A~wmXuWqo<*NZiVBh+-b8aND za3;6A-WEe$J9wld_QW5s*tCveFu1uQ`ON$stgHBAi>{B`20NKtH1to%3*PU3yDuM$ zYP;1FhZK@v$l%f%odkPvx`8d7)+5!e8eUHBr2rI6}kdr3Lud z$J}~hEK79y&fvEYM0J*9iIwFriRZ~Qf3b(2Rh9Yikf@9~PJC`v4|Y}>2;H45pQX$R zn&VS&!bz)suYClb0&nI^f=DFf1+ma9~jD0BMlt`K1kRc<$tMAFU6KrLSfw*-nCKM=m4wK{fm z0>Ra2(nz$(4pIVXr^hUY1bbM&ZI|~j$2R9XE-U>RVGjFonU&mJKzKY}^M4>fT+2c8 z)FkR?0dC_gip>`@;!i*Hm__g>$K&9O%lf@ct{zGYL?K>P?5hR|Z~h!2fmAHMO}#dw zjett_J|m1o(XYEE+E<3~N)6W@@F_z~&(JXNa8C^&IsEvu;N&-3dFG;6(yV)M_BsRg zi4_n3V696KiAr6nqBB8;R^9Z-V#NuEi5poNAxcbB`ez;|)ndC`oY28&j>R9b^&lUs z(F@+`N_5;d)LY&Ga#SuzIo+ov3z9i3_CK@?Kz$K5oVX}WU$gjanF(KLcTCt@9pI5Q zurRtO&*5g<3mx?&PfjRyWgYz!_n#0kxEt6V!C~a#H%rELqvN^lqL}owH|^QjZY=6) zQF}N|Uoq()mCv#v!Y^%g1Kd^;9E7T;II$$u>xUfvKF6DdgUH_2Wl8OFir-9KCiI4# z8&Gr1V~Z6ckN*CtK|LyNJ4Su*?4a&Oe^r?vV!n&WfK`JvKXy4x#ez~+M555qS9hwVgZn0} z8v2Xzk(4h`Xa{o9hi57Nr4iK&}cY`*yELbG>C z)%e(s4;-h8QYPVeaV0)*ffzq5962ur#`P{=JJME7I>Xn8iCA0YV>Av$($LRFFjs0Z zGB;C}wd?sj8l+V2e zB-E?Q84;bDnrUpT2_06|K!$VDWOx|8^5>VYv05r@#zybT_s$6V$_1d=iz1?m(yxwU zlgtVpd)iJ6Gg}zXUDeu04`EVY0x2ZBIAZyOV*Jf4zrV!2<(N`{C}3Ph5>W1adD7<> zK)|l6%SD+L7Cr&4M&rqz;xmI7HadgkzA1&Z-{-`9&|?m4&dnZae3?8G4>WU8aT-M< zW?1c(>or;f%f5`X1l&4 zEKlExTRlvd8Fu>3Bl(%7(#*y6m!I(~YpoiuD|Zcw=$j+uMtYj!SwAWi7QDbylW_e> zv=%OBx}F|hbD{A03PVl;j&js7^ZnEcKW-Zbi}jywbK23G_FI(P_6{g|@yER7)a5oa z(k9w%Zuxb7U!MXqxS#dh9tT%cd!n(qSxLUDeQlVx&yXvU)~xgaW?v6G%KG-#%jOz7 zsdZM_1*(u)5(=~V?j0?PVHPdsUK2jXzEi*zf0V2q( zN~x>v#3dAVwqHZZ$;(~lt*Z?s8t|U1VHeUvyZ?-ps&ze+TnuE zrp~W7pFnMWyY73rOu1^{~V$plwXiLh3A)g`5{9eQ)JJoNi_bh!p=bkzv?h zh?J-*(6*kPbAiRVpOK*YL>nOvY4o<+?H~YZ-Q##zOmAlYy~iwhOPp`SOyn}(9>o81 zR%~D{*ZDVL)b>*zB!9z9kfepGVQvwu?oso86*%L*+cNHuGmbW0eleWV6$cAc^A+5d zDn}*1emg73eMMchb4Kg$SeQvYzh=CAKSL1ll`n&AHrQPe5yrBHyB=?s0)I*oc7nfg zMgb0*#z*JlWn=6!)>kX9%al}4zKpQKVkSIiRB53=>XG5>6ZA1t<_;&x#N^+$wn@V~ zvXB$RsR?gwPp)&h8GI*`*&4J{eYzwvE*Z~bgWi_2+gqQw){fw7nh-(=5iz>kvJgO^CS6qKp_Ex(1VgS%aDD1# zKd?i^nN@tM8HmcR=kZZH6-kl!dw(U95<;WvlxXPZH{IqtO z08D_CB`#%L6P$#qRgcL&#>9q2Li0s1x+{Wz+v7EwJ+02uUy&p>Zi}6)K$l;cslvW9 zdRXq;?RYR|6np%0*WU&F6YxX|O@C(jdJdbUpq+1w^Mj3DxSRDa^h%3uY4Xa7Xk&;S zi;PBndhsIa%^Pm+Bh$#dCD=+ij4HNaxiYj#^}OWrDIlgX@FIk;WVAbI**w=`|6-bB zuVze^S2panX5hT-Hr}mNPF8$;oFT@Aj2Hg9{|DZrb8dnp(rR8KhBVEu_wEu@A7Ckl zJgsZ3RHd4wHF?2GRR3Cuifyg5Nd$1xrH}L%Cz%zP33bDO-=%<=V3aU}8h7=A_efcp z#Cej`vaRdLNz24}E`Ao7mZZ1E8mlRS! zJz`9hykp-w3>GjPutHuusM&Q3R}d$LqW=6szM2S)k=$hBue4h z;Pw~7hw~*W3T69?0l!nfDs@Q{Bpqk@lafYcdkdlvfPo0gZd;i^hx?_i#@yGDrTPe%1Gu#}M8y?YC~PDSJiF~R_-r&& zJbq4O%~Ds>nj8l`lGXat_os)fZCatM+)-OU#S!>1l>ItQe|X|^f@D5Z{KH6O(SH2j z?p2!;OLe;LKM8-qIwn=gZj zZF^$dwr$(CJ+W=uwllG9PHf{BY~J_3yS267`a?g}x2vAM-Cg&bb6KCuJ-Gzp5L>Ui zO0%DDCpO6?Bs_~iuk9QFy_t+F$y8tWd zb!-fj5jh!r%LG303%tepvji#=^7wtwc56qhlX(=W1`yE;_(zDuB;eC#ID_`Gd3FX2 z&=G+aHTZ|Y$gmqs-_xB@Y9}>*R&*<&S)Ax3|A!uu>M+5w6miDky8%CC= zwpO@^t7S5^@s`9zMX1=ibkP0FaWxNCe@ZobPZ#2L8GZ_j9nR~dL5aw)XX#fN7sjh^ z^f;vu(SsSG7-g?FYx3tz;P@IC@N~{3oS4aWH&zP)6~r;$H)vnf^ibOEFlsT6xQBqA z_8Yz&*8Cr0VKFg-7u3AI%4dd^2X5T`sn#Ik=S7ol9f&tvq`>HPPvEjKysg=i?HDW! z50m!R8ZgRpD@0>dITZ^hDD== zbb*@{u)Y%79owI!om&lEu?eeQg&^3&2-5M}rB2+?Gk<#Scb{ z4qqL0K5~G^EgxWQ%gksDJ!lkY?Dx_;GlO$OW&3$OWI5W%EJS8(fLR{}iyHgoN3G42 z8W3|VTM~zB^v5bXa&Di}Z z+3zDRDYq!;bDYKHJnCC4T8{Q0kVvH=u82>LfP`;Rslk@}{okExc?&bgBk<&GH~ily zjlN98iD=r9iD;dz3u<<3#TRe;e0qLwv@k4WIUyy|yn3F}*B)Pi)wGCrP7UC`e_T;GqkO7QeD|9`bX@F$1L zJF*Z2OkCtFiY2K{QmRHlVtTrZS*h$#Wfe`|%@wBG^wR)tZkf?&aBAa29gOO;!>1=- z^rdCP#$ZqPx+9JK%RJgw{I@5fNYdnr?N{NsYxl$07-K)bSF!nxr-bQ?KWN6|`xCaO z!)1Bl7ty2IisZnD53KH!2Kq+PZmF>ku;FOB8Mq^4QsB&YQ#sk6r$Arm; zq(1O~0C!A2DP-<#qw1P8)uk`q{n1;7N8IX+F%`iKZtM>m-06OOwf1tp*^)`$%d57w zXdUPy%0}-!Qv5?2Rf$g&P@`VlU9u^cm0LiER7@2TMyr5FbPJiVUtiCyf9is+n zg$<4Xai@$x=66B#+1mB)tIv%>^v)`C!2I8`C;g_cK9qC_^)>~jjJ?}~PFj9=?&CyZ zZht|jG+km3U*VMCIKhOh(2yB#s!s3uK7uard6u&7@w?!-)Qek~(>KO*Eavlu_ZzbF z`Orb?>N`l&Lg-Oq#+>@&jZ!gV^01&2!x=$iFVF0onU zZdu=oVAf^|xnR_pzf60}UI=aGz+&;g$?@jo`|}7^@F4wf1x2I|VRc$Rc4mT9T#~H> z^dOQV{=1q;-OPQK`U6G zOiqSI*rVcco2-AfVl^%)Y}sA{OqQw*3D4rn*j_N)>8>JDICb`U6aG;cslKUc#e`!6 zF-zyq=yoy=R>$>lmc!Oq@Kbf$usTbbR0#sYtL#40&ibP}*rY>ry=_OfqUd$3Arf{L z5}7qmajcV5>A`ZKx@Zt4hpyI)fOQfG_~Iv8-R&nSr~=Tlx= zQx9=I;S?f|6M|nOCRRjJdNx}zZ{eg94mw8(kv{|xzK#lV+95=sb$a}QxEZt06OhC?4+K4b% zBc6Q8I|AEdc4>uEL;Hl~pV!(}X$)45F@o{)9Aku(PV>uv;~8Ez(DL6;&(VUgWn9~b z4j+uiv#b1Gt7-EMo)v&Cp=+jhzD@*f@HBojjHrMmO@pWwo}g_eD_%Zjlf1MHOE@Hh zgs;qpB~#HI50q3&fD{FiNmGKLh+TPwH*Pw3s)DWYbI)Q`)6v=gQktoxqRODO>gr?? zCrT4?MFn@}JXo!3t|Fmxtw+cTng3l5BlQckv$bQ~sjwyj2gQ7@A#YJSOy($qH5B#MH5IUauwTQY$l99F7zZGiATjH1WLJ)_S_+x6MRBtGMK9zgp^X zWIT8Lkk#6Zab=nIfTNL?To6-cnrOdXHLKS`FbdEc{Kf-iedNhsePZW&%~6<4?~(Xf z{}ZP9W09dw{bqrK?W@Y2*P2I)toeEkbe4l4^z2~d#{*7l$Av!&qo7QS5mq-(`h~?# zU~>7@@puC}y*4}puDw$WXO;q^qrU}~AYnsIwxaMY_-3cq0YSN0ov>C(sYBDh(FOUz;5MU+*Oxne+0LPlXq$EaD~Z|q1(4~_?{ zpB;A+EtAY6?;BZeExcifnQ97>TLeatQRlZ+~oOznV%XKCi4?Bo#IGQENCZ=3X5^ zc>7%}YE#RSbrv*Dc7I|t|4 z$0!trTd)H3aS9D;oHS}5g(S=W$sRJZ6j9LaMP|6VWRfgMt)Q#npSyzeuCU!$y%#$s z&}!I2*72{{Q;WakTySBIJ$?1#2J@x!`F(~%8Iy&<;Kx~Zb^uP1{EBDn2kPgP$)?en z->U8DcCSo80w(?L7H@1dzDE3=8PbRDREBy;+z9^N+ZB*;CDCP14ZGA2j!VZE#X2jK zdDO8~GQGRs2-TOcvdh1Yt8+O0X?gn_#J-rz5xBvnjZ0V<@wk8EfSxY=LT(&cnm$~= zylnfHuv}EgEKV@MF32!h?D)dg#Z+5pLLpCDt<)4)pja}_PeFzzi)gpD2W&$QWiyFQ zEf==kHKbVYpraE0Vm{z7`P}@@{{oUwVuoPzo{?A73Ma|r^TQ>8M)a>=u{7$|`hNZX z%#NUd!;_hC$oKxd*H@0>_w=5q(~8-8efB>ujn4Rdn5uvLj$JACNkY$g(7nq@`{JwH zx9~qmyOF7=-FD1uB;;nvLih(XR5IQE3pUJtfk&TmrKBzN=;H_hwbCQVwnY z!Q%V#oe1ahg;c9#dK&f&h#uI#i<%D8)nt2=xqo#;$8*t68v)=R&;~B1mA8RHnl#^8 zzJ@zc+f!Q9(p}f0k;S)f?OSaL`U=RofR~pfAbrFQQ25iTby>vLzDob)BmP!y33FVC zB;vj5Y@57-P&Uj9PAvi7?ncd!>dY0#aneO8%m zFPa#hNaWms(st`y{rt0~yx+Np2ZCWFZzHlNmW+!s*>;7@; zWNdvS)6sz2?XtW!*K6mv*maKw)^+AX<7LqzC0Ev)J|-fyqC{%TKa9d&*nDlU9DVlw zHkBK?8(?IMFKfuVID3|FIa@!=bmahOseu50t9O)OvFr7!dwGF~6!dMZ~oZ->BmddGgJyIU(jXU|PeY0RgdzWJ0RrU0osVnVoI#ITQnBqk?BLm+? zTbiMJRsEW$bf<%92*rspDU5GAC>QX{(VqH{<5XBcUzDI_n3?XqA-jDi@^AThjUx$w3xy!`-2j018SlW^Rw zD_NQhhH7Wa8PG`s<;1wSSPrC62K1;mYMELgYL319EFEw_ZfbUj*H9=5-+hYna7q7l zDxp_8FxL+(Ju4Gom!P-GVDU9^OmjPj>^xJN*^0o^Nq1$tE!tM`{uDl#a_@7&;>ZS6 zlwg6=rkEy}6uk*_?gAS?1VO?~Cbhh}Vh94ngQLA3cL)H%o|4x0_4m;cIc|F|BcR%G zTv;ftr$i}iw!JFNwe8xtpzm^YcaqM6>c-_ zHeL}@w8>%<${17Re6n0Tp2dvFsqb4Dh%1G(Pct-Br%(ekmozym7Kp>dZ)-1cM-XRCTyCF(leA zrM^CWiSq_4?w2~)r~}8E+Q0f506#|9N$7j~(iWdhq^5u-9=_?Il$TzFeL7r@z+aQJYmcYL}i3q1rA$5>R8F6wQGXgNOF2KeCZ?MqySOha%8|K=?c`GH2P0z-(F%9V;(Rzh-n zbVb#>uo5OSMi3^SA;c?`wv{y{m(o6?)Udz!0V)U>`t}y8i0RrdDo%mIWhKmEvHx%8DYucIikl*Lb3mjh2lM@{|(=${)##gL5)W7p_A&tPf>TCC23Ib zAjCtQu-Uz$kYXE{-oF0eJELW(Jim`?sc=q#IrtfUk_)!_~le!5OQ}mnlz4v?&?vzSG;^(rIh*mlDH-?T9 zw<4#0M2v!2ZOcZG*Z!JK8!w6*{Rm_~oW^)f;zbG={r$D!An2Zo+ARQriinQ1Y8n*@ ziNvL=v=Q%Ppm((tG1q%tio*l@?=u+qPN+_#p;Nd}=C-)Dif^+&315pxV>uO)_p_rT zkf!ml=%1V2lYTtAudNz~aB(Cie|Vz_lrJr7cvV8`iX$1*NXTMmqGT+Lv(3r+x}LZr z=38>dH)F6>55fsfemAj9ege6G*drT}<0*B$%sYUvd!vC}9&FGab1;5ZUY*Qkdbfoz zx`;15Cn*udLmpyssR|hQsc#Q@@$xt*9~%WI8|RKmfI#kJL+E})d)$Rw4vPCnSq!a! zn=`4MJCZcsaZK)S+xlVpghmaajLvCmG~yP^J}FV3`4Fqz#69)c>#gBT4oTxO{9=>F z!h|(o$|5Yh%6}uZA_*Z(0FMwRM8r|Tn>S+gKVo5E#nq;fQ=U6L-n@W8@@cLTWTw6F%Y&=TCKQFIlJ9lJW7-7aOE!ZUyL7-EOFr86_;bo3Ajr{-}gSajsB>;szM z+X(cLC~<%+c^wzFg!pHbLuU-o>)H>~Xw+vCxh39V8T-(uZU+# z3?SW>eOjFhH$wwwRT8tnx>0GaCFDA}TSY`6qQS`EQ?akR2K(tM!SftKSP)lcu^a9J zTS&^>OfZDWf)DbP59}J;*9A`=HxXi~F^)^oi&KO4e8F1oHm$QYGcb~W80-iNw%F)F zi@n~+ljqA>#^N(*KU}Er&YaPa&>K4619FU(4GUnBdc?kg9gU@i!LT+KPRL?%sA3gL zlf@}eY7Z4}xGqt*dPm_rmij!u6(-HUc90ru;@FO|$0B}E%drx-Jl#M&8`r7aOV$$d z&UrXXR!3td^%H%cFH0m%-`$*mMf=!Ves|4@k3ig|NWqqlX_c(hLbRhGFv9DbCc>Tw zK1A$VT$Hf}Su%5XKp&r_#P?Yf7GlL@Z0lJC7Y>@Oo6G4*%WG##F>1uojD9`)bGMTBRcUf=j&!fU+o7TdvI`Mq^sGq z({z;qgBdNdK;#J(e3$p!lE?;Ng5>8=8?amW0RY(kgE;>g1?W#MZCwFIED_^D%HZCy z>;hXL06FrqBS#oE_Hh(RoW2}f>Erqz%0<7xIh0X~FDB1Cn0 zXWk{qUp~+B>qr!>WKGZh{PeU)Hn;ky>4S^5g^OT$ z)pM7e`{HI@UeWYi%p2~j4DOzM7Uc;RK2amY@z6YCqxP(RXd52Z(F}HpihqVTo$j?9 z5R%Vn@wdGq2$=Vu1@HOkem4f9#43pcx4KXUOAdDO1BL_OhPln}%94f$f^#+Qmg1}l z{aj>g;tK`fe!KmU*yY;}%+<;_y~Y&+d4uzMD-sb5q(!LObp;VGcgT8a)I*6u10yYDwv-i>>7~)wAQ}kbd7)$%>brEGaVWFP~w% z+c8C6`V0o$i>P>7Q|(SuAsIzj2w-qDT28MGbgonWJ=iM#nWCB-mpEqgPQW%ik7ilifHi%*bV0+Oy|*L^ua!nLJ@$U zNr|@xrVDV1%625l?tNrj#E}c#mJ*)*P2~kR~Js3MJSL# zGOaD8*ERYgO%^)03Y@TaXtoT?@={4AH8|*fFy>qFF61M;1_oVpx5^RhtQcLM+pueL zYsHi|O^0-H%aoT*PNB=5t!l6Bu>v_8Bo><_7wk%~?|v^0c$5gCE1V}KnCGy!Wncp} z>w7NXvAbw>)UYF<^|kA7)J1DXiKsGjH9ErSV?j-Pa6(O>;EsEkJZPE^d&!<8ql^ z)+k!^XL$CQ<0iGhH$&%YSfH*?`NGyX+jMvT$9F68cLiWKo(0ZEUKj z(9Om8yY?1>#ee0M#)pp*zs=lLm+0%@<+yaonKG|y`$wfx}Y_PN|aw6V&ZmQ>N28N@~SF*@|u z@I3LeIalwEd&6}@KE%y)keUsbc|xe)@i*TkS7b(jAJzA zz!XgN{&cfPiNt+~Q<3XoIIs18;(1lsxoK!hEsskfJo3sCOwgkLM^?rRpKqa!m7G~* zY4c3#90cTHxzEn>2gHZ-1H{VVV(;y&8Z`=!MYiJ^y6Zo08?WnY!GHIEuKmRqNqnLH zB9ka71VR)af*V5e8#iw&s8B?6APWq2*j4up9dhhwyzrv)-II*vJ0o{Infw2IquX!>`AyR5-F%$mtEpOci!A8y9N8hCq+SSf1~8=-sYyL46w`?C z2#mPorkkmlLscucAK5l8C)}60bicpR`Nq7yu>o`VL+17y!XMI7SX~^YM($<2JdPBL z#SRq0;0SlG+e^D2+>I7vf`z>8X%^O1w&xeQHT?e$m%o0S2oTT5;mK!y@Z2bgl9Nu} zTGzgeG3i_aX#6i9s>YHQzeLWN{EUNo28y0r=WQhS#_oy@4TvqDZ@UVGGjJbnkT`8v z?uL7`7Ia_K;k!*Yawn00b%idBS&#ey|MP^soI2X(ND;hvwIg$ixRHbegZb|g)XCH0 ztYLV4(KvFYmx~xVdbpa4;-Wyij}~dXM80_BFi>kH5e*22G`JWn5Eb&l$H1cn^;K@h zWp;ahlwXIvHLZ`I|5YjDIhx#LN5R}elN+M%iur^9i{)^J??gCw*{!8?r|09SLwFkP z)mIl<1TjaZ2FhtusDtMrdBJNL&w9yPx5qqJ%+nZ~a!Pqr8q_eWdVYNp{Qv{gMn4G> zwwE}k&SDpSzMjEx>mM7Akx<$EsEF=e;NhTUlX-(5Ba{fi3LB|B&Uok1qh{JRQYQUj zmpEw|-{-fvOx9+f-x9}Qg9~RcrG%TUFBA(W7A?H#*lmMC^d@r_s6YGDah0Ti8}7s< zc{tl)WJsDxF+3;(M-Jku7~k80(C+E}ZpAZx<k??~=onL8y#acd1I0}1V$=(2C#y>Pen z4;?x~Hz^*nbl$*QD|4pPY!o~o&wOC-Mx%$1Vp^$&@M!DwPPYd7Ro`bxX2iH07QgRQ ze_^1-E3Fqy1^mwQjV)vzr5hXUV51r-dlz2MF!r1qU;odxW=jFQTqE7ad`GeS!mXw-S>UwH_*0h_aA zs^@yPY?Pf}>#NGn=(B7RgS%c_SMdW^Y`nFI_Cuc^SH%_V_CERc(hhd8@2x@DQ_^C- z(5!j)!dk9FK=&6*z8m%hg^|DQAbg zRT?tzpCGF$htlPyqOtx8zGH6@?Fv3~txvVjFe5KCPwA9oejXJ@OywpM<AzjJh2DrxxgG|oD|k7okqJJ5#Rx&BDLPdPCc4GWJ5mFzr#F<^79Hr`I?jwR7V_YK ziQhV@bZ}av=4?w0ymqdpUxe|}pe^FPz;gZEvoxE>ZufoqPU!u|Va2tylzM530pr}s zlc`-jdGq2VQ8)vAKT~p1E~aoX@v#4-ZnD0e_W)(9b!1^h#SDt9sC?lZ=Ugaeqf|!! z(&KL#?aWhS?9F{e=Vb0OkogQQa!>Lbs)n!gj$hys^+CG2x%ulB_pgzHP4y|Pb@cr$ z7{A~R+qfAuZ2y1|0G3iC0&-{28jPmaC^E-iAoUcHk^`Aw2v_Hhe6WAe-jgW<3OjPM zwAD4tKoJ9a$?TUtvO2HaPSsq3h~ivB4@SWU9`-!OXW>)~cc*)h4#3CnLjt}1ys6)3lj za_~zj*nOHf)Qr4JWvHYxgborw?3F%c8Vs`u3!r%!dh2l)&)f5yu`Gs4H-d0dO{|s7 zU#9O)pw#A}2a|Vo>+MvWvM#Kw+0~nJAfs7QJCl?xiCtoh>28%0ZwUXOoS5n!>29R@eEUPTNXmHzD-=2)LA|e`R7#!6bP-^K>=U`%&<&c^ zQiM0rJo)Z9*wV(1gkXb71&>#c{QPXMyRGbgS#9syxj;qCot$v@i6f8LTd)qesCA$q zF`ng~MM=@Sd2$WQ__gg_HU92O-`tt1pC~VrXLk!nhY_+sk1 z=k;O&0BEJc9_kpGc7+ks;OrYlGNg)Y&?nJh9eTWnW^Vfq{=#bT2mOfmFcof{>}4V5 z;gwn>q0{m+nw{4uwtRj0xLXgTLBYn1q&k=EXL(rXGV?vZC}XhsdFfrt2q`Dc+pjZ| zqwsp@Y542y4A`D43Eyzee@>7k9x zbX7%EhD9p7BEX&Umdc&zm|-#46pGvVHTeMs++0WqzMu4%9@b-idmL!wow{sPuV}wS zLCYuT%1;p`eKn*)D(-O80WeToIg%3`4=xRn?*HTVrUNMvT z!clTOA$~-kMGeA9qI+KIxa=iw7I6Cve_%DP?+!c)XsM>dV;h~w zMS6DabWvHTF@F>gw4al5*25*Sm5YuQq);}aSY6n<>}IPIuwA$q{swz>Cod43Cx`^5 zt>Dya;p{Hy*xsw#DJFg5S_MuMI)q?=nn-Xn|Kx^5YbowL@VN*q?8vow--Km)-Qczo zpOUeJmz09u>jDFp7?A7lqeqM5AxC77IpwG!3gLY*)qq`Gxv74vTS)3#`xHCw2>yLD za5468m!7l%r3_KkhJ{EFyN&A?Ikvq5Iq$Gv50B`OB)~16+y6ZT^*E16St*xju>EfM z-;Mt=1e!%s{uZv&ewO_BpSoRgt{!K853&IfwVwI_8D5So*!Ll!1qQ+a9=sDUEn8W| z>+!trHyMlZJJ40#RtG=R0{coDZcmS^$=}|iC#}dYW~ull8yyHWt{$H>Dx2IK<|n2Y z6J=52w*}Y0z_cW0LmbHK-1+xg1>+c3U``1wW(+dS>+#pc-Y@F8Q{^yeV@?fG09)g* zt|coy3SM7r=4#)eA`a_Fn39db2Ic2rDw@Avq9mqF^!m=ZF*hD! zsT(&Y*G_0baU>g>T(?f{H%1?ldUmyLyQKJmYcP8!BYA>9CqIX&BXW_9YL&8*H!ZrP zUV}U7_Ek8*N{gWM<6z93rM>L+I2P;cD6~gn2)}A3*t_O5gd{X|qkAvK0MHr%1AecM zw%k(2Z1&XSnV#y+y7%+vp-x~KLm*o;<#iZ|oFP1@w1BKkY3@h8|!n_r!}#=k8}8quM9eD&uA_|nfosg<+?QCq z&2k^to)2ipzgJ=kt52&JwPBYY4GMn$4QAzqg?V>Qf#w2&3zn4Xy8^Q`HWPE8hzJ}1 zNW+=w(Rd=Chn{vN-}lfIrz@M{OS?RJ!ocSl4E9qG&pQ@f;Q6fpq zs(M|y_eGV8cBPyn#Y#eA0ZtJZDaj)i!6t*LR0=8?SsH7?+1erUM(fL5SM1_OsiOC| zW6Yo+<5iiL+<{8S_S(`Fp{fx#?W!FAxpacld-mYIYw7w$dpU+`;;5Q`2-TlmPgKZ* zANdeN;vE2%02Hg9Je>p(J{q4bs-mJmkzrZ7LXi;l zy{9Qc6Y}rH)Nr39F-sT|+;t7lmw&lm^ZU1vtS;gPAuuCO%Hf=26S51F2axr2%y~%H;0O~4iFy`{#|Jm|QB-T+9yOGh-bleoh@WlZbw=)!Q?LhKKTp<`Ot zg4#(0=E6QwiOCNz)ho$Jn&}m(ZtTm>Vs3KUYRwfvK(>-=O!&9(zkp`MC@f_cnwNcP zW+iLx@709BY@edD@qi`#IxfY1}<7y>Q zg*o33#GOrApZu#3LfSdq4?>)F&-Bzdm49*Qo(Or%cEM$?xURPkbu!V1Q;O&Z*;Zo$ zZy*w@R(M5rkm#+kt3nB2xu~?fbcj`+3v%%rR%AR`<^2%b8f>W|B{FEukfCf)qO6(0 zizZmnw7Ic=VfIl9GzBH;uu^r8P2h%OUUnc8I~RD29iepQOvO<;*wD*$e!xDdzt+J4 z7mj)zlJur-Us)}XM@4cLAj8Cv%S3Uv8ybmm<-2Di>m+s#Acr@_mZA?p@ynQV?hcqD z5B?&|8FHfhHL4{sW!PqDM{m}>SQB=#N*h$M1OU)!0N}a(1}7pNgMr#4e?N+2 zdTdHnsw`kHMXy?^5(yl$Y^hA2>IC#(7t?O8(!3n-eDIZ}`|e3_ckZ$`6h>+$>?LyK zrDRS@g~@&~EN69D9zvw>ebIGZT+Ls7o{)~hQ-UA77v`V#^oS zkrg`e_TP`X0va65Qi4v{DETW|#RC^}x^>!O@u|DeU-&zBbWh&WN{W)?$!7-FUx2Kg z*nNUlO8b|clkp+O2SC4iZM5VHP}8h-2Dt-oepF2FO-y8}+FV=`2%g$si|}u%7v2Dl zWr5DoY02ssseCC8TN0GuH?k+a*twO_Z*WWGAZIqTy}j?+5ZHr88TW8~5fXq)!Y2kX zt6nmTokPA7VNTw+#o>FT+=o>eX<*4SWn0t(fCtk>R30nc(L4%%BA3v zF^Y?-L)-@9oK$HJ^&#^RYM02V4$9;OQU+=%tzY48kiS2X4+2;~#XD1$5*d{kBu`ReCuENA z+gSUZ@>{LD&Mau~y&1z_s*|-U4cV$R@?evoSCGnm^}L`f-BRn{lWX7fc02X84KRK2 zbWq#EVN7171>_suvpe9L()^K!^Jru)Qk1Rv7zPpx-Kh`Gnl~L!Iki@g$B_F`JHfmk z%BUu-O+2n&`nHY0^E0WntBwb5yt4}NtseG$$*cn1+~I?}z0>bcA%T=P-Pu{aQ?=4l z)$RmE$n)HA*UT{tQrpXxCipE1zZONTH|40qL66VVx2_Qgl@n0>d;_C27pj| z59wpzsEi`&WT(}{Q6;c0rC^Uq%!|#0naTDXyxj1rTL%U^GMKdk*aPV)&Tv<1FIw$1 z7Q^kcor_6F2W}V#kG!)On%lZeu`{t7Wxci;&PZf>zK==c0F}iB>e8bOI5l{I*jym{ zNV%%zlbX@JrR(EO!UgT;bft6_$|8wDkE8+~?9cL=52;RS{bEJFWJE_f)0}6M8$73G z)&9uMZBh%pn~8|(;6=JIvsSVONk4Tt!7NW{o=o`Bz%IH}p@v&!`xWMZ!ovm(((>@q zk7!r;h%{#JH+OvNEdNe%lZg~?G6JP#^j0tZKNoCv(?Y)B7(6p!w)o#d9V;{ z`cyvA;;ak)+>xBQFct0t#|ZHX+}3~92%nMG`}i2}qt`I_!eHL2lLmJr#!Tz0CihN~ zb%$|*Eg>BXS~Sj~{?05 z$mCjbY_ctab0?sDy-hs_vjPJ_Mw2%P*-NBjR~H#Sey$6?)}1`5w}G!X=BUW+XSO*t z(Gp1W`zrg>)1H-Zyq;p7i$nKC^2RCOoBO#nck-2o7uMj$Ge4tRrIFDLLTo<3r?Xyi zA}b@E*G~NK((3crozPp%F zx7?fAY*a0B-bj7$Z3+d|V-4iSUhHb{R4EDG8+}W%aPrF`&FbD5^+f9TC}r*VY}CGTPV_va$SO#ErTU*N zRuuIrm2q&|b27;KL~wn@zIMg?a4K<%p}L=50PYb;;}k|6u|(( z{!4_Yo-n1F9BI96_lL?iEd8)VxX*Rc1IX3+SK$Rv%mE_gFOWb1A#uY08b5dBzs67K z{~A9P`yb=y2K>j1Fn$i{e~h2N|L?i~&mHo&%YWVf@45faJ@9{r8ASS`?g#QdKj9ue ToJs!Af43z?SZw7 literal 0 HcmV?d00001 diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/public/crossdomain.xml hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/public/crossdomain.xml new file mode 100644 index 0000000..43a2ea6 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/public/crossdomain.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/testem.json hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/testem.json new file mode 100644 index 0000000..0f35392 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/testem.json @@ -0,0 +1,12 @@ +{ + "framework": "qunit", + "test_page": "tests/index.html?hidepassed", + "disable_watching": true, + "launch_in_ci": [ + "PhantomJS" + ], + "launch_in_dev": [ + "PhantomJS", + "Chrome" + ] +} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/helpers/resolver.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/helpers/resolver.js new file mode 100644 index 0000000..f94998c --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/helpers/resolver.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 Resolver from 'ember/resolver'; +import config from '../../config/environment'; + +var resolver = Resolver.create(); + +resolver.namespace = { + modulePrefix: config.modulePrefix, + podModulePrefix: config.podModulePrefix +}; + +export default resolver; diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/helpers/start-app.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/helpers/start-app.js new file mode 100644 index 0000000..a7d05be --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/helpers/start-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'; +import Application from '../../app'; +import config from '../../config/environment'; + +export default function startApp(attrs) { + var application; + + var attributes = Ember.merge({}, config.APP); + attributes = Ember.merge(attributes, attrs); // use defaults, but you can override; + + Ember.run(function() { + application = Application.create(attributes); + application.setupForTesting(); + application.injectTestHelpers(); + }); + + return application; +} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/index.html hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/index.html new file mode 100644 index 0000000..9681e8b --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/index.html @@ -0,0 +1,51 @@ + + + + + + + + YarnUi Tests + + + + {{content-for 'head'}} + {{content-for 'test-head'}} + + + + + + {{content-for 'head-footer'}} + {{content-for 'test-head-footer'}} + + + + {{content-for 'body'}} + {{content-for 'test-body'}} + + + + + + + {{content-for 'body-footer'}} + {{content-for 'test-body-footer'}} + + diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/breadcrumb-bar-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/breadcrumb-bar-test.js new file mode 100644 index 0000000..ffc6515 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/breadcrumb-bar-test.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 { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('breadcrumb-bar', 'Integration | Component | breadcrumb bar', { + integration: true +}); + +test('it renders', function(assert) { + + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... });" + EOL + EOL + + + this.render(hbs`{{breadcrumb-bar}}`); + + assert.equal(this.$().text().trim(), ''); + + // Template block usage:" + EOL + + this.render(hbs` + {{#breadcrumb-bar}} + template block text + {{/breadcrumb-bar}} + `); + + assert.equal(this.$().text().trim(), 'template block text'); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/test-helper.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/test-helper.js new file mode 100644 index 0000000..96975ee --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/test-helper.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. + */ + +import resolver from './helpers/resolver'; +import { + setResolver +} from 'ember-qunit'; + +setResolver(resolver); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-app-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-app-test.js new file mode 100644 index 0000000..726345f --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-app-test.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 { moduleFor, test } from 'ember-qunit'; + +moduleFor('adapter:yarn-app', 'Unit | Adapter | yarn app', { + // Specify the other units that are required for this test. + // needs: ['serializer:foo'] +}); + +// Replace this with your real tests. +test('it exists', function(assert) { + var adapter = this.subject(); + assert.ok(adapter); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-container-log-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-container-log-test.js new file mode 100644 index 0000000..e6e7b43 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-container-log-test.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 { moduleFor, test } from 'ember-qunit'; +import Constants from 'yarn-ui/constants'; + +moduleFor('adapter:yarn-container-log', 'Unit | Adapter | ContainerLog', { +}); + +test('Basic creation', function(assert) { + let adapter = this.subject(); + + assert.ok(adapter); + assert.ok(adapter.urlForFindRecord); + assert.ok(adapter.ajax); + assert.ok(adapter.headers); + assert.ok(adapter.host); + assert.ok(adapter.namespace); + assert.equal(adapter.headers.Accept, "text/plain"); + assert.equal(adapter.namespace, "ws/v1/node"); +}); + +test('urlForFindRecord test', function(assert) { + let adapter = this.subject(); + let host = adapter.host; + assert.equal(adapter.urlForFindRecord("localhost:8042" + + Constants.PARAM_SEPARATOR + "container_e27_11111111111_0001_01_000001" + + Constants.PARAM_SEPARATOR + "syslog"), + host + "localhost:8042/ws/v1/node/containerlogs/" + + "container_e27_11111111111_0001_01_000001/syslog"); +}); + +test('ajaxOptions test', function(assert) { + let adapter = this.subject(); + var hash = adapter.ajaxOptions('/containerlogs', 'type', {}); + assert.equal(hash.dataType, 'text'); +}); + +test('findRecord test', function(assert) { + let adapter = this.subject(), + testModel = { modelName: "testModel" }, + testStore = {}, + testSnapshot = {}; + let host = adapter.host; + let testId = "localhost:8042" + Constants.PARAM_SEPARATOR + + "container_e27_11111111111_0001_01_000001" + Constants.PARAM_SEPARATOR + + "syslog"; + assert.expect(2); + + adapter.ajax = function (url, method) { + assert.equal(url, host + "localhost:8042/ws/v1/node/containerlogs/" + + "container_e27_11111111111_0001_01_000001/syslog"); + assert.equal(method, 'GET'); + }; + + adapter.findRecord(testStore, testModel, testId, testSnapshot); +}); + diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-node-app-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-node-app-test.js new file mode 100644 index 0000000..3a25996 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-node-app-test.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 { moduleFor, test } from 'ember-qunit'; + +moduleFor('adapter:yarn-node-app', 'Unit | Adapter | NodeApp', { +}); + +test('Basic creation', function(assert) { + let adapter = this.subject(); + assert.expect(11); + assert.ok(adapter); + assert.ok(adapter.urlForQueryRecord); + assert.ok(adapter.queryRecord); + assert.ok(adapter.urlForQuery); + assert.ok(adapter.query); + assert.ok(adapter.ajax); + assert.ok(adapter.headers); + assert.ok(adapter.host); + assert.ok(adapter.namespace); + assert.equal("application/json", adapter.headers.Accept); + assert.equal("ws/v1/node", adapter.namespace); +}); + +test('urlForQueryRecord test', function(assert) { + let adapter = this.subject(); + let host = adapter.host; + assert.equal( + host + "localhost:8042/ws/v1/node/apps/application_1111111111_1111", + adapter.urlForQueryRecord( + {nodeAddr: "localhost:8042", appId: "application_1111111111_1111"})); +}); + +test('urlForQuery test', function(assert) { + let adapter = this.subject(); + let host = adapter.host; + assert.equal(host + "localhost:8042/ws/v1/node/apps", + adapter.urlForQuery({nodeAddr: "localhost:8042"})); +}); + +test('query test', function(assert) { + let adapter = this.subject(), + testModel = { modelName: "testModel" }, + testStore = {}, + testQuery = {nodeAddr: "localhost:8042"}; + let host = adapter.host; + assert.expect(3); + + adapter.ajax = function (url, method, hash) { + assert.equal(host + "localhost:8042/ws/v1/node/apps", url); + assert.equal('GET', method); + assert.equal(null, hash.data); + }; + + adapter.query(testStore, testModel, testQuery); +}); + +test('queryRecord test', function(assert) { + let adapter = this.subject(), + testModel = { modelName: "testModel" }, + testStore = {}, + testQuery = { + nodeAddr: "localhost:8042", + appId: "application_1111111111_1111" + }; + let host = adapter.host; + assert.expect(3); + + adapter.ajax = function (url, method, hash) { + assert.equal( + host + "localhost:8042/ws/v1/node/apps/application_1111111111_1111", + url); + assert.equal('GET', method); + assert.equal(null, hash.data); + }; + + adapter.queryRecord(testStore, testModel, testQuery); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-node-container-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-node-container-test.js new file mode 100644 index 0000000..7d2bb2d --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-node-container-test.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 { moduleFor, test } from 'ember-qunit'; + +moduleFor('adapter:yarn-node-container', 'Unit | Adapter | NodeContainer', { +}); + +test('Basic creation', function(assert) { + let adapter = this.subject(); + assert.expect(11); + assert.ok(adapter); + assert.ok(adapter.urlForQueryRecord); + assert.ok(adapter.queryRecord); + assert.ok(adapter.urlForQuery); + assert.ok(adapter.query); + assert.ok(adapter.ajax); + assert.ok(adapter.headers); + assert.ok(adapter.host); + assert.ok(adapter.namespace); + assert.equal("application/json", adapter.headers.Accept); + assert.equal("ws/v1/node", adapter.namespace); +}); + +test('urlForQueryRecord test', function(assert) { + let adapter = this.subject(); + let host = adapter.host; + assert.equal(host + "localhost:8042/ws/v1/node/containers/" + + "container_e27_11111111111_0001_01_000001", + adapter.urlForQueryRecord( + {nodeHttpAddr: "localhost:8042", + containerId: "container_e27_11111111111_0001_01_000001"})); +}); + +test('urlForQuery test', function(assert) { + let adapter = this.subject(); + let host = adapter.host; + assert.equal(host + "localhost:8042/ws/v1/node/containers", + adapter.urlForQuery({nodeHttpAddr: "localhost:8042"})); +}); + +test('query test', function(assert) { + let adapter = this.subject(), + testModel = { modelName: "testModel" }, + testStore = {}, + testQuery = {nodeHttpAddr: "localhost:8042"}; + let host = adapter.host; + assert.expect(3); + + adapter.ajax = function (url, method, hash) { + assert.equal(host + "localhost:8042/ws/v1/node/containers", url); + assert.equal('GET', method); + assert.equal(null, hash.data); + }; + + adapter.query(testStore, testModel, testQuery); +}); + +test('queryRecord test', function(assert) { + let adapter = this.subject(), + testModel = { modelName: "testModel" }, + testStore = {}, + testQuery = { + nodeHttpAddr: "localhost:8042", + containerId: "container_e27_11111111111_0001_01_000001" + }; + let host = adapter.host; + assert.expect(3); + + adapter.ajax = function (url, method, hash) { + assert.equal(host + "localhost:8042/ws/v1/node/containers/" + + "container_e27_11111111111_0001_01_000001", url); + assert.equal('GET', method); + assert.equal(null, hash.data); + }; + + adapter.queryRecord(testStore, testModel, testQuery); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-node-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-node-test.js new file mode 100644 index 0000000..15aefef --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-node-test.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 { moduleFor, test } from 'ember-qunit'; + +moduleFor('adapter:yarn-node', 'Unit | Adapter | Node', { +}); + +test('Basic creation', function(assert) { + let adapter = this.subject(); + + assert.ok(adapter); + assert.ok(adapter.urlForFindRecord); + assert.ok(adapter.ajax); + assert.ok(adapter.headers); + assert.ok(adapter.host); + assert.ok(adapter.namespace); + assert.equal(adapter.headers.Accept, "application/json"); + assert.equal(adapter.namespace, "ws/v1/node"); +}); + +test('urlForFindRecord test', function(assert) { + let adapter = this.subject(); + let host = adapter.host; + assert.equal(adapter.urlForFindRecord("localhost:8042"), + host + "localhost:8042/ws/v1/node"); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-rm-node-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-rm-node-test.js new file mode 100644 index 0000000..bf009d4 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-rm-node-test.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 { moduleFor, test } from 'ember-qunit'; + +moduleFor('adapter:yarn-rm-node', 'Unit | Adapter | RMNode', { + // Specify the other units that are required for this test. + // needs: ['serializer:foo'] +}); + +test('Basic creation', function(assert) { + let adapter = this.subject(); + + assert.ok(adapter); + assert.ok(adapter.urlForFindRecord); + assert.ok(adapter.ajax); + assert.ok(adapter.headers); + assert.ok(adapter.host); + assert.ok(adapter.namespace); + assert.equal(adapter.headers.Accept, "application/json"); + assert.equal(adapter.namespace, "ws/v1/cluster"); +}); + +test('urlForFindRecord test', function(assert) { + let adapter = this.subject(); + let host = adapter.host; + assert.equal(adapter.urlForFindRecord("localhost:8042"), + host + "/ws/v1/cluster/nodes/localhost:8042"); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-app-attempt-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-app-attempt-test.js new file mode 100644 index 0000000..0d6c16c --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-app-attempt-test.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 { moduleFor, test } from 'ember-qunit'; + +moduleFor('controller:yarn-app-attempt', 'Unit | Controller | yarn app attempt', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] +}); + +// Replace this with your real tests. +test('it exists', function(assert) { + let controller = this.subject(); + assert.ok(controller); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-app-attempts-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-app-attempts-test.js new file mode 100644 index 0000000..3894db2 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-app-attempts-test.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 { moduleFor, test } from 'ember-qunit'; + +moduleFor('controller:yarn-app-attempts', 'Unit | Controller | yarn app attempts', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] +}); + +// Replace this with your real tests. +test('it exists', function(assert) { + let controller = this.subject(); + assert.ok(controller); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-app-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-app-test.js new file mode 100644 index 0000000..1cc95c5 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-app-test.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 { moduleFor, test } from 'ember-qunit'; + +moduleFor('controller:yarn-app', 'Unit | Controller | yarn app', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] +}); + +// Replace this with your real tests. +test('it exists', function(assert) { + let controller = this.subject(); + assert.ok(controller); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-apps-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-apps-test.js new file mode 100644 index 0000000..baa67cc --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-apps-test.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 { moduleFor, test } from 'ember-qunit'; + +moduleFor('controller:yarn-apps', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] +}); + +// Replace this with your real tests. +test('it exists', function(assert) { + var controller = this.subject(); + assert.ok(controller); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-container-log-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-container-log-test.js new file mode 100644 index 0000000..0f8dc03 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-container-log-test.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 { moduleFor, test } from 'ember-qunit'; + +moduleFor('controller:yarn-container-log', 'Unit | Controller | yarn container log', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] +}); + +// Replace this with your real tests. +test('it exists', function(assert) { + let controller = this.subject(); + assert.ok(controller); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-node-app-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-node-app-test.js new file mode 100644 index 0000000..852efef --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-node-app-test.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 { moduleFor, test } from 'ember-qunit'; + +moduleFor('controller:yarn-node-app', 'Unit | Controller | yarn node app', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] +}); + +// Replace this with your real tests. +test('it exists', function(assert) { + let controller = this.subject(); + assert.ok(controller); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-node-apps-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-node-apps-test.js new file mode 100644 index 0000000..40c5d44 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-node-apps-test.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 { moduleFor, test } from 'ember-qunit'; + +moduleFor('controller:yarn-node-apps', 'Unit | Controller | yarn node apps', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] +}); + +// Replace this with your real tests. +test('it exists', function(assert) { + let controller = this.subject(); + assert.ok(controller); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-node-containers-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-node-containers-test.js new file mode 100644 index 0000000..929adcd --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-node-containers-test.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 { moduleFor, test } from 'ember-qunit'; + +moduleFor('controller:yarn-node-containers', 'Unit | Controller | yarn node containers', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] +}); + +// Replace this with your real tests. +test('it exists', function(assert) { + let controller = this.subject(); + assert.ok(controller); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-node-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-node-test.js new file mode 100644 index 0000000..59f443f --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-node-test.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 { moduleFor, test } from 'ember-qunit'; + +moduleFor('controller:yarn-node', 'Unit | Controller | yarn node', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] +}); + +// Replace this with your real tests. +test('it exists', function(assert) { + let controller = this.subject(); + assert.ok(controller); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-nodes-heatmap-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-nodes-heatmap-test.js new file mode 100644 index 0000000..4833302 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-nodes-heatmap-test.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 { moduleFor, test } from 'ember-qunit'; + +moduleFor('controller:yarn-nodes-heatmap', 'Unit | Controller | yarn nodes heatmap', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] +}); + +// Replace this with your real tests. +test('it exists', function(assert) { + let controller = this.subject(); + assert.ok(controller); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-nodes-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-nodes-test.js new file mode 100644 index 0000000..ccd0bff --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-nodes-test.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 { moduleFor, test } from 'ember-qunit'; + +moduleFor('controller:yarn-nodes', 'Unit | Controller | yarn nodes', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] +}); + +// Replace this with your real tests. +test('it exists', function(assert) { + let controller = this.subject(); + assert.ok(controller); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-queue-apps-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-queue-apps-test.js new file mode 100644 index 0000000..adf2e07 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-queue-apps-test.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 { moduleFor, test } from 'ember-qunit'; + +moduleFor('controller:yarn-queue-apps', 'Unit | Controller | yarn queue apps', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] +}); + +// Replace this with your real tests. +test('it exists', function(assert) { + let controller = this.subject(); + assert.ok(controller); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-queues-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-queues-test.js new file mode 100644 index 0000000..0978208 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-queues-test.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 { moduleFor, test } from 'ember-qunit'; + +moduleFor('controller:yarn-queues', 'Unit | Controller | yarn queues', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] +}); + +// Replace this with your real tests. +test('it exists', function(assert) { + let controller = this.subject(); + assert.ok(controller); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-services-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-services-test.js new file mode 100644 index 0000000..53834e2 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-services-test.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 { moduleFor, test } from 'ember-qunit'; + +moduleFor('controller:yarn-services', 'Unit | Controller | yarn services', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] +}); + +// Replace this with your real tests. +test('it exists', function(assert) { + let controller = this.subject(); + assert.ok(controller); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/helpers/node-name-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/helpers/node-name-test.js new file mode 100644 index 0000000..8ff5eb6 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/helpers/node-name-test.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. + */ + +import { nodeName } from '../../../helpers/node-name'; +import { module, test } from 'qunit'; + +module('Unit | Helper | node name'); + +// Replace this with your real tests. +test('it works', function(assert) { + let result = nodeName(42); + assert.ok(result); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/initializers/env-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/initializers/env-test.js new file mode 100644 index 0000000..d6dacfd --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/initializers/env-test.js @@ -0,0 +1,41 @@ +/** + * 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 { initialize } from '../../../initializers/env'; +import { module, test } from 'qunit'; + +var registry, application; + +module('Unit | Initializer | env', { + beforeEach: function() { + Ember.run(function() { + application = Ember.Application.create(); + registry = application.registry; + application.deferReadiness(); + }); + } +}); + +// Replace this with your real tests. +test('it works', function(assert) { + initialize(registry, application); + + // you would normally confirm the results of the initializer here + assert.ok(true); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/initializers/hosts-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/initializers/hosts-test.js new file mode 100644 index 0000000..b9a6b27 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/initializers/hosts-test.js @@ -0,0 +1,41 @@ +/** + * 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 { initialize } from '../../../initializers/hosts'; +import { module, test } from 'qunit'; + +var registry, application; + +module('Unit | Initializer | hosts', { + beforeEach: function() { + Ember.run(function() { + application = Ember.Application.create(); + registry = application.registry; + application.deferReadiness(); + }); + } +}); + +// Replace this with your real tests. +test('it works', function(assert) { + initialize(registry, application); + + // you would normally confirm the results of the initializer here + assert.ok(true); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/initializers/jquery-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/initializers/jquery-test.js new file mode 100644 index 0000000..c7a9803 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/initializers/jquery-test.js @@ -0,0 +1,41 @@ +/** + * 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 { initialize } from '../../../initializers/jquery'; +import { module, test } from 'qunit'; + +var registry, application; + +module('Unit | Initializer | jquery', { + beforeEach: function() { + Ember.run(function() { + application = Ember.Application.create(); + registry = application.registry; + application.deferReadiness(); + }); + } +}); + +// Replace this with your real tests. +test('it works', function(assert) { + initialize(registry, application); + + // you would normally confirm the results of the initializer here + assert.ok(true); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/initializers/loader-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/initializers/loader-test.js new file mode 100644 index 0000000..cc32e92 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/initializers/loader-test.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'; +import LoaderInitializer from '../../../initializers/loader'; +import { module, test } from 'qunit'; + +let application; + +module('Unit | Initializer | loader', { + beforeEach() { + Ember.run(function() { + application = Ember.Application.create(); + application.deferReadiness(); + }); + } +}); + +// Replace this with your real tests. +test('it works', function(assert) { + LoaderInitializer.initialize(application); + + // you would normally confirm the results of the initializer here + assert.ok(true); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/mixins/charts-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/mixins/charts-test.js new file mode 100644 index 0000000..1f5ab99 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/mixins/charts-test.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 Ember from 'ember'; +import ChartsMixin from '../../../mixins/charts'; +import { module, test } from 'qunit'; + +module('Unit | Mixin | charts'); + +// Replace this with your real tests. +test('it works', function(assert) { + var ChartsObject = Ember.Object.extend(ChartsMixin); + var subject = ChartsObject.create(); + assert.ok(subject); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-app-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-app-test.js new file mode 100644 index 0000000..8b6df23 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-app-test.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 { moduleForModel, test } from 'ember-qunit'; + +moduleForModel('yarn-app', 'Unit | Model | yarn app', { + // Specify the other units that are required for this test. + needs: [] +}); + +test('it exists', function(assert) { + var model = this.subject(); + // var store = this.store(); + assert.ok(!!model); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-container-log-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-container-log-test.js new file mode 100644 index 0000000..45808a5 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-container-log-test.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 { moduleForModel, test } from 'ember-qunit'; + +moduleForModel('yarn-container-log', 'Unit | Model | ContainerLog', { + // Specify the other units that are required for this test. + needs: [] +}); + +test('Basic creation test', function(assert) { + let model = this.subject(); + assert.ok(model); + assert.ok(model._notifyProperties); + assert.ok(model.didLoad); + assert.ok(model.logs); + assert.ok(model.containerID); + assert.ok(model.logFileName); +}); + +test('test fields', function(assert) { + let model = this.subject(); + + Ember.run(function () { + model.set("logs", "This is syslog"); + model.set("containerID", "container_e32_1456000363780_0002_01_000001"); + model.set("logFileName", "syslog"); + assert.equal(model.get("logs"), "This is syslog"); + assert.equal(model.get("containerID"), "container_e32_1456000363780_0002_01_000001"); + assert.equal(model.get("logFileName"), "syslog"); + }); +}); + diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-node-app-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-node-app-test.js new file mode 100644 index 0000000..7e2e62f --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-node-app-test.js @@ -0,0 +1,65 @@ +/** + * 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 { moduleForModel, test } from 'ember-qunit'; + +moduleForModel('yarn-node-app', 'Unit | Model | NodeApp', { + // Specify the other units that are required for this test. + needs: [] +}); + +test('Basic creation test', function(assert) { + let model = this.subject(); + + assert.ok(model); + assert.ok(model._notifyProperties); + assert.ok(model.didLoad); + assert.ok(model.appId); + assert.ok(model.state); + assert.ok(model.user); + assert.ok(model.containers); +}); + +test('test fields', function(assert) { + let model = this.subject(); + + assert.expect(9); + Ember.run(function () { + model.set("appId", "application_1456251210105_0002"); + model.set("id", "application_1456251210105_0002"); + model.set("state", "RUNNING"); + model.set("user", "hadoop"); + model.set("containers", ["container_e38_1456251210105_0002_01_000001", + "container_e38_1456251210105_0002_01_000002"]); + assert.equal(model.get("appId"), "application_1456251210105_0002"); + assert.equal(model.get("state"), "RUNNING"); + assert.equal(model.get("user"), "hadoop"); + assert.deepEqual(model.get("containers"), + ["container_e38_1456251210105_0002_01_000001", + "container_e38_1456251210105_0002_01_000002"]); + assert.equal(model.get("appStateStyle"), "label label-primary"); + assert.equal(model.get("isDummyApp"), false); + model.set("id", "dummy"); + assert.equal(model.get("isDummyApp"), true); + model.set("state", "FINISHED"); + assert.equal(model.get("appStateStyle"), "label label-success"); + model.set("state", "NEW"); + assert.equal(model.get("appStateStyle"), "label label-default"); + }); +}); + diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-node-container-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-node-container-test.js new file mode 100644 index 0000000..88bf233 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-node-container-test.js @@ -0,0 +1,78 @@ +/** + * 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 { moduleForModel, test } from 'ember-qunit'; + +moduleForModel('yarn-node-container', 'Unit | Model | NodeContainer', { + // Specify the other units that are required for this test. + needs: [] +}); + +test('Basic creation test', function(assert) { + let model = this.subject(); + + assert.ok(model); + assert.ok(model._notifyProperties); + assert.ok(model.didLoad); + assert.ok(model.containerId); + assert.ok(model.state); + assert.ok(model.user); + assert.ok(model.exitCode); + assert.ok(model.totalMemoryNeeded); + assert.ok(model.totalVCoresNeeded); + assert.ok(model.containerLogFiles); + assert.ok(model.isDummyContainer); + assert.ok(model.containerStateStyle); +}); + +test('test fields', function(assert) { + let model = this.subject(); + + Ember.run(function () { + model.set("containerId", "container_e32_1456000363780_0002_01_000003"); + model.set("state", "RUNNING"); + model.set("exitCode", "-1000"); + model.set("user", "hadoop"); + model.set("id", "container_e32_1456000363780_0002_01_000003"); + model.set("totalMemoryNeeded", 1024); + model.set("totalVCoresNeeded", 1); + model.set("containerLogFiles", ["syslog", "stderr", "stdout"]); + assert.equal(model.get("containerId"), "container_e32_1456000363780_0002_01_000003"); + assert.equal(model.get("id"), "container_e32_1456000363780_0002_01_000003"); + assert.equal(model.get("totalMemoryNeeded"), 1024); + assert.equal(model.get("totalVCoresNeeded"), 1); + assert.equal(model.get("user"), "hadoop"); + assert.equal(model.get("exitCode"), "-1000"); + assert.equal(model.get("containerLogFiles").length, 3); + assert.deepEqual(model.get("containerLogFiles"), ["syslog", "stderr", "stdout"]); + assert.equal(model.get("isDummyContainer"), false); + assert.equal(model.get("containerStateStyle"), "label label-primary"); + model.set("id", "dummy"); + assert.equal(model.get("isDummyContainer"), true); + model.set("state", "EXITED_WITH_SUCCESS"); + assert.equal(model.get("containerStateStyle"), "label label-success"); + model.set("state", "EXITED_WITH_FAILURE"); + assert.equal(model.get("containerStateStyle"), "label label-danger"); + model.set("state", "DONE"); + model.set("exitCode", "0"); + assert.equal(model.get("containerStateStyle"), "label label-success"); + model.set("exitCode", "-105"); + assert.equal(model.get("containerStateStyle"), "label label-danger"); + }); +}); + diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-node-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-node-test.js new file mode 100644 index 0000000..5877589 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-node-test.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 { moduleForModel, test } from 'ember-qunit'; + +moduleForModel('yarn-node', 'Unit | Model | Node', { + // Specify the other units that are required for this test. + needs: [] +}); + +test('Basic creation test', function(assert) { + let model = this.subject(); + + assert.ok(model); + assert.ok(model._notifyProperties); + assert.ok(model.didLoad); + assert.ok(model.totalVmemAllocatedContainersMB); + assert.ok(model.vmemCheckEnabled); + assert.ok(model.pmemCheckEnabled); + assert.ok(model.nodeHealthy); + assert.ok(model.lastNodeUpdateTime); + assert.ok(model.healthReport); + assert.ok(model.nmStartupTime); + assert.ok(model.nodeManagerBuildVersion); + assert.ok(model.hadoopBuildVersion); +}); + +test('test fields', function(assert) { + let model = this.subject(); + + assert.expect(4); + Ember.run(function () { + model.set("totalVmemAllocatedContainersMB", 4096); + model.set("totalPmemAllocatedContainersMB", 2048); + model.set("totalVCoresAllocatedContainers", 4); + model.set("hadoopBuildVersion", "3.0.0-SNAPSHOT"); + assert.equal(model.get("totalVmemAllocatedContainersMB"), 4096); + assert.equal(model.get("totalPmemAllocatedContainersMB"), 2048); + assert.equal(model.get("totalVCoresAllocatedContainers"), 4); + assert.equal(model.get("hadoopBuildVersion"), "3.0.0-SNAPSHOT"); + }); +}); + diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-rm-node-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-rm-node-test.js new file mode 100644 index 0000000..4fd2517 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-rm-node-test.js @@ -0,0 +1,95 @@ +/** + * 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 { moduleForModel, test } from 'ember-qunit'; + +moduleForModel('yarn-rm-node', 'Unit | Model | RMNode', { + // Specify the other units that are required for this test. + needs: [] +}); + +test('Basic creation test', function(assert) { + let model = this.subject(); + + assert.ok(model); + assert.ok(model._notifyProperties); + assert.ok(model.didLoad); + assert.ok(model.rack); + assert.ok(model.state); + assert.ok(model.nodeHostName); + assert.ok(model.nodeHTTPAddress); + assert.ok(model.lastHealthUpdate); + assert.ok(model.healthReport); + assert.ok(model.numContainers); + assert.ok(model.usedMemoryMB); + assert.ok(model.availMemoryMB); + assert.ok(model.usedVirtualCores); + assert.ok(model.availableVirtualCores); + assert.ok(model.version); + assert.ok(model.nodeLabels); + assert.ok(model.nodeLabelsAsString); + assert.ok(model.nodeStateStyle); + assert.ok(model.isDummyNode); + assert.ok(model.getMemoryDataForDonutChart); + assert.ok(model.getVCoreDataForDonutChart); +}); + +test('test fields', function(assert) { + let model = this.subject(); + + Ember.run(function () { + model.set("rack", "/default-rack"); + model.set("state", "RUNNING"); + model.set("nodeHostName", "localhost"); + model.set("id", "localhost:64318"); + model.set("nodeHTTPAddress", "localhost:8042"); + model.set("usedMemoryMB", 1024); + model.set("availMemoryMB", 7168); + model.set("usedVirtualCores", 1); + model.set("availableVirtualCores", 7); + model.set("nodeLabels", ["x"]); + assert.equal(model.get("rack"), "/default-rack"); + assert.equal(model.get("state"), "RUNNING"); + assert.equal(model.get("nodeHostName"), "localhost"); + assert.equal(model.get("id"), "localhost:64318"); + assert.equal(model.get("nodeHTTPAddress"), "localhost:8042"); + assert.equal(model.get("usedMemoryMB"), 1024); + assert.equal(model.get("availMemoryMB"), 7168); + assert.equal(model.get("usedVirtualCores"), 1); + assert.equal(model.get("availableVirtualCores"), 7); + assert.equal(model.get("isDummyNode"), false); + assert.deepEqual(model.get("nodeLabels"), ["x"]); + assert.equal(model.get("nodeLabelsAsString"), "x"); + assert.deepEqual(model.get("nodeStateStyle"), "label label-success"); + assert.deepEqual(model.get("getMemoryDataForDonutChart"), + [{label: "Used", value: 1024}, {label: "Available", value: 7168}]); + assert.deepEqual(model.get("getVCoreDataForDonutChart"), + [{label: "Used", value: 1}, {label: "Available", value: 7}]); + model.set("state", "SHUTDOWN"); + assert.deepEqual(model.get("nodeStateStyle"), "label label-danger"); + model.set("state", "REBOOTED"); + assert.deepEqual(model.get("nodeStateStyle"), "label label-warning"); + model.set("state", "NEW"); + assert.deepEqual(model.get("nodeStateStyle"), "label label-default"); + model.set("nodeLabels", ["x","y"]); + assert.equal(model.get("nodeLabelsAsString"), "x"); + model.set("nodeLabels", undefined); + assert.equal(model.get("nodeLabelsAsString"), ""); + }); +}); + diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-app-attempts-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-app-attempts-test.js new file mode 100644 index 0000000..917a159 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-app-attempts-test.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 { moduleFor, test } from 'ember-qunit'; + +moduleFor('route:yarn-app-attempts', 'Unit | Route | yarn app attempts', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] +}); + +test('it exists', function(assert) { + let route = this.subject(); + assert.ok(route); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-apps-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-apps-test.js new file mode 100644 index 0000000..3a69c9f --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-apps-test.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 { moduleFor, test } from 'ember-qunit'; + +moduleFor('route:yarn-apps', 'Unit | Route | yarn apps', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] +}); + +test('it exists', function(assert) { + var route = this.subject(); + assert.ok(route); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-container-log-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-container-log-test.js new file mode 100644 index 0000000..4e68da0 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-container-log-test.js @@ -0,0 +1,120 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { moduleFor, test } from 'ember-qunit'; +import Constants from 'yarn-ui/constants'; + +moduleFor('route:yarn-container-log', 'Unit | Route | ContainerLog', { +}); + +test('Basic creation test', function(assert) { + let route = this.subject(); + assert.ok(route); + assert.ok(route.model); +}); + +test('Test getting container log', function(assert) { + var response = { + logs: "This is syslog", + containerID: "container_e32_1456000363780_0002_01_000001", + logFileName: "syslog"}; + var store = { + findRecord: function(type) { + return new Ember.RSVP.Promise(function(resolve) { + resolve(response); + } + )} + }; + assert.expect(6); + var route = this.subject(); + route.set('store', store); + var model = route.model({node_id: "localhost:64318", + node_addr: "localhost:8042", + container_id: "container_e32_1456000363780_0002_01_000001", + filename: "syslog"}); + model.then(function(value) { + assert.ok(value); + assert.ok(value.containerLog); + assert.deepEqual(value.containerLog, response); + assert.ok(value.nodeInfo); + assert.equal(value.nodeInfo.addr, 'localhost:8042'); + assert.equal(value.nodeInfo.id, 'localhost:64318'); + }); +}); + +/** + * This can happen when an empty response is sent from server + */ +test('Test non HTTP error while getting container log', function(assert) { + var error = {}; + var response = { + logs: "", + containerID: "container_e32_1456000363780_0002_01_000001", + logFileName: "syslog"}; + var store = { + findRecord: function(type) { + return new Ember.RSVP.Promise(function(resolve, reject) { + reject(error); + } + )} + }; + assert.expect(6); + var route = this.subject(); + route.set('store', store); + var model = route.model({node_id: "localhost:64318", + node_addr: "localhost:8042", + container_id: "container_e32_1456000363780_0002_01_000001", + filename: "syslog"}); + model.then(function(value) { + assert.ok(value); + assert.ok(value.containerLog); + assert.deepEqual(value.containerLog, response); + assert.ok(value.nodeInfo); + assert.equal(value.nodeInfo.addr, 'localhost:8042'); + assert.equal(value.nodeInfo.id, 'localhost:64318'); + }); +}); + +test('Test HTTP error while getting container log', function(assert) { + var error = {errors: [{status: 404, responseText: 'Not Found'}]}; + var response = { + logs: "", + containerID: "container_e32_1456000363780_0002_01_000001", + logFileName: "syslog"}; + var store = { + findRecord: function(type) { + return new Ember.RSVP.Promise(function(resolve, reject) { + reject(error); + } + )} + }; + assert.expect(5); + var route = this.subject(); + route.set('store', store); + var model = route.model({node_id: "localhost:64318", + node_addr: "localhost:8042", + container_id: "container_e32_1456000363780_0002_01_000001", + filename: "syslog"}); + model.then(function(value) { + assert.ok(value); + assert.ok(value.errors); + assert.equal(value.errors.length, 1); + assert.equal(value.errors[0].status, 404); + assert.equal(value.errors[0].responseText, 'Not Found'); + }); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-node-app-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-node-app-test.js new file mode 100644 index 0000000..8e5acf9 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-node-app-test.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 { moduleFor, test } from 'ember-qunit'; + +moduleFor('route:yarn-node-app', 'Unit | Route | NodeApp', { +}); + +test('Basic creation test', function(assert) { + let route = this.subject(); + assert.ok(route); + assert.ok(route.model); +}); + +test('Test getting specific app on a node', function(assert) { + var response = + {id:"application_1456251210105_0001", state:"FINISHED", user:"root"}; + var store = { + queryRecord: function(type, query) { + return new Ember.RSVP.Promise(function(resolve) { + resolve(response); + }); + } + }; + assert.expect(6); + var route = this.subject(); + route.set('store', store); + var model = + route.model({node_id:"localhost:64318", node_addr:"localhost:8042", + app_id:"application_1456251210105_0001"}). + then( + function(value){ + assert.ok(value); + assert.ok(value.nodeApp); + assert.deepEqual(value.nodeApp, response); + assert.ok(value.nodeInfo); + assert.equal(value.nodeInfo.addr, 'localhost:8042'); + assert.equal(value.nodeInfo.id, 'localhost:64318'); + } + ); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-node-apps-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-node-apps-test.js new file mode 100644 index 0000000..44d9995 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-node-apps-test.js @@ -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. + */ + +import { moduleFor, test } from 'ember-qunit'; + +moduleFor('route:yarn-node-apps', 'Unit | Route | NodeApps', { +}); + +test('Basic creation test', function(assert) { + let route = this.subject(); + assert.ok(route); + assert.ok(route.model); +}); + +test('Test getting apps on a node', function(assert) { + var response = [ + {id:"application_1456251210105_0001", state:"FINISHED", user:"root"}, + {id:"application_1456251210105_0002", state:"RUNNING",user:"root", + containerids:["container_e38_1456251210105_0002_01_000001", + "container_e38_1456251210105_0002_01_000002"]}]; + var store = { + query: function(type, query) { + return new Ember.RSVP.Promise(function(resolve) { + resolve(response.slice()); + }); + } + }; + assert.expect(8); + var route = this.subject(); + route.set('store', store); + var model = + route.model({node_id:"localhost:64318", node_addr:"localhost:8042"}). + then( + function(value){ + assert.ok(value); + assert.ok(value.apps); + assert.equal(value.apps.length, 2); + assert.deepEqual(response[0], value.apps[0]); + assert.deepEqual(response[1], value.apps[1]); + assert.ok(value.nodeInfo); + assert.equal(value.nodeInfo.addr, 'localhost:8042'); + assert.equal(value.nodeInfo.id, 'localhost:64318'); + } + ); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-node-container-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-node-container-test.js new file mode 100644 index 0000000..f0b68fc --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-node-container-test.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 { moduleFor, test } from 'ember-qunit'; + +moduleFor('route:yarn-node-container', 'Unit | Route | NodeContainer', { +}); + +test('Basic creation test', function(assert) { + let route = this.subject(); + assert.ok(route); + assert.ok(route.model); +}); + +test('Test getting specific container on a node', function(assert) { + var response = + {id: "container_e32_1456000363780_0002_01_000001", state: "RUNNING", + exitCode:-1000,diagnostics:"",user:"root",totalMemoryNeededMB:2048, + totalVCoresNeeded:1,containerLogsLink: "http://localhost:8042/node/" + + "containerlogs/container_e32_1456000363780_0002_01_000001/root", + nodeId: "localhost:64318", containerLogFiles:["syslog","stderr", + "stdout"]}; + var store = { + queryRecord: function(type, query) { + return new Ember.RSVP.Promise(function(resolve) { + resolve(response); + }); + } + }; + assert.expect(6); + var route = this.subject(); + route.set('store', store); + var model = + route.model({node_id:"localhost:64318", node_addr:"localhost:8042", + container_id:"container_e32_1456000363780_0002_01_000001"}). + then( + function(value){ + assert.ok(value); + assert.ok(value.nodeContainer); + assert.deepEqual(value.nodeContainer, response); + assert.ok(value.nodeInfo); + assert.equal(value.nodeInfo.addr, 'localhost:8042'); + assert.equal(value.nodeInfo.id, 'localhost:64318'); + } + ); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-node-containers-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-node-containers-test.js new file mode 100644 index 0000000..8359713 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-node-containers-test.js @@ -0,0 +1,68 @@ +/** + * 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 { moduleFor, test } from 'ember-qunit'; + +moduleFor('route:yarn-node-containers', 'Unit | Route | NodeContainers', { +}); + +test('Basic creation test', function(assert) { + let route = this.subject(); + assert.ok(route); + assert.ok(route.model); +}); + +test('Test getting apps on a node', function(assert) { + var response = + [{id: "container_e32_1456000363780_0002_01_000001", state: "RUNNING", + exitCode:-1000,diagnostics:"",user:"root",totalMemoryNeededMB:2048, + totalVCoresNeeded:1,containerLogsLink: "http://localhost:8042/node/" + + "containerlogs/container_e32_1456000363780_0002_01_000001/root", + nodeId: "localhost:64318", containerLogFiles:["syslog","stderr", + "stdout"]}, + {id:"container_e32_1456000363780_0002_01_000003", state:"RUNNING", + exitCode:-1000, diagnostics:"", user:"root", totalMemoryNeededMB:1024, + totalVCoresNeeded:1,containerLogsLink:"http://localhost:8042/node" + + "/containerlogs/container_e32_1456000363780_0002_01_000003/root", + nodeId:"localhost:64318",containerLogFiles:["syslog","stderr", + "syslog.shuffle","stdout"]}]; + var store = { + query: function(type, query) { + return new Ember.RSVP.Promise(function(resolve) { + resolve(response.slice()); + }); + } + }; + assert.expect(8); + var route = this.subject(); + route.set('store', store); + var model = + route.model({node_id:"localhost:64318", node_addr:"localhost:8042"}). + then( + function(value){ + assert.ok(value); + assert.ok(value.containers); + assert.equal(value.containers.length, 2); + assert.deepEqual(value.containers[0], response[0]); + assert.deepEqual(value.containers[1], response[1]); + assert.ok(value.nodeInfo); + assert.equal(value.nodeInfo.addr, 'localhost:8042'); + assert.equal(value.nodeInfo.id, 'localhost:64318'); + } + ); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-node-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-node-test.js new file mode 100644 index 0000000..4e82f1b --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-node-test.js @@ -0,0 +1,84 @@ +/** + * 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 { moduleFor, test } from 'ember-qunit'; +import Ember from 'ember'; + +moduleFor('route:yarn-node', 'Unit | Route | Node', { +}); + +test('Basic creation test', function(assert) { + let route = this.subject(); + assert.ok(route); + assert.ok(route.model); +}); + +test('Test getting a node', function(assert) { + var nodeResponse = + {healthReport: "Healthy", totalVmemAllocatedContainersMB: 344064, + totalPmemAllocatedContainersMB: 163840, + totalVCoresAllocatedContainers: 160, + vmemCheckEnabled: true, pmemCheckEnabled: true, + lastNodeUpdateTime: 1456250210310, nodeHealthy: true, + nodeManagerVersion: "3.0.0-SNAPSHOT", + nodeManagerBuildVersion: "3.0.0-SNAPSHOT", + nodeManagerVersionBuiltOn: "2000-01-01T00:00Z", + hadoopVersion: "3.0.0-SNAPSHOT", + hadoopBuildVersion: "3.0.0-SNAPSHOT", + hadoopVersionBuiltOn: "2000-01-01T00:00Z", + id: "localhost:64318", nodeHostName: "192.168.0.102", + nmStartupTime: 1456250208231}; + var rmNodeResponse = + {rack: "/default-rack", state: "RUNNING", id: "localhost:64318", + nodeHostName: "localhost", nodeHTTPAddress: "localhost:8042", + lastHealthUpdate: 1456251290905, version: "3.0.0-SNAPSHOT", + healthReport: "", numContainers: 0, usedMemoryMB: 0, + availMemoryMB: 163840, usedVirtualCores: 0, + availableVirtualCores: 160, + resourceUtilization: { + nodePhysicalMemoryMB: 4549, nodeVirtualMemoryMB: 4549, + nodeCPUUsage: 0.14995001256465912, + aggregatedContainersPhysicalMemoryMB: 0, + aggregatedContainersVirtualMemoryMB: 0, + containersCPUUsage: 0 + }}; + + // Create store which returns appropriate responses. + var store = { + findRecord: function(type) { + if (type == 'yarnNode') { + return new Ember.RSVP.Promise(function(resolve) { + resolve(nodeResponse); + }); + } else if (type == 'yarnRmNode') { + return new Ember.RSVP.Promise(function(resolve) { + resolve(rmNodeResponse); + }); + } + } + }; + var route = this.subject(); + assert.expect(4); + route.set('store', store); + var model = route.model( + {node_addr:"localhost:8042", node_id:"localhost:64318"})._result; + assert.ok(model.node); + assert.deepEqual(model.node, nodeResponse); + assert.ok(model.rmNode); + assert.deepEqual(model.rmNode, rmNodeResponse); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-nodes-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-nodes-test.js new file mode 100644 index 0000000..baa5bd6 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-nodes-test.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 { moduleFor, test } from 'ember-qunit'; +import Ember from 'ember'; + +moduleFor('route:yarn-nodes', 'Unit | Route | Nodes', { +}); + +test('Basic creation test', function(assert) { + let route = this.subject(); + assert.ok(route); + assert.ok(route.model); +}); + +test('Test getting nodes', function(assert) { + var response = [{ + rack: "/default-rack", state: "RUNNING", id: "192.168.1.1:64318", + nodeHostName: "192.168.1.1", nodeHTTPAddress: "192.168.1.1:8042", + lastHealthUpdate: 1456251290905, version: "3.0.0-SNAPSHOT", + healthReport: "", numContainers: 0, usedMemoryMB: 0, + availMemoryMB: 163840, usedVirtualCores: 0, + availableVirtualCores: 160, + resourceUtilization: { + nodePhysicalMemoryMB: 4549, nodeVirtualMemoryMB: 4549, + nodeCPUUsage: 0.14995001256465912, + aggregatedContainersPhysicalMemoryMB: 0, + aggregatedContainersVirtualMemoryMB: 0, + containersCPUUsage: 0 + }}, + {rack: "/default-rack", state: "RUNNING", id: "192.168.1.2:64318", + nodeHostName: "192.168.1.2", nodeHTTPAddress: "192.168.1.2:8042", + lastHealthUpdate: 1456251290905, version: "3.0.0-SNAPSHOT", + healthReport: "", numContainers: 0, usedMemoryMB: 0, + availMemoryMB: 163840, usedVirtualCores: 0, + availableVirtualCores: 160, + resourceUtilization: { + nodePhysicalMemoryMB: 4549, nodeVirtualMemoryMB: 4549, + nodeCPUUsage: 0.14995001256465912, + aggregatedContainersPhysicalMemoryMB: 0, + aggregatedContainersVirtualMemoryMB: 0, + containersCPUUsage: 0 + }}]; + var store = { + findAll: function(type) { + return new Ember.RSVP.Promise(function(resolve) { + resolve(response); + }); + } + }; + var route = this.subject(); + route.set('store', store); + var model = route.model()._result; + assert.expect(4); + assert.ok(model); + assert.equal(model.length, 2); + assert.deepEqual(response[0], model[0]); + assert.deepEqual(response[1], model[1]); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-queue-apps-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-queue-apps-test.js new file mode 100644 index 0000000..6738ea0 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-queue-apps-test.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 { moduleFor, test } from 'ember-qunit'; + +moduleFor('route:yarn-queue-apps', 'Unit | Route | yarn queue apps', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] +}); + +test('it exists', function(assert) { + let route = this.subject(); + assert.ok(route); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-queues-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-queues-test.js new file mode 100644 index 0000000..5153435 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-queues-test.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 { moduleFor, test } from 'ember-qunit'; + +moduleFor('route:yarn-queues', 'Unit | Route | yarn queues', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] +}); + +test('it exists', function(assert) { + let route = this.subject(); + assert.ok(route); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/serializers/yarn-app-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/serializers/yarn-app-test.js new file mode 100644 index 0000000..4158612 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/serializers/yarn-app-test.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 { moduleForModel, test } from 'ember-qunit'; + +moduleForModel('yarn-app', 'Unit | Serializer | yarn app', { + // Specify the other units that are required for this test. + needs: ['serializer:yarn-app'] +}); + +// Replace this with your real tests. +test('it serializes records', function(assert) { + var record = this.subject(); + + var serializedRecord = record.serialize(); + + assert.ok(serializedRecord); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/serializers/yarn-container-log-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/serializers/yarn-container-log-test.js new file mode 100644 index 0000000..2349dc2 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/serializers/yarn-container-log-test.js @@ -0,0 +1,49 @@ +/** + * 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 { moduleFor, test } from 'ember-qunit'; + +moduleFor('serializer:yarn-container-log', 'Unit | Serializer | ContainerLog', { +}); + +test('Basic creation test', function(assert) { + let serializer = this.subject(); + + assert.ok(serializer); + assert.ok(serializer.normalizeSingleResponse); +}); + +test('normalizeSingleResponse test', function(assert) { + let serializer = this.subject(), + modelClass = { + modelName: "yarn-container-log" + }, + payload = "This is syslog"; + var id = "localhost:64318!container_e32_1456000363780_0002_01_000001!syslog"; + assert.expect(6); + var response = + serializer.normalizeSingleResponse({}, modelClass, payload, id, null); + assert.ok(response.data); + assert.equal(response.data.id, id); + assert.equal(response.data.type, modelClass.modelName); + assert.equal(response.data.attributes.logs, payload); + assert.equal(response.data.attributes.containerID, + "container_e32_1456000363780_0002_01_000001"); + assert.equal(response.data.attributes.logFileName, "syslog"); +}); + diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/serializers/yarn-node-app-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/serializers/yarn-node-app-test.js new file mode 100644 index 0000000..21a715c --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/serializers/yarn-node-app-test.js @@ -0,0 +1,102 @@ +/** + * 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 { moduleFor, test } from 'ember-qunit'; + +moduleFor('serializer:yarn-node-app', 'Unit | Serializer | NodeApp', { +}); + +test('Basic creation test', function(assert) { + let serializer = this.subject(); + + assert.ok(serializer); + assert.ok(serializer.normalizeSingleResponse); + assert.ok(serializer.normalizeArrayResponse); + assert.ok(serializer.internalNormalizeSingleResponse); +}); + +test('normalizeArrayResponse test', function(assert) { + let serializer = this.subject(), + modelClass = { + modelName: "yarn-node-app" + }, + payload = { + apps: { + app: [{ + id:"application_1456251210105_0001", state:"FINISHED", user:"root" + },{ + id:"application_1456251210105_0002", state:"RUNNING",user:"root", + containerids:["container_e38_1456251210105_0002_01_000001", + "container_e38_1456251210105_0002_01_000002"] + }] + } + }; + assert.expect(15); + var response = + serializer.normalizeArrayResponse({}, modelClass, payload, null, null); + assert.ok(response.data); + assert.equal(response.data.length, 2); + assert.equal(response.data[0].attributes.containers, undefined); + assert.equal(response.data[1].attributes.containers.length, 2); + assert.deepEqual(response.data[1].attributes.containers, + payload.apps.app[1].containerids); + for (var i = 0; i < 2; i++) { + assert.equal(response.data[i].type, modelClass.modelName); + assert.equal(response.data[i].id, payload.apps.app[i].id); + assert.equal(response.data[i].attributes.appId, payload.apps.app[i].id); + assert.equal(response.data[i].attributes.state, payload.apps.app[i].state); + assert.equal(response.data[i].attributes.user, payload.apps.app[i].user); + } +}); + +test('normalizeArrayResponse no apps test', function(assert) { + let serializer = this.subject(), + modelClass = { + modelName: "yarn-node-app" + }, + payload = { apps: null }; + assert.expect(5); + var response = + serializer.normalizeArrayResponse({}, modelClass, payload, null, null); + assert.ok(response.data); + assert.equal(response.data.length, 1); + assert.equal(response.data[0].type, modelClass.modelName); + assert.equal(response.data[0].id, "dummy"); + assert.equal(response.data[0].attributes.appId, undefined); +}); + +test('normalizeSingleResponse test', function(assert) { + let serializer = this.subject(), + modelClass = { + modelName: "yarn-node-app" + }, + payload = { + app: {id:"application_1456251210105_0001", state:"FINISHED", user:"root"} + }; + assert.expect(7); + var response = + serializer.normalizeSingleResponse({}, modelClass, payload, null, null); + assert.ok(response.data); + assert.equal(payload.app.id, response.data.id); + assert.equal(modelClass.modelName, response.data.type); + assert.equal(payload.app.id, response.data.attributes.appId); + assert.equal(payload.app.state, response.data.attributes.state); + assert.equal(payload.app.user, response.data.attributes.user); + assert.equal(response.data.attributes.containers, undefined); +}); + diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/serializers/yarn-node-container-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/serializers/yarn-node-container-test.js new file mode 100644 index 0000000..1f08467 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/serializers/yarn-node-container-test.js @@ -0,0 +1,128 @@ +/** + * 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 { moduleFor, test } from 'ember-qunit'; + +moduleFor('serializer:yarn-node-container', 'Unit | Serializer | NodeContainer', { +}); + +test('Basic creation test', function(assert) { + let serializer = this.subject(); + + assert.ok(serializer); + assert.ok(serializer.normalizeSingleResponse); + assert.ok(serializer.normalizeArrayResponse); + assert.ok(serializer.internalNormalizeSingleResponse); +}); + +test('normalizeArrayResponse test', function(assert) { + let serializer = this.subject(), + modelClass = { + modelName: "yarn-node-container" + }, + payload = { + containers: { + container: [{ + id: "container_e32_1456000363780_0002_01_000001", state: "RUNNING", + exitCode:-1000,diagnostics:"",user:"root",totalMemoryNeededMB:2048, + totalVCoresNeeded:1,containerLogsLink: "http://localhost:8042/node/" + + "containerlogs/container_e32_1456000363780_0002_01_000001/root", + nodeId: "localhost:64318", containerLogFiles:["syslog","stderr", + "stdout"] + },{ + id:"container_e32_1456000363780_0002_01_000003", state:"RUNNING", + exitCode:-1000, diagnostics:"", user:"root", totalMemoryNeededMB:1024, + totalVCoresNeeded:1,containerLogsLink:"http://localhost:8042/node" + + "/containerlogs/container_e32_1456000363780_0002_01_000003/root", + nodeId:"localhost:64318",containerLogFiles:["syslog","stderr", + "syslog.shuffle","stdout"] + }] + } + }; + assert.expect(14); + var response = + serializer.normalizeArrayResponse({}, modelClass, payload, null, null); + assert.ok(response.data); + assert.equal(response.data.length, 2); + assert.equal(response.data[0].id, + "container_e32_1456000363780_0002_01_000001"); + assert.equal(response.data[1].id, + "container_e32_1456000363780_0002_01_000003"); + assert.equal(response.data[0].attributes.containerLogFiles.length, 3); + assert.equal(response.data[1].attributes.containerLogFiles.length, 4); + for (var i = 0; i < 2; i++) { + assert.equal(response.data[i].type, modelClass.modelName); + assert.deepEqual(response.data[i].attributes.containerLogFiles, + payload.containers.container[i].containerLogFiles); + assert.equal(response.data[i].attributes.state, + payload.containers.container[i].state); + assert.equal(response.data[i].attributes.user, + payload.containers.container[i].user); + } +}); + +test('normalizeArrayResponse no containers test', function(assert) { + let serializer = this.subject(), + modelClass = { + modelName: "yarn-node-container" + }, + payload = { containers: null }; + assert.expect(5); + var response = + serializer.normalizeArrayResponse({}, modelClass, payload, null, null); + assert.ok(response.data); + assert.equal(response.data.length, 1); + assert.equal(response.data[0].type, modelClass.modelName); + assert.equal(response.data[0].id, "dummy"); + assert.equal(response.data[0].attributes.containerId, undefined); +}); + +test('normalizeSingleResponse test', function(assert) { + let serializer = this.subject(), + modelClass = { + modelName: "yarn-node-container" + }, + payload = { + container: { + id: "container_e32_1456000363780_0002_01_000001", state: "RUNNING", + exitCode:-1000,diagnostics:"",user:"root",totalMemoryNeededMB:2048, + totalVCoresNeeded:1,containerLogsLink: "http://localhost:8042/node/" + + "containerlogs/container_e32_1456000363780_0002_01_000001/root", + nodeId: "localhost:64318", containerLogFiles:["syslog","stderr", + "stdout"] + } + }; + assert.expect(11); + var response = + serializer.normalizeSingleResponse({}, modelClass, payload, null, null); + assert.ok(response.data); + assert.equal(response.data.id, payload.container.id); + assert.equal(response.data.type, modelClass.modelName); + assert.equal(response.data.attributes.containerId, payload.container.id); + assert.equal(response.data.attributes.state, payload.container.state); + assert.equal(response.data.attributes.user, payload.container.user); + assert.equal(response.data.attributes.exitCode, payload.container.exitCode); + assert.equal(response.data.attributes.totalMemoryNeededMB, + payload.container.totalMemoryNeeded); + assert.equal(response.data.attributes.totalVCoresNeeded, + payload.container.totalVCoresNeeded); + assert.equal(response.data.attributes.containerLogFiles.length, 3); + assert.deepEqual(response.data.attributes.containerLogFiles, + payload.container.containerLogFiles); +}); + diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/serializers/yarn-node-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/serializers/yarn-node-test.js new file mode 100644 index 0000000..0e76ccb --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/serializers/yarn-node-test.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 { moduleFor, test } from 'ember-qunit'; +import Converter from 'yarn-ui/utils/converter'; + +moduleFor('serializer:yarn-node', 'Unit | Serializer | Node', { +}); + +test('Basic creation test', function(assert) { + let serializer = this.subject(); + + assert.ok(serializer); + assert.ok(serializer.normalizeSingleResponse); + assert.ok(serializer.internalNormalizeSingleResponse); +}); + +test('normalizeSingleResponse test', function(assert) { + let serializer = this.subject(), + modelClass = { + modelName: "yarn-node" + }, + payload = { + nodeInfo: { + healthReport: "Healthy", totalVmemAllocatedContainersMB: 344064, + totalPmemAllocatedContainersMB: 163840, + totalVCoresAllocatedContainers: 160, + vmemCheckEnabled: true, pmemCheckEnabled: true, + lastNodeUpdateTime: 1456250210310, nodeHealthy: true, + nodeManagerVersion: "3.0.0-SNAPSHOT", + nodeManagerBuildVersion: "3.0.0-SNAPSHOT", + nodeManagerVersionBuiltOn: "2000-01-01T00:00Z", + hadoopVersion: "3.0.0-SNAPSHOT", + hadoopBuildVersion: "3.0.0-SNAPSHOT", + hadoopVersionBuiltOn: "2000-01-01T00:00Z", + id: "localhost:64318", nodeHostName: "192.168.0.102", + nmStartupTime: 1456250208231 + } + }; + assert.expect(6); + var id = "localhost:64318"; + var response = serializer.normalizeSingleResponse({}, modelClass, payload, id, null); + assert.equal(response.data.id, id); + assert.equal(response.data.type, modelClass.modelName); + assert.equal(response.data.attributes.totalVmemAllocatedContainersMB, + payload.nodeInfo.totalVmemAllocatedContainersMB); + assert.equal(response.data.attributes.totalPmemAllocatedContainersMB, + payload.nodeInfo.totalPmemAllocatedContainersMB); + assert.equal(response.data.attributes.totalVCoresAllocatedContainers, + payload.nodeInfo.totalVCoresAllocatedContainers); + assert.equal(response.data.attributes.nmStartupTime, + Converter.timeStampToDate(payload.nodeInfo.nmStartupTime)); +}); + diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/serializers/yarn-rm-node-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/serializers/yarn-rm-node-test.js new file mode 100644 index 0000000..bc6397d --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/serializers/yarn-rm-node-test.js @@ -0,0 +1,153 @@ +/** + * 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 { moduleFor, test } from 'ember-qunit'; + +moduleFor('serializer:yarn-rm-node', 'Unit | Serializer | RMNode', { +}); + +test('Basic creation test', function(assert) { + let serializer = this.subject(); + + assert.ok(serializer); + assert.ok(serializer.normalizeSingleResponse); + assert.ok(serializer.normalizeArrayResponse); + assert.ok(serializer.internalNormalizeSingleResponse); +}); + +test('normalizeArrayResponse test', function(assert) { + let serializer = this.subject(), + modelClass = { + modelName: "yarn-rm-node" + }, + payload = { + nodes: { + node: [{ + rack: "/default-rack", state: "RUNNING", id: "192.168.1.1:64318", + nodeHostName: "192.168.1.1", nodeHTTPAddress: "192.168.1.1:8042", + lastHealthUpdate: 1456251290905, version: "3.0.0-SNAPSHOT", + healthReport: "", numContainers: 0, usedMemoryMB: 2048, + availMemoryMB: 161792, usedVirtualCores: 2, + availableVirtualCores: 158, nodeLabels: ["x"], + resourceUtilization: { + nodePhysicalMemoryMB: 4549, nodeVirtualMemoryMB: 4549, + nodeCPUUsage: 0.14995001256465912, + aggregatedContainersPhysicalMemoryMB: 0, + aggregatedContainersVirtualMemoryMB: 0, + containersCPUUsage: 0 + } + },{ + rack: "/default-rack", state: "RUNNING", id: "192.168.1.2:64318", + nodeHostName: "192.168.1.2", nodeHTTPAddress: "192.168.1.2:8042", + lastHealthUpdate: 1456251290905, version: "3.0.0-SNAPSHOT", + healthReport: "", numContainers: 0, usedMemoryMB: 0, + availMemoryMB: 163840, usedVirtualCores: 0, + availableVirtualCores: 160, nodeLabels: ["y"], + resourceUtilization: { + nodePhysicalMemoryMB: 4549, nodeVirtualMemoryMB: 4549, + nodeCPUUsage: 0.14995001256465912, + aggregatedContainersPhysicalMemoryMB: 0, + aggregatedContainersVirtualMemoryMB: 0, + containersCPUUsage: 0 + } + }] + } + }; + assert.expect(12); + var response = + serializer.normalizeArrayResponse({}, modelClass, payload, null, null); + assert.ok(response.data); + assert.equal(response.data.length, 2); + assert.equal(response.data[0].id, "192.168.1.1:64318"); + assert.equal(response.data[1].id, "192.168.1.2:64318"); + for (var i = 0; i < 2; i++) { + assert.equal(response.data[i].type, modelClass.modelName); + assert.equal(response.data[i].attributes.nodeHostName, + payload.nodes.node[i].nodeHostName); + assert.equal(response.data[i].attributes.nodeHTTPAddress, + payload.nodes.node[i].nodeHTTPAddress); + assert.deepEqual(response.data[i].attributes.nodeLabels, + payload.nodes.node[i].nodeLabels); + } +}); + +test('normalizeArrayResponse no nodes test', function(assert) { + let serializer = this.subject(), + modelClass = { + modelName: "yarn-rm-node" + }, + payload = { nodes: null }; + assert.expect(5); + var response = + serializer.normalizeArrayResponse({}, modelClass, payload, null, null); + console.log(response); + assert.ok(response.data); + assert.equal(response.data.length, 1); + assert.equal(response.data[0].type, modelClass.modelName); + assert.equal(response.data[0].id, "dummy"); + assert.equal(response.data[0].attributes.nodeHostName, undefined); +}); + +test('normalizeSingleResponse test', function(assert) { + let serializer = this.subject(), + modelClass = { + modelName: "yarn-rm-node" + }, + payload = { + node: { + rack: "/default-rack", state: "RUNNING", id: "192.168.1.1:64318", + nodeHostName: "192.168.1.1", nodeHTTPAddress: "192.168.1.1:8042", + lastHealthUpdate: 1456251290905, version: "3.0.0-SNAPSHOT", + healthReport: "", numContainers: 0, usedMemoryMB: 2048, + availMemoryMB: 161792, usedVirtualCores: 2, + availableVirtualCores: 158, nodeLabels: ["x"], + resourceUtilization: { + nodePhysicalMemoryMB: 4549, nodeVirtualMemoryMB: 4549, + nodeCPUUsage: 0.14995001256465912, + aggregatedContainersPhysicalMemoryMB: 0, + aggregatedContainersVirtualMemoryMB: 0, + containersCPUUsage: 0 + } + } + }; + assert.expect(13); + var id = "localhost:64318"; + var response = + serializer.normalizeSingleResponse({}, modelClass, payload, id, null); + assert.ok(response.data); + assert.equal(response.data.id, id); + assert.equal(response.data.type, modelClass.modelName); + assert.equal(response.data.attributes.rack, payload.node.rack); + assert.equal(response.data.attributes.state, payload.node.state); + assert.equal(response.data.attributes.nodeHostName, + payload.node.nodeHostName); + assert.equal(response.data.attributes.nodeHTTPAddress, + payload.node.nodeHTTPAddress); + assert.equal(response.data.attributes.version, payload.node.version); + assert.equal(response.data.attributes.availMemoryMB, + payload.node.availMemoryMB); + assert.equal(response.data.attributes.usedMemoryMB, + payload.node.usedMemoryMB); + assert.equal(response.data.attributes.availableVirtualCores, + payload.node.availableVirtualCores); + assert.equal(response.data.attributes.usedVirtualCores, + payload.node.usedVirtualCores); + assert.deepEqual(response.data.attributes.nodeLabels, + payload.node.nodeLabels); +}); + diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/services/env-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/services/env-test.js new file mode 100644 index 0000000..9eb9367 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/services/env-test.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 { moduleFor, test } from 'ember-qunit'; + +moduleFor('service:env', 'Unit | Service | env', { + // Specify the other units that are required for this test. + // needs: ['service:foo'] +}); + +// Replace this with your real tests. +test('it exists', function(assert) { + var service = this.subject(); + assert.ok(service); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/services/hosts-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/services/hosts-test.js new file mode 100644 index 0000000..015748a --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/services/hosts-test.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 { moduleFor, test } from 'ember-qunit'; + +moduleFor('service:hosts', 'Unit | Service | hosts', { + // Specify the other units that are required for this test. + // needs: ['service:foo'] +}); + +// Replace this with your real tests. +test('it exists', function(assert) { + var service = this.subject(); + assert.ok(service); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/utils/converter-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/utils/converter-test.js new file mode 100644 index 0000000..481537d --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/utils/converter-test.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 converter from '../../../utils/converter'; +import { module, test } from 'qunit'; + +module('Unit | Utility | Converter'); + +// Replace this with your real tests. +test('it works', function(assert) { + assert.ok(converter); + assert.ok(converter.splitForContainerLogs); +}); + +test('split for container logs', function(assert) { + var id = "localhost:64318!container_e32_1456000363780_0002_01_000001!" + + "syslog"; + var arr = converter.splitForContainerLogs(id); + assert.ok(arr); + assert.deepEqual(arr, ["localhost:64318", + "container_e32_1456000363780_0002_01_000001", "syslog"]); + id = "localhost:64318!container_e32_1456000363780_0002_01_000001!" + + "syslog!logs"; + arr = converter.splitForContainerLogs(id); + assert.ok(arr); + assert.deepEqual(arr, ["localhost:64318", + "container_e32_1456000363780_0002_01_000001", "syslog!logs"]); + id = "localhost:64318!container_e32_1456000363780_0002_01_000001"; + arr = converter.splitForContainerLogs(id); + assert.notOk(arr); + id = null; + arr = converter.splitForContainerLogs(id); + assert.notOk(arr); + id = undefined; + arr = converter.splitForContainerLogs(id); + assert.notOk(arr); +}); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/utils/sorter-test.js hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/utils/sorter-test.js new file mode 100644 index 0000000..8f17380 --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/utils/sorter-test.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 Sorter from 'yarn-ui/utils/sorter'; +import { module, test } from 'qunit'; + +module('Unit | Utility | Sorter'); + +test('Basic creation test', function(assert) { + assert.ok(Sorter); +}); diff --git hadoop-yarn-project/hadoop-yarn/pom.xml hadoop-yarn-project/hadoop-yarn/pom.xml index 0611a39..3671453 100644 --- hadoop-yarn-project/hadoop-yarn/pom.xml +++ hadoop-yarn-project/hadoop-yarn/pom.xml @@ -237,5 +237,6 @@ hadoop-yarn-site hadoop-yarn-client hadoop-yarn-registry + hadoop-yarn-ui