You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tez.apache.org by sr...@apache.org on 2016/02/24 23:34:38 UTC

[01/45] tez git commit: TEZ-3018. Tez UI 2: Add config.env (sree) [Forced Update!]

Repository: tez
Updated Branches:
  refs/heads/TEZ-2980 dc6a3f3ac -> bdcdfcc54 (forced update)


TEZ-3018. Tez UI 2: Add config.env (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/d6bb483f
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/d6bb483f
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/d6bb483f

Branch: refs/heads/TEZ-2980
Commit: d6bb483feeb9085b001e5e5c6f97431fc5273c5b
Parents: 1e5a315
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Tue Dec 29 22:37:26 2015 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:31:58 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |  1 +
 tez-ui2/src/main/webapp/app/app.js              | 20 +++++++++++-
 tez-ui2/src/main/webapp/app/index.html          | 20 ++++++++++++
 tez-ui2/src/main/webapp/app/services/hosts.js   | 27 ++++++++++------
 .../main/webapp/app/templates/application.hbs   | 20 ++++++++++++
 tez-ui2/src/main/webapp/config/configs.env      |  4 +++
 tez-ui2/src/main/webapp/ember-cli-build.js      | 24 +++++---------
 tez-ui2/src/main/webapp/package.json            |  1 +
 .../webapp/tests/unit/services/hosts-test.js    | 34 ++++++++++++++++++++
 9 files changed, 125 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/d6bb483f/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index 4a4edaf..e792420 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -2,3 +2,4 @@ ALL CHANGES:
   TEZ-2982. Tez UI: Create tez-ui2 directory and get a basic dummy page working in ember 2.2
   TEZ-3016. Tez UI 2: Make bower dependency silent
   TEZ-2983. Tez UI 2: Get ember initializers functional
+  TEZ-3018. Tez UI 2: Add config.env

http://git-wip-us.apache.org/repos/asf/tez/blob/d6bb483f/tez-ui2/src/main/webapp/app/app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/app.js b/tez-ui2/src/main/webapp/app/app.js
index 8b234d6..fb4695c 100644
--- a/tez-ui2/src/main/webapp/app/app.js
+++ b/tez-ui2/src/main/webapp/app/app.js
@@ -1,5 +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.
+ */
+
 import Ember from 'ember';
-import Resolver from 'ember/resolver';
+import Resolver from 'ember-resolver';
 import loadInitializers from 'ember/load-initializers';
 import config from './config/environment';
 

http://git-wip-us.apache.org/repos/asf/tez/blob/d6bb483f/tez-ui2/src/main/webapp/app/index.html
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/index.html b/tez-ui2/src/main/webapp/app/index.html
index 23a7578..2108d0f 100644
--- a/tez-ui2/src/main/webapp/app/index.html
+++ b/tez-ui2/src/main/webapp/app/index.html
@@ -1,3 +1,21 @@
+<!--
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+-->
+
 <!DOCTYPE html>
 <html>
   <head>
@@ -17,6 +35,8 @@
   <body>
     {{content-for 'body'}}
 
+    <script src="config/configs.env"></script>
+
     <script src="assets/vendor.js"></script>
     <script src="assets/tez-ui.js"></script>
 

http://git-wip-us.apache.org/repos/asf/tez/blob/d6bb483f/tez-ui2/src/main/webapp/app/services/hosts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/services/hosts.js b/tez-ui2/src/main/webapp/app/services/hosts.js
index 5bdc6d1..7ffdc29 100644
--- a/tez-ui2/src/main/webapp/app/services/hosts.js
+++ b/tez-ui2/src/main/webapp/app/services/hosts.js
@@ -21,18 +21,27 @@ import environment from '../config/environment';
 
 export default Ember.Service.extend({
 
-  correctProtocol: function (url) {
-    var proto = window.location.protocol;
+  correctProtocol: function (url, localProto) {
+    var urlProto;
 
-    if(proto === "file:") {
-      proto = "http:";
+    localProto = localProto || window.location.protocol;
+
+    if(url.match("://")) {
+      urlProto = url.substr(0, url.indexOf("//"));
+    }
+
+    if(localProto === "file:") {
+      urlProto = urlProto || "http:";
+    }
+    else {
+      urlProto = localProto;
     }
 
     if(url.match("://")) {
       url = url.substr(url.indexOf("://") + 3);
     }
 
-    return proto + "//" + url;
+    return urlProto + "//" + url;
   },
 
   normalizeURL: function (url) {
@@ -46,13 +55,13 @@ export default Ember.Service.extend({
   },
 
   timelineBaseURL: Ember.computed(function () {
-    // Todo: Use global ENV if available
-    // Todo: Use loaded host if protocol is != file
-    return this.normalizeURL(environment.hosts.timeline);
+    var ENV = window.ENV;
+    return this.normalizeURL((ENV && ENV.timelineBaseURL) || environment.hosts.timeline);
   }),
 
   rmBaseURL: Ember.computed(function () {
-    return this.normalizeURL(environment.hosts.RM);
+    var ENV = window.ENV;
+    return this.normalizeURL((ENV && ENV.rmBaseURL) || environment.hosts.RM);
   }),
 
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/d6bb483f/tez-ui2/src/main/webapp/app/templates/application.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/application.hbs b/tez-ui2/src/main/webapp/app/templates/application.hbs
index f8bc38e..c1c380d 100644
--- a/tez-ui2/src/main/webapp/app/templates/application.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/application.hbs
@@ -1,3 +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.
+}}
+
 <h2 id="title">Welcome to Ember</h2>
 
 {{outlet}}
+
+{{hosts.timelineBaseURL}}

http://git-wip-us.apache.org/repos/asf/tez/blob/d6bb483f/tez-ui2/src/main/webapp/config/configs.env
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/config/configs.env b/tez-ui2/src/main/webapp/config/configs.env
new file mode 100644
index 0000000..6e12286
--- /dev/null
+++ b/tez-ui2/src/main/webapp/config/configs.env
@@ -0,0 +1,4 @@
+ENV = {
+  //timelineBaseURL: "http://localhost:8188",
+  //rmBaseURL: "http://localhost:8088"
+};

http://git-wip-us.apache.org/repos/asf/tez/blob/d6bb483f/tez-ui2/src/main/webapp/ember-cli-build.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/ember-cli-build.js b/tez-ui2/src/main/webapp/ember-cli-build.js
index 9f33b64..ede63b3 100644
--- a/tez-ui2/src/main/webapp/ember-cli-build.js
+++ b/tez-ui2/src/main/webapp/ember-cli-build.js
@@ -19,28 +19,20 @@
  * limitations under the License.
  */
 
+var Funnel = require("broccoli-funnel");
 var EmberApp = require('ember-cli/lib/broccoli/ember-app');
 
 module.exports = function(defaults) {
-  var app = new EmberApp(defaults, {
-    // Add options here
-  });
+  var app = new EmberApp(defaults, {});
 
-  // 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'
+  });
 
   app.import('bower_components/jquery-ui/jquery-ui.js');
   app.import('bower_components/jquery-ui/ui/tooltip.js');
 
-  return app.toTree();
+  return app.toTree(extraAssets);
 };

http://git-wip-us.apache.org/repos/asf/tez/blob/d6bb483f/tez-ui2/src/main/webapp/package.json
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/package.json b/tez-ui2/src/main/webapp/package.json
index 38c76da..da85316 100644
--- a/tez-ui2/src/main/webapp/package.json
+++ b/tez-ui2/src/main/webapp/package.json
@@ -40,6 +40,7 @@
     "ember-resolver": "^2.0.3"
   },
   "dependencies": {
+    "broccoli-funnel": "^1.0.1",
     "ember-cli-htmlbars": "^1.0.1",
     "ember-cli-less": "^1.4.0"
   }

http://git-wip-us.apache.org/repos/asf/tez/blob/d6bb483f/tez-ui2/src/main/webapp/tests/unit/services/hosts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/services/hosts-test.js b/tez-ui2/src/main/webapp/tests/unit/services/hosts-test.js
index 8136ae4..b130a2c 100644
--- a/tez-ui2/src/main/webapp/tests/unit/services/hosts-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/services/hosts-test.js
@@ -39,4 +39,38 @@ test('Test correctProtocol', function(assert) {
   assert.equal(service.correctProtocol("localhost:8088"), "http://localhost:8088");
   assert.equal(service.correctProtocol("https://localhost:8088"), "http://localhost:8088");
   assert.equal(service.correctProtocol("file://localhost:8088"), "http://localhost:8088");
+
+  assert.equal(service.correctProtocol("localhost:8088", "http:"), "http://localhost:8088");
+  assert.equal(service.correctProtocol("https://localhost:8088", "http:"), "http://localhost:8088");
+  assert.equal(service.correctProtocol("file://localhost:8088", "http:"), "http://localhost:8088");
+
+  assert.equal(service.correctProtocol("localhost:8088", "https:"), "https://localhost:8088");
+  assert.equal(service.correctProtocol("https://localhost:8088", "https:"), "https://localhost:8088");
+  assert.equal(service.correctProtocol("file://localhost:8088", "https:"), "https://localhost:8088");
+});
+
+test('Test correctProtocol with protocol=file:', function(assert) {
+  let service = this.subject();
+
+  assert.equal(service.correctProtocol("file://localhost:8088", "file:"), "file://localhost:8088");
+  assert.equal(service.correctProtocol("http://localhost:8088", "file:"), "http://localhost:8088");
+  assert.equal(service.correctProtocol("https://localhost:8088", "file:"), "https://localhost:8088");
+});
+
+test('Test base URLs', function(assert) {
+  let service = this.subject();
+
+  assert.equal(service.get("timelineBaseURL"), "http://localhost:8188");
+  assert.equal(service.get("rmBaseURL"), "http://localhost:8088");
+});
+
+test('Test base URLs with ENV set', function(assert) {
+  let service = this.subject();
+
+  window.ENV = {
+    timelineBaseURL: "https://localhost:3333",
+    rmBaseURL: "https://localhost:4444"
+  };
+  assert.equal(service.get("timelineBaseURL"), "http://localhost:3333");
+  assert.equal(service.get("rmBaseURL"), "http://localhost:4444");
 });


[11/45] tez git commit: TEZ-2985. Tez UI 2: Create loader and entity classes (sree)

Posted by sr...@apache.org.
TEZ-2985. Tez UI 2: Create loader and entity classes (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/6e18c9b9
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/6e18c9b9
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/6e18c9b9

Branch: refs/heads/TEZ-2980
Commit: 6e18c9b9414f3a2b56c76ce71a606e8c39dbdbde
Parents: 72a1060
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Mon Jan 4 03:25:04 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:31:59 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |   1 +
 .../src/main/webapp/app/adapters/abstract.js    |  54 ----
 tez-ui2/src/main/webapp/app/adapters/loader.js  |  58 ++++
 tez-ui2/src/main/webapp/app/entities/entity.js  |  65 ++++-
 .../src/main/webapp/app/initializers/loader.js  |  27 ++
 .../src/main/webapp/app/serializers/abstract.js |  26 --
 .../src/main/webapp/app/serializers/loader.js   |  81 ++++++
 tez-ui2/src/main/webapp/app/services/loader.js  | 145 ++++++++++
 .../webapp/tests/unit/adapters/abstract-test.js |  39 ---
 .../webapp/tests/unit/adapters/loader-test.js   | 137 ++++++++++
 .../webapp/tests/unit/entities/entity-test.js   | 139 ++++++++++
 .../tests/unit/initializers/loader-test.js      |  40 +++
 .../tests/unit/serializers/abstract-test.js     |  31 ---
 .../tests/unit/serializers/loader-test.js       | 193 ++++++++++++++
 .../webapp/tests/unit/services/loader-test.js   | 267 +++++++++++++++++++
 15 files changed, 1152 insertions(+), 151 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/6e18c9b9/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index da361d6..4cf5c4a 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -6,3 +6,4 @@ ALL CHANGES:
   TEZ-3019. Tez UI 2: Replace BaseURL with Host
   TEZ-2984. Tez UI 2: Create abstract classes
   TEZ-3020. Tez UI 2: Add entity blueprint
+  TEZ-2985. Tez UI 2: Create loader and entity classes

http://git-wip-us.apache.org/repos/asf/tez/blob/6e18c9b9/tez-ui2/src/main/webapp/app/adapters/abstract.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/abstract.js b/tez-ui2/src/main/webapp/app/adapters/abstract.js
deleted file mode 100644
index aca0faf..0000000
--- a/tez-ui2/src/main/webapp/app/adapters/abstract.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/*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 DS from 'ember-data';
-
-var MoreString = more.String;
-
-export default DS.RESTAdapter.extend({
-  ajax: function(url, method, hash) {
-    return this._super(url, method, Ember.$.extend(hash || {}, {
-      crossDomain: true,
-      xhrFields: {
-        withCredentials: true
-      }
-    }));
-  },
-  buildURL: function(type, id, record) {
-    var url = this._super(type, undefined, record);
-    return MoreString.fmt(url, record);
-  },
-  findQuery: function(store, type, query) {
-    var record = query.metadata;
-    delete query.metadata;
-
-    return this.ajax(this.buildURL(
-        Ember.String.pluralize(type.typeKey),
-        record.id,
-        Ember.Object.create(record)
-      ),
-      'GET',
-      {
-        data: query
-      }
-    );
-  }
-});

http://git-wip-us.apache.org/repos/asf/tez/blob/6e18c9b9/tez-ui2/src/main/webapp/app/adapters/loader.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/loader.js b/tez-ui2/src/main/webapp/app/adapters/loader.js
new file mode 100644
index 0000000..d4b502c
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/adapters/loader.js
@@ -0,0 +1,58 @@
+/*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 DS from 'ember-data';
+
+var MoreString = more.String;
+
+export default DS.RESTAdapter.extend({
+  _isLoader: true,
+
+  buildURL: function(modelName, id, snapshot, requestType, query, params) {
+    var url = this._super(modelName, id, snapshot, null, query);
+    return params ? MoreString.fmt(url, params) : url;
+  },
+
+  _loaderAjax: function (url, queryParams, nameSpace) {
+    if (this.sortQueryParams && queryParams) {
+      queryParams = this.sortQueryParams(queryParams);
+    }
+
+    // Inject nameSpace
+    return this.ajax(url, 'GET', { data: queryParams }).then(function (data) {
+      return {
+        nameSpace: nameSpace,
+        data: data
+      };
+    });
+  },
+
+  queryRecord: function(store, type, query) {
+    var queryParams = query.params,
+        url = this.buildURL(type.modelName, query.id, null, null, queryParams, query.urlParams);
+    return this._loaderAjax(url, queryParams, query.nameSpace);
+  },
+
+  query: function (store, type, query/*, recordArray*/) {
+    var queryParams = query.params,
+        url = this.buildURL(type.modelName, null, null, 'query', queryParams, query.urlParams);
+    return this._loaderAjax(url, queryParams, query.nameSpace);
+  }
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/6e18c9b9/tez-ui2/src/main/webapp/app/entities/entity.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/entities/entity.js b/tez-ui2/src/main/webapp/app/entities/entity.js
index 3d858c8..4d524fe 100644
--- a/tez-ui2/src/main/webapp/app/entities/entity.js
+++ b/tez-ui2/src/main/webapp/app/entities/entity.js
@@ -1,3 +1,4 @@
+/*global more*/
 /**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -18,5 +19,67 @@
 
 import Ember from 'ember';
 
-export default Ember.ObjectProxy.extend({
+var MoreObject = more.Object;
+
+export default Ember.Object.extend({
+
+  loadRelations: function (loader, model) {
+    var needsPromise = this.loadNeeds(loader, model);
+
+    if(needsPromise) {
+      return needsPromise.then(function () {
+        return model;
+      });
+    }
+
+    return model;
+  },
+
+  normalizeNeed: function(name, options) {
+    var attrName = name,
+        attrType = name,
+        idKey = options,
+        lazy = false;
+
+    if(typeof options === 'object') {
+      attrType = options.type || attrType;
+      idKey = options.idKey || idKey;
+      if(options.lazy) {
+        lazy = true;
+      }
+    }
+
+    return {
+      name: attrName,
+      type: attrType,
+      idKey: idKey,
+      lazy: lazy
+    };
+  },
+
+  loadNeeds: function (loader, parentModel) {
+    var needLoaders = [],
+        that = this,
+        needs = parentModel.get("needs");
+
+    if(needs) {
+      MoreObject.forEach(needs, function (name, options) {
+        var need = that.normalizeNeed(name, options),
+            needLoader = loader.queryRecord(need.type, parentModel.get(need.idKey));
+
+        needLoader.then(function (model) {
+          parentModel.set(need.name, model);
+        });
+
+        if(!need.lazy) {
+          needLoaders.push(needLoader);
+        }
+      });
+    }
+
+    if(needLoaders.length) {
+      return Ember.RSVP.all(needLoaders);
+    }
+  },
+
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/6e18c9b9/tez-ui2/src/main/webapp/app/initializers/loader.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/initializers/loader.js b/tez-ui2/src/main/webapp/app/initializers/loader.js
new file mode 100644
index 0000000..2956d2c
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/initializers/loader.js
@@ -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.
+ */
+
+export function initialize(application) {
+  application.inject('route', 'loader', 'service:loader');
+  application.inject('entity', 'loader', 'service:loader');
+}
+
+export default {
+  name: 'loader',
+  initialize
+};

http://git-wip-us.apache.org/repos/asf/tez/blob/6e18c9b9/tez-ui2/src/main/webapp/app/serializers/abstract.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/abstract.js b/tez-ui2/src/main/webapp/app/serializers/abstract.js
deleted file mode 100644
index c032c30..0000000
--- a/tez-ui2/src/main/webapp/app/serializers/abstract.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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';
-
-export default DS.RESTSerializer.extend({
-  normalize: function(type, hash /*, prop */) {
-    return Ember.JsonMapper.map(hash, this.get('map'));
-  }
-});

http://git-wip-us.apache.org/repos/asf/tez/blob/6e18c9b9/tez-ui2/src/main/webapp/app/serializers/loader.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/loader.js b/tez-ui2/src/main/webapp/app/serializers/loader.js
new file mode 100644
index 0000000..9c97886
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/serializers/loader.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';
+import DS from 'ember-data';
+
+// TODO - Move to more js
+function mapObject(hash, map) {
+  var mappedObject = Ember.Object.create();
+  for (var key in map) {
+    mappedObject.set(key, Ember.get(hash, map[key]));
+  }
+  return mappedObject;
+}
+
+export default DS.JSONSerializer.extend({
+  _isLoader: true,
+
+  maps: null,
+
+  extractId: function (modelClass, resourceHash) {
+    var id = this._super(modelClass, resourceHash.data),
+        nameSpace = resourceHash.nameSpace;
+
+    if(nameSpace) {
+      return nameSpace + ":" + id;
+    }
+    return id;
+  },
+  extractAttributes: function (modelClass, resourceHash) {
+    var maps = this.get('maps'),
+        data = resourceHash.data;
+    return this._super(modelClass, maps ? mapObject(data, maps) : data);
+  },
+  extractRelationships: function (modelClass, resourceHash) {
+    return this._super(modelClass, resourceHash.data);
+  },
+
+  extractSinglePayload: function (payload) {
+    return payload;
+  },
+  extractArrayPayload: function (payload) {
+    return payload;
+  },
+
+  normalizeSingleResponse: function (store, primaryModelClass, payload, id, requestType) {
+    payload.data = this.extractSinglePayload(payload.data);
+    return this._super(store, primaryModelClass, payload, id, requestType);
+  },
+
+  normalizeArrayResponse: function (store, primaryModelClass, payload, id, requestType) {
+    var nameSpace = payload.nameSpace;
+
+    // convert into a _normalizeResponse friendly format
+    payload = this.extractArrayPayload(payload.data);
+    Ember.assert("Loader expects an array in return for a query", Array.isArray(payload));
+    payload = payload.map(function (item) {
+      return {
+        nameSpace: nameSpace,
+        data: item
+      };
+    });
+
+    return this._super(store, primaryModelClass, payload, id, requestType);
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/6e18c9b9/tez-ui2/src/main/webapp/app/services/loader.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/services/loader.js b/tez-ui2/src/main/webapp/app/services/loader.js
new file mode 100644
index 0000000..054a6b5
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/services/loader.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 Ember from 'ember';
+
+export default Ember.Service.extend({
+
+  nameSpace: '',
+  store: Ember.inject.service('store'),
+  cache: null,
+
+  _setOptions: function (options) {
+    var nameSpace = options.nameSpace;
+    if(nameSpace) {
+      // We need to validate only if nameSpace is passed. Else it would be stored in the global space
+      Ember.assert(`Invalid nameSpace. Please pass a string instead of ${Ember.inspect(nameSpace)}`, typeof nameSpace === 'string');
+      this.set("nameSpace", nameSpace);
+    }
+  },
+
+  init: function (options) {
+    this._super();
+    this._setOptions(options || {});
+    this.set("cache", Ember.Object.create());
+  },
+
+  checkRequisite: function (type) {
+    var store = this.get("store"),
+        adapter = store.adapterFor(type),
+        serializer = store.serializerFor(type);
+
+    Ember.assert(
+      `No loader adapter found for type ${type}. Either extend loader and create a custom adapter or extend ApplicationAdapter from loader.`,
+      adapter && adapter._isLoader
+    );
+    Ember.assert(
+      `No loader serializer found for type ${type}. Either extend loader and create a custom serializer or extend ApplicationSerializer from loader.`,
+      serializer && serializer._isLoader
+    );
+  },
+
+  lookup: function (type, name) {
+    name = Ember.String.dasherize(name);
+    return this.get("container").lookup(type + ":" + name);
+  },
+
+  entityFor: function (entityName) {
+    var entity = this.lookup("entitie", entityName);
+    if(!entity) {
+      entity = this.lookup("entitie", "entity");
+    }
+    entity.name = entityName;
+    return entity;
+  },
+
+  getCacheKey: function (type, query, id) {
+    var parts = [type];
+
+    if(id) {
+      parts.push(id);
+    }
+    if(query) {
+      parts.push(JSON.stringify(query));
+    }
+
+    return parts.join(":");
+  },
+
+  queryRecord: function(type, id, query, urlParams, options) {
+    var entity = this.entityFor(type),
+        cache = this.get("cache"),
+        cacheKey = this.getCacheKey(type, query, id),
+        that = this,
+        record;
+
+    this.checkRequisite(type);
+
+    options = options || {};
+    if(!options.reload) {
+      record = cache.get(cacheKey);
+      if(record) {
+        return record;
+      }
+    }
+
+    record = this.get('store').queryRecord(type, {
+      id: id,
+      nameSpace: this.get('nameSpace'),
+      params: query,
+      urlParams: urlParams
+    }).then(function (record) {
+      return entity.loadRelations(that, record);
+    });
+
+    cache.set(cacheKey, record);
+    return record;
+  },
+  query: function(type, query, urlParams, options) {
+    var entity = this.entityFor(type),
+        cache = this.get("cache"),
+        cacheKey = this.getCacheKey(type, query),
+        that = this,
+        records;
+
+    this.checkRequisite(type);
+
+    options = options || {};
+    if(!options.reload) {
+      records = cache.get(cacheKey);
+      if(records) {
+        return records;
+      }
+    }
+
+    records = this.get('store').query(type, {
+      nameSpace: this.get('nameSpace'),
+      params: query,
+      urlParams: urlParams
+    }).then(function (records) {
+      return Ember.RSVP.all(records.map(function (record) {
+        return entity.loadRelations(that, record);
+      })).then(function () {
+       return records;
+      });
+    });
+
+    cache.set(cacheKey, records);
+    return records;
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/6e18c9b9/tez-ui2/src/main/webapp/tests/unit/adapters/abstract-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/abstract-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/abstract-test.js
deleted file mode 100644
index 00be0ac..0000000
--- a/tez-ui2/src/main/webapp/tests/unit/adapters/abstract-test.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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:abstract', 'Unit | Adapter | abstract', {
-  // 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);
-});
-
-test('buildURL test', function(assert) {
-  let adapter = this.subject();
-
-  assert.equal(adapter.buildURL("{x}/{y}/type", null, {
-    x: "x_x",
-    y: "y_y"
-  }), "/x_x/y_y/types");
-});

http://git-wip-us.apache.org/repos/asf/tez/blob/6e18c9b9/tez-ui2/src/main/webapp/tests/unit/adapters/loader-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/loader-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/loader-test.js
new file mode 100644
index 0000000..7b4a2df
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/adapters/loader-test.js
@@ -0,0 +1,137 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('adapter:loader', 'Unit | Adapter | loader', {
+  // 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._isLoader);
+  assert.ok(adapter.buildURL);
+  assert.ok(adapter._loaderAjax);
+  assert.ok(adapter.queryRecord);
+  assert.ok(adapter.query);
+});
+
+test('buildURL test', function(assert) {
+  let adapter = this.subject();
+
+  assert.equal(adapter.buildURL("dag"), "/dags");
+  assert.equal(adapter.buildURL("dag", "dag1"), "/dags/dag1");
+  assert.equal(adapter.buildURL("{x}dag", "dag1", null, null, null, {x: "x_x"}), "/x_xdags/dag1", "Test for substitution");
+});
+
+test('_loaderAjax test', function(assert) {
+  let adapter = this.subject(),
+      testURL = "/dags",
+      testQueryParams = { x:1 },
+      testRecord = {},
+      testNameSpace = "ns";
+
+  assert.expect(2 + 1 + 2);
+
+  adapter.ajax = function (url, method/*, options*/) {
+
+    assert.equal(url, testURL);
+    assert.equal(method, "GET");
+
+    return Ember.RSVP.resolve(testRecord);
+  };
+
+  adapter.sortQueryParams = function (queryParams) {
+    assert.ok(queryParams, "sortQueryParams was called with query params");
+  };
+
+  adapter._loaderAjax(testURL, testQueryParams, testNameSpace).then(function (data) {
+    assert.equal(data.nameSpace, testNameSpace, "Namespace returned");
+    assert.equal(data.data, testRecord, "Test record returned");
+  });
+});
+
+test('queryRecord test', function(assert) {
+  let adapter = this.subject(),
+      testURL = "/dags",
+      testModel = { modelName: "testModel" },
+      testStore = {},
+      testQuery = {
+        id: "test1",
+        params: {},
+        urlParams: {},
+        nameSpace: "ns"
+      };
+
+  assert.expect(4 + 3);
+
+  adapter.buildURL = function (modelName, id, snapshot, requestType, query, params) {
+    assert.equal(modelName, testModel.modelName);
+    assert.equal(id, testQuery.id);
+    assert.equal(query, testQuery.params);
+    assert.equal(params, testQuery.urlParams);
+
+    return testURL;
+  };
+
+  adapter._loaderAjax = function (url, queryParams, nameSpace) {
+    assert.equal(url, testURL);
+    assert.equal(queryParams, testQuery.params);
+    assert.equal(nameSpace, testQuery.nameSpace);
+  };
+
+  adapter.queryRecord(testStore, testModel, testQuery);
+});
+
+test('query test', function(assert) {
+  let adapter = this.subject(),
+      testURL = "/dags",
+      testModel = { modelName: "testModel" },
+      testStore = {},
+      testQuery = {
+        id: "test1",
+        params: {},
+        urlParams: {},
+        nameSpace: "ns"
+      };
+
+  assert.expect(5 + 3);
+
+  adapter.buildURL = function (modelName, id, snapshot, requestType, query, params) {
+    assert.equal(modelName, testModel.modelName);
+    assert.equal(id, null);
+    assert.equal(requestType, "query");
+    assert.equal(query, testQuery.params);
+    assert.equal(params, testQuery.urlParams);
+
+    return testURL;
+  };
+
+  adapter._loaderAjax = function (url, queryParams, nameSpace) {
+    assert.equal(url, testURL);
+    assert.equal(queryParams, testQuery.params);
+    assert.equal(nameSpace, testQuery.nameSpace);
+  };
+
+  adapter.query(testStore, testModel, testQuery);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/6e18c9b9/tez-ui2/src/main/webapp/tests/unit/entities/entity-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/entities/entity-test.js b/tez-ui2/src/main/webapp/tests/unit/entities/entity-test.js
new file mode 100644
index 0000000..23e349d
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/entities/entity-test.js
@@ -0,0 +1,139 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('entitie:entity', 'Unit | Entity | entity', {
+  // Specify the other units that are required for this test.
+  // needs: ['entitie:foo']
+});
+
+test('Basic creation', function(assert) {
+  let adapter = this.subject();
+
+  assert.ok(adapter);
+  assert.ok(adapter.loadRelations);
+  assert.ok(adapter.normalizeNeed);
+  assert.ok(adapter.loadNeeds);
+});
+
+test('loadRelations creation', function(assert) {
+  let adapter = this.subject(),
+      testLoader = {},
+      testModel = {},
+      relationsPromise;
+
+  assert.expect(2 + 1 + 2 + 2);
+
+  // Test model without needs
+  adapter.loadNeeds = function (loader, model) {
+    assert.equal(loader, testLoader);
+    assert.equal(model, testModel);
+
+    return null;
+  };
+  relationsPromise = adapter.loadRelations(testLoader, testModel);
+
+  assert.equal(relationsPromise, testModel, "Model without needs");
+
+  // Test model with needs
+  adapter.loadNeeds = function (loader, model) {
+    assert.equal(loader, testLoader);
+    assert.equal(model, testModel);
+
+    return Ember.RSVP.resolve();
+  };
+  relationsPromise = adapter.loadRelations(testLoader, testModel);
+
+  assert.notEqual(relationsPromise, testModel);
+  relationsPromise.then(function (model) {
+    assert.equal(model, testModel);
+  });
+
+});
+
+test('normalizeNeed creation', function(assert) {
+  let adapter = this.subject();
+
+  assert.deepEqual(adapter.normalizeNeed("app", "appKey"), {
+    name: "app",
+    type: "app",
+    idKey: "appKey",
+    lazy: false
+  }, "Test 1");
+
+  assert.deepEqual(adapter.normalizeNeed( "app", { idKey: "appKey" }), {
+    name: "app",
+    type: "app",
+    idKey: "appKey",
+    lazy: false
+  }, "Test 2");
+
+  assert.deepEqual(adapter.normalizeNeed( "app", { type: "application", idKey: "appKey" }), {
+    name: "app",
+    type: "application",
+    idKey: "appKey",
+    lazy: false
+  }, "Test 3");
+
+  assert.deepEqual(adapter.normalizeNeed( "app", { lazy: true, idKey: "appKey" }), {
+    name: "app",
+    type: "app",
+    idKey: "appKey",
+    lazy: true
+  }, "Test 4");
+});
+
+test('loadNeeds creation', function(assert) {
+  let adapter = this.subject(),
+      loader,
+      testModel = Ember.Object.create({
+        needs: {
+          app: "appID",
+          foo: "fooID"
+        },
+        appID: 1,
+        fooID: 2
+      });
+
+  assert.expect(1 + 2 + 1);
+
+  assert.equal(adapter.loadNeeds(loader, Ember.Object.create()), null, "Model without needs");
+
+  loader = {
+    queryRecord: function (type, id) {
+
+      // Must be called twice, once for each record
+      switch(type) {
+        case "app":
+          assert.equal(id, testModel.get("appID"));
+        break;
+        case "foo":
+          assert.equal(id, testModel.get("fooID"));
+        break;
+      }
+
+      return Ember.RSVP.resolve();
+    }
+  };
+  adapter.loadNeeds(loader, testModel).then(function () {
+    assert.ok(true);
+  });
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/6e18c9b9/tez-ui2/src/main/webapp/tests/unit/initializers/loader-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/initializers/loader-test.js b/tez-ui2/src/main/webapp/tests/unit/initializers/loader-test.js
new file mode 100644
index 0000000..cc32e92
--- /dev/null
+++ b/tez-ui2/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);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/6e18c9b9/tez-ui2/src/main/webapp/tests/unit/serializers/abstract-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/serializers/abstract-test.js b/tez-ui2/src/main/webapp/tests/unit/serializers/abstract-test.js
deleted file mode 100644
index 006d69c..0000000
--- a/tez-ui2/src/main/webapp/tests/unit/serializers/abstract-test.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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('abstract', 'Unit | Serializer | abstract', {
-  // Specify the other units that are required for this test.
-  needs: ['serializer:abstract']
-});
-
-test('it serializes records', function(assert) {
-  let record = this.subject();
-  let serializedRecord = record.serialize();
-
-  assert.ok(serializedRecord);
-});

http://git-wip-us.apache.org/repos/asf/tez/blob/6e18c9b9/tez-ui2/src/main/webapp/tests/unit/serializers/loader-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/serializers/loader-test.js b/tez-ui2/src/main/webapp/tests/unit/serializers/loader-test.js
new file mode 100644
index 0000000..5add84a
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/serializers/loader-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('serializer:loader', 'Unit | Serializer | loader', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:loader']
+});
+
+test('Basic creation test', function(assert) {
+  let serializer = this.subject();
+
+  assert.ok(serializer);
+  assert.ok(serializer._isLoader);
+
+  assert.ok(serializer.extractId);
+  assert.ok(serializer.extractAttributes);
+  assert.ok(serializer.extractRelationships);
+
+  assert.ok(serializer.extractSinglePayload);
+  assert.ok(serializer.extractArrayPayload);
+
+  assert.ok(serializer.normalizeSingleResponse);
+  assert.ok(serializer.normalizeArrayResponse);
+});
+
+test('extractId test', function(assert) {
+  let serializer = this.subject(),
+    modelClass = {},
+    resourceHash = {
+      nameSpace: "ns",
+      data: {
+        id: 1,
+        entityID: 3
+      }
+    };
+
+  assert.equal(serializer.extractId(modelClass, resourceHash), "ns:1", "With name-space");
+  assert.equal(serializer.extractId(modelClass, { data: {id: 2} }), 2, "Without name-space");
+
+  serializer.primaryKey = "entityID";
+  assert.equal(serializer.extractId(modelClass, resourceHash), "ns:3", "Different primary key");
+});
+
+test('extractAttributes test', function(assert) {
+  let serializer = this.subject(),
+    modelClass = {
+      eachAttribute: function (callback) {
+        callback("id", {type: "string"});
+        callback("appID", {type: "string"});
+        callback("status", {type: "string"});
+      }
+    },
+    resourceHash = {
+      nameSpace: "ns",
+      data: {
+        id: 1,
+        appID: 2,
+        applicationID: 3,
+        info: {
+          status: "SUCCESS"
+        }
+      }
+    };
+
+  assert.deepEqual(serializer.extractAttributes(modelClass, resourceHash), {
+    id: 1,
+    appID: 2
+  });
+
+  serializer.maps = {
+    id: "id",
+    appID: "applicationID",
+    status: "info.status"
+  };
+
+  assert.deepEqual(serializer.extractAttributes(modelClass, resourceHash), {
+    id: 1,
+    appID: 3,
+    status: "SUCCESS"
+  });
+});
+
+test('extractRelationships test', function(assert) {
+  let serializer = this.subject(),
+    modelClass = {
+      eachAttribute: Ember.K,
+      eachRelationship: function (callback) {
+        callback("app", {
+          key: "app",
+          kind: "belongsTo",
+          options: {},
+          parentType: "parent",
+          type: "app"
+        });
+      },
+      eachTransformedAttribute: Ember.K
+    },
+    resourceHash = {
+      nameSpace: "ns",
+      data: {
+        id: 1,
+        app: "",
+      }
+    };
+
+  assert.deepEqual(serializer.extractRelationships(modelClass, resourceHash), {
+    app: {
+      data: {
+        id: null,
+        type:"app"
+      }
+    }
+  });
+
+});
+
+test('normalizeSingleResponse test', function(assert) {
+  let serializer = this.subject(),
+    modelClass = {
+      eachAttribute: function (callback) {
+        callback("id", {type: "string"});
+        callback("appID", {type: "string"});
+        callback("status", {type: "string"});
+      },
+      eachRelationship: Ember.K,
+      eachTransformedAttribute: Ember.K
+    },
+    resourceHash = {
+      nameSpace: "ns",
+      data: {
+        id: 1,
+        appID: 2,
+        applicationID: 3,
+        info: {
+          status: "SUCCESS"
+        }
+      }
+    };
+
+  var response = serializer.normalizeSingleResponse({}, modelClass, resourceHash, null, null);
+
+  assert.equal(response.data.id, "ns:1");
+  assert.equal(response.data.attributes.id, 1);
+  assert.equal(response.data.attributes.appID, 2);
+});
+
+test('normalizeArrayResponse test', function(assert) {
+  let serializer = this.subject(),
+    modelClass = {
+      eachAttribute: function (callback) {
+        callback("id", {type: "string"});
+        callback("appID", {type: "string"});
+        callback("status", {type: "string"});
+      },
+      eachRelationship: Ember.K,
+      eachTransformedAttribute: Ember.K
+    },
+    resourceHash = {
+      nameSpace: "ns",
+      data: [{
+        id: 1,
+        appID: 2,
+      },{
+        id: 2,
+        appID: 4,
+      }]
+    };
+
+  var response = serializer.normalizeArrayResponse({}, modelClass, resourceHash, null, null);
+
+  assert.equal(response.data.length, 2);
+  assert.deepEqual(response.data[0].id, "ns:1");
+  assert.deepEqual(response.data[1].id, "ns:2");
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/6e18c9b9/tez-ui2/src/main/webapp/tests/unit/services/loader-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/services/loader-test.js b/tez-ui2/src/main/webapp/tests/unit/services/loader-test.js
new file mode 100644
index 0000000..548aca8
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/services/loader-test.js
@@ -0,0 +1,267 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('service:loader', 'Unit | Service | loader', {
+  // Specify the other units that are required for this test.
+  // needs: ['service:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let service = this.subject();
+
+  assert.ok(service.cache);
+  assert.ok(service.store);
+  assert.ok(service._setOptions);
+
+  assert.ok(service.checkRequisite);
+
+  assert.ok(service.lookup);
+  assert.ok(service.entityFor);
+
+  assert.ok(service.getCacheKey);
+
+  assert.ok(service.queryRecord);
+  assert.ok(service.query);
+});
+
+test('_setOptions test', function(assert) {
+  let service = this.subject();
+
+  assert.equal(service.get("nameSpace"), '');
+
+  service._setOptions({
+    nameSpace: "ns"
+  });
+
+  assert.equal(service.get("nameSpace"), 'ns');
+});
+
+test('checkRequisite test', function(assert) {
+  let service = this.subject(),
+      testType = "type";
+
+  assert.expect(3 + 3 + 2);
+
+  // Not found
+  service.store = {
+    adapterFor: function (type) {
+      assert.equal(type, testType);
+    },
+    serializerFor: function (type) {
+      assert.equal(type, testType);
+    }
+  };
+  assert.throws(function () {
+    service.checkRequisite(testType);
+  });
+
+  // Not loader found
+  service.store = {
+    adapterFor: function (type) {
+      assert.equal(type, testType);
+      return {};
+    },
+    serializerFor: function (type) {
+      assert.equal(type, testType);
+      return {};
+    }
+  };
+  assert.throws(function () {
+    service.checkRequisite(testType);
+  });
+
+  service.store = {
+    adapterFor: function (type) {
+      assert.equal(type, testType);
+      return { _isLoader: true };
+    },
+    serializerFor: function (type) {
+      assert.equal(type, testType);
+      return { _isLoader: true };
+    }
+  };
+
+  service.checkRequisite(testType);
+});
+
+test('lookup test', function(assert) {
+  let service = this.subject();
+
+  assert.expect(1);
+
+  service.container.lookup = function (fullName) {
+    assert.equal(fullName, "typ:na-me");
+  };
+
+  service.lookup("typ", "NaMe");
+});
+
+test('entityFor test', function(assert) {
+  let service = this.subject(),
+      testName = "abc",
+      entity;
+
+  assert.expect(3 + 4 + 3);
+
+  // All lookups fail
+  service.lookup = function (type, name) {
+    if(name === testName) {
+      assert.equal(type, "entitie");
+    }
+    if(name === "entity") {
+      assert.equal(type, "entitie");
+    }
+  };
+  assert.throws(function () {
+    service.entityFor(testName);
+  }, "All lookups fail");
+
+  // Default lookups succeeded
+  service.lookup = function (type, name) {
+    if(name === testName) {
+      assert.equal(type, "entitie");
+    }
+    if(name === "entity") {
+      assert.equal(type, "entitie");
+      return {
+        actualName: "entity"
+      };
+    }
+  };
+  entity = service.entityFor(testName);
+  assert.equal(entity.actualName, "entity", "Default lookups succeeded");
+  assert.equal(entity.name, testName, "Default lookups succeeded");
+
+  // Primary lookups succeeded
+  service.lookup = function (type, name) {
+    if(name === testName) {
+      assert.equal(type, "entitie");
+      return {
+        actualName: name
+      };
+    }
+    if(name === "entity") {
+      assert.equal(type, "entitie"); // Shouldn't be called
+    }
+  };
+  entity = service.entityFor(testName);
+  assert.equal(entity.name, testName, "Default lookups succeeded");
+  assert.equal(entity.name, testName, "Default lookups succeeded");
+});
+
+test('getCacheKey test', function(assert) {
+  let service = this.subject();
+
+  assert.equal(service.getCacheKey("type"), "type");
+  assert.equal(service.getCacheKey("type", {a:1}), 'type:{"a":1}');
+  assert.equal(service.getCacheKey("type", null, 1), "type:1");
+  assert.equal(service.getCacheKey("type", {a:1}, 1), 'type:1:{"a":1}');
+});
+
+test('queryRecord test', function(assert) {
+  let service = this.subject(),
+      testNameSpace = "ns",
+      testQueryParams = {},
+      testUrlParams = {},
+      testType = "type",
+      testRecord = {},
+      testID = 1,
+      cacheKey = service.getCacheKey(testType, testQueryParams, testID);
+
+  assert.expect(3 + 5 + 3);
+
+  service.nameSpace = testNameSpace;
+  service.checkRequisite = Ember.K;
+  service.entityFor = function (type) {
+    assert.equal(type, testType);
+
+    return {
+      loadRelations: function (thisService, record) {
+        assert.equal(thisService, service);
+        assert.equal(record, testRecord);
+
+        return record;
+      }
+    };
+  };
+  service.get("store").queryRecord = function (type, query) {
+    assert.equal(type, testType);
+
+    assert.equal(query.id, testID);
+    assert.equal(query.nameSpace, testNameSpace);
+    assert.equal(query.params, testQueryParams);
+    assert.equal(query.urlParams, testUrlParams);
+
+    return Ember.RSVP.resolve(testRecord);
+  };
+
+  service.cache = Ember.Object.create();
+  assert.notOk(service.get("cache").get(cacheKey));
+  service.queryRecord(testType, testID, testQueryParams, testUrlParams).then(function (record) {
+    assert.equal(record, testRecord);
+  });
+  assert.ok(service.get("cache").get(cacheKey));
+});
+
+test('query test', function(assert) {
+  let service = this.subject(),
+      testNameSpace = "ns",
+      testQueryParams = {},
+      testUrlParams = {},
+      testType = "type",
+      testRecord = {},
+      testRecords = [testRecord, testRecord],
+      cacheKey = service.getCacheKey(testType, testQueryParams);
+
+  assert.expect(1 + (2 + 2) + 4 + 3);
+
+  service.nameSpace = testNameSpace;
+  service.checkRequisite = Ember.K;
+  service.entityFor = function (type) {
+    assert.equal(type, testType);
+
+    return {
+      loadRelations: function (thisService, record) {
+        assert.equal(thisService, service);
+        assert.equal(record, testRecord);
+
+        return record;
+      }
+    };
+  };
+  service.get("store").query = function (type, query) {
+    assert.equal(type, testType);
+
+    assert.equal(query.nameSpace, testNameSpace);
+    assert.equal(query.params, testQueryParams);
+    assert.equal(query.urlParams, testUrlParams);
+
+    return Ember.RSVP.resolve(testRecords);
+  };
+
+  service.cache = Ember.Object.create();
+  assert.notOk(service.get("cache").get(cacheKey));
+  service.query(testType, testQueryParams, testUrlParams).then(function (records) {
+    assert.equal(records, testRecords);
+  });
+  assert.ok(service.get("cache").get(cacheKey));
+});


[26/45] tez git commit: Update version in branch to 0.8.2-TEZ-2980-SNAPSHOT to prevent overwriting the master build during jenkins builds.

Posted by sr...@apache.org.
Update version in branch to 0.8.2-TEZ-2980-SNAPSHOT to prevent
overwriting the master build during jenkins builds.


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/5e4d542e
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/5e4d542e
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/5e4d542e

Branch: refs/heads/TEZ-2980
Commit: 5e4d542e4a6b79def0de3ab63b3f294338976f5f
Parents: 8a4f427
Author: Siddharth Seth <ss...@apache.org>
Authored: Mon Jan 4 13:34:19 2016 -0800
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:32:40 2016 +0530

----------------------------------------------------------------------
 tez-ui2/pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/5e4d542e/tez-ui2/pom.xml
----------------------------------------------------------------------
diff --git a/tez-ui2/pom.xml b/tez-ui2/pom.xml
index 2b7503c..8dbea41 100644
--- a/tez-ui2/pom.xml
+++ b/tez-ui2/pom.xml
@@ -21,7 +21,7 @@
   <parent>
     <groupId>org.apache.tez</groupId>
     <artifactId>tez</artifactId>
-    <version>0.8.2-SNAPSHOT</version>
+    <version>0.8.3-SNAPSHOT</version>
   </parent>
   <artifactId>tez-ui2</artifactId>
   <packaging>war</packaging>


[10/45] tez git commit: TEZ-2984. Tez UI 2: Create abstract classes (sree)

Posted by sr...@apache.org.
TEZ-2984. Tez UI 2: Create abstract classes (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/95c13aaa
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/95c13aaa
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/95c13aaa

Branch: refs/heads/TEZ-2980
Commit: 95c13aaafd0e7791e7abd94ebd774d2ea7af019a
Parents: ec0a592
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Wed Dec 30 16:59:14 2015 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:31:59 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |  1 +
 .../src/main/webapp/app/adapters/abstract.js    | 54 ++++++++++++++++++++
 .../webapp/app/initializers/local-storage.js    | 26 ++++++++++
 tez-ui2/src/main/webapp/app/models/abstract.js  | 33 ++++++++++++
 tez-ui2/src/main/webapp/app/routes/abstract.js  | 32 ++++++++++++
 .../src/main/webapp/app/serializers/abstract.js | 26 ++++++++++
 .../main/webapp/app/services/local-storage.js   | 39 ++++++++++++++
 tez-ui2/src/main/webapp/bower.json              |  3 +-
 tez-ui2/src/main/webapp/ember-cli-build.js      |  2 +
 .../webapp/tests/unit/adapters/abstract-test.js | 39 ++++++++++++++
 .../unit/initializers/local-storage-test.js     | 39 ++++++++++++++
 .../webapp/tests/unit/models/abstract-test.js   | 29 +++++++++++
 .../webapp/tests/unit/routes/abstract-test.js   | 29 +++++++++++
 .../tests/unit/serializers/abstract-test.js     | 31 +++++++++++
 .../webapp/tests/unit/services/hosts-test.js    |  1 -
 .../tests/unit/services/local-storage-test.js   | 42 +++++++++++++++
 16 files changed, 424 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/95c13aaa/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index 5143309..e3fece1 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -4,3 +4,4 @@ ALL CHANGES:
   TEZ-2983. Tez UI 2: Get ember initializers functional
   TEZ-3018. Tez UI 2: Add config.env
   TEZ-3019. Tez UI 2: Replace BaseURL with Host
+  TEZ-2984. Tez UI 2: Create abstract classes

http://git-wip-us.apache.org/repos/asf/tez/blob/95c13aaa/tez-ui2/src/main/webapp/app/adapters/abstract.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/abstract.js b/tez-ui2/src/main/webapp/app/adapters/abstract.js
new file mode 100644
index 0000000..aca0faf
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/adapters/abstract.js
@@ -0,0 +1,54 @@
+/*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 DS from 'ember-data';
+
+var MoreString = more.String;
+
+export default DS.RESTAdapter.extend({
+  ajax: function(url, method, hash) {
+    return this._super(url, method, Ember.$.extend(hash || {}, {
+      crossDomain: true,
+      xhrFields: {
+        withCredentials: true
+      }
+    }));
+  },
+  buildURL: function(type, id, record) {
+    var url = this._super(type, undefined, record);
+    return MoreString.fmt(url, record);
+  },
+  findQuery: function(store, type, query) {
+    var record = query.metadata;
+    delete query.metadata;
+
+    return this.ajax(this.buildURL(
+        Ember.String.pluralize(type.typeKey),
+        record.id,
+        Ember.Object.create(record)
+      ),
+      'GET',
+      {
+        data: query
+      }
+    );
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/95c13aaa/tez-ui2/src/main/webapp/app/initializers/local-storage.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/initializers/local-storage.js b/tez-ui2/src/main/webapp/app/initializers/local-storage.js
new file mode 100644
index 0000000..8504c35
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/initializers/local-storage.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.
+ */
+
+export function initialize(application) {
+  application.inject('controller', 'localStorage', 'service:localStorage');
+}
+
+export default {
+  name: 'local-storage',
+  initialize
+};

http://git-wip-us.apache.org/repos/asf/tez/blob/95c13aaa/tez-ui2/src/main/webapp/app/models/abstract.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/abstract.js b/tez-ui2/src/main/webapp/app/models/abstract.js
new file mode 100644
index 0000000..2191d18
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/models/abstract.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({
+  timeStamp: null,
+
+  refreshTimestamp: function () {
+    this.set('timeStamp', new Date());
+  },
+
+  actions: {
+    didUpdate: function () {
+      this.refreshTimestamp();
+    }
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/95c13aaa/tez-ui2/src/main/webapp/app/routes/abstract.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/abstract.js b/tez-ui2/src/main/webapp/app/routes/abstract.js
new file mode 100644
index 0000000..a4d2bb5
--- /dev/null
+++ b/tez-ui2/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({
+  title: null, // Must be set by inheriting class
+
+  setDocTitle: function () {
+    Ember.$(document).attr('title', this.get('title'));
+  },
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    this.setDocTitle();
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/95c13aaa/tez-ui2/src/main/webapp/app/serializers/abstract.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/abstract.js b/tez-ui2/src/main/webapp/app/serializers/abstract.js
new file mode 100644
index 0000000..c032c30
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/serializers/abstract.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 Ember from 'ember';
+import DS from 'ember-data';
+
+export default DS.RESTSerializer.extend({
+  normalize: function(type, hash /*, prop */) {
+    return Ember.JsonMapper.map(hash, this.get('map'));
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/95c13aaa/tez-ui2/src/main/webapp/app/services/local-storage.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/services/local-storage.js b/tez-ui2/src/main/webapp/app/services/local-storage.js
new file mode 100644
index 0000000..d25ef9d
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/services/local-storage.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.Service.extend({
+  getStoreKey: function (key) {
+    return "tez-ui:" + key;
+  },
+  set: function (key, value) {
+    try {
+      localStorage.setItem(this.getStoreKey(key) , JSON.stringify(value));
+    }catch(e){
+      return e;
+    }
+    return value;
+  },
+  get: function (key) {
+    try {
+      return JSON.parse(localStorage.getItem(this.getStoreKey(key)));
+    }catch(e){}
+    return undefined;
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/95c13aaa/tez-ui2/src/main/webapp/bower.json
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/bower.json b/tez-ui2/src/main/webapp/bower.json
index b6c7ca5..98402b3 100644
--- a/tez-ui2/src/main/webapp/bower.json
+++ b/tez-ui2/src/main/webapp/bower.json
@@ -11,6 +11,7 @@
     "jquery": "^1.11.3",
     "loader.js": "3.3.0",
     "qunit": "~1.19.0",
-    "jquery-ui": "~1.11.4"
+    "jquery-ui": "~1.11.4",
+    "more-js": "*"
   }
 }

http://git-wip-us.apache.org/repos/asf/tez/blob/95c13aaa/tez-ui2/src/main/webapp/ember-cli-build.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/ember-cli-build.js b/tez-ui2/src/main/webapp/ember-cli-build.js
index ede63b3..c68e22b 100644
--- a/tez-ui2/src/main/webapp/ember-cli-build.js
+++ b/tez-ui2/src/main/webapp/ember-cli-build.js
@@ -34,5 +34,7 @@ module.exports = function(defaults) {
   app.import('bower_components/jquery-ui/jquery-ui.js');
   app.import('bower_components/jquery-ui/ui/tooltip.js');
 
+  app.import('bower_components/more-js/dist/more.js');
+
   return app.toTree(extraAssets);
 };

http://git-wip-us.apache.org/repos/asf/tez/blob/95c13aaa/tez-ui2/src/main/webapp/tests/unit/adapters/abstract-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/abstract-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/abstract-test.js
new file mode 100644
index 0000000..00be0ac
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/adapters/abstract-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('adapter:abstract', 'Unit | Adapter | abstract', {
+  // 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);
+});
+
+test('buildURL test', function(assert) {
+  let adapter = this.subject();
+
+  assert.equal(adapter.buildURL("{x}/{y}/type", null, {
+    x: "x_x",
+    y: "y_y"
+  }), "/x_x/y_y/types");
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/95c13aaa/tez-ui2/src/main/webapp/tests/unit/initializers/local-storage-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/initializers/local-storage-test.js b/tez-ui2/src/main/webapp/tests/unit/initializers/local-storage-test.js
new file mode 100644
index 0000000..f600fdc
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/initializers/local-storage-test.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';
+import LocalStorageInitializer from '../../../initializers/local-storage';
+import { module, test } from 'qunit';
+
+let application;
+
+module('Unit | Initializer | local storage', {
+  beforeEach() {
+    Ember.run(function() {
+      application = Ember.Application.create();
+      application.deferReadiness();
+    });
+  }
+});
+
+test('it works', function(assert) {
+  LocalStorageInitializer.initialize(application);
+
+  // you would normally confirm the results of the initializer here
+  assert.ok(true);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/95c13aaa/tez-ui2/src/main/webapp/tests/unit/models/abstract-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/abstract-test.js b/tez-ui2/src/main/webapp/tests/unit/models/abstract-test.js
new file mode 100644
index 0000000..42fe21c
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/models/abstract-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 { moduleForModel, test } from 'ember-qunit';
+
+moduleForModel('abstract', 'Unit | Model | abstract', {
+  // Specify the other units that are required for this test.
+  needs: []
+});
+
+test('Basic test for existence', function(assert) {
+  let model = this.subject();
+  assert.ok(model);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/95c13aaa/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js
new file mode 100644
index 0000000..e11183e
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/abstract-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:abstract', 'Unit | Route | abstract', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic test for existence', function(assert) {
+  let route = this.subject();
+  assert.ok(route);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/95c13aaa/tez-ui2/src/main/webapp/tests/unit/serializers/abstract-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/serializers/abstract-test.js b/tez-ui2/src/main/webapp/tests/unit/serializers/abstract-test.js
new file mode 100644
index 0000000..006d69c
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/serializers/abstract-test.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 { moduleForModel, test } from 'ember-qunit';
+
+moduleForModel('abstract', 'Unit | Serializer | abstract', {
+  // Specify the other units that are required for this test.
+  needs: ['serializer:abstract']
+});
+
+test('it serializes records', function(assert) {
+  let record = this.subject();
+  let serializedRecord = record.serialize();
+
+  assert.ok(serializedRecord);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/95c13aaa/tez-ui2/src/main/webapp/tests/unit/services/hosts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/services/hosts-test.js b/tez-ui2/src/main/webapp/tests/unit/services/hosts-test.js
index 51b558c..055fccd 100644
--- a/tez-ui2/src/main/webapp/tests/unit/services/hosts-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/services/hosts-test.js
@@ -23,7 +23,6 @@ moduleFor('service:hosts', 'Unit | Service | hosts', {
   // needs: ['service:foo']
 });
 
-// Replace this with your real tests.
 test('Test creation', function(assert) {
   let service = this.subject();
   assert.ok(service);

http://git-wip-us.apache.org/repos/asf/tez/blob/95c13aaa/tez-ui2/src/main/webapp/tests/unit/services/local-storage-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/services/local-storage-test.js b/tez-ui2/src/main/webapp/tests/unit/services/local-storage-test.js
new file mode 100644
index 0000000..6f9a1af
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/services/local-storage-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('service:local-storage', 'Unit | Service | local storage', {
+  // Specify the other units that are required for this test.
+  // needs: ['service:foo']
+});
+
+test('Test creation', function(assert) {
+  let service = this.subject();
+  assert.ok(service);
+});
+
+test('getStoreKey test', function(assert) {
+  let service = this.subject();
+
+  assert.equal(service.getStoreKey("abc"), "tez-ui:abc");
+});
+
+test('Set & get test', function(assert) {
+  let service = this.subject();
+
+  service.set("abc", "value");
+  assert.equal(service.get("abc"), "value");
+});


[25/45] tez git commit: TEZ-3050. Tez UI 2: Add counter columns (sree)

Posted by sr...@apache.org.
TEZ-3050. Tez UI 2: Add counter columns (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/8a4f4276
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/8a4f4276
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/8a4f4276

Branch: refs/heads/TEZ-2980
Commit: 8a4f4276c5b38416be36ed1124e1ebd97d16a8f9
Parents: 0798c90
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Wed Jan 20 20:55:06 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:32:16 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |   1 +
 .../webapp/app/components/column-selector.js    |  13 +-
 .../src/main/webapp/app/controllers/app/dags.js |   3 +
 tez-ui2/src/main/webapp/app/controllers/dags.js |   3 +
 .../main/webapp/app/controllers/table-page.js   |  21 +-
 .../webapp/app/controllers/task/attempts.js     |   4 +-
 .../webapp/app/controllers/vertex/attempts.js   |   4 +-
 .../main/webapp/app/controllers/vertex/tasks.js |   4 +-
 .../webapp/app/mixins/auto-counter-column.js    |  69 +++++
 .../main/webapp/app/styles/column-selector.less |  28 +-
 .../templates/components/column-selector.hbs    |  30 ++-
 .../app/utils/counter-column-definition.js      |  97 +++++++
 tez-ui2/src/main/webapp/app/utils/misc.js       |   3 +-
 .../src/main/webapp/config/default-app-conf.js  | 266 +++++++++++++++++++
 .../tests/unit/controllers/app/dags-test.js     |   1 +
 .../webapp/tests/unit/controllers/dags-test.js  |   3 +-
 .../tests/unit/controllers/table-page-test.js   |  17 ++
 .../unit/mixins/auto-counter-column-test.js     |  64 +++++
 .../utils/counter-column-definition-test.js     | 124 +++++++++
 19 files changed, 720 insertions(+), 35 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/8a4f4276/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index f92341a..6a2b343 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -22,3 +22,4 @@ ALL CHANGES:
   TEZ-3042. Tez UI 2: Create Counters pages
   TEZ-3043. Tez UI 2: Create configurations page
   TEZ-3049. Tez UI 2: Add column selector
+  TEZ-3050. Tez UI 2: Add counter columns

http://git-wip-us.apache.org/repos/asf/tez/blob/8a4f4276/tez-ui2/src/main/webapp/app/components/column-selector.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/components/column-selector.js b/tez-ui2/src/main/webapp/app/components/column-selector.js
index 9c9d4d2..8f9ac13 100644
--- a/tez-ui2/src/main/webapp/app/components/column-selector.js
+++ b/tez-ui2/src/main/webapp/app/components/column-selector.js
@@ -34,11 +34,11 @@ export default Ember.Component.extend({
         highlight = false,
         visibleColumnIDs = this.get('content.visibleColumnIDs') || {};
 
-    return this.get('content.columns').map(function (config) {
+    return this.get('content.columns').map(function (definition) {
       var css = '';
 
-      highlight = highlight ^ (config.get("counterGroupName") !== group);
-      group = config.counterGroupName;
+      highlight = highlight ^ (Ember.get(definition, "counterGroupName") !== group);
+      group = Ember.get(definition, "counterGroupName");
 
       if(highlight) {
         css += ' highlight';
@@ -48,10 +48,10 @@ export default Ember.Component.extend({
       }
 
       return Ember.Object.create({
-        id: config.get("id"),
-        displayText: config.get("headerTitle"),
+        id: Ember.get(definition, "id"),
+        displayText: Ember.get(definition, "headerTitle"),
         css: css,
-        selected: visibleColumnIDs[config.id]
+        selected: visibleColumnIDs[Ember.get(definition, "id")]
       });
     });
   }),
@@ -71,7 +71,6 @@ export default Ember.Component.extend({
 
   selectedColumnIDs: Ember.computed("options", function () {
     var columnIds = {};
-
     this.get('options').forEach(function (option) {
       columnIds[option.get("id")] = option.get('selected');
     });

http://git-wip-us.apache.org/repos/asf/tez/blob/8a4f4276/tez-ui2/src/main/webapp/app/controllers/app/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/app/dags.js b/tez-ui2/src/main/webapp/app/controllers/app/dags.js
index bcb4db8..04f8f43 100644
--- a/tez-ui2/src/main/webapp/app/controllers/app/dags.js
+++ b/tez-ui2/src/main/webapp/app/controllers/app/dags.js
@@ -95,4 +95,7 @@ export default TablePageController.extend({
     }
   }]),
 
+  getCounterColumns: function () {
+    return this._super().concat(this.get('env.app.tables.defaultColumns.dagCounters'));
+  }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8a4f4276/tez-ui2/src/main/webapp/app/controllers/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dags.js b/tez-ui2/src/main/webapp/app/controllers/dags.js
index fced7d8..7d5f1d9 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dags.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dags.js
@@ -105,4 +105,7 @@ export default TablePageController.extend({
     }
   }]),
 
+  getCounterColumns: function () {
+    return this._super().concat(this.get('env.app.tables.defaultColumns.dagCounters'));
+  }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8a4f4276/tez-ui2/src/main/webapp/app/controllers/table-page.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/table-page.js b/tez-ui2/src/main/webapp/app/controllers/table-page.js
index 09ae8ab..12f4715 100644
--- a/tez-ui2/src/main/webapp/app/controllers/table-page.js
+++ b/tez-ui2/src/main/webapp/app/controllers/table-page.js
@@ -23,6 +23,8 @@ import PageController from './page';
 import TableDefinition from 'em-table/utils/table-definition';
 import isIOCounter from '../utils/misc';
 
+import CounterColumnDefinition from '../utils/counter-column-definition';
+
 var MoreObject = more.Object;
 
 export default PageController.extend({
@@ -33,6 +35,8 @@ export default PageController.extend({
   sortOrder: "",
   pageNo: 1,
 
+  columns: [],
+
   headerComponentNames: ['em-table-search-ui', 'table-controls', 'em-table-pagination-ui'],
 
   visibleColumnIDs: {},
@@ -65,13 +69,24 @@ export default PageController.extend({
     this.set('visibleColumnIDs', visibleColumnIDs);
   })),
 
-  visibleColumns: Ember.computed('visibleColumnIDs', 'columns', function() {
+  allColumns: Ember.computed("columns", function () {
+    var columns = this.get("columns"),
+        counters = this.getCounterColumns();
+
+    return columns.concat(CounterColumnDefinition.make(counters));
+  }),
+
+  visibleColumns: Ember.computed('visibleColumnIDs', 'allColumns', function() {
     var visibleColumnIDs = this.visibleColumnIDs;
-    return this.get('columns').filter(function (column) {
+    return this.get('allColumns').filter(function (column) {
       return visibleColumnIDs[column.get("id")];
     });
   }),
 
+  getCounterColumns: function () {
+    return this.get('env.app.tables.defaultColumns.counters');
+  },
+
   actions: {
     searchChanged: function (searchText) {
       this.set("searchText", searchText);
@@ -97,7 +112,7 @@ export default PageController.extend({
         targetObject: this,
         content: {
           message: this.get('columnSelectorMessage'),
-          columns: this.get('columns'),
+          columns: this.get('allColumns'),
           visibleColumnIDs: this.get('visibleColumnIDs')
         }
       });

http://git-wip-us.apache.org/repos/asf/tez/blob/8a4f4276/tez-ui2/src/main/webapp/app/controllers/task/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/task/attempts.js b/tez-ui2/src/main/webapp/app/controllers/task/attempts.js
index 5b97033..d7bec55 100644
--- a/tez-ui2/src/main/webapp/app/controllers/task/attempts.js
+++ b/tez-ui2/src/main/webapp/app/controllers/task/attempts.js
@@ -19,7 +19,9 @@
 import TablePageController from '../table-page';
 import ColumnDefinition from 'em-table/utils/column-definition';
 
-export default TablePageController.extend({
+import AutoCounterColumn from '../../mixins/auto-counter-column';
+
+export default TablePageController.extend(AutoCounterColumn, {
   breadcrumbs: [{
     text: "Task Attempts",
     routeName: "task.attempts",

http://git-wip-us.apache.org/repos/asf/tez/blob/8a4f4276/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js b/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js
index b6a4389..b0fb983 100644
--- a/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js
+++ b/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js
@@ -19,7 +19,9 @@
 import TablePageController from '../table-page';
 import ColumnDefinition from 'em-table/utils/column-definition';
 
-export default TablePageController.extend({
+import AutoCounterColumn from '../../mixins/auto-counter-column';
+
+export default TablePageController.extend(AutoCounterColumn, {
   breadcrumbs: [{
     text: "Task Attempts",
     routeName: "vertex.attempts",

http://git-wip-us.apache.org/repos/asf/tez/blob/8a4f4276/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.js b/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.js
index f35a022..350d246 100644
--- a/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.js
+++ b/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.js
@@ -19,7 +19,9 @@
 import TablePageController from '../table-page';
 import ColumnDefinition from 'em-table/utils/column-definition';
 
-export default TablePageController.extend({
+import AutoCounterColumn from '../../mixins/auto-counter-column';
+
+export default TablePageController.extend(AutoCounterColumn, {
   breadcrumbs: [{
     text: "Tasks",
     routeName: "vertex.tasks",

http://git-wip-us.apache.org/repos/asf/tez/blob/8a4f4276/tez-ui2/src/main/webapp/app/mixins/auto-counter-column.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/mixins/auto-counter-column.js b/tez-ui2/src/main/webapp/app/mixins/auto-counter-column.js
new file mode 100644
index 0000000..7820e4a
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/mixins/auto-counter-column.js
@@ -0,0 +1,69 @@
+/*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';
+
+var MoreObject = more.Object;
+
+export default Ember.Mixin.create({
+  columnSelectorMessage: "<span class='per-io'>Per-IO counter</span> selection wouldn't persist.",
+
+  getCounterColumns: function () {
+    var columns = [],
+        records = this.get("model"),
+        counterHash = {};
+
+    this._super().forEach(function (column) {
+      var groupHash =
+          counterHash[column.counterGroupName] =
+          counterHash[column.counterGroupName] || {};
+      groupHash[column.counterName] = column.counterName;
+    });
+
+    if(records) {
+      records.forEach(function (record) {
+        let counterGroups = Ember.get(record, 'counterGroups');
+
+        if(counterGroups) {
+          counterGroups.forEach(function (group) {
+            var groupHash =
+                counterHash[group.counterGroupName] =
+                counterHash[group.counterGroupName] || {};
+
+            group.counters.forEach(function (counter) {
+              groupHash[counter.counterName] = counter.counterName;
+            });
+          });
+        }
+      });
+    }
+
+    MoreObject.forEach(counterHash, function (groupName, counters) {
+      MoreObject.forEach(counters, function (counterName) {
+        columns.push({
+          counterName: counterName,
+          counterGroupName: groupName
+        });
+      });
+    });
+
+    return columns;
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/8a4f4276/tez-ui2/src/main/webapp/app/styles/column-selector.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/column-selector.less b/tez-ui2/src/main/webapp/app/styles/column-selector.less
index 2e39995..3e061e1 100644
--- a/tez-ui2/src/main/webapp/app/styles/column-selector.less
+++ b/tez-ui2/src/main/webapp/app/styles/column-selector.less
@@ -16,19 +16,35 @@
  * limitations under the License.
  */
 
+@import "../../bower_components/snippet-ss/less/force";
+@import "../../bower_components/snippet-ss/less/effects";
+
 .column-selector {
   .message {
-    text-align: right;
-    font-size: 10px;
+    position: absolute;
+    font-size: 12px;
+    padding: 1px;
+    left: 15px;
+  }
+
+  .highlight {
+    background-color: @bg-lite;
+  }
+  .per-io {
+    color: @text-green;
   }
 
   .selection-list {
     border-bottom: 1px solid @border-color;
 
-    .highlight {
-      background-color: @bg-lite;
+    .options {
+      .force-scrollbar;
+
+      max-height: 500px;
+      overflow: auto;
     }
-    .select-option, .search-option {
+
+    .select-option, .filter-option {
       border-top: 1px dotted @border-color;
       padding: 5px 15px;
 
@@ -40,7 +56,7 @@
         vertical-align: middle;
       }
     }
-    .search-option {
+    .filter-option {
       border: none;
 
       .form-group {

http://git-wip-us.apache.org/repos/asf/tez/blob/8a4f4276/tez-ui2/src/main/webapp/app/templates/components/column-selector.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/components/column-selector.hbs b/tez-ui2/src/main/webapp/app/templates/components/column-selector.hbs
index d9be633..a5dcf9c 100644
--- a/tez-ui2/src/main/webapp/app/templates/components/column-selector.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/components/column-selector.hbs
@@ -16,11 +16,8 @@
  * limitations under the License.
 }}
 
-<div class="message">
-  {{{content.message}}}
-</div>
 <div class="selection-list">
-  <div class="search-option highlight">
+  <div class="filter-option highlight">
     <div class="form-group">
       {{input class="form-control" placeholder="Filter..." value=searchText}}
     </div>
@@ -31,18 +28,23 @@
       &nbsp;Select All
     </div>
   </div>
-  {{#if filteredOptions.length}}
-    {{#each filteredOptions as |option|}}
-      <div class="select-option {{option.css}}">
-        {{input type="checkbox" classNames='checkbox' checked=option.selected}}
-        {{option.displayText}}
-      </div>
-    {{/each}}
-  {{else}}
-    <h4>&nbsp;No options available...</h4>
-  {{/if}}
+  <div class="options">
+    {{#if filteredOptions.length}}
+      {{#each filteredOptions as |option|}}
+        <div class="select-option {{option.css}}">
+          {{input type="checkbox" classNames='checkbox' checked=option.selected}}
+          {{option.displayText}}
+        </div>
+      {{/each}}
+    {{else}}
+      <h4>&nbsp;No options available...</h4>
+    {{/if}}
+  </div>
 </div>
 <div class="form-actions">
+  <span class="message">
+    {{{content.message}}}
+  </span>
   <button type="button" class="btn btn-primary" {{action "ok"}} data-dismiss="modal" aria-label="Close">Ok</button>
   <button type="button" class="btn" data-dismiss="modal" aria-label="Close">Cancel</button>
 </div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/8a4f4276/tez-ui2/src/main/webapp/app/utils/counter-column-definition.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/utils/counter-column-definition.js b/tez-ui2/src/main/webapp/app/utils/counter-column-definition.js
new file mode 100644
index 0000000..be36053
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/utils/counter-column-definition.js
@@ -0,0 +1,97 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 isIOCounter from '../utils/misc';
+import ColumnDefinition from 'em-table/utils/column-definition';
+
+/*
+ * Returns a counter value from for a row
+ * @param row
+ * @return value
+ */
+function getCounterContent(row) {
+  var counter = Ember.get(row, this.get("contentPath"));
+
+  if(counter) {
+    counter = counter[this.get("counterGroupName")];
+    if(counter) {
+      return counter[this.get("counterName")] || null;
+    }
+    return null;
+  }
+}
+
+var CounterColumnDefinition = ColumnDefinition.extend({
+  counterName: "",
+  counterGroupName: "",
+
+  observePath: true,
+  contentPath: "counterHash",
+
+  getCellContent: getCounterContent,
+  getSearchValue: getCounterContent,
+  getSortValue: getCounterContent,
+
+  id: Ember.computed("counterName", "counterGroupName", function () {
+    var groupName = this.get("counterGroupName"),
+        counterName = this.get("counterName");
+    return `${groupName}/${counterName}`;
+  }),
+
+  groupDisplayName: Ember.computed("counterGroupName", function () {
+    var displayName = this.get("counterGroupName");
+
+    // Prune dotted path
+    displayName = displayName.substr(displayName.lastIndexOf('.') + 1);
+
+    if(isIOCounter(displayName)) {
+      displayName = displayName.replace("_INPUT_", " to Input-");
+      displayName = displayName.replace("_OUTPUT_", " to Output-");
+    }
+
+    // Prune counter text
+    displayName = displayName.replace("Counter_", " - ");
+    displayName = displayName.replace("Counter", "");
+
+    return displayName;
+  }),
+
+  headerTitle: Ember.computed("groupDisplayName", "counterName", function () {
+    var groupName = this.get("groupDisplayName"),
+        counterName = this.get("counterName");
+    return `${groupName} - ${counterName}`;
+  }),
+});
+
+CounterColumnDefinition.make = function (rawDefinition) {
+  if(Array.isArray(rawDefinition)) {
+    return rawDefinition.map(function (def) {
+      return CounterColumnDefinition.create(def);
+    });
+  }
+  else if(typeof rawDefinition === 'object') {
+    return CounterColumnDefinition.create(rawDefinition);
+  }
+  else {
+    throw new Error("rawDefinition must be an Array or an Object.");
+  }
+};
+
+export default CounterColumnDefinition;

http://git-wip-us.apache.org/repos/asf/tez/blob/8a4f4276/tez-ui2/src/main/webapp/app/utils/misc.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/utils/misc.js b/tez-ui2/src/main/webapp/app/utils/misc.js
index 5e2ecf1..93e2f0b 100644
--- a/tez-ui2/src/main/webapp/app/utils/misc.js
+++ b/tez-ui2/src/main/webapp/app/utils/misc.js
@@ -18,5 +18,6 @@
 
 export default function isIOCounter(name) {
   name = name.split('/')[0];
-  return name.match('_INPUT_') || name.match('_OUTPUT_');
+  name = name.substr(name.indexOf('_') + 1);
+  return !!(name.match('_INPUT_') || name.match('_OUTPUT_'));
 }

http://git-wip-us.apache.org/repos/asf/tez/blob/8a4f4276/tez-ui2/src/main/webapp/config/default-app-conf.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/config/default-app-conf.js b/tez-ui2/src/main/webapp/config/default-app-conf.js
index 400290a..200dc14 100644
--- a/tez-ui2/src/main/webapp/config/default-app-conf.js
+++ b/tez-ui2/src/main/webapp/config/default-app-conf.js
@@ -50,5 +50,271 @@ module.exports = { // Tez App configurations
   hrefs: {
     help: "https://tez.apache.org/tez_ui_user_data.html",
     license: "http://www.apache.org/licenses/LICENSE-2.0"
+  },
+
+  tables: {
+    defaultColumns: {
+      counters: [
+        // File System Counters
+        {
+          counterName: 'FILE_BYTES_READ',
+          counterGroupName: 'org.apache.tez.common.counters.FileSystemCounter',
+        },
+        {
+          counterName: 'FILE_BYTES_WRITTEN',
+          counterGroupName: 'org.apache.tez.common.counters.FileSystemCounter',
+        },
+        {
+          counterName: 'FILE_READ_OPS',
+          counterGroupName: 'org.apache.tez.common.counters.FileSystemCounter',
+        },
+        {
+          counterName: 'FILE_LARGE_READ_OPS',
+          counterGroupName: 'org.apache.tez.common.counters.FileSystemCounter',
+        },
+        {
+          counterName: 'FILE_WRITE_OPS',
+          counterGroupName: 'org.apache.tez.common.counters.FileSystemCounter',
+        },
+        {
+          counterName: 'HDFS_BYTES_READ',
+          counterGroupName: 'org.apache.tez.common.counters.FileSystemCounter',
+        },
+        {
+          counterName: 'HDFS_BYTES_WRITTEN',
+          counterGroupName: 'org.apache.tez.common.counters.FileSystemCounter',
+        },
+        {
+          counterName: 'HDFS_READ_OPS',
+          counterGroupName: 'org.apache.tez.common.counters.FileSystemCounter',
+        },
+        {
+          counterName: 'HDFS_LARGE_READ_OPS',
+          counterGroupName: 'org.apache.tez.common.counters.FileSystemCounter',
+        },
+        {
+          counterName: 'HDFS_WRITE_OPS',
+          counterGroupName: 'org.apache.tez.common.counters.FileSystemCounter',
+        },
+
+        // Task Counters
+        {
+          counterName: "NUM_SPECULATIONS",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "REDUCE_INPUT_GROUPS",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "REDUCE_INPUT_RECORDS",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "SPLIT_RAW_BYTES",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "COMBINE_INPUT_RECORDS",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "SPILLED_RECORDS",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "NUM_SHUFFLED_INPUTS",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "NUM_SKIPPED_INPUTS",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "NUM_FAILED_SHUFFLE_INPUTS",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "MERGED_MAP_OUTPUTS",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "GC_TIME_MILLIS",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "CPU_MILLISECONDS",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "PHYSICAL_MEMORY_BYTES",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "VIRTUAL_MEMORY_BYTES",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "COMMITTED_HEAP_BYTES",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "INPUT_RECORDS_PROCESSED",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "OUTPUT_RECORDS",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "OUTPUT_LARGE_RECORDS",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "OUTPUT_BYTES",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "OUTPUT_BYTES_WITH_OVERHEAD",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "OUTPUT_BYTES_PHYSICAL",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "ADDITIONAL_SPILLS_BYTES_WRITTEN",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "ADDITIONAL_SPILLS_BYTES_READ",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "ADDITIONAL_SPILL_COUNT",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "SHUFFLE_BYTES",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "SHUFFLE_BYTES_DECOMPRESSED",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "SHUFFLE_BYTES_TO_MEM",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "SHUFFLE_BYTES_TO_DISK",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "SHUFFLE_BYTES_DISK_DIRECT",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "NUM_MEM_TO_DISK_MERGES",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "NUM_DISK_TO_DISK_MERGES",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "SHUFFLE_PHASE_TIME",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "MERGE_PHASE_TIME",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "FIRST_EVENT_RECEIVED",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+        {
+          counterName: "LAST_EVENT_RECEIVED",
+          counterGroupName: "org.apache.tez.common.counters.TaskCounter",
+        },
+      ],
+
+      dagCounters: [
+        {
+          counterName :"NUM_FAILED_TASKS",
+          counterGroupName :"org.apache.tez.common.counters.DAGCounter",
+        },
+        {
+          counterName :"NUM_KILLED_TASKS",
+          counterGroupName :"org.apache.tez.common.counters.DAGCounter",
+        },
+        {
+          counterName :"NUM_SUCCEEDED_TASKS",
+          counterGroupName :"org.apache.tez.common.counters.DAGCounter",
+        },
+        {
+          counterName :"TOTAL_LAUNCHED_TASKS",
+          counterGroupName :"org.apache.tez.common.counters.DAGCounter",
+        },
+        {
+          counterName :"OTHER_LOCAL_TASKS",
+          counterGroupName :"org.apache.tez.common.counters.DAGCounter",
+        },
+        {
+          counterName :"DATA_LOCAL_TASKS",
+          counterGroupName :"org.apache.tez.common.counters.DAGCounter",
+        },
+        {
+          counterName :"RACK_LOCAL_TASKS",
+          counterGroupName :"org.apache.tez.common.counters.DAGCounter",
+        },
+        {
+          counterName :"SLOTS_MILLIS_TASKS",
+          counterGroupName :"org.apache.tez.common.counters.DAGCounter",
+        },
+        {
+          counterName :"FALLOW_SLOTS_MILLIS_TASKS",
+          counterGroupName :"org.apache.tez.common.counters.DAGCounter",
+        },
+        {
+          counterName :"TOTAL_LAUNCHED_UBERTASKS",
+          counterGroupName :"org.apache.tez.common.counters.DAGCounter",
+        },
+        {
+          counterName :"NUM_UBER_SUBTASKS",
+          counterGroupName :"org.apache.tez.common.counters.DAGCounter",
+        },
+        {
+          counterName :"NUM_FAILED_UBERTASKS",
+          counterGroupName :"org.apache.tez.common.counters.DAGCounter",
+        },
+
+        {
+          counterName: "REDUCE_OUTPUT_RECORDS",
+          counterGroupName: "REDUCE_OUTPUT_RECORDS",
+        },
+        {
+          counterName: "REDUCE_SKIPPED_GROUPS",
+          counterGroupName: "REDUCE_SKIPPED_GROUPS",
+        },
+        {
+          counterName: "REDUCE_SKIPPED_RECORDS",
+          counterGroupName: "REDUCE_SKIPPED_RECORDS",
+        },
+        {
+          counterName: "COMBINE_OUTPUT_RECORDS",
+          counterGroupName: "COMBINE_OUTPUT_RECORDS",
+        },
+        {
+          counterName: "SKIPPED_RECORDS",
+          counterGroupName: "SKIPPED_RECORDS",
+        },
+        {
+          counterName: "INPUT_GROUPS",
+          counterGroupName: "INPUT_GROUPS",
+        }
+      ]
+    }
   }
 };

http://git-wip-us.apache.org/repos/asf/tez/blob/8a4f4276/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js
index c60fbb5..25afc63 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js
@@ -34,4 +34,5 @@ test('Basic creation test', function(assert) {
   assert.ok(controller);
   assert.ok(controller.breadcrumbs);
   assert.ok(controller.columns);
+  assert.ok(controller.getCounterColumns);
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8a4f4276/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js
index 944f813..21dbc96 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js
@@ -26,7 +26,7 @@ moduleFor('controller:dags', 'Unit | Controller | dags', {
 });
 
 test('Basic creation test', function(assert) {
-  assert.expect(2 + 2);
+  assert.expect(2 + 3);
 
   let controller = this.subject({
     initVisibleColumns: Ember.K,
@@ -38,4 +38,5 @@ test('Basic creation test', function(assert) {
 
   assert.ok(controller);
   assert.ok(controller.columns);
+  assert.ok(controller.getCounterColumns);
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8a4f4276/tez-ui2/src/main/webapp/tests/unit/controllers/table-page-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/table-page-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/table-page-test.js
index 8aee8d7..07941b9 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/table-page-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/table-page-test.js
@@ -40,8 +40,25 @@ test('Basic creation test', function(assert) {
   assert.equal(controller.sortOrder, "");
   assert.equal(controller.pageNo, 1);
 
+  assert.ok(controller.headerComponentNames);
+  assert.ok(controller.visibleColumnIDs);
+  assert.ok(controller.columnSelectorTitle);
+  assert.ok(controller.definition);
+
+  assert.ok(controller.storageID);
+  assert.ok(controller.initVisibleColumns);
+
+  assert.ok(controller.columns);
+  assert.ok(controller.allColumns);
+  assert.ok(controller.visibleColumns);
+
+  assert.ok(controller.getCounterColumns);
+
   assert.ok(controller.actions.searchChanged);
   assert.ok(controller.actions.sortChanged);
   assert.ok(controller.actions.rowsChanged);
   assert.ok(controller.actions.pageChanged);
+
+  assert.ok(controller.actions.openColumnSelector);
+  assert.ok(controller.actions.columnsSelected);
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8a4f4276/tez-ui2/src/main/webapp/tests/unit/mixins/auto-counter-column-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/mixins/auto-counter-column-test.js b/tez-ui2/src/main/webapp/tests/unit/mixins/auto-counter-column-test.js
new file mode 100644
index 0000000..191eb67
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/mixins/auto-counter-column-test.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 Ember from 'ember';
+import AutoCounterColumnMixin from '../../../mixins/auto-counter-column';
+import { module, test } from 'qunit';
+
+module('Unit | Mixin | auto counter column');
+
+test('Basic creation test', function(assert) {
+  let AutoCounterColumnObject = Ember.Object.extend(AutoCounterColumnMixin);
+  let subject = AutoCounterColumnObject.create();
+
+  assert.ok(subject);
+  assert.ok(subject.columnSelectorMessage);
+  assert.ok(subject.getCounterColumns);
+});
+
+test('getCounterColumns test', function(assert) {
+  let TestParent = Ember.Object.extend({
+    getCounterColumns: function () { return []; }
+  });
+
+  let AutoCounterColumnObject = TestParent.extend(AutoCounterColumnMixin);
+  let subject = AutoCounterColumnObject.create({
+    model: [{
+      counterGroups: [{
+        counterGroupName: "gp1",
+        counters: [{counterName: "c11"}, {counterName: "c12"}]
+      }]
+    }, {
+      counterGroups: [{
+        counterGroupName: "gp2",
+        counters: [{counterName: "c21"}, {counterName: "c22"}]
+      }]
+    }]
+  });
+
+  let columns = subject.getCounterColumns();
+  assert.equal(columns.length, 4);
+  assert.equal(columns[0].counterGroupName, "gp1");
+  assert.equal(columns[0].counterName, "c11");
+  assert.equal(columns[1].counterGroupName, "gp1");
+  assert.equal(columns[1].counterName, "c12");
+  assert.equal(columns[2].counterGroupName, "gp2");
+  assert.equal(columns[2].counterName, "c21");
+  assert.equal(columns[3].counterGroupName, "gp2");
+  assert.equal(columns[3].counterName, "c22");
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/8a4f4276/tez-ui2/src/main/webapp/tests/unit/utils/counter-column-definition-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/utils/counter-column-definition-test.js b/tez-ui2/src/main/webapp/tests/unit/utils/counter-column-definition-test.js
new file mode 100644
index 0000000..64df664
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/utils/counter-column-definition-test.js
@@ -0,0 +1,124 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import CounterColumnDefinition from '../../../utils/counter-column-definition';
+import { module, test } from 'qunit';
+
+module('Unit | Utility | counter column definition');
+
+test('Basic creation test', function(assert) {
+  let definition = CounterColumnDefinition.create();
+
+  assert.ok(definition);
+
+  assert.ok(definition.getCellContent);
+  assert.ok(definition.getSearchValue);
+  assert.ok(definition.getSortValue);
+
+  assert.ok(definition.id);
+  assert.ok(definition.groupDisplayName);
+  assert.ok(definition.headerTitle);
+
+  assert.ok(CounterColumnDefinition.make);
+
+  assert.equal(definition.observePath, true);
+  assert.equal(definition.contentPath, "counterHash");
+});
+
+test('getCellContent, getSearchValue & getSortValue test', function(assert) {
+  let testGroupName = "t.gn",
+      testCounterName = "cn",
+      testCounterValue = "val",
+      testContent = {},
+      testRow = {
+        counterHash: testContent
+      };
+
+  testContent[testGroupName] = {};
+  testContent[testGroupName][testCounterName] = testCounterValue;
+  testContent[testGroupName]["anotherName"] = "anotherValue";
+
+  let definition = CounterColumnDefinition.create({
+    counterGroupName: testGroupName,
+    counterName: testCounterName,
+  });
+
+  assert.equal(definition.getCellContent(testRow), testCounterValue);
+  assert.equal(definition.getSearchValue(testRow), testCounterValue);
+  assert.equal(definition.getSortValue(testRow), testCounterValue);
+});
+
+test('id test', function(assert) {
+  let testGroupName = "t.gn",
+      testCounterName = "cn";
+
+  let definition = CounterColumnDefinition.create({
+    counterGroupName: testGroupName,
+    counterName: testCounterName,
+  });
+
+  assert.equal(definition.get("id"), `${testGroupName}/${testCounterName}`);
+});
+
+test('groupDisplayName test', function(assert) {
+  let definition = CounterColumnDefinition.create();
+
+  definition.set("counterGroupName", "foo");
+  assert.equal(definition.get("groupDisplayName"), "foo");
+
+  definition.set("counterGroupName", "foo.bar");
+  assert.equal(definition.get("groupDisplayName"), "bar");
+
+  definition.set("counterGroupName", "org.apache.tez.common.counters.DAGCounter");
+  assert.equal(definition.get("groupDisplayName"), "DAG");
+
+  definition.set("counterGroupName", "org.apache.tez.common.counters.FileSystemCounter");
+  assert.equal(definition.get("groupDisplayName"), "FileSystem");
+
+  definition.set("counterGroupName", "TaskCounter_ireduce1_INPUT_map");
+  assert.equal(definition.get("groupDisplayName"), "Task - ireduce1 to Input-map");
+
+  definition.set("counterGroupName", "TaskCounter_ireduce1_OUTPUT_reduce");
+  assert.equal(definition.get("groupDisplayName"), "Task - ireduce1 to Output-reduce");
+});
+
+test('headerTitle test', function(assert) {
+  let testGroupName = "t.gn",
+      testCounterName = "cn";
+
+  let definition = CounterColumnDefinition.create({
+    counterGroupName: testGroupName,
+    counterName: testCounterName,
+  });
+
+  assert.equal(definition.get("headerTitle"), "gn - cn");
+});
+
+test('CounterColumnDefinition.make test', function(assert) {
+  var definitions = CounterColumnDefinition.make([{
+    counterGroupName: "gn1",
+    counterName: "nm1",
+  }, {
+    counterGroupName: "gn2",
+    counterName: "nm2",
+  }]);
+
+  assert.equal(definitions.length, 2);
+  assert.equal(definitions[0].get("headerTitle"), "gn1 - nm1");
+  assert.equal(definitions[1].get("headerTitle"), "gn2 - nm2");
+});


[32/45] tez git commit: TEZ-3061. Tez UI 2: Display in-progress vertex table in DAG details (sree)

Posted by sr...@apache.org.
TEZ-3061. Tez UI 2: Display in-progress vertex table in DAG details (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/963e77a2
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/963e77a2
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/963e77a2

Branch: refs/heads/TEZ-2980
Commit: 963e77a23e756033ecfad48afdc8b9b5de9f972e
Parents: eb50a0e
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Sat Jan 30 01:25:20 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:32:52 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |  1 +
 tez-ui2/src/main/webapp/app/controllers/dag.js  |  4 +-
 .../webapp/app/controllers/dag/index/index.js   | 79 ++++++++++++++++++++
 tez-ui2/src/main/webapp/app/models/vertex-am.js | 10 +++
 tez-ui2/src/main/webapp/app/models/vertex.js    | 53 ++++++++++---
 tez-ui2/src/main/webapp/app/router.js           |  1 +
 .../main/webapp/app/routes/dag/index/index.js   | 57 ++++++++++++++
 .../main/webapp/app/serializers/vertex-am.js    |  9 ++-
 .../src/main/webapp/app/serializers/vertex.js   | 10 +--
 .../src/main/webapp/app/services/pollster.js    | 56 +++++++++-----
 .../src/main/webapp/app/templates/dag/index.hbs |  3 +
 .../webapp/app/templates/dag/index/index.hbs    | 38 ++++++++++
 .../unit/controllers/dag/index/index-test.js    | 39 ++++++++++
 .../webapp/tests/unit/models/vertex-test.js     |  5 +-
 .../tests/unit/routes/dag/index/index-test.js   | 50 +++++++++++++
 15 files changed, 380 insertions(+), 35 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/963e77a2/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index 60eb715..fc99577 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -27,3 +27,4 @@ ALL CHANGES:
   TEZ-3059. Tez UI 2: Make refresh functional
   TEZ-3070. Tez UI 2: Jenkins build is failing
   TEZ-3060. Tez UI 2: Activate auto-refresh
+  TEZ-3061. Tez UI 2: Display in-progress vertex table in DAG details

http://git-wip-us.apache.org/repos/asf/tez/blob/963e77a2/tez-ui2/src/main/webapp/app/controllers/dag.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag.js b/tez-ui2/src/main/webapp/app/controllers/dag.js
index f2b04d1..4c8ec1a 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag.js
@@ -26,14 +26,14 @@ export default ParentController.extend({
 
     return [{
       text: `DAG [ ${name} ]`,
-      routeName: "dag.index",
+      routeName: "dag.index.index",
       model: this.get("model.entityID")
     }];
   }),
 
   tabs: [{
     text: "DAG Details",
-    routeName: "dag.index"
+    routeName: "dag.index.index"
   }, {
     text: "DAG Counters",
     routeName: "dag.counters"

http://git-wip-us.apache.org/repos/asf/tez/blob/963e77a2/tez-ui2/src/main/webapp/app/controllers/dag/index/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/index/index.js b/tez-ui2/src/main/webapp/app/controllers/dag/index/index.js
new file mode 100644
index 0000000..8dc27a5
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/index/index.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 MultiTableController from '../../multi-table';
+import ColumnDefinition from 'em-table/utils/column-definition';
+
+export default MultiTableController.extend({
+  columns: ColumnDefinition.make([{
+    id: 'name',
+    headerTitle: 'Vertex Name',
+    contentPath: 'name',
+    cellComponentName: 'em-table-linked-cell',
+    getCellContent: function (row) {
+      return {
+        routeName: "vertex",
+        model: row.get("entityID"),
+        text: row.get("name")
+      };
+    }
+  },{
+    id: 'status',
+    headerTitle: 'Status',
+    contentPath: 'status',
+    cellComponentName: 'em-table-status-cell',
+    observePath: true
+  },{
+    id: 'progress',
+    headerTitle: 'Progress',
+    contentPath: 'progress',
+    cellComponentName: 'em-table-progress-cell',
+    observePath: true
+  },{
+    id: 'totalTasks',
+    headerTitle: 'Total Tasks',
+    contentPath: 'totalTasks',
+    observePath: true
+  },{
+    id: 'successfulTasks',
+    headerTitle: 'Successful Tasks',
+    contentPath: 'successfulTasks',
+    observePath: true
+  },{
+    id: 'runningTasks',
+    headerTitle: 'Running Tasks',
+    contentPath: 'runningTasks',
+    observePath: true
+  },{
+    id: 'pendingTasks',
+    headerTitle: 'Pending Tasks',
+    contentPath: 'pendingTasks',
+    observePath: true
+  },{
+    id: 'failedTaskAttempts',
+    headerTitle: 'Failed Task Attempts',
+    contentPath: 'failedTaskAttempts',
+    observePath: true
+  },{
+    id: 'killedTaskAttempts',
+    headerTitle: 'Killed Task Attempts',
+    contentPath: 'killedTaskAttempts',
+    observePath: true
+  }])
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/963e77a2/tez-ui2/src/main/webapp/app/models/vertex-am.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/vertex-am.js b/tez-ui2/src/main/webapp/app/models/vertex-am.js
index 55722b6..54339b2 100644
--- a/tez-ui2/src/main/webapp/app/models/vertex-am.js
+++ b/tez-ui2/src/main/webapp/app/models/vertex-am.js
@@ -16,7 +16,17 @@
  * limitations under the License.
  */
 
+import DS from 'ember-data';
+
 import AMModel from './am';
 
 export default AMModel.extend({
+
+  totalTasks: DS.attr("number"),
+  successfulTasks: DS.attr("number"),
+  runningTasks: DS.attr("number"),
+  pendingTasks: DS.attr("number"),
+  failedTaskAttempts: DS.attr("number"),
+  killedTaskAttempts: DS.attr("number"),
+
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/963e77a2/tez-ui2/src/main/webapp/app/models/vertex.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/vertex.js b/tez-ui2/src/main/webapp/app/models/vertex.js
index 51e50b1..d8f1b43 100644
--- a/tez-ui2/src/main/webapp/app/models/vertex.js
+++ b/tez-ui2/src/main/webapp/app/models/vertex.js
@@ -21,6 +21,16 @@ import DS from 'ember-data';
 
 import AMTimelineModel from './am-timeline';
 
+function valueComputerFactory(path1, path2) {
+  return function () {
+    var value = this.get(path1);
+    if(value === undefined || value === null){
+      value = this.get(path2);
+    }
+    return value;
+  };
+}
+
 export default AMTimelineModel.extend({
   needs: {
     dag: {
@@ -53,19 +63,44 @@ export default AMTimelineModel.extend({
   lastTaskFinishTime: DS.attr('number'),
 
   totalTasks: DS.attr('number'),
-  failedTasks: DS.attr('number'),
-  successfulTasks: DS.attr('number'),
-  killedTasks: DS.attr('number'),
+  _failedTasks: DS.attr('number'),
+  _successfulTasks: DS.attr('number'),
+  _killedTasks: DS.attr('number'),
+  failedTasks: Ember.computed("am.failedTasks", "_failedTasks",
+    valueComputerFactory("am.failedTasks", "_failedTasks")
+  ),
+  successfulTasks: Ember.computed("am.successfulTasks", "_successfulTasks",
+    valueComputerFactory("am.successfulTasks", "_successfulTasks")
+  ),
+  killedTasks: Ember.computed("am.killedTasks", "_killedTasks",
+    valueComputerFactory("am.killedTasks", "_killedTasks")
+  ),
 
-  runningTasks: Ember.computed("status", function () {
-    return this.get("status") === 'SUCCEEDED' ? 0 : null;
+  runningTasks: Ember.computed("am.runningTasks", "status", function () {
+    var runningTasks = this.get("am.runningTasks");
+    if(runningTasks === undefined) {
+      runningTasks = this.get("status") === 'SUCCEEDED' ? 0 : null;
+    }
+    return  runningTasks;
   }),
-  pendingTasks: Ember.computed("status", function () {
-    return this.get("status") === 'SUCCEEDED' ? 0 : null;
+  pendingTasks: Ember.computed("totalTasks", "successfulTasks", "runningTasks", function () {
+    var pendingTasks = null,
+        runningTasks = this.get("runningTasks"),
+        totalTasks = this.get("totalTasks");
+    if(totalTasks!== null && runningTasks !== null) {
+      pendingTasks = totalTasks - this.get("successfulTasks") - runningTasks;
+    }
+    return pendingTasks;
   }),
 
-  failedTaskAttempts: DS.attr('number'),
-  killedTaskAttempts: DS.attr('number'),
+  _failedTaskAttempts: DS.attr('number'),
+  _killedTaskAttempts: DS.attr('number'),
+  failedTaskAttempts: Ember.computed("am.failedTaskAttempts", "_failedTaskAttempts",
+    valueComputerFactory("am.failedTaskAttempts", "_failedTaskAttempts")
+  ),
+  killedTaskAttempts: Ember.computed("am.killedTaskAttempts", "_killedTaskAttempts",
+    valueComputerFactory("am.killedTaskAttempts", "_killedTaskAttempts")
+  ),
 
   minDuration: DS.attr('number'),
   maxDuration: DS.attr('number'),

http://git-wip-us.apache.org/repos/asf/tez/blob/963e77a2/tez-ui2/src/main/webapp/app/router.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/router.js b/tez-ui2/src/main/webapp/app/router.js
index db26954..1f54580 100644
--- a/tez-ui2/src/main/webapp/app/router.js
+++ b/tez-ui2/src/main/webapp/app/router.js
@@ -30,6 +30,7 @@ Router.map(function() {
     this.route('tasks');
     this.route('attempts');
     this.route('counters');
+    this.route('index', function() {});
   });
   this.route('vertex', {path: '/vertex/:vertex_id'}, function() {
     this.route('tasks');

http://git-wip-us.apache.org/repos/asf/tez/blob/963e77a2/tez-ui2/src/main/webapp/app/routes/dag/index/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag/index/index.js b/tez-ui2/src/main/webapp/app/routes/dag/index/index.js
new file mode 100644
index 0000000..15d485f
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/dag/index/index.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 Ember from 'ember';
+import MultiAmPollsterRoute from '../../multi-am-pollster';
+
+export default MultiAmPollsterRoute.extend({
+  title: "DAG Details",
+
+  loaderNamespace: "dag",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (value, query, options) {
+    return this.get("loader").query('vertex', {
+      dagID: this.modelFor("dag").get("id")
+    }, options);
+  },
+
+  _canPollObserver: Ember.observer("canPoll", function () {
+    if(this.get("canPoll")) {
+      this.get("polling").setPoll(this.pollData, this, "dag.index.index");
+    }
+    else {
+      this.get("polling").resetPoll("dag.index.index");
+    }
+  }),
+
+  actions: {
+    reload: function () {
+      return true;
+    },
+    willTransition: function () {
+      this.set("loadedValue", null);
+      return true;
+    },
+  }
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/963e77a2/tez-ui2/src/main/webapp/app/serializers/vertex-am.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/vertex-am.js b/tez-ui2/src/main/webapp/app/serializers/vertex-am.js
index 163cf5c..e3b7eaf 100644
--- a/tez-ui2/src/main/webapp/app/serializers/vertex-am.js
+++ b/tez-ui2/src/main/webapp/app/serializers/vertex-am.js
@@ -19,5 +19,12 @@
 import AMSerializer from './am';
 
 export default AMSerializer.extend({
-  payloadNamespace: "vertices"
+  payloadNamespace: "vertices",
+
+  maps: {
+    successfulTasks: "succeededTasks",
+    runningTasks: "runningTasks",
+    failedTaskAttempts: "failedTaskAttempts",
+    killedTaskAttempts: "killedTaskAttempts",
+  }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/963e77a2/tez-ui2/src/main/webapp/app/serializers/vertex.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/vertex.js b/tez-ui2/src/main/webapp/app/serializers/vertex.js
index 7c36074..1f99f3a 100644
--- a/tez-ui2/src/main/webapp/app/serializers/vertex.js
+++ b/tez-ui2/src/main/webapp/app/serializers/vertex.js
@@ -33,12 +33,12 @@ export default TimelineSerializer.extend({
     lastTaskFinishTime: 'otherinfo.stats.lastTaskFinishTime',
 
     totalTasks: 'otherinfo.numTasks',
-    failedTasks: 'otherinfo.numFailedTasks',
-    successfulTasks: 'otherinfo.numSucceededTasks',
-    killedTasks: 'otherinfo.numKilledTasks',
+    _failedTasks: 'otherinfo.numFailedTasks',
+    _successfulTasks: 'otherinfo.numSucceededTasks',
+    _killedTasks: 'otherinfo.numKilledTasks',
 
-    failedTaskAttempts: 'otherinfo.numFailedTaskAttempts',
-    killedTaskAttempts: 'otherinfo.numKilledTaskAttempts',
+    _failedTaskAttempts: 'otherinfo.numFailedTaskAttempts',
+    _killedTaskAttempts: 'otherinfo.numKilledTaskAttempts',
 
     minDuration:  'otherinfo.stats.minTaskDuration',
     maxDuration:  'otherinfo.stats.maxTaskDuration',

http://git-wip-us.apache.org/repos/asf/tez/blob/963e77a2/tez-ui2/src/main/webapp/app/services/pollster.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/services/pollster.js b/tez-ui2/src/main/webapp/app/services/pollster.js
index 8e76bc9..00a0c6c 100644
--- a/tez-ui2/src/main/webapp/app/services/pollster.js
+++ b/tez-ui2/src/main/webapp/app/services/pollster.js
@@ -1,3 +1,4 @@
+/*global more*/
 /**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -18,7 +19,10 @@
 
 import Ember from 'ember';
 
-const STATE_STORAGE_KEY = "pollingIsActive";
+const STATE_STORAGE_KEY = "pollingIsActive",
+      DEFAULT_LABEL = "default_label";
+
+var MoreObject = more.Object;
 
 export default Ember.Service.extend({
   localStorage: Ember.inject.service("localStorage"),
@@ -30,8 +34,8 @@ export default Ember.Service.extend({
   isPolling: false,
   scheduleID: null,
 
-  poll: null,
-  pollContext: null,
+  polls: {},
+  pollCount: 0,
 
   initState: Ember.on("init", function () {
     Ember.run.later(this, function () {
@@ -43,16 +47,23 @@ export default Ember.Service.extend({
     this.callPoll();
   }),
 
-  isReady: Ember.computed("active", "poll", function () {
-    return this.get("active") && this.get("poll");
+  isReady: Ember.computed("active", "pollCount", function () {
+    return !!(this.get("active") && this.get("pollCount"));
   }),
 
   callPoll: function () {
     var that = this;
     this.unSchedulePoll();
     if(this.get("isReady") && !this.get("isPolling")) {
+      var pollsPromises = [];
+
       this.set("isPolling", true);
-      this.get("poll").call(this.get("pollContext")).finally(function () {
+
+      MoreObject.forEach(this.get("polls"), function (label, pollDef) {
+        pollsPromises.push(pollDef.callback.call(pollDef.context));
+      });
+
+      Ember.RSVP.allSettled(pollsPromises).finally(function () {
         that.set("isPolling", false);
         that.schedulePoll();
       });
@@ -66,18 +77,29 @@ export default Ember.Service.extend({
     clearTimeout(this.get("scheduleID"));
   },
 
-  setPoll: function (pollFunction, context) {
-    this.setProperties({
-      pollContext: context,
-      poll: pollFunction,
-    });
+  setPoll: function (pollFunction, context, label) {
+    var polls = this.get("polls"),
+        pollCount;
+
+    label = label || DEFAULT_LABEL;
+    polls[label] = {
+      context: context,
+      callback: pollFunction,
+    };
+    this.set("pollCount", pollCount = Object.keys(polls).length);
+
     this.callPoll();
   },
-  resetPoll: function () {
-    this.unSchedulePoll();
-    this.setProperties({
-      poll: null,
-      pollContext: null
-    });
+  resetPoll: function (label) {
+    var polls = this.get("polls"),
+        pollCount;
+
+    label = label || DEFAULT_LABEL;
+    delete polls[label];
+    this.set("pollCount", pollCount = Object.keys(polls).length);
+
+    if(!pollCount) {
+      this.unSchedulePoll();
+    }
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/963e77a2/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/index.hbs b/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
index b81194f..d7e23fc 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
@@ -73,6 +73,9 @@
       </tr>
     </tbody>
   </table>
+
+  {{outlet}}
+
 {{else}}
   {{partial "loading"}}
 {{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/963e77a2/tez-ui2/src/main/webapp/app/templates/dag/index/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/index/index.hbs b/tez-ui2/src/main/webapp/app/templates/dag/index/index.hbs
new file mode 100644
index 0000000..1321b9f
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/dag/index/index.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.
+}}
+
+{{#if loaded}}
+  {{em-table
+  columns=visibleColumns
+  rows=model
+
+  definition=definition
+
+  enableSearch=false
+  enablePagination=false
+
+  searchAction="searchChanged"
+  sortAction="sortChanged"
+  rowAction="rowCountChanged"
+  pageAction="pageChanged"
+
+  rowsChanged="rowsChanged"
+  }}
+{{else}}
+  {{partial "loading"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/963e77a2/tez-ui2/src/main/webapp/tests/unit/controllers/dag/index/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/index/index-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/index/index-test.js
new file mode 100644
index 0000000..956eee3
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/index/index-test.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';
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:dag/index/index', 'Unit | Controller | dag/index/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K,
+    initVisibleColumns: Ember.K,
+    getCounterColumns: function () {
+      return [];
+    }
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.columns);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/963e77a2/tez-ui2/src/main/webapp/tests/unit/models/vertex-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/vertex-test.js b/tez-ui2/src/main/webapp/tests/unit/models/vertex-test.js
index c0d2047..9ca049a 100644
--- a/tez-ui2/src/main/webapp/tests/unit/models/vertex-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/models/vertex-test.js
@@ -51,8 +51,11 @@ test('pendingTasks test', function(assert) {
   let model = this.subject();
 
   Ember.run(function () {
+    model.set("totalTasks", null);
     assert.equal(model.get("pendingTasks"), null);
+    model.set("totalTasks", 2);
+    model.set("_successfulTasks", 1);
     model.set("status", "SUCCEEDED");
-    assert.equal(model.get("pendingTasks"), 0);
+    assert.equal(model.get("pendingTasks"), 1);
   });
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/963e77a2/tez-ui2/src/main/webapp/tests/unit/routes/dag/index/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/dag/index/index-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/dag/index/index-test.js
new file mode 100644
index 0000000..dc767ba
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/dag/index/index-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:dag/index/index', 'Unit | Route | dag/index/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.loaderNamespace);
+  assert.ok(route.setupController);
+  assert.ok(route.load);
+
+  assert.ok(route._canPollObserver);
+  assert.ok(route.actions.reload);
+  assert.ok(route.actions.willTransition);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});


[16/45] tez git commit: TEZ-2986. Tez UI 2: Implement All DAGs page (sree)

Posted by sr...@apache.org.
http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/tests/unit/serializers/dag-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/serializers/dag-test.js b/tez-ui2/src/main/webapp/tests/unit/serializers/dag-test.js
new file mode 100644
index 0000000..7dd635c
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/serializers/dag-test.js
@@ -0,0 +1,109 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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:dag', 'Unit | Serializer | dag', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:dag']
+});
+
+test('Basic creation test', function(assert) {
+  let serializer = this.subject();
+
+  assert.ok(serializer);
+  assert.ok(serializer.maps.atsStatus);
+  assert.ok(serializer.maps.startTime);
+  assert.ok(serializer.maps.endTime);
+  assert.ok(serializer.maps.containerLogs);
+});
+
+test('atsStatus test', function(assert) {
+  let serializer = this.subject(),
+      mapper = serializer.maps.atsStatus;
+
+  assert.equal(mapper({
+    events: [{eventtype: "SOME_EVENT"}]
+  }), undefined);
+
+  assert.equal(mapper({
+    events: [{eventtype: "DAG_STARTED"}]
+  }), "RUNNING");
+
+  assert.equal(mapper({
+    otherinfo: {status: "STATUS1"},
+    primaryfilters: {status: ["STATUS2"]},
+    events: [{eventtype: "DAG_STARTED"}]
+  }), "STATUS1");
+
+  assert.equal(mapper({
+    primaryfilters: {status: ["STATUS2"]},
+    events: [{eventtype: "DAG_STARTED"}]
+  }), "STATUS2");
+});
+
+test('startTime test', function(assert) {
+  let serializer = this.subject(),
+      mapper = serializer.maps.startTime,
+      testTimestamp = Date.now();
+
+  assert.equal(mapper({
+    events: [{eventtype: "SOME_EVENT"}]
+  }), undefined);
+
+  assert.equal(mapper({
+    events: [{eventtype: "DAG_STARTED", timestamp: testTimestamp}]
+  }), testTimestamp);
+
+  assert.equal(mapper({
+    otherinfo: {startTime: testTimestamp},
+    events: [{eventtype: "DAG_STARTED"}]
+  }), testTimestamp);
+});
+
+test('endTime test', function(assert) {
+  let serializer = this.subject(),
+      mapper = serializer.maps.endTime,
+      testTimestamp = Date.now();
+
+  assert.equal(mapper({
+    events: [{eventtype: "SOME_EVENT"}]
+  }), undefined);
+
+  assert.equal(mapper({
+    events: [{eventtype: "DAG_FINISHED", timestamp: testTimestamp}]
+  }), testTimestamp);
+
+  assert.equal(mapper({
+    otherinfo: {endTime: testTimestamp},
+    events: [{eventtype: "DAG_FINISHED"}]
+  }), testTimestamp);
+});
+
+test('containerLogs test', function(assert) {
+  let serializer = this.subject(),
+      mapper = serializer.maps.containerLogs;
+
+  assert.deepEqual(mapper({
+    otherinfo: {},
+  }), [], "No logs");
+
+  assert.deepEqual(mapper({
+    otherinfo: {inProgressLogsURL_1: "foo", inProgressLogsURL_2: "bar"},
+  }), [{text: "1", href: "http://foo"}, {text: "2", href: "http://bar"}], "2 logs");
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/tests/unit/transforms/object-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/transforms/object-test.js b/tez-ui2/src/main/webapp/tests/unit/transforms/object-test.js
new file mode 100644
index 0000000..79b1bde
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/transforms/object-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('transform:object', 'Unit | Transform | object', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:foo']
+});
+
+// Replace this with your real tests.
+test('it exists', function(assert) {
+  let transform = this.subject();
+  assert.ok(transform);
+});


[38/45] tez git commit: TEZ-2916. Tez UI 2: Show counts of running tasks on the DAG visualization page (sree)

Posted by sr...@apache.org.
TEZ-2916. Tez UI 2: Show counts of running tasks on the DAG visualization page (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/9cb1da43
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/9cb1da43
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/9cb1da43

Branch: refs/heads/TEZ-2980
Commit: 9cb1da43b2bbe7d13a195c3d617638ee5edb8d21
Parents: 32bcb39
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Wed Feb 17 15:59:56 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:32:53 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |  1 +
 .../webapp/app/controllers/dag/graphical.js     | 15 +++++++
 .../main/webapp/app/controllers/dag/vertices.js | 36 +++++++++++++++-
 .../src/main/webapp/app/controllers/table.js    |  2 +-
 .../tests/unit/controllers/dag/vertices-test.js | 43 ++++++++++++++++++++
 5 files changed, 95 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/9cb1da43/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index 9d949ca..512492b 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -36,3 +36,4 @@ ALL CHANGES:
   TEZ-3092. Tez UI 2: Tuneups & Improvements
   TEZ-3095. Tez UI 2: Tuneups & Improvements
   TEZ-3088. Tez UI 2: Licenses of all the packages used by Tez Ui must be documented
+  TEZ-2916. Tez UI 2: Show counts of running tasks on the DAG visualization page

http://git-wip-us.apache.org/repos/asf/tez/blob/9cb1da43/tez-ui2/src/main/webapp/app/controllers/dag/graphical.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/graphical.js b/tez-ui2/src/main/webapp/app/controllers/dag/graphical.js
index 86d534a..470628c 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag/graphical.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/graphical.js
@@ -85,6 +85,21 @@ export default MultiTableController.extend({
     headerTitle: 'Tasks',
     contentPath: 'totalTasks',
   },{
+    id: 'succeededTasks',
+    headerTitle: 'Succeeded Tasks',
+    contentPath: 'succeededTasks',
+    observePath: true
+  },{
+    id: 'runningTasks',
+    headerTitle: 'Running Tasks',
+    contentPath: 'runningTasks',
+    observePath: true
+  },{
+    id: 'pendingTasks',
+    headerTitle: 'Pending Tasks',
+    contentPath: 'pendingTasks',
+    observePath: true
+  },{
     id: 'processorClassName',
     headerTitle: 'Processor Class',
     contentPath: 'processorClassName',

http://git-wip-us.apache.org/repos/asf/tez/blob/9cb1da43/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js b/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
index f42a667..306d606 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
@@ -80,9 +80,43 @@ export default MultiTableController.extend({
     headerTitle: 'Tasks',
     contentPath: 'totalTasks',
   },{
+    id: 'succeededTasks',
+    headerTitle: 'Succeeded Tasks',
+    contentPath: 'succeededTasks',
+    observePath: true
+  },{
+    id: 'runningTasks',
+    headerTitle: 'Running Tasks',
+    contentPath: 'runningTasks',
+    observePath: true
+  },{
+    id: 'pendingTasks',
+    headerTitle: 'Pending Tasks',
+    contentPath: 'pendingTasks',
+    observePath: true
+  },{
     id: 'processorClassName',
     headerTitle: 'Processor Class',
     contentPath: 'processorClassName',
-  }])
+  }]),
+
+  beforeSort: function (columnDefinition) {
+    if(this._super(columnDefinition)) {
+      if(this.get("polling.isReady")) {
+        let columnName = columnDefinition.get("headerTitle");
+        switch(columnDefinition.get("contentPath")) {
+          case "succeededTasks":
+          case "runningTasks":
+          case "pendingTasks":
+            this.send("openModal", {
+              title: "Cannot sort!",
+              content: `Sorting on ${columnName} is disabled for running DAGs!`
+            });
+            return false;
+        }
+      }
+    }
+    return true;
+  }
 
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/9cb1da43/tez-ui2/src/main/webapp/app/controllers/table.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/table.js b/tez-ui2/src/main/webapp/app/controllers/table.js
index ca2bae8..f0bce1c 100644
--- a/tez-ui2/src/main/webapp/app/controllers/table.js
+++ b/tez-ui2/src/main/webapp/app/controllers/table.js
@@ -45,7 +45,7 @@ export default AbstractController.extend({
 
   polling: Ember.inject.service("pollster"),
 
-  definition: Ember.computed(function () {
+  definition: Ember.computed("model", function () {
     return TableDefinition.create({
       rowCount: this.get("rowCount"),
       searchText: this.get("searchText"),

http://git-wip-us.apache.org/repos/asf/tez/blob/9cb1da43/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
index fa7bec0..0c5f766 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
@@ -38,4 +38,47 @@ test('Basic creation test', function(assert) {
   assert.ok(controller);
   assert.ok(controller.breadcrumbs);
   assert.ok(controller.columns);
+  assert.ok(controller.beforeSort);
+});
+
+test('beforeSort test', function(assert) {
+  let controller = this.subject({
+    initVisibleColumns: Ember.K,
+    getCounterColumns: function () {
+      return [];
+    },
+    polling: {
+      isReady: true
+    },
+    send: function (actionName) {
+      if(actionName === "openModal") {
+        assert.ok(true);
+      }
+    }
+  });
+
+  // Bind poilyfill
+  Function.prototype.bind = function (context) {
+    var that = this;
+    return function (val) {
+      return that.call(context, val);
+    };
+  };
+
+  assert.expect(1 + 3 + 3);
+
+  assert.ok(controller.beforeSort(Ember.Object.create({
+    contentPath: "NonDisabledColumn"
+  })), "NonDisabledColumn");
+
+  assert.notOk(controller.beforeSort(Ember.Object.create({
+    contentPath: "succeededTasks"
+  })), "succeededTasks");
+  assert.notOk(controller.beforeSort(Ember.Object.create({
+    contentPath: "runningTasks"
+  })), "runningTasks");
+  assert.notOk(controller.beforeSort(Ember.Object.create({
+    contentPath: "pendingTasks"
+  })), "pendingTasks");
+
 });


[24/45] tez git commit: TEZ-3049. Tez UI 2: Add column selector (sree)

Posted by sr...@apache.org.
TEZ-3049. Tez UI 2: Add column selector (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/0798c907
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/0798c907
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/0798c907

Branch: refs/heads/TEZ-2980
Commit: 0798c907f3179791d28ae4006c926d5c5299449a
Parents: 90ac7cc
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Wed Jan 20 03:55:24 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:32:16 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |   1 +
 .../webapp/app/components/column-selector.js    | 105 +++++++++++++++++++
 .../webapp/app/components/table-controls.js     |  29 +++++
 .../main/webapp/app/controllers/table-page.js   |  60 +++++++++++
 .../src/main/webapp/app/routes/application.js   |  26 +++++
 tez-ui2/src/main/webapp/app/styles/app.less     |   2 +
 .../main/webapp/app/styles/column-selector.less |  65 ++++++++++++
 tez-ui2/src/main/webapp/app/styles/shared.less  |   4 +-
 .../main/webapp/app/styles/table-controls.less  |  28 +++++
 .../src/main/webapp/app/templates/app/dags.hbs  |  16 +--
 .../main/webapp/app/templates/application.hbs   |   2 +
 .../templates/components/column-selector.hbs    |  48 +++++++++
 .../app/templates/components/table-controls.hbs |  19 ++++
 .../main/webapp/app/templates/dag/attempts.hbs  |   4 +-
 .../src/main/webapp/app/templates/dag/tasks.hbs |   4 +-
 .../main/webapp/app/templates/dag/vertices.hbs  |   4 +-
 tez-ui2/src/main/webapp/app/templates/dags.hbs  |   4 +-
 .../main/webapp/app/templates/simple-modal.hbs  |  33 ++++++
 .../main/webapp/app/templates/task/attempts.hbs |  16 +--
 .../webapp/app/templates/vertex/attempts.hbs    |  16 +--
 .../main/webapp/app/templates/vertex/tasks.hbs  |  16 +--
 tez-ui2/src/main/webapp/app/utils/misc.js       |  22 ++++
 tez-ui2/src/main/webapp/ember-cli-build.js      |   1 +
 .../components/column-selector-test.js          |  87 +++++++++++++++
 .../components/table-controls-test.js           |  43 ++++++++
 .../tests/unit/controllers/abstract-test.js     |   3 +-
 .../webapp/tests/unit/controllers/app-test.js   |   3 +-
 .../tests/unit/controllers/app/configs-test.js  |   3 +-
 .../tests/unit/controllers/app/dags-test.js     |   3 +-
 .../tests/unit/controllers/app/index-test.js    |   3 +-
 .../tests/unit/controllers/attempt-test.js      |   3 +-
 .../unit/controllers/attempt/counters-test.js   |   3 +-
 .../unit/controllers/attempt/index-test.js      |   3 +-
 .../unit/controllers/counters-page-test.js      |   4 +-
 .../webapp/tests/unit/controllers/dag-test.js   |   3 +-
 .../tests/unit/controllers/dag/attempts-test.js |   3 +-
 .../tests/unit/controllers/dag/counters-test.js |   3 +-
 .../tests/unit/controllers/dag/index-test.js    |   3 +-
 .../tests/unit/controllers/dag/tasks-test.js    |   3 +-
 .../tests/unit/controllers/dag/vertices-test.js |   3 +-
 .../webapp/tests/unit/controllers/dags-test.js  |   3 +
 .../webapp/tests/unit/controllers/page-test.js  |   6 +-
 .../tests/unit/controllers/table-page-test.js   |   3 +-
 .../webapp/tests/unit/controllers/task-test.js  |   3 +-
 .../unit/controllers/task/attempts-test.js      |   3 +-
 .../unit/controllers/task/counters-test.js      |   3 +-
 .../tests/unit/controllers/task/index-test.js   |   3 +-
 .../tests/unit/controllers/vertex-test.js       |   3 +-
 .../unit/controllers/vertex/attempts-test.js    |   3 +-
 .../unit/controllers/vertex/counters-test.js    |   3 +-
 .../tests/unit/controllers/vertex/index-test.js |   3 +-
 .../tests/unit/controllers/vertex/tasks-test.js |   5 +-
 .../main/webapp/tests/unit/utils/misc-test.js   |  26 +++++
 53 files changed, 706 insertions(+), 62 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index c1fd7ae..f92341a 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -21,3 +21,4 @@ ALL CHANGES:
   TEZ-3048. Tez UI 2: Make PhantomJS a local dependency for build tests
   TEZ-3042. Tez UI 2: Create Counters pages
   TEZ-3043. Tez UI 2: Create configurations page
+  TEZ-3049. Tez UI 2: Add column selector

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/app/components/column-selector.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/components/column-selector.js b/tez-ui2/src/main/webapp/app/components/column-selector.js
new file mode 100644
index 0000000..9c9d4d2
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/components/column-selector.js
@@ -0,0 +1,105 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 isIOCounter from '../utils/misc';
+
+export default Ember.Component.extend({
+
+  classNames: ['column-selector'],
+
+  searchText: "",
+  selectAll: false,
+
+  content: null,
+
+  options: Ember.computed("content.columns", "content.visibleColumnIDs", function () {
+    var group,
+        highlight = false,
+        visibleColumnIDs = this.get('content.visibleColumnIDs') || {};
+
+    return this.get('content.columns').map(function (config) {
+      var css = '';
+
+      highlight = highlight ^ (config.get("counterGroupName") !== group);
+      group = config.counterGroupName;
+
+      if(highlight) {
+        css += ' highlight';
+      }
+      if(group && isIOCounter(group)) {
+        css += ' per-io';
+      }
+
+      return Ember.Object.create({
+        id: config.get("id"),
+        displayText: config.get("headerTitle"),
+        css: css,
+        selected: visibleColumnIDs[config.id]
+      });
+    });
+  }),
+
+  filteredOptions: Ember.computed("options", "searchText", function () {
+    var options = this.get('options'),
+        searchText = this.get('searchText');
+
+    if (!searchText) {
+      return options;
+    }
+
+    return options.filter(function (option) {
+      return option.get('displayText').match(searchText);
+    });
+  }),
+
+  selectedColumnIDs: Ember.computed("options", function () {
+    var columnIds = {};
+
+    this.get('options').forEach(function (option) {
+      columnIds[option.get("id")] = option.get('selected');
+    });
+
+    return columnIds;
+  }),
+
+  _selectObserver: Ember.observer('filteredOptions.@each.selected', function () {
+    var selectedCount = 0;
+    this.get('filteredOptions').forEach(function (option) {
+      if(Ember.get(option, 'selected')) {
+        selectedCount++;
+      }
+    });
+    this.set('selectAll', selectedCount > 0 && selectedCount === this.get('filteredOptions.length'));
+  }),
+
+  actions: {
+    selectAll: function (checked) {
+      this.get('filteredOptions').forEach(function (option) {
+        Ember.set(option, 'selected', checked);
+      });
+    },
+    closeModal: function () {
+      this.get("targetObject").send("closeModal");
+    },
+    ok: function () {
+      this.get("targetObject").send("columnsSelected", this.get("selectedColumnIDs"));
+    }
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/app/components/table-controls.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/components/table-controls.js b/tez-ui2/src/main/webapp/app/components/table-controls.js
new file mode 100644
index 0000000..9923711
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/components/table-controls.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.Component.extend({
+  classNames: ['table-controls'],
+
+  actions: {
+    cogClicked: function () {
+      this.get('targetObject.targetObject').send('openColumnSelector');
+    }
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/app/controllers/table-page.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/table-page.js b/tez-ui2/src/main/webapp/app/controllers/table-page.js
index 1f2fe57..09ae8ab 100644
--- a/tez-ui2/src/main/webapp/app/controllers/table-page.js
+++ b/tez-ui2/src/main/webapp/app/controllers/table-page.js
@@ -1,3 +1,4 @@
+/*global more*/
 /**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -20,6 +21,9 @@ import Ember from 'ember';
 
 import PageController from './page';
 import TableDefinition from 'em-table/utils/table-definition';
+import isIOCounter from '../utils/misc';
+
+var MoreObject = more.Object;
 
 export default PageController.extend({
   queryParams: ["rowCount", "searchText", "sortColumnId", "sortOrder", "pageNo"],
@@ -29,6 +33,12 @@ export default PageController.extend({
   sortOrder: "",
   pageNo: 1,
 
+  headerComponentNames: ['em-table-search-ui', 'table-controls', 'em-table-pagination-ui'],
+
+  visibleColumnIDs: {},
+  columnSelectorTitle: 'Column Selector',
+  columnSelectorMessage: "",
+
   definition: Ember.computed(function () {
     return TableDefinition.create({
       rowCount: this.get("rowCount"),
@@ -39,6 +49,29 @@ export default PageController.extend({
     });
   }),
 
+  storageID: Ember.computed("name", function () {
+    return this.get("name") + ":visibleColumnIDs";
+  }),
+
+  initVisibleColumns: Ember.on("init", Ember.observer("columns", function () { //To reset on entity change
+    var visibleColumnIDs = this.get("localStorage").get(this.get("storageID")) || {};
+
+    this.get('columns').forEach(function (config) {
+      if(visibleColumnIDs[config.id] !== false) {
+        visibleColumnIDs[config.id] = true;
+      }
+    });
+
+    this.set('visibleColumnIDs', visibleColumnIDs);
+  })),
+
+  visibleColumns: Ember.computed('visibleColumnIDs', 'columns', function() {
+    var visibleColumnIDs = this.visibleColumnIDs;
+    return this.get('columns').filter(function (column) {
+      return visibleColumnIDs[column.get("id")];
+    });
+  }),
+
   actions: {
     searchChanged: function (searchText) {
       this.set("searchText", searchText);
@@ -56,5 +89,32 @@ export default PageController.extend({
     pageChanged: function (pageNum) {
       this.set("pageNo", pageNum);
     },
+
+    // Column selection actions
+    openColumnSelector: function () {
+      this.send("openModal", "column-selector", {
+        title: this.get('columnSelectorTitle'),
+        targetObject: this,
+        content: {
+          message: this.get('columnSelectorMessage'),
+          columns: this.get('columns'),
+          visibleColumnIDs: this.get('visibleColumnIDs')
+        }
+      });
+    },
+    columnsSelected: function (visibleColumnIDs) {
+      var columnIDs = {};
+
+      MoreObject.forEach(visibleColumnIDs, function (key, value) {
+        if(!isIOCounter(key)) {
+          columnIDs[key] = value;
+        }
+      });
+
+      if(!MoreObject.equals(columnIDs, this.get("visibleColumnIDs"))) {
+        this.get("localStorage").set(this.get("storageID"), columnIDs);
+        this.set('visibleColumnIDs', columnIDs);
+      }
+    }
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/app/routes/application.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/application.js b/tez-ui2/src/main/webapp/app/routes/application.js
index 8da6a31..998cce4 100644
--- a/tez-ui2/src/main/webapp/app/routes/application.js
+++ b/tez-ui2/src/main/webapp/app/routes/application.js
@@ -35,6 +35,32 @@ export default Ember.Route.extend({
     },
     bubbleBreadcrumbs: function (breadcrumbs) {
       this.set("controller.breadcrumbs", breadcrumbs);
+    },
+
+    // Modal window actions
+    openModal: function (componentName, options) {
+      options = options || {};
+      this.render(options.modalName || "simple-modal", {
+        into: 'application',
+        outlet: 'modal',
+        model: {
+          title: options.title,
+          componentName: componentName,
+          content: options.content,
+          targetObject: options.targetObject
+        }
+      });
+      Ember.run.later(function () {
+        Ember.$(".simple-modal").modal();
+      });
+    },
+    destroyModal: function () {
+      Ember.run.later(this, function () {
+        this.disconnectOutlet({
+          outlet: 'modal',
+          parentView: 'application'
+        });
+      });
     }
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/app/styles/app.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/app.less b/tez-ui2/src/main/webapp/app/styles/app.less
index bdf9480..d697ba7 100644
--- a/tez-ui2/src/main/webapp/app/styles/app.less
+++ b/tez-ui2/src/main/webapp/app/styles/app.less
@@ -25,3 +25,5 @@
 
 @import "page-layout";
 @import "details-page";
+@import "table-controls";
+@import "column-selector";

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/app/styles/column-selector.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/column-selector.less b/tez-ui2/src/main/webapp/app/styles/column-selector.less
new file mode 100644
index 0000000..2e39995
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/styles/column-selector.less
@@ -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.
+ */
+
+.column-selector {
+  .message {
+    text-align: right;
+    font-size: 10px;
+  }
+
+  .selection-list {
+    border-bottom: 1px solid @border-color;
+
+    .highlight {
+      background-color: @bg-lite;
+    }
+    .select-option, .search-option {
+      border-top: 1px dotted @border-color;
+      padding: 5px 15px;
+
+      .checkbox {
+        display: inline-block;
+
+        margin-right: 10px;
+        float: left;
+        vertical-align: middle;
+      }
+    }
+    .search-option {
+      border: none;
+
+      .form-group {
+        display: inline-block;
+
+        width: 100%;
+        margin: 0px;
+      }
+
+      .select-all {
+        display: inline-block;
+
+        height: 15px;
+        margin-top: 3px;
+      }
+    }
+  }
+}
+.form-actions {
+  padding: 10px;
+  text-align: right;
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/app/styles/shared.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/shared.less b/tez-ui2/src/main/webapp/app/styles/shared.less
index db79db4..0dc70f7 100644
--- a/tez-ui2/src/main/webapp/app/styles/shared.less
+++ b/tez-ui2/src/main/webapp/app/styles/shared.less
@@ -27,8 +27,8 @@ b {
 
 .left-delim {
   border-left: 1px solid @border-color;
-  margin-left: 5px;
-  padding-left: 5px;
+  margin-left: 10px;
+  padding-left: 10px;
 }
 
 .align-checknradio {

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/app/styles/table-controls.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/table-controls.less b/tez-ui2/src/main/webapp/app/styles/table-controls.less
new file mode 100644
index 0000000..aa9f9e6
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/styles/table-controls.less
@@ -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 "shared";
+
+.table-controls {
+  .left-delim;
+
+  cursor: pointer;
+
+  float: right;
+  font-size: 24px;
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/app/templates/app/dags.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/app/dags.hbs b/tez-ui2/src/main/webapp/app/templates/app/dags.hbs
index cdb28aa..6d8d4c3 100644
--- a/tez-ui2/src/main/webapp/app/templates/app/dags.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/app/dags.hbs
@@ -18,15 +18,17 @@
 
 {{#if loaded}}
   {{em-table
-  columns=columns
-  rows=model
+    columns=visibleColumns
+    rows=model
 
-  definition=definition
+    headerComponentNames=headerComponentNames
 
-  searchAction="searchChanged"
-  sortAction="sortChanged"
-  rowAction="rowsChanged"
-  pageAction="pageChanged"
+    definition=definition
+
+    searchAction="searchChanged"
+    sortAction="sortChanged"
+    rowAction="rowsChanged"
+    pageAction="pageChanged"
   }}
 {{else}}
   {{partial "partials/loading-anim"}}

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/app/templates/application.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/application.hbs b/tez-ui2/src/main/webapp/app/templates/application.hbs
index 5d1df11..16a0329 100644
--- a/tez-ui2/src/main/webapp/app/templates/application.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/application.hbs
@@ -62,3 +62,5 @@
     </div>
   </div>
 </div>
+
+{{outlet "modal"}}

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/app/templates/components/column-selector.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/components/column-selector.hbs b/tez-ui2/src/main/webapp/app/templates/components/column-selector.hbs
new file mode 100644
index 0000000..d9be633
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/components/column-selector.hbs
@@ -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.
+}}
+
+<div class="message">
+  {{{content.message}}}
+</div>
+<div class="selection-list">
+  <div class="search-option highlight">
+    <div class="form-group">
+      {{input class="form-control" placeholder="Filter..." value=searchText}}
+    </div>
+    <div class="select-all">
+      <input type="checkbox"
+             checked={{selectAll}}
+             onclick={{action "selectAll" value="target.checked"}} />
+      &nbsp;Select All
+    </div>
+  </div>
+  {{#if filteredOptions.length}}
+    {{#each filteredOptions as |option|}}
+      <div class="select-option {{option.css}}">
+        {{input type="checkbox" classNames='checkbox' checked=option.selected}}
+        {{option.displayText}}
+      </div>
+    {{/each}}
+  {{else}}
+    <h4>&nbsp;No options available...</h4>
+  {{/if}}
+</div>
+<div class="form-actions">
+  <button type="button" class="btn btn-primary" {{action "ok"}} data-dismiss="modal" aria-label="Close">Ok</button>
+  <button type="button" class="btn" data-dismiss="modal" aria-label="Close">Cancel</button>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/app/templates/components/table-controls.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/components/table-controls.hbs b/tez-ui2/src/main/webapp/app/templates/components/table-controls.hbs
new file mode 100644
index 0000000..b70d19d
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/components/table-controls.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.
+}}
+
+<i class='fa fa-cog' {{action 'cogClicked'}}></i>

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/app/templates/dag/attempts.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/attempts.hbs b/tez-ui2/src/main/webapp/app/templates/dag/attempts.hbs
index 932db09..6d8d4c3 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag/attempts.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag/attempts.hbs
@@ -18,9 +18,11 @@
 
 {{#if loaded}}
   {{em-table
-    columns=columns
+    columns=visibleColumns
     rows=model
 
+    headerComponentNames=headerComponentNames
+
     definition=definition
 
     searchAction="searchChanged"

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/app/templates/dag/tasks.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/tasks.hbs b/tez-ui2/src/main/webapp/app/templates/dag/tasks.hbs
index 932db09..6d8d4c3 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag/tasks.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag/tasks.hbs
@@ -18,9 +18,11 @@
 
 {{#if loaded}}
   {{em-table
-    columns=columns
+    columns=visibleColumns
     rows=model
 
+    headerComponentNames=headerComponentNames
+
     definition=definition
 
     searchAction="searchChanged"

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/app/templates/dag/vertices.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/vertices.hbs b/tez-ui2/src/main/webapp/app/templates/dag/vertices.hbs
index 932db09..6d8d4c3 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag/vertices.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag/vertices.hbs
@@ -18,9 +18,11 @@
 
 {{#if loaded}}
   {{em-table
-    columns=columns
+    columns=visibleColumns
     rows=model
 
+    headerComponentNames=headerComponentNames
+
     definition=definition
 
     searchAction="searchChanged"

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/app/templates/dags.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dags.hbs b/tez-ui2/src/main/webapp/app/templates/dags.hbs
index ddbc72a..1fd0eef 100644
--- a/tez-ui2/src/main/webapp/app/templates/dags.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dags.hbs
@@ -18,10 +18,12 @@
 
 {{#if loaded}}
   {{em-table
-    columns=columns
+    columns=visibleColumns
     rows=model
     rowCount=rowCount
 
+    headerComponentNames=headerComponentNames
+
     enableSearch=false
     enableSort=false
 

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/app/templates/simple-modal.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/simple-modal.hbs b/tez-ui2/src/main/webapp/app/templates/simple-modal.hbs
new file mode 100644
index 0000000..59b3aaa
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/simple-modal.hbs
@@ -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.
+}}
+
+<div class="modal fade simple-modal" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel">
+  <div class="modal-dialog">
+    <div class="modal-content">
+      <div class="modal-header">
+        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+          <span aria-hidden="true">&times;</span>
+        </button>
+        <h4 class="modal-title">{{model.title}}</h4>
+      </div>
+      {{#if model.componentName}}
+        {{component model.componentName content=model.content targetObject=model.targetObject}}
+      {{/if}}
+    </div>
+  </div>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/app/templates/task/attempts.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/task/attempts.hbs b/tez-ui2/src/main/webapp/app/templates/task/attempts.hbs
index cdb28aa..6d8d4c3 100644
--- a/tez-ui2/src/main/webapp/app/templates/task/attempts.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/task/attempts.hbs
@@ -18,15 +18,17 @@
 
 {{#if loaded}}
   {{em-table
-  columns=columns
-  rows=model
+    columns=visibleColumns
+    rows=model
 
-  definition=definition
+    headerComponentNames=headerComponentNames
 
-  searchAction="searchChanged"
-  sortAction="sortChanged"
-  rowAction="rowsChanged"
-  pageAction="pageChanged"
+    definition=definition
+
+    searchAction="searchChanged"
+    sortAction="sortChanged"
+    rowAction="rowsChanged"
+    pageAction="pageChanged"
   }}
 {{else}}
   {{partial "partials/loading-anim"}}

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/app/templates/vertex/attempts.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/vertex/attempts.hbs b/tez-ui2/src/main/webapp/app/templates/vertex/attempts.hbs
index cdb28aa..6d8d4c3 100644
--- a/tez-ui2/src/main/webapp/app/templates/vertex/attempts.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/vertex/attempts.hbs
@@ -18,15 +18,17 @@
 
 {{#if loaded}}
   {{em-table
-  columns=columns
-  rows=model
+    columns=visibleColumns
+    rows=model
 
-  definition=definition
+    headerComponentNames=headerComponentNames
 
-  searchAction="searchChanged"
-  sortAction="sortChanged"
-  rowAction="rowsChanged"
-  pageAction="pageChanged"
+    definition=definition
+
+    searchAction="searchChanged"
+    sortAction="sortChanged"
+    rowAction="rowsChanged"
+    pageAction="pageChanged"
   }}
 {{else}}
   {{partial "partials/loading-anim"}}

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/app/templates/vertex/tasks.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/vertex/tasks.hbs b/tez-ui2/src/main/webapp/app/templates/vertex/tasks.hbs
index cdb28aa..6d8d4c3 100644
--- a/tez-ui2/src/main/webapp/app/templates/vertex/tasks.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/vertex/tasks.hbs
@@ -18,15 +18,17 @@
 
 {{#if loaded}}
   {{em-table
-  columns=columns
-  rows=model
+    columns=visibleColumns
+    rows=model
 
-  definition=definition
+    headerComponentNames=headerComponentNames
 
-  searchAction="searchChanged"
-  sortAction="sortChanged"
-  rowAction="rowsChanged"
-  pageAction="pageChanged"
+    definition=definition
+
+    searchAction="searchChanged"
+    sortAction="sortChanged"
+    rowAction="rowsChanged"
+    pageAction="pageChanged"
   }}
 {{else}}
   {{partial "partials/loading-anim"}}

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/app/utils/misc.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/utils/misc.js b/tez-ui2/src/main/webapp/app/utils/misc.js
new file mode 100644
index 0000000..5e2ecf1
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/utils/misc.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.
+ */
+
+export default function isIOCounter(name) {
+  name = name.split('/')[0];
+  return name.match('_INPUT_') || name.match('_OUTPUT_');
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/ember-cli-build.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/ember-cli-build.js b/tez-ui2/src/main/webapp/ember-cli-build.js
index ac5eea9..dee919b 100644
--- a/tez-ui2/src/main/webapp/ember-cli-build.js
+++ b/tez-ui2/src/main/webapp/ember-cli-build.js
@@ -33,6 +33,7 @@ module.exports = function(defaults) {
      destDir: '/config'
   });
 
+  app.import('bower_components/bootstrap/dist/js/bootstrap.js');
   app.import('bower_components/jquery-ui/jquery-ui.js');
   app.import('bower_components/jquery-ui/ui/tooltip.js');
 

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/tests/integration/components/column-selector-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/integration/components/column-selector-test.js b/tez-ui2/src/main/webapp/tests/integration/components/column-selector-test.js
new file mode 100644
index 0000000..0034059
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/integration/components/column-selector-test.js
@@ -0,0 +1,87 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 { moduleForComponent, test } from 'ember-qunit';
+import hbs from 'htmlbars-inline-precompile';
+
+moduleForComponent('column-selector', 'Integration | Component | column selector', {
+  integration: true
+});
+
+test('Basic creation test', function(assert) {
+
+  this.set("content", {
+    columns: [Ember.Object.create({
+      headerTitle: "Test Column"
+    })]
+  });
+  this.render(hbs`{{column-selector content=content}}`);
+
+  assert.equal(this.$(".select-option ").text().trim(), 'Test Column');
+
+  // Template block usage:" + EOL +
+  this.render(hbs`
+    {{#column-selector content=content}}
+      template block text
+    {{/column-selector}}
+  `);
+
+  assert.equal(this.$(".select-option ").text().trim(), 'Test Column');
+});
+
+test('visibleColumnIDs test', function(assert) {
+
+  this.setProperties({
+    content: {
+      visibleColumnIDs: {
+        testID: true,
+      },
+      columns: [Ember.Object.create({
+        id: "testID",
+        headerTitle: "Test Column"
+      })]
+    }
+  });
+
+  this.render(hbs`{{column-selector content=content}}`);
+
+  assert.equal(this.$(".select-option").text().trim(), 'Test Column');
+  assert.equal(this.$(".select-option input")[0].checked, true);
+});
+
+test('searchText test', function(assert) {
+
+  this.setProperties({
+    searchText: "nothing",
+    content: {
+      visibleColumnIDs: {
+        testID: true,
+      },
+      columns: [Ember.Object.create({
+        id: "testID",
+        headerTitle: "Test Column"
+      })]
+    }
+  });
+
+  this.render(hbs`{{column-selector content=content searchText=searchText}}`);
+
+  assert.equal(this.$(".select-option").text().trim(), '');
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/tests/integration/components/table-controls-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/integration/components/table-controls-test.js b/tez-ui2/src/main/webapp/tests/integration/components/table-controls-test.js
new file mode 100644
index 0000000..79170ee
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/integration/components/table-controls-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('table-controls', 'Integration | Component | table controls', {
+  integration: true
+});
+
+test('Basic creation test', function(assert) {
+
+  // Set any properties with this.set('myProperty', 'value');
+  // Handle any actions with this.on('myAction', function(val) { ... });" + EOL + EOL +
+
+  this.render(hbs`{{table-controls}}`);
+
+  assert.equal(this.$().text().trim(), '');
+
+  // Template block usage:" + EOL +
+  this.render(hbs`
+    {{#table-controls}}
+      template block text
+    {{/table-controls}}
+  `);
+
+  assert.equal(this.$().text().trim(), '');
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/tests/unit/controllers/abstract-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/abstract-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/abstract-test.js
index 640e1e5..9cde1e7 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/abstract-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/abstract-test.js
@@ -27,7 +27,8 @@ moduleFor('controller:abstract', 'Unit | Controller | abstract', {
 
 test('Basic creation test', function(assert) {
   let controller = this.subject({
-    send: Ember.K
+    send: Ember.K,
+    initVisibleColumns: Ember.K
   });
 
   assert.ok(controller.name);

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/tests/unit/controllers/app-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/app-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/app-test.js
index 304321e..2fc7276 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/app-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/app-test.js
@@ -27,7 +27,8 @@ moduleFor('controller:dag', 'Unit | Controller | dag', {
 
 test('Basic creation test', function(assert) {
   let controller = this.subject({
-    send: Ember.K
+    send: Ember.K,
+    initVisibleColumns: Ember.K
   });
 
   assert.ok(controller);

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/tests/unit/controllers/app/configs-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/app/configs-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/app/configs-test.js
index c04e5c2..4661e8c 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/app/configs-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/app/configs-test.js
@@ -27,7 +27,8 @@ moduleFor('controller:app/configs', 'Unit | Controller | app/configs', {
 
 test('Basic creation test', function(assert) {
   let controller = this.subject({
-    send: Ember.K
+    send: Ember.K,
+    initVisibleColumns: Ember.K
   });
 
   assert.ok(controller);

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js
index c3e5c2b..c60fbb5 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js
@@ -27,7 +27,8 @@ moduleFor('controller:app/dags', 'Unit | Controller | app/dags', {
 
 test('Basic creation test', function(assert) {
   let controller = this.subject({
-    send: Ember.K
+    send: Ember.K,
+    initVisibleColumns: Ember.K
   });
 
   assert.ok(controller);

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/tests/unit/controllers/app/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/app/index-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/app/index-test.js
index 641a415..9bd6604 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/app/index-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/app/index-test.js
@@ -27,7 +27,8 @@ moduleFor('controller:app/index', 'Unit | Controller | app/index', {
 
 test('Basic creation test', function(assert) {
   let controller = this.subject({
-    send: Ember.K
+    send: Ember.K,
+    initVisibleColumns: Ember.K
   });
 
   assert.ok(controller);

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/tests/unit/controllers/attempt-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/attempt-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/attempt-test.js
index 9408204..da451f7 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/attempt-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/attempt-test.js
@@ -27,7 +27,8 @@ moduleFor('controller:attempt', 'Unit | Controller | attempt', {
 
 test('Basic creation test', function(assert) {
   let controller = this.subject({
-    send: Ember.K
+    send: Ember.K,
+    initVisibleColumns: Ember.K
   });
 
   assert.ok(controller);

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/counters-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/counters-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/counters-test.js
index 9b94804..8226f36 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/counters-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/counters-test.js
@@ -27,7 +27,8 @@ moduleFor('controller:attempt/counters', 'Unit | Controller | attempt/counters',
 
 test('Basic creation test', function(assert) {
   let controller = this.subject({
-    send: Ember.K
+    send: Ember.K,
+    initVisibleColumns: Ember.K
   });
 
   assert.ok(controller);

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/index-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/index-test.js
index 00e2c9e..3733692 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/index-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/index-test.js
@@ -27,7 +27,8 @@ moduleFor('controller:attempt/index', 'Unit | Controller | attempt/index', {
 
 test('Basic creation test', function(assert) {
   let controller = this.subject({
-    send: Ember.K
+    send: Ember.K,
+    initVisibleColumns: Ember.K
   });
 
   assert.ok(controller);

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/tests/unit/controllers/counters-page-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/counters-page-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/counters-page-test.js
index 44a888e..6faad2d 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/counters-page-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/counters-page-test.js
@@ -27,7 +27,8 @@ moduleFor('controller:counters-page', 'Unit | Controller | counters page', {
 
 test('Basic creation test', function(assert) {
   let controller = this.subject({
-    send: Ember.K
+    send: Ember.K,
+    initVisibleColumns: Ember.K
   });
 
   assert.ok(controller);
@@ -38,6 +39,7 @@ test('Basic creation test', function(assert) {
 test('counters test', function(assert) {
   let controller = this.subject({
     send: Ember.K,
+    initVisibleColumns: Ember.K,
     model: {
       counterGroups: [{
         counterGroupName: "a.b.foo",

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/tests/unit/controllers/dag-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag-test.js
index 304321e..2fc7276 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dag-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag-test.js
@@ -27,7 +27,8 @@ moduleFor('controller:dag', 'Unit | Controller | dag', {
 
 test('Basic creation test', function(assert) {
   let controller = this.subject({
-    send: Ember.K
+    send: Ember.K,
+    initVisibleColumns: Ember.K
   });
 
   assert.ok(controller);

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js
index 11bb0fa..3fa8ff7 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js
@@ -27,7 +27,8 @@ moduleFor('controller:dag/attempts', 'Unit | Controller | dag/attempts', {
 
 test('Basic creation test', function(assert) {
   let controller = this.subject({
-    send: Ember.K
+    send: Ember.K,
+    initVisibleColumns: Ember.K
   });
 
   assert.ok(controller);

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/tests/unit/controllers/dag/counters-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/counters-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/counters-test.js
index a90df3c..7e72b95 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/counters-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/counters-test.js
@@ -27,7 +27,8 @@ moduleFor('controller:dag/counters', 'Unit | Controller | dag/counters', {
 
 test('Basic creation test', function(assert) {
   let controller = this.subject({
-    send: Ember.K
+    send: Ember.K,
+    initVisibleColumns: Ember.K
   });
 
   assert.ok(controller);

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/tests/unit/controllers/dag/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/index-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/index-test.js
index 0b64e86..176b9e7 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/index-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/index-test.js
@@ -27,7 +27,8 @@ moduleFor('controller:dag/index', 'Unit | Controller | dag/index', {
 
 test('Basic creation test', function(assert) {
   let controller = this.subject({
-    send: Ember.K
+    send: Ember.K,
+    initVisibleColumns: Ember.K
   });
 
   assert.ok(controller);

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js
index 073e3d3..eace870 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js
@@ -27,7 +27,8 @@ moduleFor('controller:dag/tasks', 'Unit | Controller | dag/tasks', {
 
 test('Basic creation test', function(assert) {
   let controller = this.subject({
-    send: Ember.K
+    send: Ember.K,
+    initVisibleColumns: Ember.K
   });
 
   assert.ok(controller);

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
index fc75935..f54b1a8 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
@@ -27,7 +27,8 @@ moduleFor('controller:dag/vertices', 'Unit | Controller | dag/vertices', {
 
 test('Basic creation test', function(assert) {
   let controller = this.subject({
-    send: Ember.K
+    send: Ember.K,
+    initVisibleColumns: Ember.K
   });
 
   assert.ok(controller);

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js
index ddf6c44..944f813 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js
@@ -16,6 +16,8 @@
  * limitations under the License.
  */
 
+import Ember from 'ember';
+
 import { moduleFor, test } from 'ember-qunit';
 
 moduleFor('controller:dags', 'Unit | Controller | dags', {
@@ -27,6 +29,7 @@ test('Basic creation test', function(assert) {
   assert.expect(2 + 2);
 
   let controller = this.subject({
+    initVisibleColumns: Ember.K,
     send: function (name, query) {
       assert.equal(name, "setBreadcrumbs");
       assert.ok(query);

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/tests/unit/controllers/page-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/page-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/page-test.js
index ffbdd60..75a8a54 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/page-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/page-test.js
@@ -27,7 +27,8 @@ moduleFor('controller:page', 'Unit | Controller | page', {
 
 test('Basic creation test', function(assert) {
   let controller = this.subject({
-    send: Ember.K
+    send: Ember.K,
+    initVisibleColumns: Ember.K
   });
 
   assert.ok(controller);
@@ -38,7 +39,8 @@ test('Basic creation test', function(assert) {
 
 test('loaded test', function(assert) {
   let controller = this.subject({
-    send: Ember.K
+    send: Ember.K,
+    initVisibleColumns: Ember.K
   });
 
   assert.notOk(controller.get("loaded"));

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/tests/unit/controllers/table-page-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/table-page-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/table-page-test.js
index 4c41a20..8aee8d7 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/table-page-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/table-page-test.js
@@ -27,7 +27,8 @@ moduleFor('controller:table-page', 'Unit | Controller | table page', {
 
 test('Basic creation test', function(assert) {
   let controller = this.subject({
-    send: Ember.K
+    send: Ember.K,
+    initVisibleColumns: Ember.K
   });
 
   assert.ok(controller);

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/tests/unit/controllers/task-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/task-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/task-test.js
index 0a5bed1..c9cee79 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/task-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/task-test.js
@@ -27,7 +27,8 @@ moduleFor('controller:task', 'Unit | Controller | task', {
 
 test('Basic creation test', function(assert) {
   let controller = this.subject({
-    send: Ember.K
+    send: Ember.K,
+    initVisibleColumns: Ember.K
   });
 
   assert.ok(controller);

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.js
index fb9439f..43badfc 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.js
@@ -27,7 +27,8 @@ moduleFor('controller:task/attempts', 'Unit | Controller | task/attempts', {
 
 test('Basic creation test', function(assert) {
   let controller = this.subject({
-    send: Ember.K
+    send: Ember.K,
+    initVisibleColumns: Ember.K
   });
 
   assert.ok(controller);

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/tests/unit/controllers/task/counters-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/task/counters-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/task/counters-test.js
index fb453f7..6ee8adb 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/task/counters-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/task/counters-test.js
@@ -27,7 +27,8 @@ moduleFor('controller:task/counters', 'Unit | Controller | task/counters', {
 
 test('Basic creation test', function(assert) {
   let controller = this.subject({
-    send: Ember.K
+    send: Ember.K,
+    initVisibleColumns: Ember.K
   });
 
   assert.ok(controller);

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/tests/unit/controllers/task/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/task/index-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/task/index-test.js
index a229ee9..86d63e9 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/task/index-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/task/index-test.js
@@ -27,7 +27,8 @@ moduleFor('controller:task/index', 'Unit | Controller | task/index', {
 
 test('Basic creation test', function(assert) {
   let controller = this.subject({
-    send: Ember.K
+    send: Ember.K,
+    initVisibleColumns: Ember.K
   });
 
   assert.ok(controller);

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/tests/unit/controllers/vertex-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex-test.js
index 0061f74..e8e9b3f 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex-test.js
@@ -27,7 +27,8 @@ moduleFor('controller:vertex', 'Unit | Controller | vertex', {
 
 test('Basic creation test', function(assert) {
   let controller = this.subject({
-    send: Ember.K
+    send: Ember.K,
+    initVisibleColumns: Ember.K
   });
 
   assert.ok(controller);

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/attempts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/attempts-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/attempts-test.js
index 933096e..de89864 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/attempts-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/attempts-test.js
@@ -27,7 +27,8 @@ moduleFor('controller:vertex/attempts', 'Unit | Controller | vertex/attempts', {
 
 test('Basic creation test', function(assert) {
   let controller = this.subject({
-    send: Ember.K
+    send: Ember.K,
+    initVisibleColumns: Ember.K
   });
 
   assert.ok(controller);

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/counters-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/counters-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/counters-test.js
index cc73e6c..0a17240 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/counters-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/counters-test.js
@@ -27,7 +27,8 @@ moduleFor('controller:vertex/counters', 'Unit | Controller | vertex/counters', {
 
 test('Basic creation test', function(assert) {
   let controller = this.subject({
-    send: Ember.K
+    send: Ember.K,
+    initVisibleColumns: Ember.K
   });
 
   assert.ok(controller);

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/index-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/index-test.js
index e9b46b5..bcf6203 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/index-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/index-test.js
@@ -27,7 +27,8 @@ moduleFor('controller:vertex/index', 'Unit | Controller | vertex/index', {
 
 test('Basic creation test', function(assert) {
   let controller = this.subject({
-    send: Ember.K
+    send: Ember.K,
+    initVisibleColumns: Ember.K
   });
 
   assert.ok(controller);

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/tasks-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/tasks-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/tasks-test.js
index a449dc2..23393ef 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/tasks-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/tasks-test.js
@@ -22,12 +22,13 @@ import { moduleFor, test } from 'ember-qunit';
 
 moduleFor('controller:vertex/tasks', 'Unit | Controller | vertex/tasks', {
   // Specify the other units that are required for this test.
-  // needs: ['controller:foo']
+  // needs: ['service:local-storage']
 });
 
 test('Basic creation test', function(assert) {
   let controller = this.subject({
-    send: Ember.K
+    send: Ember.K,
+    initVisibleColumns: Ember.K
   });
 
   assert.ok(controller);

http://git-wip-us.apache.org/repos/asf/tez/blob/0798c907/tez-ui2/src/main/webapp/tests/unit/utils/misc-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/utils/misc-test.js b/tez-ui2/src/main/webapp/tests/unit/utils/misc-test.js
new file mode 100644
index 0000000..7e282cd
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/utils/misc-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 isIOCounter from '../../../utils/misc';
+import { module, test } from 'qunit';
+
+module('Unit | Utility | misc');
+
+test('Basic creation test', function(assert) {
+  assert.ok(isIOCounter);
+});


[35/45] tez git commit: TEZ-3062. Tez UI 2: Integrate graphical view (sree)

Posted by sr...@apache.org.
TEZ-3062. Tez UI 2: Integrate graphical view (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/9c232cc9
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/9c232cc9
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/9c232cc9

Branch: refs/heads/TEZ-2980
Commit: 9c232cc9e88dee808abd0bd1a0b1d6fb893454a4
Parents: 6d4bb2c
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Mon Feb 1 15:49:31 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:32:52 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |   1 +
 tez-ui2/src/main/webapp/app/controllers/dag.js  |   3 +
 .../webapp/app/controllers/dag/graphical.js     | 165 +++++++++++++++++++
 tez-ui2/src/main/webapp/app/entities/entity.js  |   1 +
 tez-ui2/src/main/webapp/app/models/dag.js       |   5 +
 tez-ui2/src/main/webapp/app/router.js           |   1 +
 .../src/main/webapp/app/routes/dag/graphical.js |  79 +++++++++
 tez-ui2/src/main/webapp/app/routes/pollster.js  |   1 +
 tez-ui2/src/main/webapp/app/serializers/dag.js  |   4 +
 .../main/webapp/app/templates/dag/graphical.hbs |  14 ++
 tez-ui2/src/main/webapp/config/environment.js   |   3 +-
 tez-ui2/src/main/webapp/package.json            |   1 +
 .../unit/controllers/dag/graphical-test.js      |  46 ++++++
 .../tests/unit/routes/dag/graphical-test.js     |  38 +++++
 14 files changed, 361 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/9c232cc9/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index 0457cb0..653899c 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -29,3 +29,4 @@ ALL CHANGES:
   TEZ-3060. Tez UI 2: Activate auto-refresh
   TEZ-3061. Tez UI 2: Display in-progress vertex table in DAG details
   TEZ-3069. Tez UI 2: Make error bar fully functional
+  TEZ-3062. Tez UI 2: Integrate graphical view

http://git-wip-us.apache.org/repos/asf/tez/blob/9c232cc9/tez-ui2/src/main/webapp/app/controllers/dag.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag.js b/tez-ui2/src/main/webapp/app/controllers/dag.js
index 4c8ec1a..2ef4fac 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag.js
@@ -38,6 +38,9 @@ export default ParentController.extend({
     text: "DAG Counters",
     routeName: "dag.counters"
   }, {
+    text: "Graphical View",
+    routeName: "dag.graphical"
+  }, {
     text: "All Vertices",
     routeName: "dag.vertices"
   }, {

http://git-wip-us.apache.org/repos/asf/tez/blob/9c232cc9/tez-ui2/src/main/webapp/app/controllers/dag/graphical.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/graphical.js b/tez-ui2/src/main/webapp/app/controllers/dag/graphical.js
new file mode 100644
index 0000000..a6e42c3
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/graphical.js
@@ -0,0 +1,165 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 MultiTableController from '../multi-table';
+import ColumnDefinition from 'em-table/utils/column-definition';
+
+export default MultiTableController.extend({
+
+  columnSelectorTitle: 'Customize vertex tooltip',
+
+  breadcrumbs: [{
+    text: "Graphical View",
+    routeName: "dag.graphical",
+  }],
+
+  columns: ColumnDefinition.make([{
+    id: 'name',
+    headerTitle: 'Vertex Name',
+    contentPath: 'name',
+    cellComponentName: 'em-table-linked-cell',
+    getCellContent: function (row) {
+      return {
+        routeName: "vertex",
+        model: row.get("entityID"),
+        text: row.get("name")
+      };
+    }
+  },{
+    id: 'entityID',
+    headerTitle: 'Vertex Id',
+    contentPath: 'entityID'
+  },{
+    id: 'status',
+    headerTitle: 'Status',
+    contentPath: 'status',
+    cellComponentName: 'em-table-status-cell',
+    observePath: true
+  },{
+    id: 'progress',
+    headerTitle: 'Progress',
+    contentPath: 'progress',
+    cellComponentName: 'em-table-progress-cell',
+    observePath: true
+  },{
+    id: 'startTime',
+    headerTitle: 'Start Time',
+    contentPath: 'startTime',
+    cellDefinition: {
+      type: 'date'
+    }
+  },{
+    id: 'endTime',
+    headerTitle: 'End Time',
+    contentPath: 'endTime',
+    cellDefinition: {
+      type: 'date'
+    }
+  },{
+    id: 'duration',
+    headerTitle: 'Duration',
+    contentPath: 'duration',
+    cellDefinition: {
+      type: 'duration'
+    }
+  },{
+    id: 'firstTaskStartTime',
+    headerTitle: 'First Task Start Time',
+    contentPath: 'firstTaskStartTime',
+    cellDefinition: {
+     type: 'date'
+    }
+  },{
+    id: 'totalTasks',
+    headerTitle: 'Tasks',
+    contentPath: 'totalTasks',
+  },{
+    id: 'processorClassName',
+    headerTitle: 'Processor Class',
+    contentPath: 'processorClassName',
+  }]),
+
+  redirect: function (details) {
+    switch(details.type) {
+      case 'vertex':
+        this.transitionToRoute('vertex.index', details.d.get('data.entityID'));
+      break;
+      case 'task':
+        this.transitionToRoute('vertex.tasks', details.d.get('data.entityID'));
+      break;
+      case 'io':
+      break;
+      case 'input':
+      break;
+      case 'output':
+      break;
+    }
+  },
+
+  actions: {
+    entityClicked: function (details) {
+
+      /**
+       * In IE 11 under Windows 7, mouse events are not delivered to the page
+       * anymore at all after a SVG use element that was under the mouse is
+       * removed from the DOM in the event listener in response to a mouse click.
+       * See https://connect.microsoft.com/IE/feedback/details/796745
+       *
+       * This condition and related actions must be removed once the bug is fixed
+       * in all supported IE versions
+       */
+      if(this.get("env.ENV.isIE")) {
+        var pageType = details.type === "io" ? "additionals" : details.type,
+            message = `You will be redirected to ${pageType} page`;
+
+        alert(message);
+      }
+      this.redirect(details);
+    }
+  },
+
+  viewData: Ember.computed("model", function () {
+    var model = this.get("model"),
+        dag, vertices, entities;
+
+    if(!model) {
+      return {};
+    }
+
+    dag = this.get('model.firstObject.dag');
+    vertices = this.get('model.firstObject.dag.vertices') || [];
+    entities = {};
+
+    model.forEach(function (vertexData) {
+      entities[vertexData.get('name')] = vertexData;
+    });
+
+    vertices.forEach(function (vertex) {
+      vertex.data = entities[vertex.vertexName];
+    });
+
+    return {
+      vertices: vertices,
+      edges: dag.get('edges'),
+      vertexGroups: dag.get('vertexGroups')
+    };
+  })
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/9c232cc9/tez-ui2/src/main/webapp/app/entities/entity.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/entities/entity.js b/tez-ui2/src/main/webapp/app/entities/entity.js
index 6f98097..f763dcf 100644
--- a/tez-ui2/src/main/webapp/app/entities/entity.js
+++ b/tez-ui2/src/main/webapp/app/entities/entity.js
@@ -100,6 +100,7 @@ var Entity = Ember.Object.extend(NameMixin, {
     needLoader.then(function (model) {
       parentModel.refreshLoadTime();
       parentModel.set(needOptions.name, model);
+      return model;
     });
 
     if(needOptions.silent) {

http://git-wip-us.apache.org/repos/asf/tez/blob/9c232cc9/tez-ui2/src/main/webapp/app/models/dag.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/dag.js b/tez-ui2/src/main/webapp/app/models/dag.js
index bb4c5df..4c4cd96 100644
--- a/tez-ui2/src/main/webapp/app/models/dag.js
+++ b/tez-ui2/src/main/webapp/app/models/dag.js
@@ -46,6 +46,11 @@ export default AMTimelineModel.extend({
   submitter: DS.attr("string"),
   contextID: DS.attr("string"),
 
+  // Serialize when required
+  vertices: DS.attr('object'),
+  edges: DS.attr('object'),
+  vertexGroups: DS.attr('object'),
+
   domain: DS.attr("string"),
   containerLogs: DS.attr("object"),
   queue: Ember.computed("app", function () {

http://git-wip-us.apache.org/repos/asf/tez/blob/9c232cc9/tez-ui2/src/main/webapp/app/router.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/router.js b/tez-ui2/src/main/webapp/app/router.js
index 1f54580..eb3afb3 100644
--- a/tez-ui2/src/main/webapp/app/router.js
+++ b/tez-ui2/src/main/webapp/app/router.js
@@ -31,6 +31,7 @@ Router.map(function() {
     this.route('attempts');
     this.route('counters');
     this.route('index', function() {});
+    this.route('graphical');
   });
   this.route('vertex', {path: '/vertex/:vertex_id'}, function() {
     this.route('tasks');

http://git-wip-us.apache.org/repos/asf/tez/blob/9c232cc9/tez-ui2/src/main/webapp/app/routes/dag/graphical.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag/graphical.js b/tez-ui2/src/main/webapp/app/routes/dag/graphical.js
new file mode 100644
index 0000000..3d9550f
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/dag/graphical.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 Ember from 'ember';
+import MultiAmPollsterRoute from '../multi-am-pollster';
+
+export default MultiAmPollsterRoute.extend({
+  title: "Graphical View",
+
+  loaderNamespace: "dag",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (value, query, options) {
+    return this.get("loader").query('vertex', {
+      dagID: this.modelFor("dag").get("id")
+    }, options);
+  },
+
+  _loadedValueObserver: Ember.observer("loadedValue", function () {
+    var loadedValue = this.get("loadedValue"),
+        records = [];
+
+    loadedValue.forEach(function (record) {
+      records.push(record);
+    });
+
+    this.set("polledRecords", records);
+    Ember.run.later(this, "setViewHeight", 100);
+  }),
+
+  setViewHeight: function () {
+    var container = Ember.$('#graphical-view-component-container'),
+        offset;
+
+    if(container) {
+      offset = container.offset();
+      container.height(
+        Math.max(
+          // 50 pixel is left at the bottom
+          offset ? Ember.$(window).height() - offset.top - 70 : 0,
+          500 // Minimum dag view component container height
+        )
+      );
+    }
+  },
+
+  actions: {
+    didTransition: function () {
+      Ember.$(window).on('resize', this.setViewHeight);
+      this._super();
+      return true;
+    },
+    willTransition: function () {
+      Ember.$(window).off('resize', this.setViewHeight);
+      this._super();
+      return true;
+    },
+  }
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/9c232cc9/tez-ui2/src/main/webapp/app/routes/pollster.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/pollster.js b/tez-ui2/src/main/webapp/app/routes/pollster.js
index 7d62c39..9e1e40d 100644
--- a/tez-ui2/src/main/webapp/app/routes/pollster.js
+++ b/tez-ui2/src/main/webapp/app/routes/pollster.js
@@ -22,6 +22,7 @@ import AbstractRoute from './abstract';
 export default AbstractRoute.extend({
   polling: Ember.inject.service("pollster"),
 
+  // Todo - Change name to recordsToPoll
   polledRecords: null,
 
   // Must be implemented by inheriting classes

http://git-wip-us.apache.org/repos/asf/tez/blob/9c232cc9/tez-ui2/src/main/webapp/app/serializers/dag.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/dag.js b/tez-ui2/src/main/webapp/app/serializers/dag.js
index 9da7bb5..f7d2f21 100644
--- a/tez-ui2/src/main/webapp/app/serializers/dag.js
+++ b/tez-ui2/src/main/webapp/app/serializers/dag.js
@@ -116,6 +116,10 @@ export default TimelineSerializer.extend({
     endTime: getEndTime,
     // duration
 
+    vertices: 'otherinfo.dagPlan.vertices',
+    edges: 'otherinfo.dagPlan.edges',
+    vertexGroups: 'otherinfo.dagPlan.vertexGroups',
+
     // appID
     domain: 'domain',
     // queue

http://git-wip-us.apache.org/repos/asf/tez/blob/9c232cc9/tez-ui2/src/main/webapp/app/templates/dag/graphical.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/graphical.hbs b/tez-ui2/src/main/webapp/app/templates/dag/graphical.hbs
new file mode 100644
index 0000000..fcb7e86
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/dag/graphical.hbs
@@ -0,0 +1,14 @@
+{{#if loaded}}
+  <br/>
+  <div id="graphical-view-component-container">
+    {{em-tgraph
+      data=viewData
+      vertexProperties=visibleColumns
+      entityClicked='entityClicked'
+      configure='openColumnSelector'
+    }}
+    <div class="dag-view-legend">Refresh updates only the tooltip values. When sources & sinks are hidden, double click green bubble to toggle visibility locally.</div>
+  </div>
+{{else}}
+  {{partial "loading"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/9c232cc9/tez-ui2/src/main/webapp/config/environment.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/config/environment.js b/tez-ui2/src/main/webapp/config/environment.js
index b102c8f..e5fc8ac 100644
--- a/tez-ui2/src/main/webapp/config/environment.js
+++ b/tez-ui2/src/main/webapp/config/environment.js
@@ -37,7 +37,8 @@ module.exports = function(environment) {
 
     contentSecurityPolicy: {
       'connect-src': "* 'self'",
-      'style-src': "'self' 'unsafe-inline'"
+      'style-src': "'self' 'unsafe-inline'",
+      'script-src': "'self' 'unsafe-inline'"
     }
   };
 

http://git-wip-us.apache.org/repos/asf/tez/blob/9c232cc9/tez-ui2/src/main/webapp/package.json
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/package.json b/tez-ui2/src/main/webapp/package.json
index 9cb055b..e30d5bc 100644
--- a/tez-ui2/src/main/webapp/package.json
+++ b/tez-ui2/src/main/webapp/package.json
@@ -23,6 +23,7 @@
   "devDependencies": {
     "bower": "^1.7.1",
     "broccoli-asset-rev": "^2.2.0",
+    "em-tgraph": "0.0.3",
     "ember-bootstrap": "0.5.1",
     "ember-cli": "1.13.13",
     "ember-cli-app-version": "^1.0.0",

http://git-wip-us.apache.org/repos/asf/tez/blob/9c232cc9/tez-ui2/src/main/webapp/tests/unit/controllers/dag/graphical-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/graphical-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/graphical-test.js
new file mode 100644
index 0000000..cb9ab66
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/graphical-test.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';
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:dag/graphical', 'Unit | Controller | dag/graphical', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K,
+    initVisibleColumns: Ember.K,
+    getCounterColumns: function () {
+      return [];
+    }
+  });
+
+  assert.ok(controller);
+
+  assert.ok(controller.columnSelectorTitle);
+  assert.ok(controller.breadcrumbs);
+  assert.ok(controller.columns);
+
+  assert.ok(controller.redirect);
+  assert.ok(controller.actions.entityClicked);
+  assert.ok(controller.viewData);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/9c232cc9/tez-ui2/src/main/webapp/tests/unit/routes/dag/graphical-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/dag/graphical-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/dag/graphical-test.js
new file mode 100644
index 0000000..ab838c5
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/dag/graphical-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:dag/graphical', 'Unit | Route | dag/graphical', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.loaderNamespace);
+  assert.ok(route.setupController);
+  assert.ok(route.load);
+  assert.ok(route._loadedValueObserver);
+  assert.ok(route.setViewHeight);
+  assert.ok(route.actions.didTransition);
+  assert.ok(route.actions.willTransition);
+});


[06/45] tez git commit: TEZ-3023. Tez UI 2: Abstract adapter and route (sree)

Posted by sr...@apache.org.
TEZ-3023. Tez UI 2: Abstract adapter and route (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/a0dd70c1
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/a0dd70c1
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/a0dd70c1

Branch: refs/heads/TEZ-2980
Commit: a0dd70c191228d6ddfb37fe17e4dd3f59a43fd2d
Parents: 1292bf4
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Mon Jan 4 22:28:44 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:31:59 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |   1 +
 .../src/main/webapp/app/adapters/abstract.js    |  58 ++++++
 .../main/webapp/app/errors/unlinked-promise.js  |  34 ++++
 tez-ui2/src/main/webapp/app/routes/abstract.js  |  68 +++++++
 .../webapp/tests/unit/adapters/abstract-test.js |  82 ++++++++
 .../webapp/tests/unit/routes/abstract-test.js   | 186 ++++++++++++++++++-
 6 files changed, 428 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/a0dd70c1/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index 77a8d29..0eb31bf 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -8,3 +8,4 @@ ALL CHANGES:
   TEZ-3020. Tez UI 2: Add entity blueprint
   TEZ-2985. Tez UI 2: Create loader and entity classes
   TEZ-3021. Tez UI 2: Add env service & initializer
+  TEZ-3023. Tez UI 2: Abstract adapter and route

http://git-wip-us.apache.org/repos/asf/tez/blob/a0dd70c1/tez-ui2/src/main/webapp/app/adapters/abstract.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/abstract.js b/tez-ui2/src/main/webapp/app/adapters/abstract.js
new file mode 100644
index 0000000..b412a46
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/adapters/abstract.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 LoaderAdapter from './loader';
+
+export default LoaderAdapter.extend({
+  serverName: null, //Must be set by inheriting classes
+
+  host: Ember.computed("serverName", function () {
+    var serverName = this.get("serverName");
+    return this.get(`hosts.${serverName}`);
+  }),
+  namespace: Ember.computed("serverName", function () {
+    var serverName = this.get("serverName"),
+        env = this.get("env");
+    return env.getAppConfig(`namespaces.webService.${serverName}`);
+  }),
+  pathTypeHash: Ember.computed("serverName", function () {
+    var serverName = this.get("serverName"),
+        env = this.get("env");
+
+    return env.getAppConfig(`paths.${serverName}`);
+  }),
+
+  ajaxOptions: function(url, method, options) {
+    options = options || {};
+    options.crossDomain = true;
+    options.xhrFields = {
+      withCredentials: true
+    };
+    options.targetServer = this.get('serverName');
+    return this._super(url, method, options);
+  },
+
+  pathForType: function(type) {
+    var serverName = this.get("serverName"),
+        path = this.get("pathTypeHash")[type];
+    Ember.assert(`Path not found for type:${type} to server:${serverName}`, path);
+    return path;
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a0dd70c1/tez-ui2/src/main/webapp/app/errors/unlinked-promise.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/errors/unlinked-promise.js b/tez-ui2/src/main/webapp/app/errors/unlinked-promise.js
new file mode 100644
index 0000000..770b095
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/errors/unlinked-promise.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';
+
+let UnlinkedPromise = function (errors, message = 'Promise chain was unlinked.') {
+  Ember.Error.call(this, message);
+
+  this.errors = errors || [
+    {
+      title: 'Unlinked promise chain.',
+      detail: message
+    }
+  ];
+};
+
+UnlinkedPromise.prototype = Object.create(Ember.Error.prototype);
+
+export default UnlinkedPromise;

http://git-wip-us.apache.org/repos/asf/tez/blob/a0dd70c1/tez-ui2/src/main/webapp/app/routes/abstract.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/abstract.js b/tez-ui2/src/main/webapp/app/routes/abstract.js
index a4d2bb5..d0f3c3d 100644
--- a/tez-ui2/src/main/webapp/app/routes/abstract.js
+++ b/tez-ui2/src/main/webapp/app/routes/abstract.js
@@ -17,10 +17,18 @@
  */
 
 import Ember from 'ember';
+import LoaderService from '../services/loader';
+import UnlinkedPromise from '../errors/unlinked-promise';
 
 export default Ember.Route.extend({
   title: null, // Must be set by inheriting class
 
+  isLoading: false,
+  currentPromiseId: null,
+  loadedValue: null,
+
+  queryParams: null,
+
   setDocTitle: function () {
     Ember.$(document).attr('title', this.get('title'));
   },
@@ -28,5 +36,65 @@ export default Ember.Route.extend({
   setupController: function (controller, model) {
     this._super(controller, model);
     this.setDocTitle();
+  },
+
+  beforeModel: function (transition) {
+    this.set('queryParams', transition.queryParams);
+    return this._super(transition);
+  },
+
+  checkAndCall: function (id, functionName, value) {
+    if(id === this.get("currentPromiseId")) {
+      return this[functionName](value);
+    }
+    else {
+      throw new UnlinkedPromise();
+    }
+  },
+
+  loadData: Ember.observer("queryParams", function () {
+    var promiseId = Math.random();
+
+    this.set('currentPromiseId', promiseId);
+
+    return Ember.RSVP.resolve().
+      then(this.checkAndCall.bind(this, promiseId, "setLoading")).
+      then(this.checkAndCall.bind(this, promiseId, "beforeLoad")).
+      then(this.checkAndCall.bind(this, promiseId, "load")).
+      then(this.checkAndCall.bind(this, promiseId, "afterLoad")).
+      then(this.checkAndCall.bind(this, promiseId, "setValue"));
+  }),
+
+  setLoading: function () {
+    this.set('isLoading', true);
+  },
+  beforeLoad: function (value) {
+    return value;
+  },
+  load: function (value) {
+    return value;
+  },
+  afterLoad: function (value) {
+    return value;
+  },
+  setValue: function (value) {
+    this.set('loadedValue', value);
+    this.set('isLoading', false);
+  },
+
+  _setControllerModel: Ember.observer("_controller", "loadedValue", function () {
+    var controller = this.get("controller");
+    if(controller) {
+      controller.set("model", this.get("loadedValue"));
+    }
+  }),
+
+  setLoader: function (nameSpace) {
+    this.set("loader", LoaderService.create({
+      nameSpace: nameSpace,
+      store: this.get("store"),
+      container: this.get("container")
+    }));
   }
+
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/a0dd70c1/tez-ui2/src/main/webapp/tests/unit/adapters/abstract-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/abstract-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/abstract-test.js
new file mode 100644
index 0000000..bc00679
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/adapters/abstract-test.js
@@ -0,0 +1,82 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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:abstract', 'Unit | Adapter | abstract', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let adapter = this.subject();
+
+  assert.ok(adapter);
+  assert.equal(adapter.serverName, null);
+
+  assert.ok(adapter.host);
+  assert.ok(adapter.namespace);
+  assert.ok(adapter.pathTypeHash);
+
+  assert.ok(adapter.ajaxOptions);
+  assert.ok(adapter.pathForType);
+});
+
+test('ajaxOptions test', function(assert) {
+  let adapter = this.subject(),
+      testUrl = "foo.bar",
+      testMethod = "tm",
+      testOptions = {
+        a: 1
+      },
+      testServer = "ts",
+
+      result;
+
+  // Without options
+  adapter.serverName = testServer;
+  result = adapter.ajaxOptions(testUrl, testMethod);
+  assert.ok(result);
+  assert.ok(result.crossDomain);
+  assert.ok(result.xhrFields.withCredentials);
+  assert.equal(result.targetServer, testServer);
+
+  // Without options
+  adapter.serverName = testServer;
+  result = adapter.ajaxOptions(testUrl, testMethod, testOptions);
+  assert.ok(result);
+  assert.ok(result.crossDomain);
+  assert.ok(result.xhrFields.withCredentials);
+  assert.equal(result.targetServer, testServer);
+  assert.equal(result.a, testOptions.a);
+});
+
+test('pathForType test', function(assert) {
+  let adapter = this.subject(),
+      testHash = {
+        typ: "type"
+      };
+
+  assert.expect(2);
+
+  adapter.pathTypeHash = testHash;
+  assert.equal(adapter.pathForType("typ"), testHash.typ);
+  assert.throws(function () {
+    adapter.pathForType("noType");
+  });
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a0dd70c1/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js
index e11183e..9513b91 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js
@@ -16,6 +16,10 @@
  * limitations under the License.
  */
 
+import Ember from 'ember';
+
+import UnlinkedPromise from '../../../errors/unlinked-promise';
+
 import { moduleFor, test } from 'ember-qunit';
 
 moduleFor('route:abstract', 'Unit | Route | abstract', {
@@ -23,7 +27,187 @@ moduleFor('route:abstract', 'Unit | Route | abstract', {
   // needs: ['controller:foo']
 });
 
-test('Basic test for existence', function(assert) {
+test('Basic creation test', function(assert) {
   let route = this.subject();
+
   assert.ok(route);
+  assert.ok(route.setDocTitle);
+  assert.ok(route.setupController);
+  assert.ok(route.beforeModel);
+
+  assert.ok(route.checkAndCall);
+
+  assert.ok(route.setLoading);
+  assert.ok(route.loadData);
+  assert.ok(route.beforeLoad);
+  assert.ok(route.load);
+  assert.ok(route.afterLoad);
+  assert.ok(route.setValue);
+
+  assert.ok(route._setControllerModel);
+  assert.ok(route.setLoader);
+});
+
+test('beforeModel test', function(assert) {
+  let route = this.subject(),
+      testQueryParams = {};
+
+  route.loadData = Ember.K;
+  assert.notOk(route.queryParams.queryParams);
+  route.beforeModel({queryParams: testQueryParams});
+  assert.equal(route.queryParams, testQueryParams);
+});
+
+test('checkAndCall test', function(assert) {
+  let route = this.subject(),
+      testValue = {};
+
+  assert.expect(2);
+
+  route.testFunction = function (value) {
+    assert.equal(value, testValue, "Call with current id");
+  };
+  route.currentPromiseId = 1;
+
+  route.checkAndCall(1, "testFunction", testValue);
+  assert.throws(function () {
+    route.checkAndCall(2, "testFunction", testValue);
+  });
+});
+
+test('loadData test - Hook sequence check', function(assert) {
+  let route = this.subject();
+
+  // Bind poilyfill
+  Function.prototype.bind = function (context, val1, val2) {
+    var that = this;
+    return function (val) {
+      return that.call(context, val1, val2, val);
+    };
+  };
+
+  assert.expect(4 + 1);
+
+  route.setLoading = function () {
+    return 1;
+  };
+  route.beforeLoad = function (value) {
+    assert.equal(value, 1, "beforeLoad");
+    return ++value;
+  };
+  route.load = function (value) {
+    assert.equal(value, 2, "load");
+    return ++value;
+  };
+  route.afterLoad = function (value) {
+    assert.equal(value, 3, "afterLoad");
+    return ++value;
+  };
+  route.setValue = function (value) {
+    assert.equal(value, 4, "setValue");
+    return ++value;
+  };
+
+  route.loadData().then(function (value) {
+    assert.equal(value, 5, "Value returned by loadData");
+  });
+
+});
+
+test('loadData test - ID change check with exception throw', function(assert) {
+  let route = this.subject();
+
+  // Bind poilyfill
+  Function.prototype.bind = function (context, val1, val2) {
+    var that = this;
+    return function (val) {
+      return that.call(context, val1, val2, val);
+    };
+  };
+
+  assert.expect(2 + 1);
+
+  route.setLoading = function () {
+    return 1;
+  };
+  route.beforeLoad = function (value) {
+    assert.equal(value, 1, "beforeLoad");
+    return ++value;
+  };
+  route.load = function (value) {
+    assert.equal(value, 2, "load");
+
+    route.currentPromiseId = 0;
+
+    return ++value;
+  };
+  route.afterLoad = function (value) {
+    assert.equal(value, 3, "afterLoad");
+    return ++value;
+  };
+  route.setValue = function (value) {
+    assert.equal(value, 4, "setValue");
+    return ++value;
+  };
+
+  route.loadData().then(function () {
+    assert.notOk("Shouldn't be called");
+  }).catch(function (e) {
+    assert.ok(e instanceof UnlinkedPromise, "Exception thrown");
+  });
+});
+
+test('setLoading test', function(assert) {
+  let route = this.subject();
+
+  assert.equal(route.get("isLoading"), false);
+  route.setLoading();
+  assert.equal(route.get("isLoading"), true);
+});
+
+test('beforeLoad load afterLoad test', function(assert) {
+  let route = this.subject(),
+      testVal = {};
+
+  assert.equal(route.beforeLoad(testVal), testVal);
+  assert.equal(route.load(testVal), testVal);
+  assert.equal(route.afterLoad(testVal), testVal);
+});
+
+test('setValue test', function(assert) {
+  let route = this.subject(),
+      testVal = {};
+
+  route.setLoading();
+  assert.equal(route.get("loadedValue"), null);
+  assert.equal(route.get("isLoading"), true);
+  assert.equal(route.setValue(testVal), testVal);
+  assert.equal(route.get("loadedValue"), testVal);
+  assert.equal(route.get("isLoading"), false);
+});
+
+test('_setControllerModel test', function(assert) {
+  let route = this.subject(),
+      testValue = {},
+      testController = Ember.Object.create();
+
+  route.set("loadedValue", testValue);
+  route.set("controller", testController);
+
+  assert.notOk(testController.model);
+  route._setControllerModel();
+  assert.equal(testController.model, testValue, "With controller");
+});
+
+test('setLoader test', function(assert) {
+  let route = this.subject(),
+      testNamespace = "tn",
+      oldLoader = route.get("loader");
+
+  route.setLoader(testNamespace);
+
+  assert.notEqual(route.get("loader"), oldLoader);
+  assert.equal(route.get("loader.nameSpace"), testNamespace);
+  assert.equal(route.get("loader.store"), route.get("store"));
+  assert.equal(route.get("loader.container"), route.get("container"));
 });


[07/45] tez git commit: TEZ-3021. Tez UI 2: Add env service & initializer (sree)

Posted by sr...@apache.org.
TEZ-3021. Tez UI 2: Add env service & initializer (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/1292bf41
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/1292bf41
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/1292bf41

Branch: refs/heads/TEZ-2980
Commit: 1292bf41a36026b2bfd245f081a920168cfbb51d
Parents: 6e18c9b
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Mon Jan 4 16:28:41 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:31:59 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |  1 +
 tez-ui2/src/main/webapp/app/initializers/env.js | 28 ++++++++
 tez-ui2/src/main/webapp/app/services/env.js     | 55 +++++++++++++++
 tez-ui2/src/main/webapp/app/services/hosts.js   | 11 +--
 tez-ui2/src/main/webapp/config/configs.env      |  6 +-
 .../src/main/webapp/config/default-app-conf.js  | 38 +++++++++++
 tez-ui2/src/main/webapp/config/environment.js   | 12 ++--
 .../webapp/tests/unit/initializers/env-test.js  | 40 +++++++++++
 .../main/webapp/tests/unit/services/env-test.js | 70 ++++++++++++++++++++
 .../webapp/tests/unit/services/hosts-test.js    |  8 ++-
 10 files changed, 252 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/1292bf41/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index 4cf5c4a..77a8d29 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -7,3 +7,4 @@ ALL CHANGES:
   TEZ-2984. Tez UI 2: Create abstract classes
   TEZ-3020. Tez UI 2: Add entity blueprint
   TEZ-2985. Tez UI 2: Create loader and entity classes
+  TEZ-3021. Tez UI 2: Add env service & initializer

http://git-wip-us.apache.org/repos/asf/tez/blob/1292bf41/tez-ui2/src/main/webapp/app/initializers/env.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/initializers/env.js b/tez-ui2/src/main/webapp/app/initializers/env.js
new file mode 100644
index 0000000..43bc291
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/initializers/env.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', 'env', 'service:env');
+  application.inject('route', 'env', 'service:env');
+  application.inject('adapter', 'env', 'service:env');
+}
+
+export default {
+  name: 'env',
+  initialize
+};

http://git-wip-us.apache.org/repos/asf/tez/blob/1292bf41/tez-ui2/src/main/webapp/app/services/env.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/services/env.js b/tez-ui2/src/main/webapp/app/services/env.js
new file mode 100644
index 0000000..397293d
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/services/env.js
@@ -0,0 +1,55 @@
+/*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({
+  _configs: null,
+
+  init: function () {
+    this.collateConfigs();
+  },
+
+  collateConfigs: function () {
+    var configs = {},
+        ENV = window.ENV;
+
+    MoreObject.merge(configs, environment);
+
+    if(ENV) {
+      MoreObject.merge(configs.APP, ENV);
+    }
+
+    this.set("_configs", configs);
+  },
+
+  getConfig: function (path) {
+    var configs = this.get("_configs");
+    return Ember.get(configs, path);
+  },
+
+  getAppConfig: function (path) {
+    var configs = this.get("_configs.APP");
+    return Ember.get(configs, path);
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/1292bf41/tez-ui2/src/main/webapp/app/services/hosts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/services/hosts.js b/tez-ui2/src/main/webapp/app/services/hosts.js
index f549f2c..07de04d 100644
--- a/tez-ui2/src/main/webapp/app/services/hosts.js
+++ b/tez-ui2/src/main/webapp/app/services/hosts.js
@@ -17,10 +17,11 @@
  */
 
 import Ember from 'ember';
-import environment from '../config/environment';
 
 export default Ember.Service.extend({
 
+  env: Ember.inject.service("env"),
+
   correctProtocol: function (url, localProto) {
     var urlProto;
 
@@ -55,13 +56,13 @@ export default Ember.Service.extend({
   },
 
   timeline: Ember.computed(function () {
-    var ENV = window.ENV;
-    return this.normalizeURL((ENV && ENV.timelineHost) || environment.hosts.timeline);
+    var env = this.get("env");
+    return this.normalizeURL(env.getAppConfig("hosts.timeline"));
   }),
 
   rm: Ember.computed(function () {
-    var ENV = window.ENV;
-    return this.normalizeURL((ENV && ENV.rmHost) || environment.hosts.RM);
+    var env = this.get("env");
+    return this.normalizeURL(env.getAppConfig("hosts.rm"));
   }),
 
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/1292bf41/tez-ui2/src/main/webapp/config/configs.env
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/config/configs.env b/tez-ui2/src/main/webapp/config/configs.env
index 5f5ec17..60421fd 100644
--- a/tez-ui2/src/main/webapp/config/configs.env
+++ b/tez-ui2/src/main/webapp/config/configs.env
@@ -1,4 +1,6 @@
 ENV = {
-  //timelineHost: "http://localhost:8188",
-  //rmHost: "http://localhost:8088"
+  hosts: {
+    //timeline: "http://localhost:8188",
+    //rm: "http://localhost:8088"
+  }
 };

http://git-wip-us.apache.org/repos/asf/tez/blob/1292bf41/tez-ui2/src/main/webapp/config/default-app-conf.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/config/default-app-conf.js b/tez-ui2/src/main/webapp/config/default-app-conf.js
new file mode 100644
index 0000000..c8f6dd9
--- /dev/null
+++ b/tez-ui2/src/main/webapp/config/default-app-conf.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.
+ */
+
+module.exports = { // Tez App configurations
+  hosts: {
+    timeline: 'localhost:8188',
+    rm: 'localhost:8088',
+  },
+  namespaces: {
+    webService: {
+      timeline: 'ws/v1/timeline',
+      history: 'ws/v1/applicationhistory',
+      am: {
+        v1: 'proxy/__app_id__/ws/v1/tez',
+        v2: 'proxy/__app_id__/ws/v2/tez',
+      },
+      cluster: 'ws/v1/cluster',
+    },
+    web: {
+      cluster: 'cluster'
+    },
+  },
+};

http://git-wip-us.apache.org/repos/asf/tez/blob/1292bf41/tez-ui2/src/main/webapp/config/environment.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/config/environment.js b/tez-ui2/src/main/webapp/config/environment.js
index e061066..4201f9a 100644
--- a/tez-ui2/src/main/webapp/config/environment.js
+++ b/tez-ui2/src/main/webapp/config/environment.js
@@ -18,6 +18,8 @@
  * limitations under the License.
  */
 
+const DEFAULT_APP_CONF = require('./default-app-conf');
+
 module.exports = function(environment) {
   var ENV = {
     modulePrefix: 'tez-ui',
@@ -31,14 +33,10 @@ module.exports = function(environment) {
       }
     },
 
-    APP: {
-      // Here you can pass flags/options to your application instance
-      // when it is created
-    },
+    APP: DEFAULT_APP_CONF,
 
-    hosts: {
-      timeline: 'localhost:8188',
-      RM: 'localhost:8088'
+    contentSecurityPolicy: {
+      'connect-src': "* 'self'"
     }
   };
 

http://git-wip-us.apache.org/repos/asf/tez/blob/1292bf41/tez-ui2/src/main/webapp/tests/unit/initializers/env-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/initializers/env-test.js b/tez-ui2/src/main/webapp/tests/unit/initializers/env-test.js
new file mode 100644
index 0000000..7f6f287
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/initializers/env-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 EnvInitializer from '../../../initializers/env';
+import { module, test } from 'qunit';
+
+let application;
+
+module('Unit | Initializer | env', {
+  beforeEach() {
+    Ember.run(function() {
+      application = Ember.Application.create();
+      application.deferReadiness();
+    });
+  }
+});
+
+// Replace this with your real tests.
+test('it works', function(assert) {
+  EnvInitializer.initialize(application);
+
+  // you would normally confirm the results of the initializer here
+  assert.ok(true);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/1292bf41/tez-ui2/src/main/webapp/tests/unit/services/env-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/services/env-test.js b/tez-ui2/src/main/webapp/tests/unit/services/env-test.js
new file mode 100644
index 0000000..a8a064b
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/services/env-test.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.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+import environment from '../../../config/environment';
+
+moduleFor('service:env', 'Unit | Service | env', {
+  // Specify the other units that are required for this test.
+  // needs: ['service:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let service = this.subject();
+
+  assert.ok(service);
+  assert.ok(service.collateConfigs);
+  assert.ok(service.getConfig);
+  assert.ok(service.getAppConfig);
+});
+
+test('collateConfigs test', function(assert) {
+  let service = this.subject(),
+      APP = environment.APP;
+
+  APP.a = 11;
+  APP.b = 22;
+  window.ENV = {
+    a: 1
+  };
+
+  service.collateConfigs();
+
+  APP = service._configs.APP;
+  assert.equal(APP.a, 1, "Test window.ENV merge onto environment.APP");
+  assert.equal(APP.b, 22);
+});
+
+test('getConfig test', function(assert) {
+  let service = this.subject();
+
+  window.ENV = {};
+  environment.a = 11;
+  service.collateConfigs();
+  assert.equal(service.getConfig("a"), environment.a);
+});
+
+test('getAppConfig test', function(assert) {
+  let service = this.subject();
+
+  window.ENV = {};
+  environment.APP.a = 11;
+  service.collateConfigs();
+  assert.equal(service.getAppConfig("a"), environment.APP.a);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/1292bf41/tez-ui2/src/main/webapp/tests/unit/services/hosts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/services/hosts-test.js b/tez-ui2/src/main/webapp/tests/unit/services/hosts-test.js
index 055fccd..026f21b 100644
--- a/tez-ui2/src/main/webapp/tests/unit/services/hosts-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/services/hosts-test.js
@@ -20,7 +20,7 @@ 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']
+  needs: ['service:env']
 });
 
 test('Test creation', function(assert) {
@@ -67,8 +67,10 @@ test('Test host URLs with ENV set', function(assert) {
   let service = this.subject();
 
   window.ENV = {
-    timelineHost: "https://localhost:3333",
-    rmHost: "https://localhost:4444"
+    hosts: {
+      timeline: "https://localhost:3333",
+      rm: "https://localhost:4444"
+    }
   };
   assert.equal(service.get("timeline"), "http://localhost:3333");
   assert.equal(service.get("rm"), "http://localhost:4444");


[36/45] tez git commit: TEZ-3136. Tez UI 2: Pre-merge: Update CHANGES.txt and remove from excluded list (sree)

Posted by sr...@apache.org.
TEZ-3136. Tez UI 2: Pre-merge: Update CHANGES.txt and remove from excluded list (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/bdcdfcc5
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/bdcdfcc5
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/bdcdfcc5

Branch: refs/heads/TEZ-2980
Commit: bdcdfcc54f4cae749f861fba30fa580d014ecffb
Parents: 37513ba
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Thu Feb 25 02:08:58 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:32:53 2016 +0530

----------------------------------------------------------------------
 CHANGES.txt          | 42 ++++++++++++++++++++++++++++++++++++++++++
 TEZ-2980-CHANGES.txt | 41 -----------------------------------------
 pom.xml              |  1 -
 3 files changed, 42 insertions(+), 42 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/bdcdfcc5/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index fb0e8b6..c521890 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -37,6 +37,48 @@ ALL CHANGES:
   TEZ-3032. DAG start time getting logged using system time instead of recorded time in startTime field.
   TEZ-3101. Tez UI: Task attempt log link doesn't have the correct protocol.
 
+TEZ-2980: Tez UI 2 - Umbrella:
+  TEZ-2982. Tez UI: Create tez-ui2 directory and get a basic dummy page working in ember 2.2
+  TEZ-3016. Tez UI 2: Make bower dependency silent
+  TEZ-2983. Tez UI 2: Get ember initializers functional
+  TEZ-3018. Tez UI 2: Add config.env
+  TEZ-3019. Tez UI 2: Replace BaseURL with Host
+  TEZ-2984. Tez UI 2: Create abstract classes
+  TEZ-3020. Tez UI 2: Add entity blueprint
+  TEZ-2985. Tez UI 2: Create loader and entity classes
+  TEZ-3021. Tez UI 2: Add env service & initializer
+  TEZ-3023. Tez UI 2: Abstract adapter and route
+  TEZ-3022. Tez UI 2: Add serializer & adapter for timeline server
+  TEZ-3026. Tez UI 2: Add adapters for RM & AM
+  TEZ-3027. Tez UI 2: Add header and footer elements
+  TEZ-2986. Tez UI 2: Implement All DAGs page
+  TEZ-3038. Tez UI 2: Create DAG details page
+  TEZ-3039. Tez UI 2: Create all sub-pages for DAG
+  TEZ-3040. Tez UI 2: Create Vertex details page & sub tables
+  TEZ-3041. Tez UI 2: Create Task & Attempt details page with sub tables
+  TEZ-3045. Tez UI 2: Create application details page with DAGs tab
+  TEZ-3048. Tez UI 2: Make PhantomJS a local dependency for build tests
+  TEZ-3042. Tez UI 2: Create Counters pages
+  TEZ-3043. Tez UI 2: Create configurations page
+  TEZ-3049. Tez UI 2: Add column selector
+  TEZ-3050. Tez UI 2: Add counter columns
+  TEZ-3064. Tez UI 2: Add All DAGs filters
+  TEZ-3059. Tez UI 2: Make refresh functional
+  TEZ-3070. Tez UI 2: Jenkins build is failing
+  TEZ-3060. Tez UI 2: Activate auto-refresh
+  TEZ-3061. Tez UI 2: Display in-progress vertex table in DAG details
+  TEZ-3069. Tez UI 2: Make error bar fully functional
+  TEZ-3062. Tez UI 2: Integrate graphical view
+  TEZ-3058. Tez UI 2: Add download data functionality
+  TEZ-3084. Tez UI 2: Display caller type and info
+  TEZ-3080. Tez UI 2: Ensure UI 2 is in-line with UI 1
+  TEZ-3092. Tez UI 2: Tuneups & Improvements
+  TEZ-3095. Tez UI 2: Tuneups & Improvements
+  TEZ-3088. Tez UI 2: Licenses of all the packages used by Tez Ui must be documented
+  TEZ-2916. Tez UI 2: Show counts of running tasks on the DAG visualization page
+  TEZ-3125. Tez UI 2: All auto-refresh pages refresh multiple times shortly after application complete
+  TEZ-3127. Tez UI 2: Release audit is failing
+
 Release 0.8.2: 2016-01-19
 
 INCOMPATIBLE CHANGES

http://git-wip-us.apache.org/repos/asf/tez/blob/bdcdfcc5/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
deleted file mode 100644
index d09ebc3..0000000
--- a/TEZ-2980-CHANGES.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-ALL CHANGES:
-  TEZ-2982. Tez UI: Create tez-ui2 directory and get a basic dummy page working in ember 2.2
-  TEZ-3016. Tez UI 2: Make bower dependency silent
-  TEZ-2983. Tez UI 2: Get ember initializers functional
-  TEZ-3018. Tez UI 2: Add config.env
-  TEZ-3019. Tez UI 2: Replace BaseURL with Host
-  TEZ-2984. Tez UI 2: Create abstract classes
-  TEZ-3020. Tez UI 2: Add entity blueprint
-  TEZ-2985. Tez UI 2: Create loader and entity classes
-  TEZ-3021. Tez UI 2: Add env service & initializer
-  TEZ-3023. Tez UI 2: Abstract adapter and route
-  TEZ-3022. Tez UI 2: Add serializer & adapter for timeline server
-  TEZ-3026. Tez UI 2: Add adapters for RM & AM
-  TEZ-3027. Tez UI 2: Add header and footer elements
-  TEZ-2986. Tez UI 2: Implement All DAGs page
-  TEZ-3038. Tez UI 2: Create DAG details page
-  TEZ-3039. Tez UI 2: Create all sub-pages for DAG
-  TEZ-3040. Tez UI 2: Create Vertex details page & sub tables
-  TEZ-3041. Tez UI 2: Create Task & Attempt details page with sub tables
-  TEZ-3045. Tez UI 2: Create application details page with DAGs tab
-  TEZ-3048. Tez UI 2: Make PhantomJS a local dependency for build tests
-  TEZ-3042. Tez UI 2: Create Counters pages
-  TEZ-3043. Tez UI 2: Create configurations page
-  TEZ-3049. Tez UI 2: Add column selector
-  TEZ-3050. Tez UI 2: Add counter columns
-  TEZ-3064. Tez UI 2: Add All DAGs filters
-  TEZ-3059. Tez UI 2: Make refresh functional
-  TEZ-3070. Tez UI 2: Jenkins build is failing
-  TEZ-3060. Tez UI 2: Activate auto-refresh
-  TEZ-3061. Tez UI 2: Display in-progress vertex table in DAG details
-  TEZ-3069. Tez UI 2: Make error bar fully functional
-  TEZ-3062. Tez UI 2: Integrate graphical view
-  TEZ-3058. Tez UI 2: Add download data functionality
-  TEZ-3084. Tez UI 2: Display caller type and info
-  TEZ-3080. Tez UI 2: Ensure UI 2 is in-line with UI 1
-  TEZ-3092. Tez UI 2: Tuneups & Improvements
-  TEZ-3095. Tez UI 2: Tuneups & Improvements
-  TEZ-3088. Tez UI 2: Licenses of all the packages used by Tez Ui must be documented
-  TEZ-2916. Tez UI 2: Show counts of running tasks on the DAG visualization page
-  TEZ-3125. Tez UI 2: All auto-refresh pages refresh multiple times shortly after application complete
-  TEZ-3127. Tez UI 2: Release audit is failing

http://git-wip-us.apache.org/repos/asf/tez/blob/bdcdfcc5/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 058ee79..26abc24 100644
--- a/pom.xml
+++ b/pom.xml
@@ -800,7 +800,6 @@
           <configuration>
             <excludes>
               <exclude>CHANGES.txt</exclude>
-              <exclude>TEZ-2980-CHANGES.txt</exclude>
               <exclude>**/LICENSE*</exclude>
               <!-- IDE files -->
               <exclude>.idea/**</exclude>


[27/45] tez git commit: TEZ-3070. Tez UI 2: Jenkins build is failing (sree)

Posted by sr...@apache.org.
TEZ-3070. Tez UI 2: Jenkins build is failing (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/1c88ee41
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/1c88ee41
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/1c88ee41

Branch: refs/heads/TEZ-2980
Commit: 1c88ee41216fbfc1c162fb4d69a155e8824eb96a
Parents: 8f6bedd
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Sat Jan 23 02:26:22 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:32:52 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                                    | 1 +
 tez-ui2/README.md                                       | 4 ++++
 tez-ui2/src/main/webapp/app/styles/column-selector.less | 4 ++--
 tez-ui2/src/main/webapp/app/styles/page-layout.less     | 2 +-
 tez-ui2/src/main/webapp/bower.json                      | 4 ++--
 tez-ui2/src/main/webapp/ember-cli-build.js              | 4 ++++
 tez-ui2/src/main/webapp/package.json                    | 4 ++--
 7 files changed, 16 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/1c88ee41/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index e413bc3..f5660a5 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -25,3 +25,4 @@ ALL CHANGES:
   TEZ-3050. Tez UI 2: Add counter columns
   TEZ-3064. Tez UI 2: Add All DAGs filters
   TEZ-3059. Tez UI 2: Make refresh functional
+  TEZ-3070. Tez UI 2: Jenkins build is failing

http://git-wip-us.apache.org/repos/asf/tez/blob/1c88ee41/tez-ui2/README.md
----------------------------------------------------------------------
diff --git a/tez-ui2/README.md b/tez-ui2/README.md
index e4ce2f5..3ec46de 100644
--- a/tez-ui2/README.md
+++ b/tez-ui2/README.md
@@ -20,6 +20,10 @@ You will need the following things properly installed on your computer.
 * In tez/tez-ui2/src/main/webapp
 * `npm install`
 
+## Configuring
+* By default timeline is expected at localhost:8188 & RM at localhost:8088
+* You can point the UI to custom locations by setting the environment variables in src/main/webapp/config/configs.env
+
 ## Running / Development
 
 * `ember server`

http://git-wip-us.apache.org/repos/asf/tez/blob/1c88ee41/tez-ui2/src/main/webapp/app/styles/column-selector.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/column-selector.less b/tez-ui2/src/main/webapp/app/styles/column-selector.less
index 3e061e1..c83bdde 100644
--- a/tez-ui2/src/main/webapp/app/styles/column-selector.less
+++ b/tez-ui2/src/main/webapp/app/styles/column-selector.less
@@ -16,8 +16,8 @@
  * limitations under the License.
  */
 
-@import "../../bower_components/snippet-ss/less/force";
-@import "../../bower_components/snippet-ss/less/effects";
+@import "bower_components/snippet-ss/less/force";
+@import "bower_components/snippet-ss/less/effects";
 
 .column-selector {
   .message {

http://git-wip-us.apache.org/repos/asf/tez/blob/1c88ee41/tez-ui2/src/main/webapp/app/styles/page-layout.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/page-layout.less b/tez-ui2/src/main/webapp/app/styles/page-layout.less
index 5a49abc..0411fa0 100644
--- a/tez-ui2/src/main/webapp/app/styles/page-layout.less
+++ b/tez-ui2/src/main/webapp/app/styles/page-layout.less
@@ -17,7 +17,7 @@
  */
 
 @import "colors";
-@import "../../bower_components/snippet-ss/less/no";
+@import "bower_components/snippet-ss/less/no";
 
 body, html, body > .ember-view {
   height: 100%;

http://git-wip-us.apache.org/repos/asf/tez/blob/1c88ee41/tez-ui2/src/main/webapp/bower.json
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/bower.json b/tez-ui2/src/main/webapp/bower.json
index 1448fd3..eb9569d 100644
--- a/tez-ui2/src/main/webapp/bower.json
+++ b/tez-ui2/src/main/webapp/bower.json
@@ -12,11 +12,11 @@
     "qunit": "~1.19.0",
     "more-js": "*",
     "bootstrap": "~3.3.5",
-    "snippet-ss": "*",
     "font-awesome": "~4.5.0",
     "jquery-ui": "1.11.4",
     "moment": "^2.8.0",
     "moment-timezone": "^0.5.0",
-    "numeral": "1.5.3"
+    "numeral": "1.5.3",
+    "snippet-ss": "~1.11.0"
   }
 }

http://git-wip-us.apache.org/repos/asf/tez/blob/1c88ee41/tez-ui2/src/main/webapp/ember-cli-build.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/ember-cli-build.js b/tez-ui2/src/main/webapp/ember-cli-build.js
index dee919b..d5cd31a 100644
--- a/tez-ui2/src/main/webapp/ember-cli-build.js
+++ b/tez-ui2/src/main/webapp/ember-cli-build.js
@@ -33,6 +33,10 @@ module.exports = function(defaults) {
      destDir: '/config'
   });
 
+  app.import("bower_components/snippet-ss/less/force.less");
+  app.import("bower_components/snippet-ss/less/effects.less");
+  app.import("bower_components/snippet-ss/less/no.less");
+
   app.import('bower_components/bootstrap/dist/js/bootstrap.js');
   app.import('bower_components/jquery-ui/jquery-ui.js');
   app.import('bower_components/jquery-ui/ui/tooltip.js');

http://git-wip-us.apache.org/repos/asf/tez/blob/1c88ee41/tez-ui2/src/main/webapp/package.json
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/package.json b/tez-ui2/src/main/webapp/package.json
index ec84b18..f484913 100644
--- a/tez-ui2/src/main/webapp/package.json
+++ b/tez-ui2/src/main/webapp/package.json
@@ -48,8 +48,8 @@
   },
   "dependencies": {
     "broccoli-funnel": "^1.0.1",
-    "em-helpers": "0.5.7",
-    "em-table": "0.3.7",
+    "em-helpers": "0.5.8",
+    "em-table": "0.3.8",
     "ember-cli-htmlbars": "^1.0.1",
     "ember-cli-less": "^1.4.0",
     "phantomjs": "^1.9.19"


[22/45] tez git commit: TEZ-3043. Tez UI 2: Create configurations page (sree)

Posted by sr...@apache.org.
TEZ-3043. Tez UI 2: Create configurations page (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/90ac7cc5
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/90ac7cc5
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/90ac7cc5

Branch: refs/heads/TEZ-2980
Commit: 90ac7cc5dd4c64099ff00a8fd4e8466f20543f36
Parents: a3a4637
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Tue Jan 19 16:07:26 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:32:16 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |  1 +
 tez-ui2/src/main/webapp/app/controllers/app.js  |  3 +
 .../main/webapp/app/controllers/app/configs.js  | 60 ++++++++++++++++++++
 tez-ui2/src/main/webapp/app/models/app.js       |  2 +
 tez-ui2/src/main/webapp/app/router.js           |  1 +
 .../src/main/webapp/app/routes/app/configs.js   | 33 +++++++++++
 tez-ui2/src/main/webapp/app/serializers/app.js  |  2 +
 .../main/webapp/app/templates/app/configs.hbs   | 34 +++++++++++
 .../main/webapp/tests/unit/adapters/app-test.js |  2 +-
 .../tests/unit/controllers/app/configs-test.js  | 39 +++++++++++++
 .../tests/unit/controllers/app/dags-test.js     |  2 +-
 .../tests/unit/controllers/app/index-test.js    |  2 +-
 .../tests/unit/controllers/attempt-test.js      |  2 +-
 .../unit/controllers/attempt/counters-test.js   |  2 +-
 .../unit/controllers/attempt/index-test.js      |  2 +-
 .../tests/unit/controllers/dag/counters-test.js |  2 +-
 .../webapp/tests/unit/controllers/task-test.js  |  2 +-
 .../unit/controllers/task/attempts-test.js      |  2 +-
 .../unit/controllers/task/counters-test.js      |  2 +-
 .../tests/unit/controllers/task/index-test.js   |  2 +-
 .../unit/controllers/vertex/counters-test.js    |  2 +-
 .../main/webapp/tests/unit/models/app-test.js   |  2 +-
 .../tests/unit/routes/app/configs-test.js       | 45 +++++++++++++++
 .../webapp/tests/unit/routes/app/dags-test.js   |  2 +-
 .../webapp/tests/unit/routes/app/index-test.js  |  2 +-
 .../webapp/tests/unit/routes/attempt-test.js    |  2 +-
 .../tests/unit/routes/attempt/counters-test.js  |  2 +-
 .../tests/unit/routes/attempt/index-test.js     |  2 +-
 .../tests/unit/routes/dag/counters-test.js      |  2 +-
 .../main/webapp/tests/unit/routes/task-test.js  |  2 +-
 .../tests/unit/routes/task/attempts-test.js     |  2 +-
 .../tests/unit/routes/task/counters-test.js     |  2 +-
 .../webapp/tests/unit/routes/task/index-test.js |  2 +-
 .../tests/unit/routes/vertex/counters-test.js   |  2 +-
 .../webapp/tests/unit/serializers/app-test.js   |  2 +-
 35 files changed, 245 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index a79198e..c1fd7ae 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -20,3 +20,4 @@ ALL CHANGES:
   TEZ-3045. Tez UI 2: Create application details page with DAGs tab
   TEZ-3048. Tez UI 2: Make PhantomJS a local dependency for build tests
   TEZ-3042. Tez UI 2: Create Counters pages
+  TEZ-3043. Tez UI 2: Create configurations page

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/app/controllers/app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/app.js b/tez-ui2/src/main/webapp/app/controllers/app.js
index 95159c5..8333220 100644
--- a/tez-ui2/src/main/webapp/app/controllers/app.js
+++ b/tez-ui2/src/main/webapp/app/controllers/app.js
@@ -37,5 +37,8 @@ export default AbstractController.extend({
   }, {
     text: "DAGs",
     routeName: "app.dags"
+  }, {
+    text: "Configurations",
+    routeName: "app.configs"
   }]
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/app/controllers/app/configs.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/app/configs.js b/tez-ui2/src/main/webapp/app/controllers/app/configs.js
new file mode 100644
index 0000000..517d43b
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/app/configs.js
@@ -0,0 +1,60 @@
+/*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 TablePageController from '../table-page';
+import ColumnDefinition from 'em-table/utils/column-definition';
+
+var MoreObject = more.Object;
+
+export default TablePageController.extend({
+  searchText: "tez",
+
+  breadcrumbs: [{
+    text: "Configurations",
+    routeName: "app.configs",
+  }],
+
+  columns: ColumnDefinition.make([{
+    id: 'configName',
+    headerTitle: 'Configuration Name',
+    contentPath: 'configName',
+  }, {
+    id: 'configValue',
+    headerTitle: 'Configuration Value',
+    contentPath: 'configValue',
+  }]),
+
+  configs: Ember.computed("model.configs", function () {
+    var configs = this.get("model.configs"),
+        configRows = [];
+
+    if(configs) {
+      MoreObject.forEach(configs, function (key, value) {
+        configRows.push(Ember.Object.create({
+          configName: key,
+          configValue: value
+        }));
+      });
+    }
+
+    return Ember.A(configRows);
+  })
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/app/models/app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/app.js b/tez-ui2/src/main/webapp/app/models/app.js
index 42fa1c5..82ffffc 100644
--- a/tez-ui2/src/main/webapp/app/models/app.js
+++ b/tez-ui2/src/main/webapp/app/models/app.js
@@ -49,4 +49,6 @@ export default TimelineModel.extend({
   buildTime: DS.attr("string"),
   tezRevision: DS.attr("string"),
   tezVersion: DS.attr("string"),
+
+  configs: DS.attr("object"),
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/app/router.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/router.js b/tez-ui2/src/main/webapp/app/router.js
index 0193672..4e8cb0b 100644
--- a/tez-ui2/src/main/webapp/app/router.js
+++ b/tez-ui2/src/main/webapp/app/router.js
@@ -45,6 +45,7 @@ Router.map(function() {
   });
   this.route('app', {path: '/app/:app_id'}, function () {
     this.route('dags');
+    this.route('configs');
   });
 });
 

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/app/routes/app/configs.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/app/configs.js b/tez-ui2/src/main/webapp/app/routes/app/configs.js
new file mode 100644
index 0000000..b6768fa
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/app/configs.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';
+import AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  title: "Application Details",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (/*value, query*/) {
+    return this.get("loader").queryRecord('app', this.modelFor("app").id);
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/app/serializers/app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/app.js b/tez-ui2/src/main/webapp/app/serializers/app.js
index 86d8fa0..0d05c6c 100644
--- a/tez-ui2/src/main/webapp/app/serializers/app.js
+++ b/tez-ui2/src/main/webapp/app/serializers/app.js
@@ -26,5 +26,7 @@ export default TimelineSerializer.extend({
     buildTime: 'otherinfo.tezVersion.buildTime',
     tezRevision: 'otherinfo.tezVersion.revision',
     tezVersion: 'otherinfo.tezVersion.version',
+
+    configs: 'otherinfo.config',
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/app/templates/app/configs.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/app/configs.hbs b/tez-ui2/src/main/webapp/app/templates/app/configs.hbs
new file mode 100644
index 0000000..8617c81
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/app/configs.hbs
@@ -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.
+}}
+
+{{#if loaded}}
+  {{em-table
+  columns=columns
+  rows=configs
+
+  rowCount=configs.length
+  definition=definition
+
+  enablePagination=false
+
+  searchAction="searchChanged"
+  sortAction="sortChanged"
+  }}
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/tests/unit/adapters/app-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/app-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/app-test.js
index dd2db50..08d2c44 100644
--- a/tez-ui2/src/main/webapp/tests/unit/adapters/app-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/adapters/app-test.js
@@ -18,7 +18,7 @@
 
 import { moduleFor, test } from 'ember-qunit';
 
-moduleFor('adapter:app', 'Unit | Adapter | dag', {
+moduleFor('adapter:app', 'Unit | Adapter | app', {
   // Specify the other units that are required for this test.
   // needs: ['serializer:foo']
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/tests/unit/controllers/app/configs-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/app/configs-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/app/configs-test.js
new file mode 100644
index 0000000..c04e5c2
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/app/configs-test.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';
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:app/configs', 'Unit | Controller | app/configs', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+  assert.ok(controller.columns);
+  assert.ok(controller.configs);
+
+  assert.ok(controller.get("searchText"), "tez");
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js
index 10ba8a3..c3e5c2b 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js
@@ -20,7 +20,7 @@ import Ember from 'ember';
 
 import { moduleFor, test } from 'ember-qunit';
 
-moduleFor('controller:app/dags', 'Unit | Controller | vertex/attempts', {
+moduleFor('controller:app/dags', 'Unit | Controller | app/dags', {
   // Specify the other units that are required for this test.
   // needs: ['controller:foo']
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/tests/unit/controllers/app/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/app/index-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/app/index-test.js
index c2004ba..641a415 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/app/index-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/app/index-test.js
@@ -20,7 +20,7 @@ import Ember from 'ember';
 
 import { moduleFor, test } from 'ember-qunit';
 
-moduleFor('controller:app/index', 'Unit | Controller | vertex/index', {
+moduleFor('controller:app/index', 'Unit | Controller | app/index', {
   // Specify the other units that are required for this test.
   // needs: ['controller:foo']
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/tests/unit/controllers/attempt-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/attempt-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/attempt-test.js
index 32c6347..9408204 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/attempt-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/attempt-test.js
@@ -20,7 +20,7 @@ import Ember from 'ember';
 
 import { moduleFor, test } from 'ember-qunit';
 
-moduleFor('controller:attempt', 'Unit | Controller | vertex', {
+moduleFor('controller:attempt', 'Unit | Controller | attempt', {
   // Specify the other units that are required for this test.
   // needs: ['controller:foo']
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/counters-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/counters-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/counters-test.js
index 0231fa6..9b94804 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/counters-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/counters-test.js
@@ -20,7 +20,7 @@ import Ember from 'ember';
 
 import { moduleFor, test } from 'ember-qunit';
 
-moduleFor('controller:attempt/counters', 'Unit | Controller | vertex/index', {
+moduleFor('controller:attempt/counters', 'Unit | Controller | attempt/counters', {
   // Specify the other units that are required for this test.
   // needs: ['controller:foo']
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/index-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/index-test.js
index b20e402..00e2c9e 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/index-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/index-test.js
@@ -20,7 +20,7 @@ import Ember from 'ember';
 
 import { moduleFor, test } from 'ember-qunit';
 
-moduleFor('controller:attempt/index', 'Unit | Controller | vertex/index', {
+moduleFor('controller:attempt/index', 'Unit | Controller | attempt/index', {
   // Specify the other units that are required for this test.
   // needs: ['controller:foo']
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/tests/unit/controllers/dag/counters-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/counters-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/counters-test.js
index 982bea0..a90df3c 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/counters-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/counters-test.js
@@ -20,7 +20,7 @@ import Ember from 'ember';
 
 import { moduleFor, test } from 'ember-qunit';
 
-moduleFor('controller:dag/counters', 'Unit | Controller | vertex/index', {
+moduleFor('controller:dag/counters', 'Unit | Controller | dag/counters', {
   // Specify the other units that are required for this test.
   // needs: ['controller:foo']
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/tests/unit/controllers/task-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/task-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/task-test.js
index f59817e..0a5bed1 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/task-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/task-test.js
@@ -20,7 +20,7 @@ import Ember from 'ember';
 
 import { moduleFor, test } from 'ember-qunit';
 
-moduleFor('controller:task', 'Unit | Controller | vertex', {
+moduleFor('controller:task', 'Unit | Controller | task', {
   // Specify the other units that are required for this test.
   // needs: ['controller:foo']
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.js
index bf389da..fb9439f 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.js
@@ -20,7 +20,7 @@ import Ember from 'ember';
 
 import { moduleFor, test } from 'ember-qunit';
 
-moduleFor('controller:task/attempts', 'Unit | Controller | vertex/attempts', {
+moduleFor('controller:task/attempts', 'Unit | Controller | task/attempts', {
   // Specify the other units that are required for this test.
   // needs: ['controller:foo']
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/tests/unit/controllers/task/counters-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/task/counters-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/task/counters-test.js
index e4f2532..fb453f7 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/task/counters-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/task/counters-test.js
@@ -20,7 +20,7 @@ import Ember from 'ember';
 
 import { moduleFor, test } from 'ember-qunit';
 
-moduleFor('controller:task/counters', 'Unit | Controller | vertex/index', {
+moduleFor('controller:task/counters', 'Unit | Controller | task/counters', {
   // Specify the other units that are required for this test.
   // needs: ['controller:foo']
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/tests/unit/controllers/task/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/task/index-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/task/index-test.js
index e3014ae..a229ee9 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/task/index-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/task/index-test.js
@@ -20,7 +20,7 @@ import Ember from 'ember';
 
 import { moduleFor, test } from 'ember-qunit';
 
-moduleFor('controller:task/index', 'Unit | Controller | vertex/index', {
+moduleFor('controller:task/index', 'Unit | Controller | task/index', {
   // Specify the other units that are required for this test.
   // needs: ['controller:foo']
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/counters-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/counters-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/counters-test.js
index 83d946c..cc73e6c 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/counters-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/counters-test.js
@@ -20,7 +20,7 @@ import Ember from 'ember';
 
 import { moduleFor, test } from 'ember-qunit';
 
-moduleFor('controller:vertex/counters', 'Unit | Controller | vertex/index', {
+moduleFor('controller:vertex/counters', 'Unit | Controller | vertex/counters', {
   // Specify the other units that are required for this test.
   // needs: ['controller:foo']
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/tests/unit/models/app-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/app-test.js b/tez-ui2/src/main/webapp/tests/unit/models/app-test.js
index e0fb7f0..06d7386 100644
--- a/tez-ui2/src/main/webapp/tests/unit/models/app-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/models/app-test.js
@@ -18,7 +18,7 @@
 
 import { moduleForModel, test } from 'ember-qunit';
 
-moduleForModel('app', 'Unit | Model | task', {
+moduleForModel('app', 'Unit | Model | app', {
   // Specify the other units that are required for this test.
   needs: []
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/tests/unit/routes/app/configs-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/app/configs-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/app/configs-test.js
new file mode 100644
index 0000000..9ca6a7a
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/app/configs-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:app/configs', 'Unit | Route | app/configs', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+  assert.ok(route.load);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/tests/unit/routes/app/dags-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/app/dags-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/app/dags-test.js
index 05c1436..f7ac141 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/app/dags-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/app/dags-test.js
@@ -18,7 +18,7 @@
 
 import { moduleFor, test } from 'ember-qunit';
 
-moduleFor('route:app/dags', 'Unit | Route | vertex/attempts', {
+moduleFor('route:app/dags', 'Unit | Route | app/dags', {
   // Specify the other units that are required for this test.
   // needs: ['controller:foo']
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/tests/unit/routes/app/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/app/index-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/app/index-test.js
index 83697f4..2ea4415 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/app/index-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/app/index-test.js
@@ -18,7 +18,7 @@
 
 import { moduleFor, test } from 'ember-qunit';
 
-moduleFor('route:app/index', 'Unit | Route | vertex/index', {
+moduleFor('route:app/index', 'Unit | Route | app/index', {
   // Specify the other units that are required for this test.
   // needs: ['controller:foo']
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/tests/unit/routes/attempt-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/attempt-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/attempt-test.js
index dbfe590..a5eb447 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/attempt-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/attempt-test.js
@@ -18,7 +18,7 @@
 
 import { moduleFor, test } from 'ember-qunit';
 
-moduleFor('route:attempt', 'Unit | Route | vertex', {
+moduleFor('route:attempt', 'Unit | Route | attempt', {
   // Specify the other units that are required for this test.
   // needs: ['controller:foo']
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/tests/unit/routes/attempt/counters-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/attempt/counters-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/attempt/counters-test.js
index 5a65685..32d808d 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/attempt/counters-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/attempt/counters-test.js
@@ -18,7 +18,7 @@
 
 import { moduleFor, test } from 'ember-qunit';
 
-moduleFor('route:attempt/counters', 'Unit | Route | vertex/index', {
+moduleFor('route:attempt/counters', 'Unit | Route | attempt/counters', {
   // Specify the other units that are required for this test.
   // needs: ['controller:foo']
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/tests/unit/routes/attempt/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/attempt/index-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/attempt/index-test.js
index 8576090..b0e3d2f 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/attempt/index-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/attempt/index-test.js
@@ -18,7 +18,7 @@
 
 import { moduleFor, test } from 'ember-qunit';
 
-moduleFor('route:attempt/index', 'Unit | Route | vertex/index', {
+moduleFor('route:attempt/index', 'Unit | Route | attempt/index', {
   // Specify the other units that are required for this test.
   // needs: ['controller:foo']
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/tests/unit/routes/dag/counters-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/dag/counters-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/dag/counters-test.js
index 24940b2..41ca35c 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/dag/counters-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/dag/counters-test.js
@@ -18,7 +18,7 @@
 
 import { moduleFor, test } from 'ember-qunit';
 
-moduleFor('route:dag/counters', 'Unit | Route | dag/index', {
+moduleFor('route:dag/counters', 'Unit | Route | dag/counters', {
   // Specify the other units that are required for this test.
   // needs: ['controller:foo']
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/tests/unit/routes/task-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/task-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/task-test.js
index af802b8..9252a3e 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/task-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/task-test.js
@@ -18,7 +18,7 @@
 
 import { moduleFor, test } from 'ember-qunit';
 
-moduleFor('route:task', 'Unit | Route | vertex', {
+moduleFor('route:task', 'Unit | Route | task', {
   // Specify the other units that are required for this test.
   // needs: ['controller:foo']
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/tests/unit/routes/task/attempts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/task/attempts-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/task/attempts-test.js
index 1209012..2c139b7 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/task/attempts-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/task/attempts-test.js
@@ -18,7 +18,7 @@
 
 import { moduleFor, test } from 'ember-qunit';
 
-moduleFor('route:task/attempts', 'Unit | Route | vertex/attempts', {
+moduleFor('route:task/attempts', 'Unit | Route | task/attempts', {
   // Specify the other units that are required for this test.
   // needs: ['controller:foo']
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/tests/unit/routes/task/counters-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/task/counters-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/task/counters-test.js
index 472a635..fafb2a0 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/task/counters-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/task/counters-test.js
@@ -18,7 +18,7 @@
 
 import { moduleFor, test } from 'ember-qunit';
 
-moduleFor('route:task/counters', 'Unit | Route | vertex/index', {
+moduleFor('route:task/counters', 'Unit | Route | task/counters', {
   // Specify the other units that are required for this test.
   // needs: ['controller:foo']
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/tests/unit/routes/task/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/task/index-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/task/index-test.js
index 8f4f6b9..603a8d6 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/task/index-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/task/index-test.js
@@ -18,7 +18,7 @@
 
 import { moduleFor, test } from 'ember-qunit';
 
-moduleFor('route:task/index', 'Unit | Route | vertex/index', {
+moduleFor('route:task/index', 'Unit | Route | task/index', {
   // Specify the other units that are required for this test.
   // needs: ['controller:foo']
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/tests/unit/routes/vertex/counters-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/vertex/counters-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/vertex/counters-test.js
index ec33b8a..6f76c1c 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/vertex/counters-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/vertex/counters-test.js
@@ -18,7 +18,7 @@
 
 import { moduleFor, test } from 'ember-qunit';
 
-moduleFor('route:vertex/counters', 'Unit | Route | vertex/index', {
+moduleFor('route:vertex/counters', 'Unit | Route | vertex/counters', {
   // Specify the other units that are required for this test.
   // needs: ['controller:foo']
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/90ac7cc5/tez-ui2/src/main/webapp/tests/unit/serializers/app-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/serializers/app-test.js b/tez-ui2/src/main/webapp/tests/unit/serializers/app-test.js
index fc79ae9..ec6b6b4 100644
--- a/tez-ui2/src/main/webapp/tests/unit/serializers/app-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/serializers/app-test.js
@@ -18,7 +18,7 @@
 
 import { moduleFor, test } from 'ember-qunit';
 
-moduleFor('serializer:task', 'Unit | Serializer | task', {
+moduleFor('serializer:app', 'Unit | Serializer | app', {
   // Specify the other units that are required for this test.
   // needs: ['serializer:task']
 });


[41/45] tez git commit: TEZ-3125. Tez UI 2: All auto-refresh pages refresh multiple times shortly after application complete (sree)

Posted by sr...@apache.org.
TEZ-3125. Tez UI 2: All auto-refresh pages refresh multiple times shortly after application complete (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/6b8e328f
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/6b8e328f
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/6b8e328f

Branch: refs/heads/TEZ-2980
Commit: 6b8e328ff4cb817a37db68680536f91054e03a30
Parents: 9cb1da4
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Thu Feb 18 14:42:09 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:32:53 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |  1 +
 .../main/webapp/app/controllers/app/index.js    |  1 -
 tez-ui2/src/main/webapp/app/entities/entity.js  | 35 ++++++--
 tez-ui2/src/main/webapp/app/models/app.js       |  8 ++
 tez-ui2/src/main/webapp/app/models/dag.js       |  5 ++
 tez-ui2/src/main/webapp/app/models/timeline.js  |  2 +-
 .../src/main/webapp/app/routes/am-pollster.js   |  9 +-
 tez-ui2/src/main/webapp/app/routes/dags.js      |  4 +-
 .../src/main/webapp/app/templates/app/index.hbs |  8 +-
 .../webapp/tests/unit/entities/entity-test.js   | 94 ++++++++++++++++++++
 .../tests/unit/routes/am-pollster-test.js       |  1 +
 11 files changed, 151 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/6b8e328f/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index 512492b..949dcb6 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -37,3 +37,4 @@ ALL CHANGES:
   TEZ-3095. Tez UI 2: Tuneups & Improvements
   TEZ-3088. Tez UI 2: Licenses of all the packages used by Tez Ui must be documented
   TEZ-2916. Tez UI 2: Show counts of running tasks on the DAG visualization page
+  TEZ-3125. Tez UI 2: All auto-refresh pages refresh multiple times shortly after application complete

http://git-wip-us.apache.org/repos/asf/tez/blob/6b8e328f/tez-ui2/src/main/webapp/app/controllers/app/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/app/index.js b/tez-ui2/src/main/webapp/app/controllers/app/index.js
index cf199f8..7f7bc78 100644
--- a/tez-ui2/src/main/webapp/app/controllers/app/index.js
+++ b/tez-ui2/src/main/webapp/app/controllers/app/index.js
@@ -22,7 +22,6 @@ import PageController from '../page';
 export default PageController.extend({
 
   trackingURL: Ember.computed("model.appID", function () {
-    console.log(this.get("hosts.rm"));
     return [
       this.get("hosts.rm"),
       this.get("env.app.namespaces.web.rm"),

http://git-wip-us.apache.org/repos/asf/tez/blob/6b8e328f/tez-ui2/src/main/webapp/app/entities/entity.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/entities/entity.js b/tez-ui2/src/main/webapp/app/entities/entity.js
index 8280558..462a148 100644
--- a/tez-ui2/src/main/webapp/app/entities/entity.js
+++ b/tez-ui2/src/main/webapp/app/entities/entity.js
@@ -88,27 +88,46 @@ var Entity = Ember.Object.extend(NameMixin, {
     return Ember.Object.create(need, overrides);
   },
 
-  _loadNeed: function (loader, parentModel, needOptions, options) {
-    var needLoader = loader.queryRecord(
-      needOptions.type,
+  _loadNeed: function (loader, parentModel, needOptions, options, index) {
+    var needLoader,
+        that = this,
+        types = needOptions.type,
+        type;
+
+    if(!Array.isArray(types)) {
+      types = [types];
+    }
+
+    index = index || 0;
+    type = types[index];
+
+    needLoader = loader.queryRecord(
+      type,
       parentModel.get(needOptions.idKey),
       options,
       needOptions.queryParams,
       needOptions.urlParams
     );
 
-    needLoader.then(function (model) {
+    needLoader = needLoader.then(function (model) {
       parentModel.set(needOptions.name, model);
       parentModel.refreshLoadTime();
       return model;
     });
 
-    if(needOptions.silent) {
-      needLoader = needLoader.catch(function () {
+    needLoader = needLoader.catch(function (err) {
+      if(++index < types.length) {
+        return that._loadNeed(loader, parentModel, needOptions, options, index);
+      }
+
+      if(needOptions.silent) {
         parentModel.set(needOptions.name, null);
         parentModel.refreshLoadTime();
-      });
-    }
+      }
+      else {
+        throw(err);
+      }
+    });
 
     return needLoader;
   },

http://git-wip-us.apache.org/repos/asf/tez/blob/6b8e328f/tez-ui2/src/main/webapp/app/models/app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/app.js b/tez-ui2/src/main/webapp/app/models/app.js
index 6dcedd1..eabb61f 100644
--- a/tez-ui2/src/main/webapp/app/models/app.js
+++ b/tez-ui2/src/main/webapp/app/models/app.js
@@ -22,6 +22,14 @@ import DS from 'ember-data';
 import TimelineModel from './timeline';
 
 export default TimelineModel.extend({
+  needs:{
+    app: {
+      type: ["AhsApp", "appRm"],
+      idKey: "appID",
+      silent: true
+    }
+  },
+
   appID: Ember.computed("entityID", function () {
     return this.get("entityID").substr(4);
   }),

http://git-wip-us.apache.org/repos/asf/tez/blob/6b8e328f/tez-ui2/src/main/webapp/app/models/dag.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/dag.js b/tez-ui2/src/main/webapp/app/models/dag.js
index 7114a7c..8e7b523 100644
--- a/tez-ui2/src/main/webapp/app/models/dag.js
+++ b/tez-ui2/src/main/webapp/app/models/dag.js
@@ -38,6 +38,11 @@ export default AMTimelineModel.extend({
           app_id: model.get("appID")
         };
       }
+    },
+    app: {
+      type: ["AhsApp", "appRm"],
+      idKey: "appID",
+      silent: true
     }
   },
 

http://git-wip-us.apache.org/repos/asf/tez/blob/6b8e328f/tez-ui2/src/main/webapp/app/models/timeline.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/timeline.js b/tez-ui2/src/main/webapp/app/models/timeline.js
index ca82193..a739ec4 100644
--- a/tez-ui2/src/main/webapp/app/models/timeline.js
+++ b/tez-ui2/src/main/webapp/app/models/timeline.js
@@ -25,7 +25,7 @@ export default AbstractModel.extend({
 
   needs:{
     app: {
-      type: "AhsApp",
+      type: ["appRm", "AhsApp"],
       idKey: "appID",
       silent: true
     }

http://git-wip-us.apache.org/repos/asf/tez/blob/6b8e328f/tez-ui2/src/main/webapp/app/routes/am-pollster.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/am-pollster.js b/tez-ui2/src/main/webapp/app/routes/am-pollster.js
index 35d6611..e26c0aa 100644
--- a/tez-ui2/src/main/webapp/app/routes/am-pollster.js
+++ b/tez-ui2/src/main/webapp/app/routes/am-pollster.js
@@ -44,17 +44,22 @@ export default PollsterRoute.extend({
 
     this.get("loader").queryRecord("appRm", record.get("appID"), {reload: true}).then(function (appRm) {
       if(appRm.get('isComplete')) {
-        that.reload();
+        that.scheduleReload();
       }
       else {
         that.send("error", error);
       }
     }, function (error) {
       that.send("error", error);
-      Ember.run.later(that, "reload", that.get("polling.interval") * 3);
+      that.scheduleReload();
     });
   },
 
+  scheduleReload: function () {
+    this.set("polledRecords", null);
+    Ember.run.debounce(this, "reload", this.get("polling.interval") * 2);
+  },
+
   reload: function () {
     this.set("polledRecords", null);
     this.send("reload");

http://git-wip-us.apache.org/repos/asf/tez/blob/6b8e328f/tez-ui2/src/main/webapp/app/routes/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dags.js b/tez-ui2/src/main/webapp/app/routes/dags.js
index 4902460..ebbbe92 100644
--- a/tez-ui2/src/main/webapp/app/routes/dags.js
+++ b/tez-ui2/src/main/webapp/app/routes/dags.js
@@ -93,7 +93,9 @@ export default AbstractRoute.extend({
       records = that.filterRecords(records, query);
       records.forEach(function (record) {
         if(record.get("status") === "RUNNING") {
-          that.get("loader").loadNeed(record, "am", {reload: true});
+          that.get("loader").loadNeed(record, "am", {reload: true}).catch(function () {
+            record.set("am", null);
+          });
         }
       });
       return records;

http://git-wip-us.apache.org/repos/asf/tez/blob/6b8e328f/tez-ui2/src/main/webapp/app/templates/app/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/app/index.hbs b/tez-ui2/src/main/webapp/app/templates/app/index.hbs
index bf77bf1..2c04d2c 100644
--- a/tez-ui2/src/main/webapp/app/templates/app/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/app/index.hbs
@@ -35,11 +35,11 @@
       </tr>
       <tr>
         <td>Start Time</td>
-        <td>{{date-formatter content=model.startTime}}</td>
+        <td>{{date-formatter content=model.app.startTime}}</td>
       </tr>
       <tr>
         <td>End Time</td>
-        <td>{{date-formatter content=model.endTime}}</td>
+        <td>{{date-formatter content=model.app.endTime}}</td>
       </tr>
       <tr>
         <td>Duration</td>
@@ -87,8 +87,8 @@
     </thead>
     <tbody>
       <tr>
-        <td>Application ID</td>
-        <td>{{model.appID}}</td>
+        <td>Entity ID</td>
+        <td>{{model.entityID}}</td>
       </tr>
       <tr>
         <td>Domain</td>

http://git-wip-us.apache.org/repos/asf/tez/blob/6b8e328f/tez-ui2/src/main/webapp/tests/unit/entities/entity-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/entities/entity-test.js b/tez-ui2/src/main/webapp/tests/unit/entities/entity-test.js
index 9e2550d..3e1da55 100644
--- a/tez-ui2/src/main/webapp/tests/unit/entities/entity-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/entities/entity-test.js
@@ -167,3 +167,97 @@ test('loadAllNeeds silent=true test', function(assert) {
   });
 });
 
+test('_loadNeed single string type test', function(assert) {
+  let adapter = this.subject(),
+      loader,
+      testModel = Ember.Object.create({
+        refreshLoadTime: Ember.K,
+        needs: {
+          app: {
+            type: "appRm",
+            idKey: "appID",
+            silent: true
+          },
+        },
+        appID: 1,
+      });
+
+  assert.expect(2 + 1);
+
+  loader = {
+    queryRecord: function (type, id) {
+      assert.equal(id, testModel.get("appID"));
+      assert.equal(type, "appRm");
+      return Ember.RSVP.resolve();
+    }
+  };
+  adapter.loadAllNeeds(loader, testModel).then(function (val) {
+    assert.ok(val);
+  });
+});
+
+test('_loadNeed multiple type test', function(assert) {
+  let adapter = this.subject(),
+      loader,
+      testModel = Ember.Object.create({
+        refreshLoadTime: Ember.K,
+        needs: {
+          app: {
+            type: ["AhsApp", "appRm"],
+            idKey: "appID",
+            silent: true
+          },
+        },
+        appID: 1,
+      });
+
+  assert.expect(2 * 2 + 1);
+
+  loader = {
+    queryRecord: function (type, id) {
+      assert.equal(id, testModel.get("appID"));
+
+      if(type === "AhsApp") {
+        assert.ok(true);
+        return Ember.RSVP.reject();
+      }
+      else {
+        assert.equal(type, "appRm");
+        return Ember.RSVP.resolve();
+      }
+    }
+  };
+  adapter.loadAllNeeds(loader, testModel).then(function (val) {
+    assert.ok(val);
+  });
+});
+
+test('_loadNeed test with silent false', function(assert) {
+  let adapter = this.subject(),
+      loader,
+      testModel = Ember.Object.create({
+        refreshLoadTime: Ember.K,
+        needs: {
+          app: {
+            type: ["AhsApp"],
+            idKey: "appID",
+            silent: false
+          },
+        },
+        appID: 1,
+      }),
+      testErr = {};
+
+  assert.expect(2 + 1);
+
+  loader = {
+    queryRecord: function (type, id) {
+      assert.equal(id, testModel.get("appID"));
+      assert.equal(type, "AhsApp");
+      return Ember.RSVP.reject(testErr);
+    }
+  };
+  adapter.loadAllNeeds(loader, testModel).catch(function (err) {
+    assert.equal(err, testErr);
+  });
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/6b8e328f/tez-ui2/src/main/webapp/tests/unit/routes/am-pollster-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/am-pollster-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/am-pollster-test.js
index a5383ab..c736491 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/am-pollster-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/am-pollster-test.js
@@ -29,6 +29,7 @@ test('Basic creation test', function(assert) {
   assert.ok(route);
   assert.ok(route.onRecordPoll);
   assert.ok(route.onPollFailure);
+  assert.ok(route.scheduleReload);
   assert.ok(route.reload);
   assert.ok(route.actions.countersToPollChanged);
 });


[29/45] tez git commit: TEZ-3060. Tez UI 2: Activate auto-refresh (sree)

Posted by sr...@apache.org.
http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/models/task-am.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/task-am.js b/tez-ui2/src/main/webapp/app/models/task-am.js
new file mode 100644
index 0000000..55722b6
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/models/task-am.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 AMModel from './am';
+
+export default AMModel.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/models/task.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/task.js b/tez-ui2/src/main/webapp/app/models/task.js
index 2ded910..4db732e 100644
--- a/tez-ui2/src/main/webapp/app/models/task.js
+++ b/tez-ui2/src/main/webapp/app/models/task.js
@@ -19,39 +19,41 @@
 import Ember from 'ember';
 import DS from 'ember-data';
 
-import TimelineModel from './timeline';
-/*
-  Inherited properties
+import AMTimelineModel from './am-timeline';
 
-  entityID - String
-  appID - Computed from entityID
-
-  status - String
-  progress - Computed from status
-
-  startTime - Number
-  endTime - Number
-  duration - Computed from start & end times
-
-  counterGroups - Array
-  counterHash - Computed from counterGroups
-*/
-
-export default TimelineModel.extend({
+export default AMTimelineModel.extend({
   needs: {
     dag: {
       type: "dag",
       idKey: "dagID",
       silent: true
+    },
+    am: {
+      type: "taskAm",
+      idKey: "entityID",
+      loadType: "demand",
+      queryParams: function (model) {
+        var vertexIndex = parseInt(model.get("vertexIndex")),
+            taskIndex = parseInt(model.get("index"));
+        return {
+          taskID: `${vertexIndex}_${taskIndex}`,
+          dagID: parseInt(model.get("dag.index")),
+          counters: "*"
+        };
+      },
+      urlParams: function (model) {
+        return {
+          app_id: model.get("appID")
+        };
+      }
     }
   },
 
-  index: Ember.computed("entityID", function () {
-    var idParts = this.get("entityID").split("_");
-    return idParts.slice(Math.max(idParts.length - 2, 1)).join("_");
-  }),
-
   vertexID: DS.attr('string'),
+  vertexIndex: Ember.computed("vertexID", function () {
+    var id = this.get("vertexID") || "";
+    return id.substr(id.lastIndexOf('_') + 1);
+  }),
   vertexName: Ember.computed("vertexID", "dag", function () {
     var vertexID = this.get("vertexID");
     return this.get(`dag.vertexIdNameMap.${vertexID}`);

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/models/timeline.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/timeline.js b/tez-ui2/src/main/webapp/app/models/timeline.js
index cdd8d22..60157d3 100644
--- a/tez-ui2/src/main/webapp/app/models/timeline.js
+++ b/tez-ui2/src/main/webapp/app/models/timeline.js
@@ -31,7 +31,6 @@ export default AbstractModel.extend({
     }
   },
 
-  entityID: DS.attr("string"),
   appID: Ember.computed("entityID", function () {
     var idParts = this.get("entityID").split("_");
     return `application_${idParts[1]}_${idParts[2]}`;
@@ -39,7 +38,7 @@ export default AbstractModel.extend({
   app: DS.attr("object"), // Either RMApp or AHSApp
 
   atsStatus: DS.attr("string"),
-  status: Ember.computed("atsStatus", "app.status", function () {
+  status: Ember.computed("atsStatus", "app.status", "app.finalStatus", function () {
     var status = this.get("atsStatus"),
         yarnStatus = this.get("app.status");
 
@@ -53,6 +52,7 @@ export default AbstractModel.extend({
 
     return this.get("app.finalStatus");
   }),
+
   progress: Ember.computed("status", function () {
     return this.get("status") === "SUCCEEDED" ? 1 : null;
   }),
@@ -64,10 +64,11 @@ export default AbstractModel.extend({
     return duration > 0 ? duration : null;
   }),
 
-  counterGroups: DS.attr('object'),
-  counterHash: Ember.computed("counterGroups", function () {
+  // Hash will be created only on demand, till then counters will be stored in _counterGroups
+  _counterGroups: DS.attr('object'),
+  counterGroupsHash: Ember.computed("_counterGroups", function () {
     var counterHash = {},
-        counterGroups = this.get("counterGroups") || [];
+        counterGroups = this.get("_counterGroups") || [];
 
     counterGroups.forEach(function (group) {
       var counters = group.counters,

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/models/vertex-am.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/vertex-am.js b/tez-ui2/src/main/webapp/app/models/vertex-am.js
new file mode 100644
index 0000000..55722b6
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/models/vertex-am.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 AMModel from './am';
+
+export default AMModel.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/models/vertex.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/vertex.js b/tez-ui2/src/main/webapp/app/models/vertex.js
index 4192771..51e50b1 100644
--- a/tez-ui2/src/main/webapp/app/models/vertex.js
+++ b/tez-ui2/src/main/webapp/app/models/vertex.js
@@ -19,30 +19,31 @@
 import Ember from 'ember';
 import DS from 'ember-data';
 
-import TimelineModel from './timeline';
-/*
-  Inherited properties
+import AMTimelineModel from './am-timeline';
 
-  entityID - String
-  appID - Computed from entityID
-
-  status - String
-  progress - Computed from status
-
-  startTime - Number
-  endTime - Number
-  duration - Computed from start & end times
-
-  counterGroups - Array
-  counterHash - Computed from counterGroups
-*/
-
-export default TimelineModel.extend({
+export default AMTimelineModel.extend({
   needs: {
     dag: {
       type: "dag",
       idKey: "dagID",
       silent: true
+    },
+    am: {
+      type: "vertexAm",
+      idKey: "entityID",
+      loadType: "demand",
+      queryParams: function (model) {
+        return {
+          vertexID: parseInt(model.get("index")),
+          dagID: parseInt(model.get("dag.index")),
+          counters: "*"
+        };
+      },
+      urlParams: function (model) {
+        return {
+          app_id: model.get("appID")
+        };
+      }
     }
   },
 

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/router.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/router.js b/tez-ui2/src/main/webapp/app/router.js
index 4e8cb0b..db26954 100644
--- a/tez-ui2/src/main/webapp/app/router.js
+++ b/tez-ui2/src/main/webapp/app/router.js
@@ -47,6 +47,8 @@ Router.map(function() {
     this.route('dags');
     this.route('configs');
   });
+  this.route('multi-am-pollster');
+  this.route('single-am-pollster');
 });
 
 export default Router;

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/routes/abstract.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/abstract.js b/tez-ui2/src/main/webapp/app/routes/abstract.js
index c3efc18..923ac96 100644
--- a/tez-ui2/src/main/webapp/app/routes/abstract.js
+++ b/tez-ui2/src/main/webapp/app/routes/abstract.js
@@ -68,7 +68,7 @@ export default Ember.Route.extend(NameMixin, {
   },
 
   setDocTitle: function () {
-    Ember.$(document).attr('title', this.get('title'));
+    Ember.$(document).attr('title', "Tez UI : " + this.get('title'));
   },
 
   setupController: function (controller, model) {
@@ -171,6 +171,9 @@ export default Ember.Route.extend(NameMixin, {
     },
     reload: function () {
       Ember.run.later(this, "loadData", {reload: true});
-    }
+    },
+    willTransition: function () {
+      this.set("loadedValue", null);
+    },
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/routes/am-pollster.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/am-pollster.js b/tez-ui2/src/main/webapp/app/routes/am-pollster.js
new file mode 100644
index 0000000..5907a91
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/am-pollster.js
@@ -0,0 +1,88 @@
+/*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 PollsterRoute from './pollster';
+
+var MoreObject = more.Object;
+
+export default PollsterRoute.extend({
+
+  countersToPoll: null,
+
+  onRecordPoll: function (record) {
+    var query = {},
+        countersToPoll = this.get("countersToPoll");
+
+    if(countersToPoll !== null) {
+      query.counters = countersToPoll;
+    }
+
+    return this.get("loader").loadNeed(record, "am", {reload: true}, query);
+  },
+
+  onPollFailure: function (error) {
+    var that = this,
+        record = this.get("polledRecords.0");
+
+    this.get("loader").queryRecord("appRm", record.get("appID"), {reload: true}).then(function (appRm) {
+      if(appRm.get('isComplete')) {
+        that.reload();
+      }
+      else {
+        error.message = "Application Master (AM) is out of reach. Either it's down, or CORS is not enabled for YARN ResourceManager.";
+        that.send("error", error);
+      }
+    }, function (error) {
+      error.message = "Resource Manager (RM) is out of reach. Either it's down, or CORS is not enabled.";
+      that.send("error", error);
+      that.reload();
+    });
+  },
+
+  reload: function () {
+    this.set("polledRecords", null);
+    this.send("reload");
+  },
+
+  actions: {
+    countersToPollChanged: function (counterColumnDefinitions) {
+      var counterGroupHash = {},
+          counterGroups = [];
+
+      if(counterColumnDefinitions){
+        counterColumnDefinitions.forEach(function (definition) {
+          var counterGroupName = definition.get("counterGroupName"),
+              counterNames = counterGroupHash[counterGroupName];
+          if(!counterNames) {
+            counterNames = counterGroupHash[counterGroupName] = [];
+          }
+          counterNames.push(definition.get("counterName"));
+        });
+
+        MoreObject.forEach(counterGroupHash, function (groupName, counters) {
+          counters = counters.join(",");
+          counterGroups.push(`${groupName}/${counters}`);
+        });
+      }
+
+      this.set("countersToPoll", counterGroups.join(";"));
+    }
+  }
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/routes/app/configs.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/app/configs.js b/tez-ui2/src/main/webapp/app/routes/app/configs.js
index 825bdad..bdd53ae 100644
--- a/tez-ui2/src/main/webapp/app/routes/app/configs.js
+++ b/tez-ui2/src/main/webapp/app/routes/app/configs.js
@@ -17,13 +17,15 @@
  */
 
 import Ember from 'ember';
-import AbstractRoute from '../abstract';
+import SingleAmPollsterRoute from '../single-am-pollster';
 
-export default AbstractRoute.extend({
+export default SingleAmPollsterRoute.extend({
   title: "Application Details",
 
   loaderNamespace: "app",
 
+  canPoll: false,
+
   setupController: function (controller, model) {
     this._super(controller, model);
     Ember.run.later(this, "startCrumbBubble");

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/routes/app/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/app/dags.js b/tez-ui2/src/main/webapp/app/routes/app/dags.js
index 80643c0..8264299 100644
--- a/tez-ui2/src/main/webapp/app/routes/app/dags.js
+++ b/tez-ui2/src/main/webapp/app/routes/app/dags.js
@@ -17,9 +17,9 @@
  */
 
 import Ember from 'ember';
-import AbstractRoute from '../abstract';
+import MultiAmPollsterRoute from '../multi-am-pollster';
 
-export default AbstractRoute.extend({
+export default MultiAmPollsterRoute.extend({
   title: "DAGs",
 
   loaderNamespace: "app",

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/routes/app/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/app/index.js b/tez-ui2/src/main/webapp/app/routes/app/index.js
index 825bdad..7df42e5 100644
--- a/tez-ui2/src/main/webapp/app/routes/app/index.js
+++ b/tez-ui2/src/main/webapp/app/routes/app/index.js
@@ -17,9 +17,9 @@
  */
 
 import Ember from 'ember';
-import AbstractRoute from '../abstract';
+import SingleAmPollsterRoute from '../single-am-pollster';
 
-export default AbstractRoute.extend({
+export default SingleAmPollsterRoute.extend({
   title: "Application Details",
 
   loaderNamespace: "app",
@@ -29,6 +29,10 @@ export default AbstractRoute.extend({
     Ember.run.later(this, "startCrumbBubble");
   },
 
+  onRecordPoll: function () {
+    this.reload();
+  },
+
   load: function (value, query, options) {
     return this.get("loader").queryRecord('app', this.modelFor("app").get("id"), options);
   },

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/routes/application.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/application.js b/tez-ui2/src/main/webapp/app/routes/application.js
index 998cce4..121eda2 100644
--- a/tez-ui2/src/main/webapp/app/routes/application.js
+++ b/tez-ui2/src/main/webapp/app/routes/application.js
@@ -37,6 +37,11 @@ export default Ember.Route.extend({
       this.set("controller.breadcrumbs", breadcrumbs);
     },
 
+    error: function (error) {
+      // Display error bar
+      Ember.Logger.error(error);
+    },
+
     // Modal window actions
     openModal: function (componentName, options) {
       options = options || {};

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/routes/attempt.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/attempt.js b/tez-ui2/src/main/webapp/app/routes/attempt.js
index ff9d4fb..4a1ac20 100644
--- a/tez-ui2/src/main/webapp/app/routes/attempt.js
+++ b/tez-ui2/src/main/webapp/app/routes/attempt.js
@@ -19,7 +19,7 @@
 import AbstractRoute from './abstract';
 
 export default AbstractRoute.extend({
-  title: "Vertex",
+  title: "Attempt",
 
   loaderQueryParams: {
     id: "attempt_id"

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/routes/attempt/counters.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/attempt/counters.js b/tez-ui2/src/main/webapp/app/routes/attempt/counters.js
index e63e6ab..add4ce5 100644
--- a/tez-ui2/src/main/webapp/app/routes/attempt/counters.js
+++ b/tez-ui2/src/main/webapp/app/routes/attempt/counters.js
@@ -17,9 +17,9 @@
  */
 
 import Ember from 'ember';
-import AbstractRoute from '../abstract';
+import SingleAmPollsterRoute from '../single-am-pollster';
 
-export default AbstractRoute.extend({
+export default SingleAmPollsterRoute.extend({
   title: "DAG Details",
 
   loaderNamespace: "attempt",

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/routes/attempt/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/attempt/index.js b/tez-ui2/src/main/webapp/app/routes/attempt/index.js
index e63e6ab..add4ce5 100644
--- a/tez-ui2/src/main/webapp/app/routes/attempt/index.js
+++ b/tez-ui2/src/main/webapp/app/routes/attempt/index.js
@@ -17,9 +17,9 @@
  */
 
 import Ember from 'ember';
-import AbstractRoute from '../abstract';
+import SingleAmPollsterRoute from '../single-am-pollster';
 
-export default AbstractRoute.extend({
+export default SingleAmPollsterRoute.extend({
   title: "DAG Details",
 
   loaderNamespace: "attempt",

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/routes/dag/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag/attempts.js b/tez-ui2/src/main/webapp/app/routes/dag/attempts.js
index c8c897a..167c10e 100644
--- a/tez-ui2/src/main/webapp/app/routes/dag/attempts.js
+++ b/tez-ui2/src/main/webapp/app/routes/dag/attempts.js
@@ -17,9 +17,9 @@
  */
 
 import Ember from 'ember';
-import AbstractRoute from '../abstract';
+import MultiAmPollsterRoute from '../multi-am-pollster';
 
-export default AbstractRoute.extend({
+export default MultiAmPollsterRoute.extend({
   title: "All Task Attempts",
 
   loaderNamespace: "dag",

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/routes/dag/counters.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag/counters.js b/tez-ui2/src/main/webapp/app/routes/dag/counters.js
index 51b3fc5..be60c1d 100644
--- a/tez-ui2/src/main/webapp/app/routes/dag/counters.js
+++ b/tez-ui2/src/main/webapp/app/routes/dag/counters.js
@@ -17,9 +17,9 @@
  */
 
 import Ember from 'ember';
-import AbstractRoute from '../abstract';
+import SingleAmPollsterRoute from '../single-am-pollster';
 
-export default AbstractRoute.extend({
+export default SingleAmPollsterRoute.extend({
   title: "DAG Details",
 
   loaderNamespace: "dag",

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/routes/dag/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag/index.js b/tez-ui2/src/main/webapp/app/routes/dag/index.js
index 51b3fc5..be60c1d 100644
--- a/tez-ui2/src/main/webapp/app/routes/dag/index.js
+++ b/tez-ui2/src/main/webapp/app/routes/dag/index.js
@@ -17,9 +17,9 @@
  */
 
 import Ember from 'ember';
-import AbstractRoute from '../abstract';
+import SingleAmPollsterRoute from '../single-am-pollster';
 
-export default AbstractRoute.extend({
+export default SingleAmPollsterRoute.extend({
   title: "DAG Details",
 
   loaderNamespace: "dag",

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/routes/dag/tasks.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag/tasks.js b/tez-ui2/src/main/webapp/app/routes/dag/tasks.js
index 859a712..744913d 100644
--- a/tez-ui2/src/main/webapp/app/routes/dag/tasks.js
+++ b/tez-ui2/src/main/webapp/app/routes/dag/tasks.js
@@ -17,9 +17,9 @@
  */
 
 import Ember from 'ember';
-import AbstractRoute from '../abstract';
+import MultiAmPollsterRoute from '../multi-am-pollster';
 
-export default AbstractRoute.extend({
+export default MultiAmPollsterRoute.extend({
   title: "All Tasks",
 
   loaderNamespace: "dag",

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/routes/dag/vertices.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag/vertices.js b/tez-ui2/src/main/webapp/app/routes/dag/vertices.js
index 063f2cc..0b7d63b 100644
--- a/tez-ui2/src/main/webapp/app/routes/dag/vertices.js
+++ b/tez-ui2/src/main/webapp/app/routes/dag/vertices.js
@@ -17,9 +17,9 @@
  */
 
 import Ember from 'ember';
-import AbstractRoute from '../abstract';
+import MultiAmPollsterRoute from '../multi-am-pollster';
 
-export default AbstractRoute.extend({
+export default MultiAmPollsterRoute.extend({
   title: "All Vertices",
 
   loaderNamespace: "dag",

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/routes/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dags.js b/tez-ui2/src/main/webapp/app/routes/dags.js
index 5fab777..45fd25d 100644
--- a/tez-ui2/src/main/webapp/app/routes/dags.js
+++ b/tez-ui2/src/main/webapp/app/routes/dags.js
@@ -75,18 +75,18 @@ export default AbstractRoute.extend({
     });
   },
 
-  load: function (value, query, options) {
+  load: function (value, query/*, options*/) {
     var loader,
         that = this;
 
     if(query.dagID) {
       that.set("loadedRecords", []);
-      loader = this.get("loader").queryRecord('dag', query.dagID, options).then(function (record) {
+      loader = this.get("loader").queryRecord('dag', query.dagID, {reload: true}).then(function (record) {
         return [record];
       });
     }
     else {
-      loader = this.get("loader").query('dag', query, options);
+      loader = this.get("loader").query('dag', query, {reload: true});
     }
 
     return loader.then(function (records) {

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/routes/multi-am-pollster.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/multi-am-pollster.js b/tez-ui2/src/main/webapp/app/routes/multi-am-pollster.js
new file mode 100644
index 0000000..c3260a6
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/multi-am-pollster.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 AmPollsterRoute from './am-pollster';
+
+export default AmPollsterRoute.extend({
+
+  canPoll: Ember.computed("polledRecords.0.app.isComplete", "loadedValue", function () {
+    var isComplete = this.get("polledRecords.0.app.isComplete");
+    return isComplete === false && this._super();
+  }),
+
+  actions: {
+    setPollingRecords: function (records) {
+      this.set("polledRecords", records);
+    }
+  }
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/routes/pollster.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/pollster.js b/tez-ui2/src/main/webapp/app/routes/pollster.js
new file mode 100644
index 0000000..5a7af16
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/pollster.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 Ember from 'ember';
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+  polling: Ember.inject.service("pollster"),
+
+  polledRecords: null,
+
+  // Must be implemented by inheriting classes
+  onRecordPoll: Ember.K,
+  onPollSuccess: Ember.K,
+  onPollFailure: Ember.K,
+
+  pollData: function () {
+    var polledRecords = this.get("polledRecords");
+
+    if(!this.get("isLoading") && polledRecords) {
+      polledRecords = polledRecords.map(this.onRecordPoll.bind(this));
+      return Ember.RSVP.all(polledRecords).then(
+        this.onPollSuccess.bind(this),
+        this.onPollFailure.bind(this)
+      );
+    }
+    return Ember.RSVP.reject();
+  },
+
+  canPoll: Ember.computed("polledRecords", "loadedValue", function () {
+    return this.get("polledRecords") && this.get("loadedValue");
+  }),
+
+  _canPollInit: Ember.on("init", function () {
+    // This sets a flag that ensures that the _canPollObserver is called whenever
+    // canPoll changes. By default observers on un-used computed properties
+    // are not called.
+    this.get("canPoll");
+  }),
+
+  _canPollObserver: Ember.observer("canPoll", function () {
+    if(this.get("canPoll")) {
+      this.get("polling").setPoll(this.pollData, this);
+    }
+    else {
+      this.get("polling").resetPoll();
+    }
+  }),
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/routes/single-am-pollster.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/single-am-pollster.js b/tez-ui2/src/main/webapp/app/routes/single-am-pollster.js
new file mode 100644
index 0000000..4a0d507
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/single-am-pollster.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 AmPollsterRoute from './am-pollster';
+
+export default AmPollsterRoute.extend({
+
+  canPoll: Ember.computed("polledRecords", "loadedValue.app.isComplete", function () {
+    var isComplete = this.get("loadedValue.app.isComplete");
+    return isComplete === false && this._super();
+  }),
+
+  _loadedValueObserver: Ember.observer("loadedValue", function () {
+    var loadedValue = this.get("loadedValue");
+    this.set("polledRecords", loadedValue ? [this.get("loadedValue")] : null);
+  })
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/routes/task.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/task.js b/tez-ui2/src/main/webapp/app/routes/task.js
index 835243f..42d9715 100644
--- a/tez-ui2/src/main/webapp/app/routes/task.js
+++ b/tez-ui2/src/main/webapp/app/routes/task.js
@@ -19,7 +19,7 @@
 import AbstractRoute from './abstract';
 
 export default AbstractRoute.extend({
-  title: "Vertex",
+  title: "Task",
 
   loaderQueryParams: {
     id: "task_id"

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/routes/task/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/task/attempts.js b/tez-ui2/src/main/webapp/app/routes/task/attempts.js
index 3a0bc18..536d085 100644
--- a/tez-ui2/src/main/webapp/app/routes/task/attempts.js
+++ b/tez-ui2/src/main/webapp/app/routes/task/attempts.js
@@ -17,9 +17,9 @@
  */
 
 import Ember from 'ember';
-import AbstractRoute from '../abstract';
+import MultiAmPollsterRoute from '../multi-am-pollster';
 
-export default AbstractRoute.extend({
+export default MultiAmPollsterRoute.extend({
   title: "Task Attempts",
 
   loaderNamespace: "task",

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/routes/task/counters.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/task/counters.js b/tez-ui2/src/main/webapp/app/routes/task/counters.js
index a2d5d33..086e0cc 100644
--- a/tez-ui2/src/main/webapp/app/routes/task/counters.js
+++ b/tez-ui2/src/main/webapp/app/routes/task/counters.js
@@ -17,9 +17,9 @@
  */
 
 import Ember from 'ember';
-import AbstractRoute from '../abstract';
+import SingleAmPollsterRoute from '../single-am-pollster';
 
-export default AbstractRoute.extend({
+export default SingleAmPollsterRoute.extend({
   title: "DAG Details",
 
   loaderNamespace: "task",

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/routes/task/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/task/index.js b/tez-ui2/src/main/webapp/app/routes/task/index.js
index a2d5d33..086e0cc 100644
--- a/tez-ui2/src/main/webapp/app/routes/task/index.js
+++ b/tez-ui2/src/main/webapp/app/routes/task/index.js
@@ -17,9 +17,9 @@
  */
 
 import Ember from 'ember';
-import AbstractRoute from '../abstract';
+import SingleAmPollsterRoute from '../single-am-pollster';
 
-export default AbstractRoute.extend({
+export default SingleAmPollsterRoute.extend({
   title: "DAG Details",
 
   loaderNamespace: "task",

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/routes/vertex/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/vertex/attempts.js b/tez-ui2/src/main/webapp/app/routes/vertex/attempts.js
index aa0a83d..b0b33b2 100644
--- a/tez-ui2/src/main/webapp/app/routes/vertex/attempts.js
+++ b/tez-ui2/src/main/webapp/app/routes/vertex/attempts.js
@@ -17,9 +17,9 @@
  */
 
 import Ember from 'ember';
-import AbstractRoute from '../abstract';
+import MultiAmPollsterRoute from '../multi-am-pollster';
 
-export default AbstractRoute.extend({
+export default MultiAmPollsterRoute.extend({
   title: "Task Attempts",
 
   loaderNamespace: "vertex",

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/routes/vertex/counters.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/vertex/counters.js b/tez-ui2/src/main/webapp/app/routes/vertex/counters.js
index bb5a9ce..d7cae37 100644
--- a/tez-ui2/src/main/webapp/app/routes/vertex/counters.js
+++ b/tez-ui2/src/main/webapp/app/routes/vertex/counters.js
@@ -17,9 +17,9 @@
  */
 
 import Ember from 'ember';
-import AbstractRoute from '../abstract';
+import SingleAmPollsterRoute from '../single-am-pollster';
 
-export default AbstractRoute.extend({
+export default SingleAmPollsterRoute.extend({
   title: "DAG Details",
 
   loaderNamespace: "vertex",

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/routes/vertex/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/vertex/index.js b/tez-ui2/src/main/webapp/app/routes/vertex/index.js
index bb5a9ce..d7cae37 100644
--- a/tez-ui2/src/main/webapp/app/routes/vertex/index.js
+++ b/tez-ui2/src/main/webapp/app/routes/vertex/index.js
@@ -17,9 +17,9 @@
  */
 
 import Ember from 'ember';
-import AbstractRoute from '../abstract';
+import SingleAmPollsterRoute from '../single-am-pollster';
 
-export default AbstractRoute.extend({
+export default SingleAmPollsterRoute.extend({
   title: "DAG Details",
 
   loaderNamespace: "vertex",

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/routes/vertex/tasks.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/vertex/tasks.js b/tez-ui2/src/main/webapp/app/routes/vertex/tasks.js
index f392343..25e0f4b 100644
--- a/tez-ui2/src/main/webapp/app/routes/vertex/tasks.js
+++ b/tez-ui2/src/main/webapp/app/routes/vertex/tasks.js
@@ -17,9 +17,9 @@
  */
 
 import Ember from 'ember';
-import AbstractRoute from '../abstract';
+import MultiAmPollsterRoute from '../multi-am-pollster';
 
-export default AbstractRoute.extend({
+export default MultiAmPollsterRoute.extend({
   title: "All Tasks",
 
   loaderNamespace: "vertex",

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/serializers/am.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/am.js b/tez-ui2/src/main/webapp/app/serializers/am.js
new file mode 100644
index 0000000..f9c5848
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/serializers/am.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 LoaderSerializer from './loader';
+
+export default LoaderSerializer.extend({
+  primaryKey: 'id',
+
+  payloadNamespace: null, // Must be set by inheriting classes
+
+  extractSinglePayload: function (rawPayload) {
+    return rawPayload[this.get("payloadNamespace")][0];
+  },
+  extractArrayPayload: function(rawPayload) {
+    return rawPayload[this.get("payloadNamespace")];
+  },
+
+  maps: {
+    entityID: 'id',
+
+    status: 'status',
+    progress: 'progress',
+
+    counterGroupsHash: 'counters'
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/serializers/app-rm.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/app-rm.js b/tez-ui2/src/main/webapp/app/serializers/app-rm.js
new file mode 100644
index 0000000..37166c3
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/serializers/app-rm.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';
+
+import RMSerializer from './rm';
+
+export default RMSerializer.extend({
+
+  extractSinglePayload: function (rawPayload) {
+    return Ember.get(rawPayload, "app");
+  },
+
+  extractArrayPayload: function(rawPayload) {
+    return Ember.get(rawPayload, "apps.app");
+  },
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/serializers/attempt-am.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/attempt-am.js b/tez-ui2/src/main/webapp/app/serializers/attempt-am.js
new file mode 100644
index 0000000..277a0d5
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/serializers/attempt-am.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.
+ */
+
+import AMSerializer from './am';
+
+export default AMSerializer.extend({
+  payloadNamespace: "attempts"
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/serializers/dag-am.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/dag-am.js b/tez-ui2/src/main/webapp/app/serializers/dag-am.js
new file mode 100644
index 0000000..510d6f1
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/serializers/dag-am.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 AMSerializer from './am';
+
+export default AMSerializer.extend({
+  extractSinglePayload: function (rawPayload) {
+    return rawPayload.dag;
+  },
+  extractArrayPayload: function(rawPayload) {
+    return rawPayload.dag;
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/serializers/loader.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/loader.js b/tez-ui2/src/main/webapp/app/serializers/loader.js
index 82899f6..102f4e9 100644
--- a/tez-ui2/src/main/webapp/app/serializers/loader.js
+++ b/tez-ui2/src/main/webapp/app/serializers/loader.js
@@ -42,6 +42,7 @@ function mapObject(hash, map) {
 export default DS.JSONSerializer.extend({
   _isLoader: true,
 
+  mergedProperties: ["maps"],
   maps: null,
 
   extractId: function (modelClass, resourceHash) {

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/serializers/rm.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/rm.js b/tez-ui2/src/main/webapp/app/serializers/rm.js
new file mode 100644
index 0000000..fbb91c3
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/serializers/rm.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 LoaderSerializer from './loader';
+
+export default LoaderSerializer.extend({
+  primaryKey: 'id',
+
+  maps: {
+    entityID: 'id',
+    status: 'state',
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/serializers/task-am.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/task-am.js b/tez-ui2/src/main/webapp/app/serializers/task-am.js
new file mode 100644
index 0000000..129f5e0
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/serializers/task-am.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.
+ */
+
+import AMSerializer from './am';
+
+export default AMSerializer.extend({
+  payloadNamespace: "tasks"
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/serializers/timeline.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/timeline.js b/tez-ui2/src/main/webapp/app/serializers/timeline.js
index 7e20317..2f6a0d5 100644
--- a/tez-ui2/src/main/webapp/app/serializers/timeline.js
+++ b/tez-ui2/src/main/webapp/app/serializers/timeline.js
@@ -21,8 +21,6 @@ import LoaderSerializer from './loader';
 export default LoaderSerializer.extend({
   primaryKey: 'entity',
 
-  mergedProperties: ["maps"],
-
   extractArrayPayload: function (payload) {
     return payload.entities;
   },
@@ -35,6 +33,6 @@ export default LoaderSerializer.extend({
     startTime: 'otherinfo.startTime',
     endTime: 'otherinfo.endTime',
 
-    counterGroups: 'otherinfo.counters.counterGroups'
+    _counterGroups: 'otherinfo.counters.counterGroups'
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/serializers/vertex-am.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/vertex-am.js b/tez-ui2/src/main/webapp/app/serializers/vertex-am.js
new file mode 100644
index 0000000..163cf5c
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/serializers/vertex-am.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.
+ */
+
+import AMSerializer from './am';
+
+export default AMSerializer.extend({
+  payloadNamespace: "vertices"
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/services/hosts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/services/hosts.js b/tez-ui2/src/main/webapp/app/services/hosts.js
index a3dc1f3..0da7fe5 100644
--- a/tez-ui2/src/main/webapp/app/services/hosts.js
+++ b/tez-ui2/src/main/webapp/app/services/hosts.js
@@ -63,4 +63,8 @@ export default Ember.Service.extend({
     return this.normalizeURL(this.get("env.app.hosts.rm"));
   }),
 
+  am: Ember.computed(function () {
+    return this.normalizeURL(this.get("env.app.hosts.rm"));
+  }),
+
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/services/loader.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/services/loader.js b/tez-ui2/src/main/webapp/app/services/loader.js
index 92758e3..0fd44d2 100644
--- a/tez-ui2/src/main/webapp/app/services/loader.js
+++ b/tez-ui2/src/main/webapp/app/services/loader.js
@@ -54,17 +54,17 @@ export default Ember.Service.extend({
     );
   },
 
-  lookup: function (type, name) {
+  lookup: function (type, name, options) {
     name = Ember.String.dasherize(name);
-    return this.get("container").lookup(type + ":" + name);
+    return this.get("container").lookup(type + ":" + name, options);
   },
 
   entityFor: function (entityName) {
     var entity = this.lookup("entitie", entityName);
     if(!entity) {
-      entity = this.lookup("entitie", "entity");
+      entity = this.lookup("entitie", "entity", { singleton: false });
+      entity.set("name", entityName);
     }
-    entity.name = entityName;
     return entity;
   },
 
@@ -78,68 +78,61 @@ export default Ember.Service.extend({
       parts.push(JSON.stringify(query));
     }
 
-    return parts.join(":");
+    return parts.join(":").replace(/\./g, ":");
+  },
+
+  loadNeed: function (record, needName, options, queryParams, urlParams) {
+    var entity = this.entityFor(record.get("constructor.modelName"));
+    return entity.loadNeed(this, record, needName, options, queryParams, urlParams);
+  },
+
+  normalizeOptions: function (options) {
+    options = options || {};
+
+    if(!options.cache){
+      options = Ember.$.extend({}, options);
+      options.cache = options.reload ? Ember.Object.create() : this.get("cache");
+    }
+
+    return options;
   },
 
   queryRecord: function(type, id, options, query, urlParams) {
     var entity = this.entityFor(type),
-        cache = this.get("cache"),
         cacheKey = this.getCacheKey(type, query, id),
-        that = this,
         record;
 
     this.checkRequisite(type);
 
-    options = options || {};
-    if(!options.reload) {
-      record = cache.get(cacheKey);
-      if(record) {
-        return record;
-      }
+    options = this.normalizeOptions(options);
+
+    record = options.cache.get(cacheKey);
+    if(record) {
+      return record;
     }
 
-    record = this.get('store').queryRecord(type, {
-      id: id,
-      nameSpace: this.get('nameSpace'),
-      params: query,
-      urlParams: urlParams
-    }).then(function (record) {
-      return entity.loadRelations(that, record, options, urlParams);
-    });
+    record = entity.queryRecord(this, id, options, query, urlParams);
+    options.cache.set(cacheKey, record);
 
-    cache.set(cacheKey, record);
     return record;
   },
   query: function(type, query, options, urlParams) {
     var entity = this.entityFor(type),
-        cache = this.get("cache"),
         cacheKey = this.getCacheKey(type, query),
-        that = this,
         records;
 
     this.checkRequisite(type);
 
-    options = options || {};
-    if(!options.reload) {
-      records = cache.get(cacheKey);
-      if(records) {
-        return records;
-      }
+    options = this.normalizeOptions(options);
+
+    records = options.cache.get(cacheKey);
+    if(records) {
+      return records;
     }
 
-    records = this.get('store').query(type, {
-      nameSpace: this.get('nameSpace'),
-      params: query,
-      urlParams: urlParams
-    }).then(function (records) {
-      return Ember.RSVP.all(records.map(function (record) {
-        return entity.loadRelations(that, record, options, urlParams);
-      })).then(function () {
-       return records;
-      });
-    });
-
-    cache.set(cacheKey, records);
+    records = entity.query(this, query, options, urlParams);
+    options.cache.set(cacheKey, records);
+
     return records;
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/services/pollster.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/services/pollster.js b/tez-ui2/src/main/webapp/app/services/pollster.js
new file mode 100644
index 0000000..8e76bc9
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/services/pollster.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.
+ */
+
+import Ember from 'ember';
+
+const STATE_STORAGE_KEY = "pollingIsActive";
+
+export default Ember.Service.extend({
+  localStorage: Ember.inject.service("localStorage"),
+  env: Ember.inject.service("env"),
+
+  interval: Ember.computed.oneWay("env.app.pollingInterval"),
+
+  active: false,
+  isPolling: false,
+  scheduleID: null,
+
+  poll: null,
+  pollContext: null,
+
+  initState: Ember.on("init", function () {
+    Ember.run.later(this, function () {
+      this.set("active", this.get("localStorage").get(STATE_STORAGE_KEY));
+    });
+  }),
+  stateObserver: Ember.observer("active", function () {
+    this.get("localStorage").set(STATE_STORAGE_KEY, this.get("active"));
+    this.callPoll();
+  }),
+
+  isReady: Ember.computed("active", "poll", function () {
+    return this.get("active") && this.get("poll");
+  }),
+
+  callPoll: function () {
+    var that = this;
+    this.unSchedulePoll();
+    if(this.get("isReady") && !this.get("isPolling")) {
+      this.set("isPolling", true);
+      this.get("poll").call(this.get("pollContext")).finally(function () {
+        that.set("isPolling", false);
+        that.schedulePoll();
+      });
+    }
+  },
+
+  schedulePoll: function () {
+    this.set("scheduleID", setTimeout(this.callPoll.bind(this), this.get("interval")));
+  },
+  unSchedulePoll: function () {
+    clearTimeout(this.get("scheduleID"));
+  },
+
+  setPoll: function (pollFunction, context) {
+    this.setProperties({
+      pollContext: context,
+      poll: pollFunction,
+    });
+    this.callPoll();
+  },
+  resetPoll: function () {
+    this.unSchedulePoll();
+    this.setProperties({
+      poll: null,
+      pollContext: null
+    });
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/templates/app.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/app.hbs b/tez-ui2/src/main/webapp/app/templates/app.hbs
index 80ec4f4..8906371 100644
--- a/tez-ui2/src/main/webapp/app/templates/app.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/app.hbs
@@ -16,5 +16,5 @@
  * limitations under the License.
 }}
 
-{{tab-n-refresh tabs=tabs loadTime=loadTime}}
+{{tab-n-refresh tabs=tabs loadTime=loadTime autoRefreshEnabled=polling.active}}
 {{outlet}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/templates/app/dags.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/app/dags.hbs b/tez-ui2/src/main/webapp/app/templates/app/dags.hbs
index 57cfe86..d36678a 100644
--- a/tez-ui2/src/main/webapp/app/templates/app/dags.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/app/dags.hbs
@@ -27,8 +27,10 @@
 
     searchAction="searchChanged"
     sortAction="sortChanged"
-    rowAction="rowsChanged"
+    rowAction="rowCountChanged"
     pageAction="pageChanged"
+
+    rowsChanged="rowsChanged"
   }}
 {{else}}
   {{partial "loading"}}

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/templates/attempt.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/attempt.hbs b/tez-ui2/src/main/webapp/app/templates/attempt.hbs
index 80ec4f4..8906371 100644
--- a/tez-ui2/src/main/webapp/app/templates/attempt.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/attempt.hbs
@@ -16,5 +16,5 @@
  * limitations under the License.
 }}
 
-{{tab-n-refresh tabs=tabs loadTime=loadTime}}
+{{tab-n-refresh tabs=tabs loadTime=loadTime autoRefreshEnabled=polling.active}}
 {{outlet}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/templates/attempt/counters.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/attempt/counters.hbs b/tez-ui2/src/main/webapp/app/templates/attempt/counters.hbs
index aa4c127..649cfe2 100644
--- a/tez-ui2/src/main/webapp/app/templates/attempt/counters.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/attempt/counters.hbs
@@ -21,7 +21,7 @@
   columns=columns
   rows=counters
 
-  rowCount=counters.length
+  rowCount=countersCount
   definition=definition
 
   enablePagination=false

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs b/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs
index 9edaacd..1d77e25 100644
--- a/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs
@@ -42,9 +42,11 @@
       </tr>
       <tr>
         <td>Status</td>
-        <td>
-          {{em-table-status-cell content=model.status}}
-        </td>
+        <td>{{em-table-status-cell content=model.status}}</td>
+      </tr>
+      <tr>
+        <td>Progress</td>
+        <td>{{em-table-progress-cell content=model.progress}}</td>
       </tr>
       <tr>
         <td>Start Time</td>

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs b/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs
index 9b6a594..9d80c6a 100644
--- a/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs
@@ -26,13 +26,13 @@
   {{/each}}
   <span class="refresh-ui">
     <span class="text-elements">
-      <span class="auto-refresh {{unless autoRefreshEnabled 'no-visible'}}">
-        {{input type="checkbox" name="autoEnabled" checked=autoEnabled}}
+      <span class="auto-refresh {{unless autoRefreshVisible 'no-visible'}}">
+        {{input type="checkbox" name="autoEnabled" checked=autoRefreshEnabled}}
         Auto Refresh
         <br/>
       </span>
       {{#if loadTime}}
-        Last refreshed at <b>{{txt loadTime type="date" format="DD MMM YYYY HH:mm:ss"}}</b>
+        Last refreshed at <b>{{txt loadTime type="date"}}</b>
       {{else}}
         Load time not available!
       {{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/templates/dag.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag.hbs b/tez-ui2/src/main/webapp/app/templates/dag.hbs
index 80ec4f4..8906371 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag.hbs
@@ -16,5 +16,5 @@
  * limitations under the License.
 }}
 
-{{tab-n-refresh tabs=tabs loadTime=loadTime}}
+{{tab-n-refresh tabs=tabs loadTime=loadTime autoRefreshEnabled=polling.active}}
 {{outlet}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/templates/dag/attempts.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/attempts.hbs b/tez-ui2/src/main/webapp/app/templates/dag/attempts.hbs
index 57cfe86..d36678a 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag/attempts.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag/attempts.hbs
@@ -27,8 +27,10 @@
 
     searchAction="searchChanged"
     sortAction="sortChanged"
-    rowAction="rowsChanged"
+    rowAction="rowCountChanged"
     pageAction="pageChanged"
+
+    rowsChanged="rowsChanged"
   }}
 {{else}}
   {{partial "loading"}}

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/templates/dag/counters.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/counters.hbs b/tez-ui2/src/main/webapp/app/templates/dag/counters.hbs
index aa4c127..649cfe2 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag/counters.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag/counters.hbs
@@ -21,7 +21,7 @@
   columns=columns
   rows=counters
 
-  rowCount=counters.length
+  rowCount=countersCount
   definition=definition
 
   enablePagination=false

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/index.hbs b/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
index 2f4a214..b81194f 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
@@ -50,6 +50,10 @@
         <td>{{em-table-status-cell content=model.status}}</td>
       </tr>
       <tr>
+        <td>Progress</td>
+        <td>{{em-table-progress-cell content=model.progress}}</td>
+      </tr>
+      <tr>
         <td>Start Time</td>
         <td>{{txt model.startTime type="date"}}</td>
       </tr>

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/templates/dag/tasks.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/tasks.hbs b/tez-ui2/src/main/webapp/app/templates/dag/tasks.hbs
index 57cfe86..d36678a 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag/tasks.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag/tasks.hbs
@@ -27,8 +27,10 @@
 
     searchAction="searchChanged"
     sortAction="sortChanged"
-    rowAction="rowsChanged"
+    rowAction="rowCountChanged"
     pageAction="pageChanged"
+
+    rowsChanged="rowsChanged"
   }}
 {{else}}
   {{partial "loading"}}

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/templates/dag/vertices.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/vertices.hbs b/tez-ui2/src/main/webapp/app/templates/dag/vertices.hbs
index 57cfe86..d36678a 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag/vertices.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag/vertices.hbs
@@ -27,8 +27,10 @@
 
     searchAction="searchChanged"
     sortAction="sortChanged"
-    rowAction="rowsChanged"
+    rowAction="rowCountChanged"
     pageAction="pageChanged"
+
+    rowsChanged="rowsChanged"
   }}
 {{else}}
   {{partial "loading"}}

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/templates/dags.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dags.hbs b/tez-ui2/src/main/webapp/app/templates/dags.hbs
index 56621e9..cb75f26 100644
--- a/tez-ui2/src/main/webapp/app/templates/dags.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dags.hbs
@@ -16,7 +16,7 @@
  * limitations under the License.
 }}
 
-{{tab-n-refresh tabs=tabs autoRefreshEnabled=false loadTime=loadTime}}
+{{tab-n-refresh tabs=tabs autoRefreshVisible=false loadTime=loadTime}}
 
 {{#if loaded}}
   {{em-table
@@ -33,7 +33,7 @@
 
     searchAction="searchChanged"
     sortAction="sortChanged"
-    rowAction="rowsChanged"
+    rowAction="rowCountChanged"
     pageAction="pageChanged"
   }}
 {{else}}

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/templates/task.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/task.hbs b/tez-ui2/src/main/webapp/app/templates/task.hbs
index 80ec4f4..8906371 100644
--- a/tez-ui2/src/main/webapp/app/templates/task.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/task.hbs
@@ -16,5 +16,5 @@
  * limitations under the License.
 }}
 
-{{tab-n-refresh tabs=tabs loadTime=loadTime}}
+{{tab-n-refresh tabs=tabs loadTime=loadTime autoRefreshEnabled=polling.active}}
 {{outlet}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/templates/task/attempts.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/task/attempts.hbs b/tez-ui2/src/main/webapp/app/templates/task/attempts.hbs
index 57cfe86..d36678a 100644
--- a/tez-ui2/src/main/webapp/app/templates/task/attempts.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/task/attempts.hbs
@@ -27,8 +27,10 @@
 
     searchAction="searchChanged"
     sortAction="sortChanged"
-    rowAction="rowsChanged"
+    rowAction="rowCountChanged"
     pageAction="pageChanged"
+
+    rowsChanged="rowsChanged"
   }}
 {{else}}
   {{partial "loading"}}

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/templates/task/counters.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/task/counters.hbs b/tez-ui2/src/main/webapp/app/templates/task/counters.hbs
index aa4c127..649cfe2 100644
--- a/tez-ui2/src/main/webapp/app/templates/task/counters.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/task/counters.hbs
@@ -21,7 +21,7 @@
   columns=columns
   rows=counters
 
-  rowCount=counters.length
+  rowCount=countersCount
   definition=definition
 
   enablePagination=false

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/templates/task/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/task/index.hbs b/tez-ui2/src/main/webapp/app/templates/task/index.hbs
index ee6b0c6..b9d98c8 100644
--- a/tez-ui2/src/main/webapp/app/templates/task/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/task/index.hbs
@@ -34,9 +34,11 @@
       </tr>
       <tr>
         <td>Status</td>
-        <td>
-          {{em-table-status-cell content=model.status}}
-        </td>
+        <td>{{em-table-status-cell content=model.status}}</td>
+      </tr>
+      <tr>
+        <td>Progress</td>
+        <td>{{em-table-progress-cell content=model.progress}}</td>
       </tr>
       <tr>
         <td>Start Time</td>

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/templates/vertex.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/vertex.hbs b/tez-ui2/src/main/webapp/app/templates/vertex.hbs
index 80ec4f4..8906371 100644
--- a/tez-ui2/src/main/webapp/app/templates/vertex.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/vertex.hbs
@@ -16,5 +16,5 @@
  * limitations under the License.
 }}
 
-{{tab-n-refresh tabs=tabs loadTime=loadTime}}
+{{tab-n-refresh tabs=tabs loadTime=loadTime autoRefreshEnabled=polling.active}}
 {{outlet}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/templates/vertex/attempts.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/vertex/attempts.hbs b/tez-ui2/src/main/webapp/app/templates/vertex/attempts.hbs
index 57cfe86..d36678a 100644
--- a/tez-ui2/src/main/webapp/app/templates/vertex/attempts.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/vertex/attempts.hbs
@@ -27,8 +27,10 @@
 
     searchAction="searchChanged"
     sortAction="sortChanged"
-    rowAction="rowsChanged"
+    rowAction="rowCountChanged"
     pageAction="pageChanged"
+
+    rowsChanged="rowsChanged"
   }}
 {{else}}
   {{partial "loading"}}

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/templates/vertex/counters.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/vertex/counters.hbs b/tez-ui2/src/main/webapp/app/templates/vertex/counters.hbs
index aa4c127..649cfe2 100644
--- a/tez-ui2/src/main/webapp/app/templates/vertex/counters.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/vertex/counters.hbs
@@ -21,7 +21,7 @@
   columns=columns
   rows=counters
 
-  rowCount=counters.length
+  rowCount=countersCount
   definition=definition
 
   enablePagination=false

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs b/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs
index 153d583..eb3a477 100644
--- a/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs
@@ -53,6 +53,10 @@
         <td>{{em-table-status-cell content=model.status}}</td>
       </tr>
       <tr>
+        <td>Progress</td>
+        <td>{{em-table-progress-cell content=model.progress}}</td>
+      </tr>
+      <tr>
         <td>Start Time</td>
         <td>{{txt model.startTime type="date"}}</td>
       </tr>

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/templates/vertex/tasks.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/vertex/tasks.hbs b/tez-ui2/src/main/webapp/app/templates/vertex/tasks.hbs
index 57cfe86..d36678a 100644
--- a/tez-ui2/src/main/webapp/app/templates/vertex/tasks.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/vertex/tasks.hbs
@@ -27,8 +27,10 @@
 
     searchAction="searchChanged"
     sortAction="sortChanged"
-    rowAction="rowsChanged"
+    rowAction="rowCountChanged"
     pageAction="pageChanged"
+
+    rowsChanged="rowsChanged"
   }}
 {{else}}
   {{partial "loading"}}

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/utils/counter-column-definition.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/utils/counter-column-definition.js b/tez-ui2/src/main/webapp/app/utils/counter-column-definition.js
index be36053..d66e551 100644
--- a/tez-ui2/src/main/webapp/app/utils/counter-column-definition.js
+++ b/tez-ui2/src/main/webapp/app/utils/counter-column-definition.js
@@ -43,7 +43,7 @@ var CounterColumnDefinition = ColumnDefinition.extend({
   counterGroupName: "",
 
   observePath: true,
-  contentPath: "counterHash",
+  contentPath: "counterGroupsHash",
 
   getCellContent: getCounterContent,
   getSearchValue: getCounterContent,

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/config/default-app-conf.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/config/default-app-conf.js b/tez-ui2/src/main/webapp/config/default-app-conf.js
index 200dc14..084e9b7 100644
--- a/tez-ui2/src/main/webapp/config/default-app-conf.js
+++ b/tez-ui2/src/main/webapp/config/default-app-conf.js
@@ -20,6 +20,8 @@ module.exports = { // Tez App configurations
   buildVersion: "",
   isStandalone: true, // Must be set false while running in wrapped mode
   rowLoadLimit: 9007199254740991,
+  pollingInterval: 3000,
+
   hosts: {
     timeline: 'localhost:8188',
     rm: 'localhost:8088',
@@ -29,7 +31,7 @@ module.exports = { // Tez App configurations
       timeline: 'ws/v1/timeline',
       appHistory: 'ws/v1/applicationhistory',
       rm: 'ws/v1/cluster',
-      am: 'proxy/{app_id}/ws/v{version}/tez',
+      am: 'proxy/{app_id}/ws/v2/tez',
     },
     web: {
       rm: 'cluster'
@@ -45,6 +47,15 @@ module.exports = { // Tez App configurations
       hiveQuery: 'HIVE_QUERY_ID',
 
       app: 'TEZ_APPLICATION'
+    },
+    am: {
+      "dag-am": 'dagInfo',
+      "vertex-am": 'verticesInfo',
+      "task-am": 'tasksInfo',
+      "attempt-am": 'attemptsInfo',
+    },
+    rm: {
+      "app-rm": "apps"
     }
   },
   hrefs: {

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/package.json
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/package.json b/tez-ui2/src/main/webapp/package.json
index f484913..9cb055b 100644
--- a/tez-ui2/src/main/webapp/package.json
+++ b/tez-ui2/src/main/webapp/package.json
@@ -49,7 +49,7 @@
   "dependencies": {
     "broccoli-funnel": "^1.0.1",
     "em-helpers": "0.5.8",
-    "em-table": "0.3.8",
+    "em-table": "0.3.9",
     "ember-cli-htmlbars": "^1.0.1",
     "ember-cli-less": "^1.4.0",
     "phantomjs": "^1.9.19"

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/adapters/am-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/am-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/am-test.js
index a452467..676656b 100644
--- a/tez-ui2/src/main/webapp/tests/unit/adapters/am-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/adapters/am-test.js
@@ -28,4 +28,23 @@ test('Basic creation test', function(assert) {
 
   assert.ok(adapter);
   assert.equal(adapter.serverName, "am");
+
+  assert.ok(adapter.queryRecord);
+});
+
+test('queryRecord test', function(assert) {
+  let testStore = {},
+      testType = {},
+      testQuery = {},
+
+      adapter = this.subject({
+        query: function (store, type, query) {
+          assert.equal(store, testStore);
+          assert.equal(type, testType);
+          assert.equal(query, testQuery);
+        }
+      });
+
+  assert.expect(3);
+  adapter.queryRecord(testStore, testType, testQuery);
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/adapters/app-rm-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/app-rm-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/app-rm-test.js
new file mode 100644
index 0000000..942b2db
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/adapters/app-rm-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('adapter:app-rm', 'Unit | Adapter | app rm', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let adapter = this.subject();
+  assert.ok(adapter);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/adapters/attempt-am-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/attempt-am-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/attempt-am-test.js
new file mode 100644
index 0000000..43c8e4a
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/adapters/attempt-am-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('adapter:attempt-am', 'Unit | Adapter | attempt am', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let adapter = this.subject();
+  assert.ok(adapter);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/adapters/dag-am-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/dag-am-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/dag-am-test.js
new file mode 100644
index 0000000..b0d3fa9
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/adapters/dag-am-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('adapter:dag-am', 'Unit | Adapter | dag am', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let adapter = this.subject();
+  assert.ok(adapter);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/adapters/task-am-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/task-am-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/task-am-test.js
new file mode 100644
index 0000000..a3eb98b
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/adapters/task-am-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('adapter:task-am', 'Unit | Adapter | task am', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let adapter = this.subject();
+  assert.ok(adapter);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/adapters/vertex-am-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/vertex-am-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/vertex-am-test.js
new file mode 100644
index 0000000..6e29aef
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/adapters/vertex-am-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('adapter:vertex-am', 'Unit | Adapter | vertex am', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let adapter = this.subject();
+  assert.ok(adapter);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/controllers/abstract-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/abstract-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/abstract-test.js
index 9cde1e7..9603b50 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/abstract-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/abstract-test.js
@@ -34,6 +34,7 @@ test('Basic creation test', function(assert) {
   assert.ok(controller.name);
   assert.ok(controller.crumbObserver);
   assert.ok(controller.setBreadcrumbs);
+  assert.ok(controller.loaded);
 });
 
 test('init test', function(assert) {

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js
index 25afc63..402b629 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js
@@ -28,7 +28,8 @@ moduleFor('controller:app/dags', 'Unit | Controller | app/dags', {
 test('Basic creation test', function(assert) {
   let controller = this.subject({
     send: Ember.K,
-    initVisibleColumns: Ember.K
+    initVisibleColumns: Ember.K,
+    getCounterColumns: Ember.K
   });
 
   assert.ok(controller);

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/controllers/counters-page-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/counters-page-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/counters-page-test.js
deleted file mode 100644
index 6faad2d..0000000
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/counters-page-test.js
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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 { moduleFor, test } from 'ember-qunit';
-
-moduleFor('controller:counters-page', 'Unit | Controller | counters page', {
-  // Specify the other units that are required for this test.
-  // needs: ['controller:foo']
-});
-
-test('Basic creation test', function(assert) {
-  let controller = this.subject({
-    send: Ember.K,
-    initVisibleColumns: Ember.K
-  });
-
-  assert.ok(controller);
-  assert.ok(controller.columns);
-  assert.ok(controller.counters);
-});
-
-test('counters test', function(assert) {
-  let controller = this.subject({
-    send: Ember.K,
-    initVisibleColumns: Ember.K,
-    model: {
-      counterGroups: [{
-        counterGroupName: "a.b.foo",
-        counters: [{
-          counterName: "Foo Name 1",
-          counterValue: "Value 1"
-        },{
-          counterName: "Foo Name 2",
-          counterValue: "Value 2"
-        },{
-          counterName: "Foo Name 3",
-          counterValue: "Value 3"
-        },]
-      },{
-        counterGroupName: "a.b.bar",
-        counters: [{
-          counterName: "Bar Name 1",
-          counterValue: "Value 1"
-        },{
-          counterName: "Bar Name 2",
-          counterValue: "Value 2"
-        },{
-          counterName: "Bar Name 3",
-          counterValue: "Value 3"
-        },]
-      }]
-    }
-  });
-
-  assert.equal(controller.get("counters.0.groupName"), "foo");
-  assert.equal(controller.get("counters.0.counterName"), "Foo Name 1");
-  assert.equal(controller.get("counters.0.counterValue"), "Value 1");
-
-  assert.equal(controller.get("counters.1.groupName"), "foo");
-  assert.equal(controller.get("counters.1.counterName"), "Foo Name 2");
-  assert.equal(controller.get("counters.1.counterValue"), "Value 2");
-
-  assert.equal(controller.get("counters.2.groupName"), "foo");
-  assert.equal(controller.get("counters.2.counterName"), "Foo Name 3");
-  assert.equal(controller.get("counters.2.counterValue"), "Value 3");
-
-
-  assert.equal(controller.get("counters.3.groupName"), "bar");
-  assert.equal(controller.get("counters.3.counterName"), "Bar Name 1");
-  assert.equal(controller.get("counters.3.counterValue"), "Value 1");
-
-  assert.equal(controller.get("counters.4.groupName"), "bar");
-  assert.equal(controller.get("counters.4.counterName"), "Bar Name 2");
-  assert.equal(controller.get("counters.4.counterValue"), "Value 2");
-
-  assert.equal(controller.get("counters.5.groupName"), "bar");
-  assert.equal(controller.get("counters.5.counterName"), "Bar Name 3");
-  assert.equal(controller.get("counters.5.counterValue"), "Value 3");
-});
-


[34/45] tez git commit: TEZ-3059. Tez UI 2: Make refresh functional (sree)

Posted by sr...@apache.org.
TEZ-3059. Tez UI 2: Make refresh functional (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/8f6beddc
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/8f6beddc
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/8f6beddc

Branch: refs/heads/TEZ-2980
Commit: 8f6beddcfd8e9228b241114ae6a7a4967dca7aba
Parents: 7040bbd
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Fri Jan 22 21:06:35 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:32:52 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |  1 +
 .../main/webapp/app/components/tab-n-refresh.js |  8 ++-
 .../src/main/webapp/app/controllers/abstract.js |  3 +
 tez-ui2/src/main/webapp/app/entities/entity.js  | 12 ++--
 tez-ui2/src/main/webapp/app/models/abstract.js  | 20 +++---
 tez-ui2/src/main/webapp/app/routes/abstract.js  | 66 +++++++++++++++-----
 tez-ui2/src/main/webapp/app/routes/app.js       |  6 ++
 .../src/main/webapp/app/routes/app/configs.js   |  6 +-
 tez-ui2/src/main/webapp/app/routes/app/dags.js  |  8 ++-
 tez-ui2/src/main/webapp/app/routes/app/index.js |  6 +-
 tez-ui2/src/main/webapp/app/routes/attempt.js   |  6 ++
 .../main/webapp/app/routes/attempt/counters.js  |  6 +-
 .../src/main/webapp/app/routes/attempt/index.js |  6 +-
 tez-ui2/src/main/webapp/app/routes/dag.js       |  6 ++
 .../src/main/webapp/app/routes/dag/attempts.js  |  8 ++-
 .../src/main/webapp/app/routes/dag/counters.js  |  6 +-
 tez-ui2/src/main/webapp/app/routes/dag/index.js |  6 +-
 tez-ui2/src/main/webapp/app/routes/dag/tasks.js |  8 ++-
 .../src/main/webapp/app/routes/dag/vertices.js  |  8 ++-
 tez-ui2/src/main/webapp/app/routes/dags.js      | 12 +++-
 tez-ui2/src/main/webapp/app/routes/task.js      |  6 ++
 .../src/main/webapp/app/routes/task/attempts.js |  8 ++-
 .../src/main/webapp/app/routes/task/counters.js |  6 +-
 .../src/main/webapp/app/routes/task/index.js    |  6 +-
 tez-ui2/src/main/webapp/app/routes/vertex.js    |  6 ++
 .../main/webapp/app/routes/vertex/attempts.js   |  8 ++-
 .../main/webapp/app/routes/vertex/counters.js   |  6 +-
 .../src/main/webapp/app/routes/vertex/index.js  |  6 +-
 .../src/main/webapp/app/routes/vertex/tasks.js  |  8 ++-
 tez-ui2/src/main/webapp/app/services/loader.js  |  8 +--
 .../webapp/app/styles/dags-page-search.less     |  2 +-
 .../main/webapp/app/styles/tab-n-refresh.less   |  2 +-
 tez-ui2/src/main/webapp/app/templates/app.hbs   |  2 +-
 .../main/webapp/app/templates/app/configs.hbs   |  2 +-
 .../src/main/webapp/app/templates/app/dags.hbs  |  2 +-
 .../src/main/webapp/app/templates/app/index.hbs |  2 +-
 .../src/main/webapp/app/templates/attempt.hbs   |  2 +-
 .../webapp/app/templates/attempt/counters.hbs   |  2 +-
 .../main/webapp/app/templates/attempt/index.hbs |  2 +-
 .../app/templates/components/tab-n-refresh.hbs  |  6 +-
 tez-ui2/src/main/webapp/app/templates/dag.hbs   |  2 +-
 .../main/webapp/app/templates/dag/attempts.hbs  |  2 +-
 .../main/webapp/app/templates/dag/counters.hbs  |  2 +-
 .../src/main/webapp/app/templates/dag/index.hbs |  4 +-
 .../src/main/webapp/app/templates/dag/tasks.hbs |  2 +-
 .../main/webapp/app/templates/dag/vertices.hbs  |  2 +-
 tez-ui2/src/main/webapp/app/templates/dags.hbs  |  4 +-
 .../src/main/webapp/app/templates/loading.hbs   | 24 +++++++
 .../app/templates/partials/loading-anim.hbs     | 24 -------
 tez-ui2/src/main/webapp/app/templates/task.hbs  |  2 +-
 .../main/webapp/app/templates/task/attempts.hbs |  2 +-
 .../main/webapp/app/templates/task/counters.hbs |  2 +-
 .../main/webapp/app/templates/task/index.hbs    |  2 +-
 .../src/main/webapp/app/templates/vertex.hbs    |  2 +-
 .../webapp/app/templates/vertex/attempts.hbs    |  2 +-
 .../webapp/app/templates/vertex/counters.hbs    |  2 +-
 .../main/webapp/app/templates/vertex/index.hbs  |  3 +-
 .../main/webapp/app/templates/vertex/tasks.hbs  |  2 +-
 .../webapp/tests/unit/models/abstract-test.js   | 31 ++++++++-
 .../webapp/tests/unit/routes/abstract-test.js   | 32 +++++++---
 .../tests/unit/routes/app/configs-test.js       |  1 +
 .../webapp/tests/unit/routes/app/dags-test.js   |  1 +
 .../webapp/tests/unit/routes/app/index-test.js  |  1 +
 .../tests/unit/routes/attempt/counters-test.js  |  1 +
 .../tests/unit/routes/attempt/index-test.js     |  1 +
 .../tests/unit/routes/dag/attempts-test.js      |  1 +
 .../tests/unit/routes/dag/counters-test.js      |  1 +
 .../webapp/tests/unit/routes/dag/index-test.js  |  1 +
 .../webapp/tests/unit/routes/dag/tasks-test.js  |  1 +
 .../tests/unit/routes/dag/vertices-test.js      |  1 +
 .../tests/unit/routes/task/attempts-test.js     |  1 +
 .../tests/unit/routes/task/counters-test.js     |  1 +
 .../webapp/tests/unit/routes/task/index-test.js |  1 +
 .../tests/unit/routes/vertex/attempts-test.js   |  1 +
 .../tests/unit/routes/vertex/counters-test.js   |  1 +
 .../tests/unit/routes/vertex/index-test.js      |  1 +
 .../tests/unit/routes/vertex/tasks-test.js      |  1 +
 .../webapp/tests/unit/services/loader-test.js   | 18 ++++--
 78 files changed, 334 insertions(+), 149 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index e34c0fd..e413bc3 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -24,3 +24,4 @@ ALL CHANGES:
   TEZ-3049. Tez UI 2: Add column selector
   TEZ-3050. Tez UI 2: Add counter columns
   TEZ-3064. Tez UI 2: Add All DAGs filters
+  TEZ-3059. Tez UI 2: Make refresh functional

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/components/tab-n-refresh.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/components/tab-n-refresh.js b/tez-ui2/src/main/webapp/app/components/tab-n-refresh.js
index 555418e..75bac20 100644
--- a/tez-ui2/src/main/webapp/app/components/tab-n-refresh.js
+++ b/tez-ui2/src/main/webapp/app/components/tab-n-refresh.js
@@ -42,5 +42,11 @@ export default Ember.Component.extend({
         active: tab.routeName === activeRouteName
       };
     });
-  })
+  }),
+
+  actions: {
+    refresh: function () {
+      this.get('targetObject').send('reload');
+    }
+  }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/controllers/abstract.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/abstract.js b/tez-ui2/src/main/webapp/app/controllers/abstract.js
index c077914..816e7d1 100644
--- a/tez-ui2/src/main/webapp/app/controllers/abstract.js
+++ b/tez-ui2/src/main/webapp/app/controllers/abstract.js
@@ -24,6 +24,9 @@ export default Ember.Controller.extend(NameMixin, {
   // Must be set by inheriting classes
   breadcrumbs: null,
 
+  // Must be set from route
+  loadTime: null,
+
   init: function () {
     this._super();
     Ember.run.later(this, "setBreadcrumbs");

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/entities/entity.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/entities/entity.js b/tez-ui2/src/main/webapp/app/entities/entity.js
index c11c6d1..9cad7b7 100644
--- a/tez-ui2/src/main/webapp/app/entities/entity.js
+++ b/tez-ui2/src/main/webapp/app/entities/entity.js
@@ -23,8 +23,8 @@ var MoreObject = more.Object;
 
 export default Ember.Object.extend({
 
-  loadRelations: function (loader, model) {
-    var needsPromise = this.loadNeeds(loader, model);
+  loadRelations: function (loader, model, options, urlParams) {
+    var needsPromise = this.loadNeeds(loader, model, options, urlParams);
 
     if(needsPromise) {
       return needsPromise.then(function () {
@@ -51,15 +51,15 @@ export default Ember.Object.extend({
     return Ember.Object.create(need);
   },
 
-  loadNeeds: function (loader, parentModel) {
+  loadNeeds: function (loader, parentModel, options, urlParams) {
     var needLoaders = [],
         that = this,
         needs = parentModel.get("needs");
 
     if(needs) {
-      MoreObject.forEach(needs, function (name, options) {
-        var need = that.normalizeNeed(name, options),
-            needLoader = loader.queryRecord(need.type, parentModel.get(need.idKey));
+      MoreObject.forEach(needs, function (name, needOptions) {
+        var need = that.normalizeNeed(name, needOptions),
+            needLoader = loader.queryRecord(need.type, parentModel.get(need.idKey), null, options, urlParams);
 
         needLoader.then(function (model) {
           parentModel.set(need.name, model);

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/models/abstract.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/abstract.js b/tez-ui2/src/main/webapp/app/models/abstract.js
index 0dd084d..cf6ea8a 100644
--- a/tez-ui2/src/main/webapp/app/models/abstract.js
+++ b/tez-ui2/src/main/webapp/app/models/abstract.js
@@ -19,17 +19,21 @@
 import DS from 'ember-data';
 
 export default DS.Model.extend({
-  timeStamp: null,
+  loadTime: null,
 
   mergedProperties: ["needs"],
 
-  refreshTimestamp: function () {
-    this.set('timeStamp', new Date());
+  refreshLoadTime: function () {
+    this.set('loadTime', new Date());
   },
 
-  actions: {
-    didUpdate: function () {
-      this.refreshTimestamp();
-    }
-  }
+  //TODO - Find a better alternative to detect property change in a model
+  _notifyProperties: function (keys) {
+    this.refreshLoadTime();
+    return this._super(keys);
+  },
+
+  didLoad: function () {
+    this.refreshLoadTime();
+  },
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/routes/abstract.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/abstract.js b/tez-ui2/src/main/webapp/app/routes/abstract.js
index 1624bea..c3efc18 100644
--- a/tez-ui2/src/main/webapp/app/routes/abstract.js
+++ b/tez-ui2/src/main/webapp/app/routes/abstract.js
@@ -18,6 +18,8 @@
  */
 
 import Ember from 'ember';
+import DS from 'ember-data';
+
 import LoaderService from '../services/loader';
 import UnlinkedPromise from '../errors/unlinked-promise';
 import NameMixin from '../mixins/name';
@@ -27,6 +29,7 @@ var MoreObject = more.Object;
 export default Ember.Route.extend(NameMixin, {
   title: null, // Must be set by inheriting class
 
+  loaderNamespace: null,
   isLoading: false,
   currentPromiseId: null,
   loadedValue: null,
@@ -35,10 +38,20 @@ export default Ember.Route.extend(NameMixin, {
   breadcrumbs: null,
   childCrumbs: null,
 
+  currentQuery: {},
+
   loaderQueryParams: {},
 
+  init: function () {
+    var namespace = this.get("loaderNamespace");
+    if(namespace) {
+      this.setLoader(namespace);
+    }
+  },
+
   model: function(params/*, transition*/) {
-    Ember.run.later(this, "loadData", this.queryFromParams(params));
+    this.set("currentQuery", this.queryFromParams(params));
+    Ember.run.later(this, "loadData");
   },
 
   queryFromParams: function (params) {
@@ -63,48 +76,68 @@ export default Ember.Route.extend(NameMixin, {
     this.setDocTitle();
   },
 
-  checkAndCall: function (id, functionName, query, value) {
+  checkAndCall: function (id, functionName, query, options, value) {
     if(id === this.get("currentPromiseId")) {
-      return this[functionName](value, query);
+      return this[functionName](value, query, options);
     }
     else {
       throw new UnlinkedPromise();
     }
   },
 
-  loadData: function (query) {
-    var promiseId = Math.random();
+  loadData: function (options) {
+    var promiseId = Math.random(),
+        query = this.get("currentQuery");
+
+    options = options || {};
 
     this.set('currentPromiseId', promiseId);
 
     return Ember.RSVP.resolve().
-      then(this.checkAndCall.bind(this, promiseId, "setLoading", query)).
-      then(this.checkAndCall.bind(this, promiseId, "beforeLoad", query)).
-      then(this.checkAndCall.bind(this, promiseId, "load", query)).
-      then(this.checkAndCall.bind(this, promiseId, "afterLoad", query)).
-      then(this.checkAndCall.bind(this, promiseId, "setValue", query));
+      then(this.checkAndCall.bind(this, promiseId, "setLoading", query, options)).
+      then(this.checkAndCall.bind(this, promiseId, "beforeLoad", query, options)).
+      then(this.checkAndCall.bind(this, promiseId, "load", query, options)).
+      then(this.checkAndCall.bind(this, promiseId, "afterLoad", query, options)).
+      then(this.checkAndCall.bind(this, promiseId, "setValue", query, options));
   },
 
-  setLoading: function () {
+  setLoading: function (/*query, options*/) {
     this.set('isLoading', true);
     this.set('controller.isLoading', true);
   },
-  beforeLoad: function (value) {
+  beforeLoad: function (value/*, query, options*/) {
     return value;
   },
-  load: function (value) {
+  load: function (value/*, query, options*/) {
     return value;
   },
-  afterLoad: function (value) {
+  afterLoad: function (value/*, query, options*/) {
     return value;
   },
-  setValue: function (value) {
+  setValue: function (value/*, query, options*/) {
     this.set('loadedValue', value);
+
     this.set('isLoading', false);
     this.set('controller.isLoading', false);
+
+    this.send("setLoadTime", this.getLoadTime(value));
+
     return value;
   },
 
+  getLoadTime: function (value) {
+    if(value instanceof DS.RecordArray) {
+      value = value.get("content.0.record");
+    }
+    else if(Array.isArray(value)) {
+      value = value[0];
+    }
+
+    if(value) {
+      return Ember.get(value, "loadTime");
+    }
+  },
+
   _setControllerModel: Ember.observer("loadedValue", function () {
     var controller = this.get("controller");
     if(controller) {
@@ -135,6 +168,9 @@ export default Ember.Route.extend(NameMixin, {
     bubbleBreadcrumbs: function (crumbs) {
       crumbs.unshift.apply(crumbs, this.get("breadcrumbs"));
       return true;
+    },
+    reload: function () {
+      Ember.run.later(this, "loadData", {reload: true});
     }
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/routes/app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/app.js b/tez-ui2/src/main/webapp/app/routes/app.js
index 2bbf14a..a60025e 100644
--- a/tez-ui2/src/main/webapp/app/routes/app.js
+++ b/tez-ui2/src/main/webapp/app/routes/app.js
@@ -27,5 +27,11 @@ export default AbstractRoute.extend({
 
   model: function (params) {
     return this.get("loader").queryRecord('app', "tez_" + this.queryFromParams(params).id);
+  },
+
+  actions: {
+    setLoadTime: function (time) {
+      this.set("controller.loadTime", time);
+    }
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/routes/app/configs.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/app/configs.js b/tez-ui2/src/main/webapp/app/routes/app/configs.js
index b6768fa..825bdad 100644
--- a/tez-ui2/src/main/webapp/app/routes/app/configs.js
+++ b/tez-ui2/src/main/webapp/app/routes/app/configs.js
@@ -22,12 +22,14 @@ import AbstractRoute from '../abstract';
 export default AbstractRoute.extend({
   title: "Application Details",
 
+  loaderNamespace: "app",
+
   setupController: function (controller, model) {
     this._super(controller, model);
     Ember.run.later(this, "startCrumbBubble");
   },
 
-  load: function (/*value, query*/) {
-    return this.get("loader").queryRecord('app', this.modelFor("app").id);
+  load: function (value, query, options) {
+    return this.get("loader").queryRecord('app', this.modelFor("app").get("id"), options);
   },
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/routes/app/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/app/dags.js b/tez-ui2/src/main/webapp/app/routes/app/dags.js
index 8c695b3..80643c0 100644
--- a/tez-ui2/src/main/webapp/app/routes/app/dags.js
+++ b/tez-ui2/src/main/webapp/app/routes/app/dags.js
@@ -22,14 +22,16 @@ import AbstractRoute from '../abstract';
 export default AbstractRoute.extend({
   title: "DAGs",
 
+  loaderNamespace: "app",
+
   setupController: function (controller, model) {
     this._super(controller, model);
     Ember.run.later(this, "startCrumbBubble");
   },
 
-  load: function (/*value, query*/) {
+  load: function (value, query, options) {
     return this.get("loader").query('dag', {
-      appID: (this.modelFor("app").id || "").substr(4)
-    });
+      appID: this.modelFor("app").get("appID")
+    }, options);
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/routes/app/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/app/index.js b/tez-ui2/src/main/webapp/app/routes/app/index.js
index b6768fa..825bdad 100644
--- a/tez-ui2/src/main/webapp/app/routes/app/index.js
+++ b/tez-ui2/src/main/webapp/app/routes/app/index.js
@@ -22,12 +22,14 @@ import AbstractRoute from '../abstract';
 export default AbstractRoute.extend({
   title: "Application Details",
 
+  loaderNamespace: "app",
+
   setupController: function (controller, model) {
     this._super(controller, model);
     Ember.run.later(this, "startCrumbBubble");
   },
 
-  load: function (/*value, query*/) {
-    return this.get("loader").queryRecord('app', this.modelFor("app").id);
+  load: function (value, query, options) {
+    return this.get("loader").queryRecord('app', this.modelFor("app").get("id"), options);
   },
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/routes/attempt.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/attempt.js b/tez-ui2/src/main/webapp/app/routes/attempt.js
index 71be6d2..ff9d4fb 100644
--- a/tez-ui2/src/main/webapp/app/routes/attempt.js
+++ b/tez-ui2/src/main/webapp/app/routes/attempt.js
@@ -27,5 +27,11 @@ export default AbstractRoute.extend({
 
   model: function (params) {
     return this.get("loader").queryRecord('attempt', this.queryFromParams(params).id);
+  },
+
+  actions: {
+    setLoadTime: function (time) {
+      this.set("controller.loadTime", time);
+    }
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/routes/attempt/counters.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/attempt/counters.js b/tez-ui2/src/main/webapp/app/routes/attempt/counters.js
index f88737d..e63e6ab 100644
--- a/tez-ui2/src/main/webapp/app/routes/attempt/counters.js
+++ b/tez-ui2/src/main/webapp/app/routes/attempt/counters.js
@@ -22,12 +22,14 @@ import AbstractRoute from '../abstract';
 export default AbstractRoute.extend({
   title: "DAG Details",
 
+  loaderNamespace: "attempt",
+
   setupController: function (controller, model) {
     this._super(controller, model);
     Ember.run.later(this, "startCrumbBubble");
   },
 
-  load: function (/*value, query*/) {
-    return this.get("loader").queryRecord('attempt', this.modelFor("attempt").id);
+  load: function (value, query, options) {
+    return this.get("loader").queryRecord('attempt', this.modelFor("attempt").get("id"), options);
   },
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/routes/attempt/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/attempt/index.js b/tez-ui2/src/main/webapp/app/routes/attempt/index.js
index f88737d..e63e6ab 100644
--- a/tez-ui2/src/main/webapp/app/routes/attempt/index.js
+++ b/tez-ui2/src/main/webapp/app/routes/attempt/index.js
@@ -22,12 +22,14 @@ import AbstractRoute from '../abstract';
 export default AbstractRoute.extend({
   title: "DAG Details",
 
+  loaderNamespace: "attempt",
+
   setupController: function (controller, model) {
     this._super(controller, model);
     Ember.run.later(this, "startCrumbBubble");
   },
 
-  load: function (/*value, query*/) {
-    return this.get("loader").queryRecord('attempt', this.modelFor("attempt").id);
+  load: function (value, query, options) {
+    return this.get("loader").queryRecord('attempt', this.modelFor("attempt").get("id"), options);
   },
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/routes/dag.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag.js b/tez-ui2/src/main/webapp/app/routes/dag.js
index 71ff019..51e6ed9 100644
--- a/tez-ui2/src/main/webapp/app/routes/dag.js
+++ b/tez-ui2/src/main/webapp/app/routes/dag.js
@@ -27,5 +27,11 @@ export default AbstractRoute.extend({
 
   model: function (params) {
     return this.get("loader").queryRecord('dag', this.queryFromParams(params).id);
+  },
+
+  actions: {
+    setLoadTime: function (time) {
+      this.set("controller.loadTime", time);
+    }
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/routes/dag/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag/attempts.js b/tez-ui2/src/main/webapp/app/routes/dag/attempts.js
index f438b95..c8c897a 100644
--- a/tez-ui2/src/main/webapp/app/routes/dag/attempts.js
+++ b/tez-ui2/src/main/webapp/app/routes/dag/attempts.js
@@ -22,14 +22,16 @@ import AbstractRoute from '../abstract';
 export default AbstractRoute.extend({
   title: "All Task Attempts",
 
+  loaderNamespace: "dag",
+
   setupController: function (controller, model) {
     this._super(controller, model);
     Ember.run.later(this, "startCrumbBubble");
   },
 
-  load: function (/*value, query*/) {
+  load: function (value, query, options) {
     return this.get("loader").query('attempt', {
-      dagID: this.modelFor("dag").id
-    });
+      dagID: this.modelFor("dag").get("id")
+    }, options);
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/routes/dag/counters.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag/counters.js b/tez-ui2/src/main/webapp/app/routes/dag/counters.js
index 90929d0..51b3fc5 100644
--- a/tez-ui2/src/main/webapp/app/routes/dag/counters.js
+++ b/tez-ui2/src/main/webapp/app/routes/dag/counters.js
@@ -22,13 +22,15 @@ import AbstractRoute from '../abstract';
 export default AbstractRoute.extend({
   title: "DAG Details",
 
+  loaderNamespace: "dag",
+
   setupController: function (controller, model) {
     this._super(controller, model);
     Ember.run.later(this, "startCrumbBubble");
   },
 
-  load: function (/*value, query*/) {
-    return this.get("loader").queryRecord('dag', this.modelFor("dag").id);
+  load: function (value, query, options) {
+    return this.get("loader").queryRecord('dag', this.modelFor("dag").get("id"), options);
   },
 
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/routes/dag/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag/index.js b/tez-ui2/src/main/webapp/app/routes/dag/index.js
index 90929d0..51b3fc5 100644
--- a/tez-ui2/src/main/webapp/app/routes/dag/index.js
+++ b/tez-ui2/src/main/webapp/app/routes/dag/index.js
@@ -22,13 +22,15 @@ import AbstractRoute from '../abstract';
 export default AbstractRoute.extend({
   title: "DAG Details",
 
+  loaderNamespace: "dag",
+
   setupController: function (controller, model) {
     this._super(controller, model);
     Ember.run.later(this, "startCrumbBubble");
   },
 
-  load: function (/*value, query*/) {
-    return this.get("loader").queryRecord('dag', this.modelFor("dag").id);
+  load: function (value, query, options) {
+    return this.get("loader").queryRecord('dag', this.modelFor("dag").get("id"), options);
   },
 
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/routes/dag/tasks.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag/tasks.js b/tez-ui2/src/main/webapp/app/routes/dag/tasks.js
index 3408a3e..859a712 100644
--- a/tez-ui2/src/main/webapp/app/routes/dag/tasks.js
+++ b/tez-ui2/src/main/webapp/app/routes/dag/tasks.js
@@ -22,14 +22,16 @@ import AbstractRoute from '../abstract';
 export default AbstractRoute.extend({
   title: "All Tasks",
 
+  loaderNamespace: "dag",
+
   setupController: function (controller, model) {
     this._super(controller, model);
     Ember.run.later(this, "startCrumbBubble");
   },
 
-  load: function (/*value, query*/) {
+  load: function (value, query, options) {
     return this.get("loader").query('task', {
-      dagID: this.modelFor("dag").id
-    });
+      dagID: this.modelFor("dag").get("id")
+    }, options);
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/routes/dag/vertices.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag/vertices.js b/tez-ui2/src/main/webapp/app/routes/dag/vertices.js
index e8c0770..063f2cc 100644
--- a/tez-ui2/src/main/webapp/app/routes/dag/vertices.js
+++ b/tez-ui2/src/main/webapp/app/routes/dag/vertices.js
@@ -22,14 +22,16 @@ import AbstractRoute from '../abstract';
 export default AbstractRoute.extend({
   title: "All Vertices",
 
+  loaderNamespace: "dag",
+
   setupController: function (controller, model) {
     this._super(controller, model);
     Ember.run.later(this, "startCrumbBubble");
   },
 
-  load: function (/*value, query*/) {
+  load: function (value, query, options) {
     return this.get("loader").query('vertex', {
-      dagID: this.modelFor("dag").id
-    });
+      dagID: this.modelFor("dag").get("id")
+    }, options);
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/routes/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dags.js b/tez-ui2/src/main/webapp/app/routes/dags.js
index b9484be..5fab777 100644
--- a/tez-ui2/src/main/webapp/app/routes/dags.js
+++ b/tez-ui2/src/main/webapp/app/routes/dags.js
@@ -75,22 +75,28 @@ export default AbstractRoute.extend({
     });
   },
 
-  load: function (value, query) {
+  load: function (value, query, options) {
     var loader,
         that = this;
 
     if(query.dagID) {
       that.set("loadedRecords", []);
-      loader = this.get("loader").queryRecord('dag', query.dagID).then(function (record) {
+      loader = this.get("loader").queryRecord('dag', query.dagID, options).then(function (record) {
         return [record];
       });
     }
     else {
-      loader = this.get("loader").query('dag', query);
+      loader = this.get("loader").query('dag', query, options);
     }
 
     return loader.then(function (records) {
       return that.filterRecords(records, query);
     });
+  },
+
+  actions: {
+    setLoadTime: function (time) {
+      this.set("controller.loadTime", time);
+    }
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/routes/task.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/task.js b/tez-ui2/src/main/webapp/app/routes/task.js
index 42809c9..835243f 100644
--- a/tez-ui2/src/main/webapp/app/routes/task.js
+++ b/tez-ui2/src/main/webapp/app/routes/task.js
@@ -27,5 +27,11 @@ export default AbstractRoute.extend({
 
   model: function (params) {
     return this.get("loader").queryRecord('task', this.queryFromParams(params).id);
+  },
+
+  actions: {
+    setLoadTime: function (time) {
+      this.set("controller.loadTime", time);
+    }
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/routes/task/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/task/attempts.js b/tez-ui2/src/main/webapp/app/routes/task/attempts.js
index bc7af27..3a0bc18 100644
--- a/tez-ui2/src/main/webapp/app/routes/task/attempts.js
+++ b/tez-ui2/src/main/webapp/app/routes/task/attempts.js
@@ -22,14 +22,16 @@ import AbstractRoute from '../abstract';
 export default AbstractRoute.extend({
   title: "Task Attempts",
 
+  loaderNamespace: "task",
+
   setupController: function (controller, model) {
     this._super(controller, model);
     Ember.run.later(this, "startCrumbBubble");
   },
 
-  load: function (/*value, query*/) {
+  load: function (value, query, options) {
     return this.get("loader").query('attempt', {
-      taskID: this.modelFor("task").id
-    });
+      taskID: this.modelFor("task").get("id")
+    }, options);
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/routes/task/counters.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/task/counters.js b/tez-ui2/src/main/webapp/app/routes/task/counters.js
index fd76df9..a2d5d33 100644
--- a/tez-ui2/src/main/webapp/app/routes/task/counters.js
+++ b/tez-ui2/src/main/webapp/app/routes/task/counters.js
@@ -22,12 +22,14 @@ import AbstractRoute from '../abstract';
 export default AbstractRoute.extend({
   title: "DAG Details",
 
+  loaderNamespace: "task",
+
   setupController: function (controller, model) {
     this._super(controller, model);
     Ember.run.later(this, "startCrumbBubble");
   },
 
-  load: function (/*value, query*/) {
-    return this.get("loader").queryRecord('task', this.modelFor("task").id);
+  load: function (value, query, options) {
+    return this.get("loader").queryRecord('task', this.modelFor("task").get("id"), options);
   },
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/routes/task/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/task/index.js b/tez-ui2/src/main/webapp/app/routes/task/index.js
index fd76df9..a2d5d33 100644
--- a/tez-ui2/src/main/webapp/app/routes/task/index.js
+++ b/tez-ui2/src/main/webapp/app/routes/task/index.js
@@ -22,12 +22,14 @@ import AbstractRoute from '../abstract';
 export default AbstractRoute.extend({
   title: "DAG Details",
 
+  loaderNamespace: "task",
+
   setupController: function (controller, model) {
     this._super(controller, model);
     Ember.run.later(this, "startCrumbBubble");
   },
 
-  load: function (/*value, query*/) {
-    return this.get("loader").queryRecord('task', this.modelFor("task").id);
+  load: function (value, query, options) {
+    return this.get("loader").queryRecord('task', this.modelFor("task").get("id"), options);
   },
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/routes/vertex.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/vertex.js b/tez-ui2/src/main/webapp/app/routes/vertex.js
index 2a38001..5e8ed33 100644
--- a/tez-ui2/src/main/webapp/app/routes/vertex.js
+++ b/tez-ui2/src/main/webapp/app/routes/vertex.js
@@ -27,5 +27,11 @@ export default AbstractRoute.extend({
 
   model: function (params) {
     return this.get("loader").queryRecord('vertex', this.queryFromParams(params).id);
+  },
+
+  actions: {
+    setLoadTime: function (time) {
+      this.set("controller.loadTime", time);
+    }
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/routes/vertex/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/vertex/attempts.js b/tez-ui2/src/main/webapp/app/routes/vertex/attempts.js
index cead8a2..aa0a83d 100644
--- a/tez-ui2/src/main/webapp/app/routes/vertex/attempts.js
+++ b/tez-ui2/src/main/webapp/app/routes/vertex/attempts.js
@@ -22,14 +22,16 @@ import AbstractRoute from '../abstract';
 export default AbstractRoute.extend({
   title: "Task Attempts",
 
+  loaderNamespace: "vertex",
+
   setupController: function (controller, model) {
     this._super(controller, model);
     Ember.run.later(this, "startCrumbBubble");
   },
 
-  load: function (/*value, query*/) {
+  load: function (value, query, options) {
     return this.get("loader").query('attempt', {
-      vertexID: this.modelFor("vertex").id
-    });
+      vertexID: this.modelFor("vertex").get("id")
+    }, options);
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/routes/vertex/counters.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/vertex/counters.js b/tez-ui2/src/main/webapp/app/routes/vertex/counters.js
index d05e5f6..bb5a9ce 100644
--- a/tez-ui2/src/main/webapp/app/routes/vertex/counters.js
+++ b/tez-ui2/src/main/webapp/app/routes/vertex/counters.js
@@ -22,12 +22,14 @@ import AbstractRoute from '../abstract';
 export default AbstractRoute.extend({
   title: "DAG Details",
 
+  loaderNamespace: "vertex",
+
   setupController: function (controller, model) {
     this._super(controller, model);
     Ember.run.later(this, "startCrumbBubble");
   },
 
-  load: function (/*value, query*/) {
-    return this.get("loader").queryRecord('vertex', this.modelFor("vertex").id);
+  load: function (value, query, options) {
+    return this.get("loader").queryRecord('vertex', this.modelFor("vertex").get("id"), options);
   },
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/routes/vertex/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/vertex/index.js b/tez-ui2/src/main/webapp/app/routes/vertex/index.js
index d05e5f6..bb5a9ce 100644
--- a/tez-ui2/src/main/webapp/app/routes/vertex/index.js
+++ b/tez-ui2/src/main/webapp/app/routes/vertex/index.js
@@ -22,12 +22,14 @@ import AbstractRoute from '../abstract';
 export default AbstractRoute.extend({
   title: "DAG Details",
 
+  loaderNamespace: "vertex",
+
   setupController: function (controller, model) {
     this._super(controller, model);
     Ember.run.later(this, "startCrumbBubble");
   },
 
-  load: function (/*value, query*/) {
-    return this.get("loader").queryRecord('vertex', this.modelFor("vertex").id);
+  load: function (value, query, options) {
+    return this.get("loader").queryRecord('vertex', this.modelFor("vertex").get("id"), options);
   },
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/routes/vertex/tasks.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/vertex/tasks.js b/tez-ui2/src/main/webapp/app/routes/vertex/tasks.js
index e959fef..f392343 100644
--- a/tez-ui2/src/main/webapp/app/routes/vertex/tasks.js
+++ b/tez-ui2/src/main/webapp/app/routes/vertex/tasks.js
@@ -22,14 +22,16 @@ import AbstractRoute from '../abstract';
 export default AbstractRoute.extend({
   title: "All Tasks",
 
+  loaderNamespace: "vertex",
+
   setupController: function (controller, model) {
     this._super(controller, model);
     Ember.run.later(this, "startCrumbBubble");
   },
 
-  load: function (/*value, query*/) {
+  load: function (value, query, options) {
     return this.get("loader").query('task', {
-      vertexID: this.modelFor("vertex").id
-    });
+      vertexID: this.modelFor("vertex").get("id")
+    }, options);
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/services/loader.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/services/loader.js b/tez-ui2/src/main/webapp/app/services/loader.js
index 054a6b5..92758e3 100644
--- a/tez-ui2/src/main/webapp/app/services/loader.js
+++ b/tez-ui2/src/main/webapp/app/services/loader.js
@@ -81,7 +81,7 @@ export default Ember.Service.extend({
     return parts.join(":");
   },
 
-  queryRecord: function(type, id, query, urlParams, options) {
+  queryRecord: function(type, id, options, query, urlParams) {
     var entity = this.entityFor(type),
         cache = this.get("cache"),
         cacheKey = this.getCacheKey(type, query, id),
@@ -104,13 +104,13 @@ export default Ember.Service.extend({
       params: query,
       urlParams: urlParams
     }).then(function (record) {
-      return entity.loadRelations(that, record);
+      return entity.loadRelations(that, record, options, urlParams);
     });
 
     cache.set(cacheKey, record);
     return record;
   },
-  query: function(type, query, urlParams, options) {
+  query: function(type, query, options, urlParams) {
     var entity = this.entityFor(type),
         cache = this.get("cache"),
         cacheKey = this.getCacheKey(type, query),
@@ -133,7 +133,7 @@ export default Ember.Service.extend({
       urlParams: urlParams
     }).then(function (records) {
       return Ember.RSVP.all(records.map(function (record) {
-        return entity.loadRelations(that, record);
+        return entity.loadRelations(that, record, options, urlParams);
       })).then(function () {
        return records;
       });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/styles/dags-page-search.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/dags-page-search.less b/tez-ui2/src/main/webapp/app/styles/dags-page-search.less
index 2fa0216..ec64d11 100644
--- a/tez-ui2/src/main/webapp/app/styles/dags-page-search.less
+++ b/tez-ui2/src/main/webapp/app/styles/dags-page-search.less
@@ -16,7 +16,7 @@
  * limitations under the License.
  */
 
-@media screen and (min-width: 1500px) {
+@media screen and (min-width: 1300px) {
   .dags-page-search{
     float: left;
     width: 1000px;

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/styles/tab-n-refresh.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/tab-n-refresh.less b/tez-ui2/src/main/webapp/app/styles/tab-n-refresh.less
index ab930f2..16ad404 100644
--- a/tez-ui2/src/main/webapp/app/styles/tab-n-refresh.less
+++ b/tez-ui2/src/main/webapp/app/styles/tab-n-refresh.less
@@ -34,7 +34,7 @@
       position: relative;
 
       line-height: 18px;
-      top: 12px;
+      top: 11px;
       text-align: right;
       font-size: .95em;
 

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/templates/app.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/app.hbs b/tez-ui2/src/main/webapp/app/templates/app.hbs
index 308b905..80ec4f4 100644
--- a/tez-ui2/src/main/webapp/app/templates/app.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/app.hbs
@@ -16,5 +16,5 @@
  * limitations under the License.
 }}
 
-{{tab-n-refresh tabs=tabs}}
+{{tab-n-refresh tabs=tabs loadTime=loadTime}}
 {{outlet}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/templates/app/configs.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/app/configs.hbs b/tez-ui2/src/main/webapp/app/templates/app/configs.hbs
index 8617c81..62010e9 100644
--- a/tez-ui2/src/main/webapp/app/templates/app/configs.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/app/configs.hbs
@@ -30,5 +30,5 @@
   sortAction="sortChanged"
   }}
 {{else}}
-  {{partial "partials/loading-anim"}}
+  {{partial "loading"}}
 {{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/templates/app/dags.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/app/dags.hbs b/tez-ui2/src/main/webapp/app/templates/app/dags.hbs
index 6d8d4c3..57cfe86 100644
--- a/tez-ui2/src/main/webapp/app/templates/app/dags.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/app/dags.hbs
@@ -31,5 +31,5 @@
     pageAction="pageChanged"
   }}
 {{else}}
-  {{partial "partials/loading-anim"}}
+  {{partial "loading"}}
 {{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/templates/app/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/app/index.hbs b/tez-ui2/src/main/webapp/app/templates/app/index.hbs
index 916051b..3567f32 100644
--- a/tez-ui2/src/main/webapp/app/templates/app/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/app/index.hbs
@@ -122,5 +122,5 @@
     </tbody>
   </table>
 {{else}}
-  {{partial "partials/loading-anim"}}
+  {{partial "loading"}}
 {{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/templates/attempt.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/attempt.hbs b/tez-ui2/src/main/webapp/app/templates/attempt.hbs
index 308b905..80ec4f4 100644
--- a/tez-ui2/src/main/webapp/app/templates/attempt.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/attempt.hbs
@@ -16,5 +16,5 @@
  * limitations under the License.
 }}
 
-{{tab-n-refresh tabs=tabs}}
+{{tab-n-refresh tabs=tabs loadTime=loadTime}}
 {{outlet}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/templates/attempt/counters.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/attempt/counters.hbs b/tez-ui2/src/main/webapp/app/templates/attempt/counters.hbs
index e590b36..aa4c127 100644
--- a/tez-ui2/src/main/webapp/app/templates/attempt/counters.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/attempt/counters.hbs
@@ -30,5 +30,5 @@
   sortAction="sortChanged"
   }}
 {{else}}
-  {{partial "partials/loading-anim"}}
+  {{partial "loading"}}
 {{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs b/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs
index cf83afe..9edaacd 100644
--- a/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs
@@ -61,5 +61,5 @@
     </tbody>
   </table>
 {{else}}
-  {{partial "partials/loading-anim"}}
+  {{partial "loading"}}
 {{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs b/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs
index 6b9c822..9b6a594 100644
--- a/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs
@@ -31,13 +31,13 @@
         Auto Refresh
         <br/>
       </span>
-      {{#if displayTime}}
-        Last refreshed at <b>{{displayTime}}</b>
+      {{#if loadTime}}
+        Last refreshed at <b>{{txt loadTime type="date" format="DD MMM YYYY HH:mm:ss"}}</b>
       {{else}}
         Load time not available!
       {{/if}}
     </span>
-    <button type="button" class="btn btn-success">
+    <button type="button" class="btn btn-success" {{action "refresh"}}>
       <i class='fa fa-refresh'></i> Refresh
     </button>
   </span>

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/templates/dag.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag.hbs b/tez-ui2/src/main/webapp/app/templates/dag.hbs
index 308b905..80ec4f4 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag.hbs
@@ -16,5 +16,5 @@
  * limitations under the License.
 }}
 
-{{tab-n-refresh tabs=tabs}}
+{{tab-n-refresh tabs=tabs loadTime=loadTime}}
 {{outlet}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/templates/dag/attempts.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/attempts.hbs b/tez-ui2/src/main/webapp/app/templates/dag/attempts.hbs
index 6d8d4c3..57cfe86 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag/attempts.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag/attempts.hbs
@@ -31,5 +31,5 @@
     pageAction="pageChanged"
   }}
 {{else}}
-  {{partial "partials/loading-anim"}}
+  {{partial "loading"}}
 {{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/templates/dag/counters.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/counters.hbs b/tez-ui2/src/main/webapp/app/templates/dag/counters.hbs
index e590b36..aa4c127 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag/counters.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag/counters.hbs
@@ -30,5 +30,5 @@
   sortAction="sortChanged"
   }}
 {{else}}
-  {{partial "partials/loading-anim"}}
+  {{partial "loading"}}
 {{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/index.hbs b/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
index fdb0a91..2f4a214 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
@@ -43,7 +43,7 @@
       </tr>
       <tr>
         <td>Submitter</td>
-        <td>{{model.user}}</td>
+        <td>{{model.submitter}}</td>
       </tr>
       <tr>
         <td>Status</td>
@@ -70,5 +70,5 @@
     </tbody>
   </table>
 {{else}}
-  {{partial "partials/loading-anim"}}
+  {{partial "loading"}}
 {{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/templates/dag/tasks.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/tasks.hbs b/tez-ui2/src/main/webapp/app/templates/dag/tasks.hbs
index 6d8d4c3..57cfe86 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag/tasks.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag/tasks.hbs
@@ -31,5 +31,5 @@
     pageAction="pageChanged"
   }}
 {{else}}
-  {{partial "partials/loading-anim"}}
+  {{partial "loading"}}
 {{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/templates/dag/vertices.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/vertices.hbs b/tez-ui2/src/main/webapp/app/templates/dag/vertices.hbs
index 6d8d4c3..57cfe86 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag/vertices.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag/vertices.hbs
@@ -31,5 +31,5 @@
     pageAction="pageChanged"
   }}
 {{else}}
-  {{partial "partials/loading-anim"}}
+  {{partial "loading"}}
 {{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/templates/dags.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dags.hbs b/tez-ui2/src/main/webapp/app/templates/dags.hbs
index 3e64a7e..56621e9 100644
--- a/tez-ui2/src/main/webapp/app/templates/dags.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dags.hbs
@@ -16,7 +16,7 @@
  * limitations under the License.
 }}
 
-{{tab-n-refresh tabs=tabs autoRefreshEnabled=false}}
+{{tab-n-refresh tabs=tabs autoRefreshEnabled=false loadTime=loadTime}}
 
 {{#if loaded}}
   {{em-table
@@ -37,5 +37,5 @@
     pageAction="pageChanged"
   }}
 {{else}}
-  {{partial "partials/loading-anim"}}
+  {{partial "loading"}}
 {{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/templates/loading.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/loading.hbs b/tez-ui2/src/main/webapp/app/templates/loading.hbs
new file mode 100644
index 0000000..0b3bb19
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/loading.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.
+}}
+
+<h3>Loading...</h3>
+
+<div class="progress">
+  <div class="progress-bar progress-bar-striped active" role="progressbar" style="width:100%">
+  </div>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/templates/partials/loading-anim.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/partials/loading-anim.hbs b/tez-ui2/src/main/webapp/app/templates/partials/loading-anim.hbs
deleted file mode 100644
index 0b3bb19..0000000
--- a/tez-ui2/src/main/webapp/app/templates/partials/loading-anim.hbs
+++ /dev/null
@@ -1,24 +0,0 @@
-{{!
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-}}
-
-<h3>Loading...</h3>
-
-<div class="progress">
-  <div class="progress-bar progress-bar-striped active" role="progressbar" style="width:100%">
-  </div>
-</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/templates/task.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/task.hbs b/tez-ui2/src/main/webapp/app/templates/task.hbs
index 308b905..80ec4f4 100644
--- a/tez-ui2/src/main/webapp/app/templates/task.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/task.hbs
@@ -16,5 +16,5 @@
  * limitations under the License.
 }}
 
-{{tab-n-refresh tabs=tabs}}
+{{tab-n-refresh tabs=tabs loadTime=loadTime}}
 {{outlet}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/templates/task/attempts.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/task/attempts.hbs b/tez-ui2/src/main/webapp/app/templates/task/attempts.hbs
index 6d8d4c3..57cfe86 100644
--- a/tez-ui2/src/main/webapp/app/templates/task/attempts.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/task/attempts.hbs
@@ -31,5 +31,5 @@
     pageAction="pageChanged"
   }}
 {{else}}
-  {{partial "partials/loading-anim"}}
+  {{partial "loading"}}
 {{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/templates/task/counters.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/task/counters.hbs b/tez-ui2/src/main/webapp/app/templates/task/counters.hbs
index e590b36..aa4c127 100644
--- a/tez-ui2/src/main/webapp/app/templates/task/counters.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/task/counters.hbs
@@ -30,5 +30,5 @@
   sortAction="sortChanged"
   }}
 {{else}}
-  {{partial "partials/loading-anim"}}
+  {{partial "loading"}}
 {{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/templates/task/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/task/index.hbs b/tez-ui2/src/main/webapp/app/templates/task/index.hbs
index b559203..ee6b0c6 100644
--- a/tez-ui2/src/main/webapp/app/templates/task/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/task/index.hbs
@@ -53,5 +53,5 @@
     </tbody>
   </table>
 {{else}}
-  {{partial "partials/loading-anim"}}
+  {{partial "loading"}}
 {{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/templates/vertex.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/vertex.hbs b/tez-ui2/src/main/webapp/app/templates/vertex.hbs
index 308b905..80ec4f4 100644
--- a/tez-ui2/src/main/webapp/app/templates/vertex.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/vertex.hbs
@@ -16,5 +16,5 @@
  * limitations under the License.
 }}
 
-{{tab-n-refresh tabs=tabs}}
+{{tab-n-refresh tabs=tabs loadTime=loadTime}}
 {{outlet}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/templates/vertex/attempts.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/vertex/attempts.hbs b/tez-ui2/src/main/webapp/app/templates/vertex/attempts.hbs
index 6d8d4c3..57cfe86 100644
--- a/tez-ui2/src/main/webapp/app/templates/vertex/attempts.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/vertex/attempts.hbs
@@ -31,5 +31,5 @@
     pageAction="pageChanged"
   }}
 {{else}}
-  {{partial "partials/loading-anim"}}
+  {{partial "loading"}}
 {{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/templates/vertex/counters.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/vertex/counters.hbs b/tez-ui2/src/main/webapp/app/templates/vertex/counters.hbs
index e590b36..aa4c127 100644
--- a/tez-ui2/src/main/webapp/app/templates/vertex/counters.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/vertex/counters.hbs
@@ -30,5 +30,5 @@
   sortAction="sortChanged"
   }}
 {{else}}
-  {{partial "partials/loading-anim"}}
+  {{partial "loading"}}
 {{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs b/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs
index 8183842..153d583 100644
--- a/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs
@@ -124,7 +124,6 @@
       </tr>
     </tbody>
   </table>
-
 {{else}}
-  {{partial "partials/loading-anim"}}
+  {{partial "loading"}}
 {{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/app/templates/vertex/tasks.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/vertex/tasks.hbs b/tez-ui2/src/main/webapp/app/templates/vertex/tasks.hbs
index 6d8d4c3..57cfe86 100644
--- a/tez-ui2/src/main/webapp/app/templates/vertex/tasks.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/vertex/tasks.hbs
@@ -31,5 +31,5 @@
     pageAction="pageChanged"
   }}
 {{else}}
-  {{partial "partials/loading-anim"}}
+  {{partial "loading"}}
 {{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/tests/unit/models/abstract-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/abstract-test.js b/tez-ui2/src/main/webapp/tests/unit/models/abstract-test.js
index 42fe21c..cec99a2 100644
--- a/tez-ui2/src/main/webapp/tests/unit/models/abstract-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/models/abstract-test.js
@@ -16,14 +16,43 @@
  * limitations under the License.
  */
 
+import Ember from 'ember';
+
 import { moduleForModel, test } from 'ember-qunit';
 
 moduleForModel('abstract', 'Unit | Model | abstract', {
   // Specify the other units that are required for this test.
-  needs: []
+  // needs: []
 });
 
 test('Basic test for existence', function(assert) {
   let model = this.subject();
+
   assert.ok(model);
+  assert.ok(model.mergedProperties);
+  assert.ok(model.refreshLoadTime);
+
+  assert.ok(model._notifyProperties);
+  assert.ok(model.didLoad);
+});
+
+test('_notifyProperties test - will fail if _notifyProperties implementation is changed in ember-data', function(assert) {
+  let model = this.subject();
+
+  Ember._beginPropertyChanges = Ember.beginPropertyChanges;
+
+  assert.expect(1 + 1);
+  // refreshLoadTime will be called by us & beginPropertyChanges by ember data
+
+  Ember.beginPropertyChanges = function () {
+    assert.ok(true);
+    Ember._beginPropertyChanges();
+  };
+  model.refreshLoadTime = function () {
+    assert.ok(true);
+  };
+
+  model._notifyProperties([]);
+
+  Ember.beginPropertyChanges = Ember._beginPropertyChanges;
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js
index e1e446a..202e889 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js
@@ -48,6 +48,7 @@ test('Basic creation test', function(assert) {
   assert.ok(route.afterLoad);
   assert.ok(route.setValue);
 
+  assert.ok(route.getLoadTime);
   assert.ok(route._setControllerModel);
   assert.ok(route.setLoader);
 
@@ -78,19 +79,21 @@ test('queryFromParams test', function(assert) {
 test('checkAndCall test', function(assert) {
   let route = this.subject(),
       testValue = {},
-      testQuery = {};
+      testQuery = {},
+      testOptions = {};
 
-  assert.expect(2 + 1);
+  assert.expect(3 + 1);
 
-  route.testFunction = function (value, query) {
+  route.testFunction = function (value, query, options) {
     assert.equal(value, testValue, "Value check for id 1");
     assert.equal(query, testQuery, "Query check for id 1");
+    assert.equal(options, testOptions, "Options check for id 1");
   };
   route.currentPromiseId = 1;
 
-  route.checkAndCall(1, "testFunction", testQuery, testValue);
+  route.checkAndCall(1, "testFunction", testQuery, testOptions, testValue);
   assert.throws(function () {
-    route.checkAndCall(2, "testFunction", testQuery, testValue);
+    route.checkAndCall(2, "testFunction", testQuery, testOptions, testValue);
   });
 });
 
@@ -98,10 +101,10 @@ test('loadData test - Hook sequence check', function(assert) {
   let route = this.subject();
 
   // Bind poilyfill
-  Function.prototype.bind = function (context, val1, val2, val3) {
+  Function.prototype.bind = function (context, val1, val2, val3, val4) {
     var that = this;
     return function (val) {
-      return that.call(context, val1, val2, val3, val);
+      return that.call(context, val1, val2, val3, val4, val);
     };
   };
 
@@ -137,10 +140,10 @@ test('loadData test - ID change check with exception throw', function(assert) {
   let route = this.subject();
 
   // Bind poilyfill
-  Function.prototype.bind = function (context, val1, val2, val3) {
+  Function.prototype.bind = function (context, val1, val2, val3, val4) {
     var that = this;
     return function (val) {
-      return that.call(context, val1, val2, val3, val);
+      return that.call(context, val1, val2, val3, val4, val);
     };
   };
 
@@ -209,6 +212,17 @@ test('setValue test', function(assert) {
   assert.equal(route.get("isLoading"), false);
 });
 
+test('getLoadTime test', function(assert) {
+  let route = this.subject(),
+      testTime = Date.now(),
+      testRecord = {
+        loadTime: testTime
+      };
+
+  assert.equal(route.getLoadTime(testRecord), testTime);
+  assert.equal(route.getLoadTime([testRecord]), testTime);
+});
+
 test('_setControllerModel test', function(assert) {
   let route = this.subject(),
       testValue = {},

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/tests/unit/routes/app/configs-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/app/configs-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/app/configs-test.js
index 9ca6a7a..c12189d 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/app/configs-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/app/configs-test.js
@@ -28,6 +28,7 @@ test('Basic creation test', function(assert) {
 
   assert.ok(route);
   assert.ok(route.title);
+  assert.ok(route.loaderNamespace);
   assert.ok(route.setupController);
   assert.ok(route.load);
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/tests/unit/routes/app/dags-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/app/dags-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/app/dags-test.js
index f7ac141..8c5f23d 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/app/dags-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/app/dags-test.js
@@ -28,6 +28,7 @@ test('Basic creation test', function(assert) {
 
   assert.ok(route);
   assert.ok(route.title);
+  assert.ok(route.loaderNamespace);
   assert.ok(route.setupController);
   assert.ok(route.load);
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/tests/unit/routes/app/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/app/index-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/app/index-test.js
index 2ea4415..191cc18 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/app/index-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/app/index-test.js
@@ -28,6 +28,7 @@ test('Basic creation test', function(assert) {
 
   assert.ok(route);
   assert.ok(route.title);
+  assert.ok(route.loaderNamespace);
   assert.ok(route.setupController);
   assert.ok(route.load);
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/tests/unit/routes/attempt/counters-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/attempt/counters-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/attempt/counters-test.js
index 32d808d..4d47431 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/attempt/counters-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/attempt/counters-test.js
@@ -28,6 +28,7 @@ test('Basic creation test', function(assert) {
 
   assert.ok(route);
   assert.ok(route.title);
+  assert.ok(route.loaderNamespace);
   assert.ok(route.setupController);
   assert.ok(route.load);
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/tests/unit/routes/attempt/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/attempt/index-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/attempt/index-test.js
index b0e3d2f..69877da 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/attempt/index-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/attempt/index-test.js
@@ -28,6 +28,7 @@ test('Basic creation test', function(assert) {
 
   assert.ok(route);
   assert.ok(route.title);
+  assert.ok(route.loaderNamespace);
   assert.ok(route.setupController);
   assert.ok(route.load);
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/tests/unit/routes/dag/attempts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/dag/attempts-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/dag/attempts-test.js
index 36a67b4..78dd520 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/dag/attempts-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/dag/attempts-test.js
@@ -28,6 +28,7 @@ test('Basic creation test', function(assert) {
 
   assert.ok(route);
   assert.ok(route.title);
+  assert.ok(route.loaderNamespace);
   assert.ok(route.setupController);
   assert.ok(route.load);
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/tests/unit/routes/dag/counters-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/dag/counters-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/dag/counters-test.js
index 41ca35c..d2cd66e 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/dag/counters-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/dag/counters-test.js
@@ -28,6 +28,7 @@ test('Basic creation test', function(assert) {
 
   assert.ok(route);
   assert.ok(route.title);
+  assert.ok(route.loaderNamespace);
   assert.ok(route.setupController);
   assert.ok(route.load);
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/tests/unit/routes/dag/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/dag/index-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/dag/index-test.js
index aef7031..8c0cb5d 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/dag/index-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/dag/index-test.js
@@ -28,6 +28,7 @@ test('Basic creation test', function(assert) {
 
   assert.ok(route);
   assert.ok(route.title);
+  assert.ok(route.loaderNamespace);
   assert.ok(route.setupController);
   assert.ok(route.load);
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/tests/unit/routes/dag/tasks-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/dag/tasks-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/dag/tasks-test.js
index fa30f2e..0dc533d 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/dag/tasks-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/dag/tasks-test.js
@@ -28,6 +28,7 @@ test('Basic creation test', function(assert) {
 
   assert.ok(route);
   assert.ok(route.title);
+  assert.ok(route.loaderNamespace);
   assert.ok(route.setupController);
   assert.ok(route.load);
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/tests/unit/routes/dag/vertices-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/dag/vertices-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/dag/vertices-test.js
index fb27c80..b8d2f2e 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/dag/vertices-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/dag/vertices-test.js
@@ -28,6 +28,7 @@ test('Basic creation test', function(assert) {
 
   assert.ok(route);
   assert.ok(route.title);
+  assert.ok(route.loaderNamespace);
   assert.ok(route.setupController);
   assert.ok(route.load);
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/tests/unit/routes/task/attempts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/task/attempts-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/task/attempts-test.js
index 2c139b7..b38cc6f 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/task/attempts-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/task/attempts-test.js
@@ -28,6 +28,7 @@ test('Basic creation test', function(assert) {
 
   assert.ok(route);
   assert.ok(route.title);
+  assert.ok(route.loaderNamespace);
   assert.ok(route.setupController);
   assert.ok(route.load);
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/tests/unit/routes/task/counters-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/task/counters-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/task/counters-test.js
index fafb2a0..87895aa 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/task/counters-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/task/counters-test.js
@@ -28,6 +28,7 @@ test('Basic creation test', function(assert) {
 
   assert.ok(route);
   assert.ok(route.title);
+  assert.ok(route.loaderNamespace);
   assert.ok(route.setupController);
   assert.ok(route.load);
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/tests/unit/routes/task/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/task/index-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/task/index-test.js
index 603a8d6..91d3e5b 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/task/index-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/task/index-test.js
@@ -28,6 +28,7 @@ test('Basic creation test', function(assert) {
 
   assert.ok(route);
   assert.ok(route.title);
+  assert.ok(route.loaderNamespace);
   assert.ok(route.setupController);
   assert.ok(route.load);
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/tests/unit/routes/vertex/attempts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/vertex/attempts-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/vertex/attempts-test.js
index 9ba3cf0..250a3b5 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/vertex/attempts-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/vertex/attempts-test.js
@@ -28,6 +28,7 @@ test('Basic creation test', function(assert) {
 
   assert.ok(route);
   assert.ok(route.title);
+  assert.ok(route.loaderNamespace);
   assert.ok(route.setupController);
   assert.ok(route.load);
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/tests/unit/routes/vertex/counters-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/vertex/counters-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/vertex/counters-test.js
index 6f76c1c..9c14e8f 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/vertex/counters-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/vertex/counters-test.js
@@ -28,6 +28,7 @@ test('Basic creation test', function(assert) {
 
   assert.ok(route);
   assert.ok(route.title);
+  assert.ok(route.loaderNamespace);
   assert.ok(route.setupController);
   assert.ok(route.load);
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/tests/unit/routes/vertex/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/vertex/index-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/vertex/index-test.js
index cc7e9de..bab59b6 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/vertex/index-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/vertex/index-test.js
@@ -28,6 +28,7 @@ test('Basic creation test', function(assert) {
 
   assert.ok(route);
   assert.ok(route.title);
+  assert.ok(route.loaderNamespace);
   assert.ok(route.setupController);
   assert.ok(route.load);
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/tests/unit/routes/vertex/tasks-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/vertex/tasks-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/vertex/tasks-test.js
index e70434f..432b619 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/vertex/tasks-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/vertex/tasks-test.js
@@ -28,6 +28,7 @@ test('Basic creation test', function(assert) {
 
   assert.ok(route);
   assert.ok(route.title);
+  assert.ok(route.loaderNamespace);
   assert.ok(route.setupController);
   assert.ok(route.load);
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8f6beddc/tez-ui2/src/main/webapp/tests/unit/services/loader-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/services/loader-test.js b/tez-ui2/src/main/webapp/tests/unit/services/loader-test.js
index 548aca8..7000188 100644
--- a/tez-ui2/src/main/webapp/tests/unit/services/loader-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/services/loader-test.js
@@ -180,6 +180,7 @@ test('getCacheKey test', function(assert) {
 test('queryRecord test', function(assert) {
   let service = this.subject(),
       testNameSpace = "ns",
+      testOptions = {},
       testQueryParams = {},
       testUrlParams = {},
       testType = "type",
@@ -187,7 +188,7 @@ test('queryRecord test', function(assert) {
       testID = 1,
       cacheKey = service.getCacheKey(testType, testQueryParams, testID);
 
-  assert.expect(3 + 5 + 3);
+  assert.expect(1 + 4 + 5 + 3);
 
   service.nameSpace = testNameSpace;
   service.checkRequisite = Ember.K;
@@ -195,9 +196,11 @@ test('queryRecord test', function(assert) {
     assert.equal(type, testType);
 
     return {
-      loadRelations: function (thisService, record) {
+      loadRelations: function (thisService, record, options, urlParams) {
         assert.equal(thisService, service);
         assert.equal(record, testRecord);
+        assert.equal(options, testOptions);
+        assert.equal(urlParams, testUrlParams);
 
         return record;
       }
@@ -216,7 +219,7 @@ test('queryRecord test', function(assert) {
 
   service.cache = Ember.Object.create();
   assert.notOk(service.get("cache").get(cacheKey));
-  service.queryRecord(testType, testID, testQueryParams, testUrlParams).then(function (record) {
+  service.queryRecord(testType, testID, testOptions, testQueryParams, testUrlParams).then(function (record) {
     assert.equal(record, testRecord);
   });
   assert.ok(service.get("cache").get(cacheKey));
@@ -225,6 +228,7 @@ test('queryRecord test', function(assert) {
 test('query test', function(assert) {
   let service = this.subject(),
       testNameSpace = "ns",
+      testOptions = {},
       testQueryParams = {},
       testUrlParams = {},
       testType = "type",
@@ -232,7 +236,7 @@ test('query test', function(assert) {
       testRecords = [testRecord, testRecord],
       cacheKey = service.getCacheKey(testType, testQueryParams);
 
-  assert.expect(1 + (2 + 2) + 4 + 3);
+  assert.expect(1 + (4 + 4) + 4 + 3);
 
   service.nameSpace = testNameSpace;
   service.checkRequisite = Ember.K;
@@ -240,9 +244,11 @@ test('query test', function(assert) {
     assert.equal(type, testType);
 
     return {
-      loadRelations: function (thisService, record) {
+      loadRelations: function (thisService, record, options, urlParams) {
         assert.equal(thisService, service);
         assert.equal(record, testRecord);
+        assert.equal(options, testOptions);
+        assert.equal(urlParams, testUrlParams);
 
         return record;
       }
@@ -260,7 +266,7 @@ test('query test', function(assert) {
 
   service.cache = Ember.Object.create();
   assert.notOk(service.get("cache").get(cacheKey));
-  service.query(testType, testQueryParams, testUrlParams).then(function (records) {
+  service.query(testType, testQueryParams, testOptions, testUrlParams).then(function (records) {
     assert.equal(records, testRecords);
   });
   assert.ok(service.get("cache").get(cacheKey));


[28/45] tez git commit: TEZ-3060. Tez UI 2: Activate auto-refresh (sree)

Posted by sr...@apache.org.
http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/controllers/counters-table-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/counters-table-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/counters-table-test.js
new file mode 100644
index 0000000..e0e7b02
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/counters-table-test.js
@@ -0,0 +1,91 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:counters-table', 'Unit | Controller | counters table', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K,
+    initVisibleColumns: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.columns);
+  assert.ok(controller.counters);
+  assert.ok(controller._countersObserver);
+
+});
+
+test('counters & _countersObserver test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K,
+    initVisibleColumns: Ember.K,
+    model: {
+      counterGroupsHash: {
+        "foo": {
+          "Foo Name 1": "Value 1",
+          "Foo Name 2": "Value 2",
+          "Foo Name 3": "Value 3"
+        },
+        "bar": {
+          "Bar Name 1": "Value 1",
+          "Bar Name 2": "Value 2",
+          "Bar Name 3": "Value 3"
+        }
+      }
+    }
+  });
+
+  assert.equal(controller.countersCount, 0);
+
+  controller._countersObserver();
+
+  assert.equal(controller.get("counters.0.groupName"), "foo");
+  assert.equal(controller.get("counters.0.counterName"), "Foo Name 1");
+  assert.equal(controller.get("counters.0.counterValue"), "Value 1");
+
+  assert.equal(controller.get("counters.1.groupName"), "foo");
+  assert.equal(controller.get("counters.1.counterName"), "Foo Name 2");
+  assert.equal(controller.get("counters.1.counterValue"), "Value 2");
+
+  assert.equal(controller.get("counters.2.groupName"), "foo");
+  assert.equal(controller.get("counters.2.counterName"), "Foo Name 3");
+  assert.equal(controller.get("counters.2.counterValue"), "Value 3");
+
+
+  assert.equal(controller.get("counters.3.groupName"), "bar");
+  assert.equal(controller.get("counters.3.counterName"), "Bar Name 1");
+  assert.equal(controller.get("counters.3.counterValue"), "Value 1");
+
+  assert.equal(controller.get("counters.4.groupName"), "bar");
+  assert.equal(controller.get("counters.4.counterName"), "Bar Name 2");
+  assert.equal(controller.get("counters.4.counterValue"), "Value 2");
+
+  assert.equal(controller.get("counters.5.groupName"), "bar");
+  assert.equal(controller.get("counters.5.counterName"), "Bar Name 3");
+  assert.equal(controller.get("counters.5.counterValue"), "Value 3");
+
+  assert.equal(controller.countersCount, 6);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js
index 3fa8ff7..f0aeeb9 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js
@@ -28,7 +28,10 @@ moduleFor('controller:dag/attempts', 'Unit | Controller | dag/attempts', {
 test('Basic creation test', function(assert) {
   let controller = this.subject({
     send: Ember.K,
-    initVisibleColumns: Ember.K
+    initVisibleColumns: Ember.K,
+    getCounterColumns: function () {
+      return [];
+    }
   });
 
   assert.ok(controller);

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js
index eace870..474c61a 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js
@@ -28,7 +28,10 @@ moduleFor('controller:dag/tasks', 'Unit | Controller | dag/tasks', {
 test('Basic creation test', function(assert) {
   let controller = this.subject({
     send: Ember.K,
-    initVisibleColumns: Ember.K
+    initVisibleColumns: Ember.K,
+    getCounterColumns: function () {
+      return [];
+    }
   });
 
   assert.ok(controller);

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
index f54b1a8..d0b32f3 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
@@ -28,7 +28,10 @@ moduleFor('controller:dag/vertices', 'Unit | Controller | dag/vertices', {
 test('Basic creation test', function(assert) {
   let controller = this.subject({
     send: Ember.K,
-    initVisibleColumns: Ember.K
+    initVisibleColumns: Ember.K,
+    getCounterColumns: function () {
+      return [];
+    }
   });
 
   assert.ok(controller);

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/controllers/multi-table-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/multi-table-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/multi-table-test.js
new file mode 100644
index 0000000..d4ab10f
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/multi-table-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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:multi-table', 'Unit | Controller | multi table', {
+  // Specify the other units that are required for this test.
+  // needs: ['service:local-storage']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K,
+    initVisibleColumns: Ember.K,
+    localStorage: Ember.Object.create(),
+    getCounterColumns: function () {
+      return [];
+    }
+  });
+
+  assert.ok(controller);
+  assert.ok(controller._visibleColumnsObserver);
+  assert.ok(controller.sendCountersChanged);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/controllers/parent-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/parent-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/parent-test.js
new file mode 100644
index 0000000..2b0ff97
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/parent-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:parent', 'Unit | Controller | parent', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K,
+    initVisibleColumns: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.polling);
+  assert.ok(controller.actions.autoRefreshChanged);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/controllers/table-page-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/table-page-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/table-page-test.js
deleted file mode 100644
index 07941b9..0000000
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/table-page-test.js
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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 { moduleFor, test } from 'ember-qunit';
-
-moduleFor('controller:table-page', 'Unit | Controller | table page', {
-  // Specify the other units that are required for this test.
-  // needs: ['controller:foo']
-});
-
-test('Basic creation test', function(assert) {
-  let controller = this.subject({
-    send: Ember.K,
-    initVisibleColumns: Ember.K
-  });
-
-  assert.ok(controller);
-  assert.ok(controller.queryParams);
-
-  assert.equal(controller.rowCount, 10);
-  assert.equal(controller.searchText, "");
-  assert.equal(controller.sortColumnId, "");
-  assert.equal(controller.sortOrder, "");
-  assert.equal(controller.pageNo, 1);
-
-  assert.ok(controller.headerComponentNames);
-  assert.ok(controller.visibleColumnIDs);
-  assert.ok(controller.columnSelectorTitle);
-  assert.ok(controller.definition);
-
-  assert.ok(controller.storageID);
-  assert.ok(controller.initVisibleColumns);
-
-  assert.ok(controller.columns);
-  assert.ok(controller.allColumns);
-  assert.ok(controller.visibleColumns);
-
-  assert.ok(controller.getCounterColumns);
-
-  assert.ok(controller.actions.searchChanged);
-  assert.ok(controller.actions.sortChanged);
-  assert.ok(controller.actions.rowsChanged);
-  assert.ok(controller.actions.pageChanged);
-
-  assert.ok(controller.actions.openColumnSelector);
-  assert.ok(controller.actions.columnsSelected);
-});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/controllers/table-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/table-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/table-test.js
new file mode 100644
index 0000000..360b6a9
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/table-test.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 Ember from 'ember';
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:table', 'Unit | Controller | table', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K,
+    initVisibleColumns: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.queryParams);
+
+  assert.equal(controller.rowCount, 10);
+  assert.equal(controller.searchText, "");
+  assert.equal(controller.sortColumnId, "");
+  assert.equal(controller.sortOrder, "");
+  assert.equal(controller.pageNo, 1);
+
+  assert.ok(controller.headerComponentNames);
+  assert.ok(controller.visibleColumnIDs);
+  assert.ok(controller.columnSelectorTitle);
+  assert.ok(controller.definition);
+
+  assert.ok(controller.storageID);
+  assert.ok(controller.initVisibleColumns);
+
+  assert.ok(controller.columns);
+  assert.ok(controller.allColumns);
+  assert.ok(controller.visibleColumns);
+
+  assert.ok(controller.getCounterColumns);
+
+  assert.ok(controller.actions.searchChanged);
+  assert.ok(controller.actions.sortChanged);
+  assert.ok(controller.actions.rowsChanged);
+  assert.ok(controller.actions.pageChanged);
+
+  assert.ok(controller.actions.openColumnSelector);
+  assert.ok(controller.actions.columnsSelected);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.js
index 43badfc..b2006de 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.js
@@ -28,7 +28,10 @@ moduleFor('controller:task/attempts', 'Unit | Controller | task/attempts', {
 test('Basic creation test', function(assert) {
   let controller = this.subject({
     send: Ember.K,
-    initVisibleColumns: Ember.K
+    initVisibleColumns: Ember.K,
+    getCounterColumns: function () {
+      return [];
+    }
   });
 
   assert.ok(controller);

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/attempts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/attempts-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/attempts-test.js
index de89864..eb68055 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/attempts-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/attempts-test.js
@@ -28,7 +28,10 @@ moduleFor('controller:vertex/attempts', 'Unit | Controller | vertex/attempts', {
 test('Basic creation test', function(assert) {
   let controller = this.subject({
     send: Ember.K,
-    initVisibleColumns: Ember.K
+    initVisibleColumns: Ember.K,
+    getCounterColumns: function () {
+      return [];
+    }
   });
 
   assert.ok(controller);

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/tasks-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/tasks-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/tasks-test.js
index 23393ef..9aae299 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/tasks-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/tasks-test.js
@@ -28,7 +28,10 @@ moduleFor('controller:vertex/tasks', 'Unit | Controller | vertex/tasks', {
 test('Basic creation test', function(assert) {
   let controller = this.subject({
     send: Ember.K,
-    initVisibleColumns: Ember.K
+    initVisibleColumns: Ember.K,
+    getCounterColumns: function () {
+      return [];
+    }
   });
 
   assert.ok(controller);

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/entities/am-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/entities/am-test.js b/tez-ui2/src/main/webapp/tests/unit/entities/am-test.js
new file mode 100644
index 0000000..b48eea5
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/entities/am-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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('entitie:am', 'Unit | Entity | am', {
+  // Specify the other units that are required for this test.
+  // needs: ['entitie:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let adapter = this.subject();
+
+  assert.ok(adapter);
+  assert.ok(adapter.resetJoiner);
+  assert.ok(adapter.queryRecord);
+  assert.ok(adapter.queryJoinedRecords);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/entities/attempt-am-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/entities/attempt-am-test.js b/tez-ui2/src/main/webapp/tests/unit/entities/attempt-am-test.js
new file mode 100644
index 0000000..2856ec5
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/entities/attempt-am-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('entitie:attempt-am', 'Unit | Entity | attempt am', {
+  // Specify the other units that are required for this test.
+  // needs: ['entitie:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let adapter = this.subject();
+
+  assert.ok(adapter);
+  assert.ok(adapter.queryPropertyToJoin);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/entities/entity-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/entities/entity-test.js b/tez-ui2/src/main/webapp/tests/unit/entities/entity-test.js
index 2129fb3..fb0bd8a 100644
--- a/tez-ui2/src/main/webapp/tests/unit/entities/entity-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/entities/entity-test.js
@@ -29,55 +29,26 @@ test('Basic creation test', function(assert) {
   let adapter = this.subject();
 
   assert.ok(adapter);
-  assert.ok(adapter.loadRelations);
-  assert.ok(adapter.normalizeNeed);
-  assert.ok(adapter.loadNeeds);
-});
-
-test('loadRelations test', function(assert) {
-  let adapter = this.subject(),
-      testLoader = {},
-      testModel = {},
-      relationsPromise;
-
-  assert.expect(2 + 1 + 2 + 2);
-
-  // Test model without needs
-  adapter.loadNeeds = function (loader, model) {
-    assert.equal(loader, testLoader);
-    assert.equal(model, testModel);
-
-    return null;
-  };
-  relationsPromise = adapter.loadRelations(testLoader, testModel);
-
-  assert.equal(relationsPromise, testModel, "Model without needs");
-
-  // Test model with needs
-  adapter.loadNeeds = function (loader, model) {
-    assert.equal(loader, testLoader);
-    assert.equal(model, testModel);
 
-    return Ember.RSVP.resolve();
-  };
-  relationsPromise = adapter.loadRelations(testLoader, testModel);
+  assert.ok(adapter.queryRecord);
+  assert.ok(adapter.query);
 
-  assert.notEqual(relationsPromise, testModel);
-  relationsPromise.then(function (model) {
-    assert.equal(model, testModel);
-  });
+  assert.ok(adapter.normalizeNeed);
+  assert.ok(adapter._loadNeed);
+  assert.ok(adapter.loadNeed);
 
+  assert.ok(adapter._loadAllNeeds);
+  assert.ok(adapter.loadAllNeeds);
 });
 
 test('normalizeNeed test', function(assert) {
   let adapter = this.subject(),
-      expectedProperties = ["name", "type", "idKey", "lazy", "silent"];
+      expectedProperties = ["name", "type", "idKey", "silent"];
 
   assert.deepEqual(adapter.normalizeNeed("app", "appKey").getProperties(expectedProperties), {
     name: "app",
     type: "app",
     idKey: "appKey",
-    lazy: false,
     silent: false
   }, "Test 1");
 
@@ -85,7 +56,6 @@ test('normalizeNeed test', function(assert) {
     name: "app",
     type: "app",
     idKey: "appKey",
-    lazy: false,
     silent: false
   }, "Test 2");
 
@@ -93,28 +63,18 @@ test('normalizeNeed test', function(assert) {
     name: "app",
     type: "application",
     idKey: "appKey",
-    lazy: false,
     silent: false
   }, "Test 3");
 
-  assert.deepEqual(adapter.normalizeNeed( "app", { lazy: true, idKey: "appKey" }).getProperties(expectedProperties), {
-    name: "app",
-    type: "app",
-    idKey: "appKey",
-    lazy: true,
-    silent: false
-  }, "Test 4");
-
   assert.deepEqual(adapter.normalizeNeed( "app", { silent: true, idKey: "appKey" }).getProperties(expectedProperties), {
     name: "app",
     type: "app",
     idKey: "appKey",
-    lazy: false,
     silent: true
-  }, "Test 5");
+  }, "Test 4");
 });
 
-test('loadNeeds basic test', function(assert) {
+test('loadAllNeeds basic test', function(assert) {
   let adapter = this.subject(),
       loader,
       testModel = Ember.Object.create({
@@ -128,7 +88,7 @@ test('loadNeeds basic test', function(assert) {
 
   assert.expect(1 + 2 + 1);
 
-  assert.equal(adapter.loadNeeds(loader, Ember.Object.create()), undefined, "Model without needs");
+  assert.equal(adapter.loadAllNeeds(loader, Ember.Object.create()), undefined, "Model without needs");
 
   loader = {
     queryRecord: function (type, id) {
@@ -146,12 +106,12 @@ test('loadNeeds basic test', function(assert) {
       return Ember.RSVP.resolve();
     }
   };
-  adapter.loadNeeds(loader, testModel).then(function () {
+  adapter.loadAllNeeds(loader, testModel).then(function () {
     assert.ok(true);
   });
 });
 
-test('loadNeeds silent=false test', function(assert) {
+test('loadAllNeeds silent=false test', function(assert) {
   let adapter = this.subject(),
       loader,
       testModel = Ember.Object.create({
@@ -173,12 +133,12 @@ test('loadNeeds silent=false test', function(assert) {
       return Ember.RSVP.reject(testErr);
     }
   };
-  adapter.loadNeeds(loader, testModel).catch(function (err) {
+  adapter.loadAllNeeds(loader, testModel).catch(function (err) {
     assert.equal(err, testErr);
   });
 });
 
-test('loadNeeds silent=true test', function(assert) {
+test('loadAllNeeds silent=true test', function(assert) {
   let adapter = this.subject(),
       loader,
       testModel = Ember.Object.create({
@@ -199,31 +159,8 @@ test('loadNeeds silent=true test', function(assert) {
       return Ember.RSVP.resolve();
     }
   };
-  adapter.loadNeeds(loader, testModel).then(function (val) {
+  adapter.loadAllNeeds(loader, testModel).then(function (val) {
     assert.ok(val);
   });
 });
 
-test('loadNeeds lazy=true test', function(assert) {
-  let adapter = this.subject(),
-      loader,
-      testModel = Ember.Object.create({
-        needs: {
-          app: {
-            idKey: "appID",
-            lazy: true
-          },
-        },
-        appID: 1,
-      });
-
-  assert.expect(1 + 1);
-
-  loader = {
-    queryRecord: function (type, id) {
-      assert.equal(id, testModel.get("appID"));
-      return Ember.RSVP.resolve();
-    }
-  };
-  assert.equal(adapter.loadNeeds(loader, testModel), undefined, "Model without needs");
-});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/entities/task-am-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/entities/task-am-test.js b/tez-ui2/src/main/webapp/tests/unit/entities/task-am-test.js
new file mode 100644
index 0000000..7caca54
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/entities/task-am-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('entitie:task-am', 'Unit | Entity | task am', {
+  // Specify the other units that are required for this test.
+  // needs: ['entitie:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let adapter = this.subject();
+
+  assert.ok(adapter);
+  assert.ok(adapter.queryPropertyToJoin);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/entities/vertex-am-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/entities/vertex-am-test.js b/tez-ui2/src/main/webapp/tests/unit/entities/vertex-am-test.js
new file mode 100644
index 0000000..19937f3
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/entities/vertex-am-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('entitie:vertex-am', 'Unit | Entity | vertex am', {
+  // Specify the other units that are required for this test.
+  // needs: ['entitie:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let adapter = this.subject();
+
+  assert.ok(adapter);
+  assert.ok(adapter.queryPropertyToJoin);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/mixins/auto-counter-column-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/mixins/auto-counter-column-test.js b/tez-ui2/src/main/webapp/tests/unit/mixins/auto-counter-column-test.js
index 191eb67..88e2e09 100644
--- a/tez-ui2/src/main/webapp/tests/unit/mixins/auto-counter-column-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/mixins/auto-counter-column-test.js
@@ -39,26 +39,40 @@ test('getCounterColumns test', function(assert) {
   let AutoCounterColumnObject = TestParent.extend(AutoCounterColumnMixin);
   let subject = AutoCounterColumnObject.create({
     model: [{
-      counterGroups: [{
-        counterGroupName: "gp1",
-        counters: [{counterName: "c11"}, {counterName: "c12"}]
-      }]
+      counterGroupsHash: {
+        gp1: {
+          c11: "v11",
+          c12: "v12"
+        }
+      }
     }, {
-      counterGroups: [{
-        counterGroupName: "gp2",
-        counters: [{counterName: "c21"}, {counterName: "c22"}]
-      }]
+      counterGroupsHash: {
+        gp2: {
+          c21: "v21",
+          c22: "v22"
+        },
+        gp3: {
+          c31: "v31",
+          c32: "v32"
+        }
+      }
     }]
   });
 
   let columns = subject.getCounterColumns();
-  assert.equal(columns.length, 4);
+  assert.equal(columns.length, 6);
   assert.equal(columns[0].counterGroupName, "gp1");
   assert.equal(columns[0].counterName, "c11");
   assert.equal(columns[1].counterGroupName, "gp1");
   assert.equal(columns[1].counterName, "c12");
+
   assert.equal(columns[2].counterGroupName, "gp2");
   assert.equal(columns[2].counterName, "c21");
   assert.equal(columns[3].counterGroupName, "gp2");
   assert.equal(columns[3].counterName, "c22");
+
+  assert.equal(columns[4].counterGroupName, "gp3");
+  assert.equal(columns[4].counterName, "c31");
+  assert.equal(columns[5].counterGroupName, "gp3");
+  assert.equal(columns[5].counterName, "c32");
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/models/abstract-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/abstract-test.js b/tez-ui2/src/main/webapp/tests/unit/models/abstract-test.js
index cec99a2..bd6f141 100644
--- a/tez-ui2/src/main/webapp/tests/unit/models/abstract-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/models/abstract-test.js
@@ -34,6 +34,11 @@ test('Basic test for existence', function(assert) {
 
   assert.ok(model._notifyProperties);
   assert.ok(model.didLoad);
+
+  assert.ok(model.entityID);
+  assert.ok(model.index);
+  assert.ok(model.status);
+  assert.ok(model.isComplete);
 });
 
 test('_notifyProperties test - will fail if _notifyProperties implementation is changed in ember-data', function(assert) {

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/models/ahs-app-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/ahs-app-test.js b/tez-ui2/src/main/webapp/tests/unit/models/ahs-app-test.js
index 04b472a..5fd9c60 100644
--- a/tez-ui2/src/main/webapp/tests/unit/models/ahs-app-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/models/ahs-app-test.js
@@ -25,5 +25,7 @@ moduleForModel('ahs-app', 'Unit | Model | ahs app', {
 
 test('Basic creation test', function(assert) {
   let model = this.subject();
+
   assert.ok(!!model);
+  assert.ok(!!model.duration);
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/models/am-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/am-test.js b/tez-ui2/src/main/webapp/tests/unit/models/am-test.js
new file mode 100644
index 0000000..75317bc
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/models/am-test.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 { moduleForModel, test } from 'ember-qunit';
+
+moduleForModel('am', 'Unit | Model | am', {
+  // Specify the other units that are required for this test.
+  needs: []
+});
+
+test('Basic creation test', function(assert) {
+  let model = this.subject();
+
+  // let store = this.store();
+  assert.ok(!!model);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/models/am-timeline-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/am-timeline-test.js b/tez-ui2/src/main/webapp/tests/unit/models/am-timeline-test.js
new file mode 100644
index 0000000..3ed9efb
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/models/am-timeline-test.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 { moduleForModel, test } from 'ember-qunit';
+
+moduleForModel('am-timeline', 'Unit | Model | am timeline', {
+  // Specify the other units that are required for this test.
+  needs: []
+});
+
+test('Basic creation test', function(assert) {
+  let model = this.subject();
+  // let store = this.store();
+
+  assert.ok(!!model);
+  assert.ok(!!model.status);
+  assert.ok(!!model.progress);
+  assert.ok(!!model.counterGroupsHash);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/models/app-rm-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/app-rm-test.js b/tez-ui2/src/main/webapp/tests/unit/models/app-rm-test.js
new file mode 100644
index 0000000..8a4a630
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/models/app-rm-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('app-rm', 'Unit | Model | app rm', {
+  // Specify the other units that are required for this test.
+  needs: []
+});
+
+test('Basic creation test', function(assert) {
+  let model = this.subject();
+
+  assert.ok(!!model);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/models/attempt-am-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/attempt-am-test.js b/tez-ui2/src/main/webapp/tests/unit/models/attempt-am-test.js
new file mode 100644
index 0000000..0e7f2d0
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/models/attempt-am-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('attempt-am', 'Unit | Model | attempt am', {
+  // Specify the other units that are required for this test.
+  needs: []
+});
+
+test('Basic creation test', function(assert) {
+  let model = this.subject();
+  // let store = this.store();
+  assert.ok(!!model);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/models/attempt-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/attempt-test.js b/tez-ui2/src/main/webapp/tests/unit/models/attempt-test.js
index 7d0a78e..c470012 100644
--- a/tez-ui2/src/main/webapp/tests/unit/models/attempt-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/models/attempt-test.js
@@ -27,9 +27,22 @@ test('Basic creation test', function(assert) {
   let model = this.subject();
 
   assert.ok(model);
-  assert.ok(model.index);
+
+  assert.ok(model.needs.dag);
+  assert.ok(model.needs.am);
+
+  assert.ok(model.taskID);
   assert.ok(model.taskIndex);
+
+  assert.ok(model.vertexID);
+  assert.ok(model.vertexIndex);
   assert.ok(model.vertexName);
+
+  assert.ok(model.dagID);
+  assert.ok(model.dag);
+
+  assert.ok(model.containerID);
+  assert.ok(model.nodeID);
 });
 
 test('index test', function(assert) {
@@ -45,7 +58,7 @@ test('taskIndex test', function(assert) {
         taskID: "1_2_3",
       });
 
-  assert.equal(model.get("taskIndex"), "2_3");
+  assert.equal(model.get("taskIndex"), "3");
 });
 
 test('vertexName test', function(assert) {

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/models/dag-am-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/dag-am-test.js b/tez-ui2/src/main/webapp/tests/unit/models/dag-am-test.js
new file mode 100644
index 0000000..58ac45a
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/models/dag-am-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('dag-am', 'Unit | Model | dag am', {
+  // Specify the other units that are required for this test.
+  needs: []
+});
+
+test('Basic creation test', function(assert) {
+  let model = this.subject();
+  // let store = this.store();
+  assert.ok(!!model);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/models/dag-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/dag-test.js b/tez-ui2/src/main/webapp/tests/unit/models/dag-test.js
index 9b04398..513af7d 100644
--- a/tez-ui2/src/main/webapp/tests/unit/models/dag-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/models/dag-test.js
@@ -34,6 +34,7 @@ test('Basic creation test', function(assert) {
     });
 
     assert.ok(!!model);
+    assert.ok(!!model.needs.am);
     assert.equal(model.get("queue"), testQueue);
   });
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/models/rm-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/rm-test.js b/tez-ui2/src/main/webapp/tests/unit/models/rm-test.js
new file mode 100644
index 0000000..39ea4b1
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/models/rm-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('rm', 'Unit | Model | rm', {
+  // Specify the other units that are required for this test.
+  needs: []
+});
+
+test('Basic creation test', function(assert) {
+  let model = this.subject();
+  // let store = this.store();
+  assert.ok(!!model);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/models/task-am-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/task-am-test.js b/tez-ui2/src/main/webapp/tests/unit/models/task-am-test.js
new file mode 100644
index 0000000..fac3a5a
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/models/task-am-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('task-am', 'Unit | Model | task am', {
+  // Specify the other units that are required for this test.
+  needs: []
+});
+
+test('Basic creation test', function(assert) {
+  let model = this.subject();
+  // let store = this.store();
+  assert.ok(!!model);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/models/task-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/task-test.js b/tez-ui2/src/main/webapp/tests/unit/models/task-test.js
index 3d59df6..076b4eb 100644
--- a/tez-ui2/src/main/webapp/tests/unit/models/task-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/models/task-test.js
@@ -27,9 +27,15 @@ test('Basic creation test', function(assert) {
   let model = this.subject();
 
   assert.ok(model);
-  assert.ok(model.needs);
-  assert.ok(model.index);
+  assert.ok(model.needs.dag);
+  assert.ok(model.needs.am);
+
+  assert.ok(model.vertexID);
+  assert.ok(model.vertexIndex);
   assert.ok(model.vertexName);
+
+  assert.ok(model.dagID);
+  assert.ok(model.dag);
 });
 
 test('index test', function(assert) {
@@ -37,7 +43,7 @@ test('index test', function(assert) {
         entityID: "1_2_3",
       });
 
-  assert.equal(model.get("index"), "2_3");
+  assert.equal(model.get("index"), "3");
 });
 
 test('vertexName test', function(assert) {

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/models/timeline-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/timeline-test.js b/tez-ui2/src/main/webapp/tests/unit/models/timeline-test.js
index fc52feb..c47054e 100644
--- a/tez-ui2/src/main/webapp/tests/unit/models/timeline-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/models/timeline-test.js
@@ -43,8 +43,8 @@ test('Basic creation test', function(assert) {
   assert.ok(model.endTime);
   assert.ok(model.duration);
 
-  assert.ok(model.counterGroups);
-  assert.ok(model.counterHash);
+  assert.ok(model._counterGroups);
+  assert.ok(model.counterGroupsHash);
 });
 
 test('appID test', function(assert) {
@@ -92,7 +92,7 @@ test('duration test', function(assert) {
   });
 });
 
-test('counterHash test', function(assert) {
+test('counterGroupsHash test', function(assert) {
   let model = this.subject(),
       testCounterGroup = [{
         counterGroupName: "group_1",
@@ -115,10 +115,10 @@ test('counterHash test', function(assert) {
       }];
 
   Ember.run(function () {
-    model.set("counterGroups", testCounterGroup);
-    assert.equal(model.get("counterHash.group_1.counter_1_1"), "value_1_1");
-    assert.equal(model.get("counterHash.group_1.counter_1_2"), "value_1_2");
-    assert.equal(model.get("counterHash.group_2.counter_2_1"), "value_2_1");
-    assert.equal(model.get("counterHash.group_2.counter_2_2"), "value_2_2");
+    model.set("_counterGroups", testCounterGroup);
+    assert.equal(model.get("counterGroupsHash.group_1.counter_1_1"), "value_1_1");
+    assert.equal(model.get("counterGroupsHash.group_1.counter_1_2"), "value_1_2");
+    assert.equal(model.get("counterGroupsHash.group_2.counter_2_1"), "value_2_1");
+    assert.equal(model.get("counterGroupsHash.group_2.counter_2_2"), "value_2_2");
   });
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/models/vertex-am-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/vertex-am-test.js b/tez-ui2/src/main/webapp/tests/unit/models/vertex-am-test.js
new file mode 100644
index 0000000..1a5bc66
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/models/vertex-am-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('vertex-am', 'Unit | Model | vertex am', {
+  // Specify the other units that are required for this test.
+  needs: []
+});
+
+test('Basic creation test', function(assert) {
+  let model = this.subject();
+  // let store = this.store();
+  assert.ok(!!model);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/models/vertex-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/vertex-test.js b/tez-ui2/src/main/webapp/tests/unit/models/vertex-test.js
index bea4317..c0d2047 100644
--- a/tez-ui2/src/main/webapp/tests/unit/models/vertex-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/models/vertex-test.js
@@ -16,6 +16,8 @@
  * limitations under the License.
  */
 
+import Ember from 'ember';
+
 import { moduleForModel, test } from 'ember-qunit';
 
 moduleForModel('vertex', 'Unit | Model | vertex', {
@@ -27,6 +29,10 @@ test('Basic creation test', function(assert) {
   let model = this.subject();
 
   assert.ok(model);
+
+  assert.ok(model.needs.dag);
+  assert.ok(model.needs.am);
+
   assert.ok(model.runningTasks);
   assert.ok(model.pendingTasks);
 });
@@ -34,15 +40,19 @@ test('Basic creation test', function(assert) {
 test('runningTasks test', function(assert) {
   let model = this.subject();
 
-  assert.equal(model.get("runningTasks"), null);
-  model.set("status", "SUCCEEDED");
-  assert.equal(model.get("runningTasks"), 0);
+  Ember.run(function () {
+    assert.equal(model.get("runningTasks"), null);
+    model.set("status", "SUCCEEDED");
+    assert.equal(model.get("runningTasks"), 0);
+  });
 });
 
 test('pendingTasks test', function(assert) {
   let model = this.subject();
 
-  assert.equal(model.get("pendingTasks"), null);
-  model.set("status", "SUCCEEDED");
-  assert.equal(model.get("pendingTasks"), 0);
+  Ember.run(function () {
+    assert.equal(model.get("pendingTasks"), null);
+    model.set("status", "SUCCEEDED");
+    assert.equal(model.get("pendingTasks"), 0);
+  });
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/routes/am-pollster-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/am-pollster-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/am-pollster-test.js
new file mode 100644
index 0000000..a5383ab
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/am-pollster-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:am-pollster', 'Unit | Route | am pollster', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.onRecordPoll);
+  assert.ok(route.onPollFailure);
+  assert.ok(route.reload);
+  assert.ok(route.actions.countersToPollChanged);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/routes/multi-am-pollster-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/multi-am-pollster-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/multi-am-pollster-test.js
new file mode 100644
index 0000000..eb3670b
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/multi-am-pollster-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:multi-am-pollster', 'Unit | Route | multi am pollster', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.canPoll);
+  assert.ok(route.actions.setPollingRecords);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/routes/pollster-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/pollster-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/pollster-test.js
new file mode 100644
index 0000000..79a5a99
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/pollster-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:pollster', 'Unit | Route | pollster', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+
+  assert.ok(route.onRecordPoll);
+  assert.ok(route.onPollSuccess);
+  assert.ok(route.onPollFailure);
+
+  assert.ok(route.pollData);
+  assert.ok(route.canPoll);
+  assert.ok(route._canPollInit);
+  assert.ok(route._canPollObserver);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/routes/single-am-pollster-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/single-am-pollster-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/single-am-pollster-test.js
new file mode 100644
index 0000000..69c9457
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/single-am-pollster-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:single-am-pollster', 'Unit | Route | single am pollster', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.canPoll);
+  assert.ok(route._loadedValueObserver);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/routes/vertex/tasks-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/vertex/tasks-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/vertex/tasks-test.js
index 432b619..ee983d8 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/vertex/tasks-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/vertex/tasks-test.js
@@ -16,6 +16,8 @@
  * limitations under the License.
  */
 
+import Ember from 'ember';
+
 import { moduleFor, test } from 'ember-qunit';
 
 moduleFor('route:vertex/tasks', 'Unit | Route | vertex/tasks', {
@@ -24,7 +26,10 @@ moduleFor('route:vertex/tasks', 'Unit | Route | vertex/tasks', {
 });
 
 test('Basic creation test', function(assert) {
-  let route = this.subject();
+  let route = this.subject({
+    initVisibleColumns: Ember.K,
+    getCounterColumns: Ember.K
+  });
 
   assert.ok(route);
   assert.ok(route.title);

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/serializers/am-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/serializers/am-test.js b/tez-ui2/src/main/webapp/tests/unit/serializers/am-test.js
new file mode 100644
index 0000000..d9476ad
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/serializers/am-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('serializer:am', 'Unit | Serializer | am', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let serializer = this.subject();
+
+  assert.ok(serializer);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/serializers/app-rm-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/serializers/app-rm-test.js b/tez-ui2/src/main/webapp/tests/unit/serializers/app-rm-test.js
new file mode 100644
index 0000000..01051cf
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/serializers/app-rm-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('serializer:app-rm', 'Unit | Serializer | app rm', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let serializer = this.subject();
+
+  assert.ok(serializer);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/serializers/attempt-am-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/serializers/attempt-am-test.js b/tez-ui2/src/main/webapp/tests/unit/serializers/attempt-am-test.js
new file mode 100644
index 0000000..6fd9e57
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/serializers/attempt-am-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('serializer:attempt-am', 'Unit | Serializer | attempt am', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let serializer = this.subject();
+
+  assert.ok(serializer);
+  assert.ok(serializer.payloadNamespace);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/serializers/dag-am-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/serializers/dag-am-test.js b/tez-ui2/src/main/webapp/tests/unit/serializers/dag-am-test.js
new file mode 100644
index 0000000..be68f98
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/serializers/dag-am-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('serializer:dag-am', 'Unit | Serializer | dag am', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let serializer = this.subject();
+
+  assert.ok(serializer);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/serializers/rm-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/serializers/rm-test.js b/tez-ui2/src/main/webapp/tests/unit/serializers/rm-test.js
new file mode 100644
index 0000000..7175d1a
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/serializers/rm-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('serializer:rm', 'Unit | Serializer | rm', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let serializer = this.subject();
+
+  assert.ok(serializer);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/serializers/task-am-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/serializers/task-am-test.js b/tez-ui2/src/main/webapp/tests/unit/serializers/task-am-test.js
new file mode 100644
index 0000000..cdd1b04
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/serializers/task-am-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('serializer:task-am', 'Unit | Serializer | task am', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let serializer = this.subject();
+
+  assert.ok(serializer);
+  assert.ok(serializer.payloadNamespace);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/serializers/vertex-am-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/serializers/vertex-am-test.js b/tez-ui2/src/main/webapp/tests/unit/serializers/vertex-am-test.js
new file mode 100644
index 0000000..254ca9f
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/serializers/vertex-am-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('serializer:vertex-am', 'Unit | Serializer | vertex am', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let serializer = this.subject();
+
+  assert.ok(serializer);
+  assert.ok(serializer.payloadNamespace);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/services/loader-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/services/loader-test.js b/tez-ui2/src/main/webapp/tests/unit/services/loader-test.js
index 7000188..dbf8faa 100644
--- a/tez-ui2/src/main/webapp/tests/unit/services/loader-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/services/loader-test.js
@@ -142,30 +142,32 @@ test('entityFor test', function(assert) {
     }
     if(name === "entity") {
       assert.equal(type, "entitie");
-      return {
-        actualName: "entity"
-      };
+      return Ember.Object.create({
+        actualName: "entity",
+        name: name
+      });
     }
   };
   entity = service.entityFor(testName);
   assert.equal(entity.actualName, "entity", "Default lookups succeeded");
-  assert.equal(entity.name, testName, "Default lookups succeeded");
+  assert.equal(entity.get("name"), testName, "Default lookups succeeded");
 
   // Primary lookups succeeded
   service.lookup = function (type, name) {
     if(name === testName) {
       assert.equal(type, "entitie");
-      return {
-        actualName: name
-      };
+      return Ember.Object.create({
+        actualName: name,
+        name: name
+      });
     }
     if(name === "entity") {
       assert.equal(type, "entitie"); // Shouldn't be called
     }
   };
   entity = service.entityFor(testName);
-  assert.equal(entity.name, testName, "Default lookups succeeded");
-  assert.equal(entity.name, testName, "Default lookups succeeded");
+  assert.equal(entity.get("name"), testName, "Default lookups succeeded");
+  assert.equal(entity.get("name"), testName, "Default lookups succeeded");
 });
 
 test('getCacheKey test', function(assert) {
@@ -180,7 +182,7 @@ test('getCacheKey test', function(assert) {
 test('queryRecord test', function(assert) {
   let service = this.subject(),
       testNameSpace = "ns",
-      testOptions = {},
+      testOptions = {opt: 1},
       testQueryParams = {},
       testUrlParams = {},
       testType = "type",
@@ -188,7 +190,7 @@ test('queryRecord test', function(assert) {
       testID = 1,
       cacheKey = service.getCacheKey(testType, testQueryParams, testID);
 
-  assert.expect(1 + 4 + 5 + 3);
+  assert.expect(1 + 5 + 3);
 
   service.nameSpace = testNameSpace;
   service.checkRequisite = Ember.K;
@@ -196,26 +198,17 @@ test('queryRecord test', function(assert) {
     assert.equal(type, testType);
 
     return {
-      loadRelations: function (thisService, record, options, urlParams) {
-        assert.equal(thisService, service);
-        assert.equal(record, testRecord);
-        assert.equal(options, testOptions);
-        assert.equal(urlParams, testUrlParams);
-
-        return record;
+      queryRecord: function (loader, id, options, query, urlParams) {
+        assert.equal(loader, service, "Loader");
+        assert.equal(id, testID, "id");
+        assert.equal(options.opt, testOptions.opt, "options");
+        assert.equal(query, testQueryParams, "query");
+        assert.equal(urlParams, testUrlParams, "urlParams");
+
+        return Ember.RSVP.resolve(testRecord);
       }
     };
   };
-  service.get("store").queryRecord = function (type, query) {
-    assert.equal(type, testType);
-
-    assert.equal(query.id, testID);
-    assert.equal(query.nameSpace, testNameSpace);
-    assert.equal(query.params, testQueryParams);
-    assert.equal(query.urlParams, testUrlParams);
-
-    return Ember.RSVP.resolve(testRecord);
-  };
 
   service.cache = Ember.Object.create();
   assert.notOk(service.get("cache").get(cacheKey));
@@ -228,7 +221,7 @@ test('queryRecord test', function(assert) {
 test('query test', function(assert) {
   let service = this.subject(),
       testNameSpace = "ns",
-      testOptions = {},
+      testOptions = {opt: 1},
       testQueryParams = {},
       testUrlParams = {},
       testType = "type",
@@ -236,7 +229,7 @@ test('query test', function(assert) {
       testRecords = [testRecord, testRecord],
       cacheKey = service.getCacheKey(testType, testQueryParams);
 
-  assert.expect(1 + (4 + 4) + 4 + 3);
+  assert.expect(1 + 4 + 3);
 
   service.nameSpace = testNameSpace;
   service.checkRequisite = Ember.K;
@@ -244,25 +237,16 @@ test('query test', function(assert) {
     assert.equal(type, testType);
 
     return {
-      loadRelations: function (thisService, record, options, urlParams) {
-        assert.equal(thisService, service);
-        assert.equal(record, testRecord);
-        assert.equal(options, testOptions);
-        assert.equal(urlParams, testUrlParams);
+      query: function (loader, query, options, urlParams) {
+        assert.equal(loader, service, "Loader");
+        assert.equal(options.opt, testOptions.opt, "options");
+        assert.equal(query, testQueryParams, "query");
+        assert.equal(urlParams, testUrlParams, "urlParams");
 
-        return record;
+        return Ember.RSVP.resolve(testRecords);
       }
     };
   };
-  service.get("store").query = function (type, query) {
-    assert.equal(type, testType);
-
-    assert.equal(query.nameSpace, testNameSpace);
-    assert.equal(query.params, testQueryParams);
-    assert.equal(query.urlParams, testUrlParams);
-
-    return Ember.RSVP.resolve(testRecords);
-  };
 
   service.cache = Ember.Object.create();
   assert.notOk(service.get("cache").get(cacheKey));

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/services/pollster-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/services/pollster-test.js b/tez-ui2/src/main/webapp/tests/unit/services/pollster-test.js
new file mode 100644
index 0000000..7687a87
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/services/pollster-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('service:pollster', 'Unit | Service | pollster', {
+  // Specify the other units that are required for this test.
+  needs: ['service:localStorage']
+});
+
+test('Basic creation test', function(assert) {
+  let service = this.subject();
+  assert.ok(service);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/tests/unit/utils/counter-column-definition-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/utils/counter-column-definition-test.js b/tez-ui2/src/main/webapp/tests/unit/utils/counter-column-definition-test.js
index 64df664..9e0476f 100644
--- a/tez-ui2/src/main/webapp/tests/unit/utils/counter-column-definition-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/utils/counter-column-definition-test.js
@@ -37,7 +37,7 @@ test('Basic creation test', function(assert) {
   assert.ok(CounterColumnDefinition.make);
 
   assert.equal(definition.observePath, true);
-  assert.equal(definition.contentPath, "counterHash");
+  assert.equal(definition.contentPath, "counterGroupsHash");
 });
 
 test('getCellContent, getSearchValue & getSortValue test', function(assert) {
@@ -46,7 +46,7 @@ test('getCellContent, getSearchValue & getSortValue test', function(assert) {
       testCounterValue = "val",
       testContent = {},
       testRow = {
-        counterHash: testContent
+        counterGroupsHash: testContent
       };
 
   testContent[testGroupName] = {};


[37/45] tez git commit: TEZ-3092. Tez UI 2: Tuneups & Improvements (sree)

Posted by sr...@apache.org.
TEZ-3092. Tez UI 2: Tuneups & Improvements (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/628f8b85
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/628f8b85
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/628f8b85

Branch: refs/heads/TEZ-2980
Commit: 628f8b85c3d6d3ffddb5144f12a028ec2b94ec9c
Parents: 08e55ce
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Thu Feb 4 14:52:31 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:32:53 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |  1 +
 tez-ui2/README.md                               | 83 +++++++++++++++-----
 tez-ui2/src/main/webapp/README.md               | 44 +++++++----
 .../main/webapp/app/components/caller-info.js   |  2 +
 tez-ui2/src/main/webapp/app/router.js           |  3 +-
 tez-ui2/src/main/webapp/app/services/hosts.js   |  3 +-
 .../src/main/webapp/app/services/pollster.js    |  7 +-
 tez-ui2/src/main/webapp/app/styles/app.less     |  1 +
 .../src/main/webapp/app/styles/caller-info.less | 26 ++++++
 .../webapp/app/styles/dags-page-search.less     | 49 ++++++++----
 .../src/main/webapp/app/styles/page-layout.less |  7 +-
 tez-ui2/src/main/webapp/app/styles/shared.less  |  6 +-
 tez-ui2/src/main/webapp/config/build-info.js    | 32 ++++++++
 tez-ui2/src/main/webapp/config/configs.env      | 29 ++++++-
 .../src/main/webapp/config/default-app-conf.js  |  4 +-
 tez-ui2/src/main/webapp/config/environment.js   |  3 +-
 16 files changed, 239 insertions(+), 61 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/628f8b85/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index b653e42..bc74ffd 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -33,3 +33,4 @@ ALL CHANGES:
   TEZ-3058. Tez UI 2: Add download data functionality
   TEZ-3084. Tez UI 2: Display caller type and info
   TEZ-3080. Tez UI 2: Ensure UI 2 is in-line with UI 1
+  TEZ-3092. Tez UI 2: Tuneups & Improvements

http://git-wip-us.apache.org/repos/asf/tez/blob/628f8b85/tez-ui2/README.md
----------------------------------------------------------------------
diff --git a/tez-ui2/README.md b/tez-ui2/README.md
index 3ec46de..6a009ee 100644
--- a/tez-ui2/README.md
+++ b/tez-ui2/README.md
@@ -1,30 +1,76 @@
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
 # Tez-ui
 
-The Tez UI is an ember based web application that provides visualization of Tez applications
-running on the Apache Hadoop YARN framework.
+The Tez UI is an ember based web-app that provides visualization of Tez applications running on the Apache Hadoop YARN framework.
+
+For more information on Tez and the Tez UI - Check the [Tez homepage](http://tez.apache.org/ "Apache Tez Homepage").
+
+## Configurations
+
+### In tez-site.xml
+  * `tez.runtime.convert.user-payload.to.history-text` : Should be enabled to get the configuration options in. If enabled, the config options are set as userpayload per input/output.
+
+### In yarn-site.xml
+  * `yarn.timeline-service.http-cross-origin.enabled` : Enable CORS in timeline.
+  * `yarn.resourcemanager.system-metrics-publisher.enabled` : Enable generic history service in timeline server
+  * `yarn.timeline-service.enabled` : Enabled the timeline server for logging details
+  * `yarn.timeline-service.webapp.address` : Value must be the IP:PORT on which timeline server is running
+
+### In configs.env
+  This environment configuration file can be found at `./src/main/webapp/config/configs.env`
+
+  * `ENV.hosts.timeline` : Timeline Server Address. By default TEZ UI looks for timeline server at http://localhost:8188.
+  * `ENV.hosts.rm` : Resource Manager Address. By default RM REST APIs are expected to be at http://localhost:8088.
+  * `ENV.hosts.rmProxy` : This is options. Value configured as RM host will be taken as proxy address by default. Use this configuration when RM web proxy is configured at a different address than RM.
+  * `ENV.timeZone` : Time Zone in which dates are displayed in the UI. If not set, local time zone will be used. Refer http://momentjs.com/timezone/docs/ for valid entries.
 
-For more information on Tez and the Tez UI - the [tez homepage](http://tez.apache.org/ "Apache Tez Homepage").
+## Package & deploy
 
-## Prerequisites
+### Get war package
+  * Tez UI is distributed as a war package.
+  * To build & package UI without running test cases, run `mvn clean package -DskipTests` in this directory.
+  * This would give you a war file in `./target`.
+  * UI build is part of tez build, refer BUILDING.txt for more info.
+
+### Using UI war
+##### Remotely:
+  Use webfront tomcat manager to upload & deploy your war remotely.
+##### Manually:
+  The war can be added to any tomcat instance.
+  1. Remove any old deployments in `$TOMCAT_HOME/webapps`
+  2. Copy the war to `$TOMCAT_HOME/webapps`
+  3. Restart tomcat and the war will get deployed. The content of the war would be available in
+     `$TOMCAT_HOME/webapps/tez-ui-[version]` directory.
+
+## Development
+
+All the following commands must be run inside `src/main/webapp`.
+
+### Prerequisites
 
 You will need the following things properly installed on your computer.
 
 * [Git](http://git-scm.com/)
 * [Node.js](http://nodejs.org/) (with NPM)
 * [Ember CLI](http://www.ember-cli.com/)
-* [PhantomJS](http://phantomjs.org/)
 
-## Installation
-
-* `git clone <repository-url>` this repository
-* In tez/tez-ui2/src/main/webapp
-* `npm install`
-
-## Configuring
-* By default timeline is expected at localhost:8188 & RM at localhost:8088
-* You can point the UI to custom locations by setting the environment variables in src/main/webapp/config/configs.env
-
-## Running / Development
+### Running UI
 
 * `ember server`
 * Visit your app at [http://localhost:4200](http://localhost:4200).
@@ -32,9 +78,10 @@ You will need the following things properly installed on your computer.
 ### Running Tests
 
 * `ember test`
-* `ember test --server`
 
-### Building
+### Building UI manually
 
 * `ember build` (development)
 * `ember build --environment production` (production)
+
+Files would be stored in "dist/"

http://git-wip-us.apache.org/repos/asf/tez/blob/628f8b85/tez-ui2/src/main/webapp/README.md
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/README.md b/tez-ui2/src/main/webapp/README.md
index fb8128e..a86e7da 100644
--- a/tez-ui2/src/main/webapp/README.md
+++ b/tez-ui2/src/main/webapp/README.md
@@ -1,9 +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.
+-->
+
 # Tez-ui
 
-The Tez UI is an ember based web application that provides visualization of Tez applications
-running on the Apache Hadoop YARN framework.
+The Tez UI is an ember based web-app that provides visualization of Tez applications running on the Apache Hadoop YARN framework.
+
+For more information on Tez and the Tez UI - Check the [Tez homepage](http://tez.apache.org/ "Apache Tez Homepage").
+
+## Configurations
 
-For more information on Tez and the Tez UI - the [tez homepage](http://tez.apache.org/ "Apache Tez Homepage").
+* By default timeline is expected at localhost:8188 & RM at localhost:8088
+* You can point the UI to custom locations by setting the environment variables in `src/main/webapp/config/configs.env`
+
+## Development
 
 ## Prerequisites
 
@@ -12,23 +35,12 @@ You will need the following things properly installed on your computer.
 * [Git](http://git-scm.com/)
 * [Node.js](http://nodejs.org/) (with NPM)
 * [Ember CLI](http://www.ember-cli.com/)
-* [PhantomJS](http://phantomjs.org/)
-
-## Installation
 
-* `git clone <repository-url>` this repository
-* change into the new directory
-* `npm install`
-
-## Running / Development
+## Running UI
 
 * `ember server`
 * Visit your app at [http://localhost:4200](http://localhost:4200).
 
-### Code Generators
-
-Make use of the many generators for code, try `ember help generate` for more details
-
 ### Running Tests
 
 * `ember test`
@@ -38,3 +50,5 @@ Make use of the many generators for code, try `ember help generate` for more det
 
 * `ember build` (development)
 * `ember build --environment production` (production)
+
+Files would be stored in "dist/"

http://git-wip-us.apache.org/repos/asf/tez/blob/628f8b85/tez-ui2/src/main/webapp/app/components/caller-info.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/components/caller-info.js b/tez-ui2/src/main/webapp/app/components/caller-info.js
index 3680049..ece33ac 100644
--- a/tez-ui2/src/main/webapp/app/components/caller-info.js
+++ b/tez-ui2/src/main/webapp/app/components/caller-info.js
@@ -28,6 +28,8 @@ export default Ember.Component.extend({
 
   codeMirror: null,
 
+  classNames: ['caller-info'],
+
   mode: Ember.computed("type", function () {
     switch(this.get("type")) {
       case 'Hive':

http://git-wip-us.apache.org/repos/asf/tez/blob/628f8b85/tez-ui2/src/main/webapp/app/router.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/router.js b/tez-ui2/src/main/webapp/app/router.js
index eb3afb3..4196675 100644
--- a/tez-ui2/src/main/webapp/app/router.js
+++ b/tez-ui2/src/main/webapp/app/router.js
@@ -30,7 +30,7 @@ Router.map(function() {
     this.route('tasks');
     this.route('attempts');
     this.route('counters');
-    this.route('index', function() {});
+    this.route('index', {path: '/'}, function() {});
     this.route('graphical');
   });
   this.route('vertex', {path: '/vertex/:vertex_id'}, function() {
@@ -45,6 +45,7 @@ Router.map(function() {
   this.route('attempt', {path: '/attempt/:attempt_id'}, function () {
     this.route('counters');
   });
+  this.route('app', {path: '/tez-app/:app_id'}, function () {}); // Alias for backward compatibility with Tez UI V1
   this.route('app', {path: '/app/:app_id'}, function () {
     this.route('dags');
     this.route('configs');

http://git-wip-us.apache.org/repos/asf/tez/blob/628f8b85/tez-ui2/src/main/webapp/app/services/hosts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/services/hosts.js b/tez-ui2/src/main/webapp/app/services/hosts.js
index 0da7fe5..c9e7d25 100644
--- a/tez-ui2/src/main/webapp/app/services/hosts.js
+++ b/tez-ui2/src/main/webapp/app/services/hosts.js
@@ -64,7 +64,8 @@ export default Ember.Service.extend({
   }),
 
   am: Ember.computed(function () {
-    return this.normalizeURL(this.get("env.app.hosts.rm"));
+    var url = this.get("env.app.hosts.rmProxy") || this.get("env.app.hosts.rm");
+    return this.normalizeURL(url);
   }),
 
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/628f8b85/tez-ui2/src/main/webapp/app/services/pollster.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/services/pollster.js b/tez-ui2/src/main/webapp/app/services/pollster.js
index 00a0c6c..7e41fa1 100644
--- a/tez-ui2/src/main/webapp/app/services/pollster.js
+++ b/tez-ui2/src/main/webapp/app/services/pollster.js
@@ -38,8 +38,13 @@ export default Ember.Service.extend({
   pollCount: 0,
 
   initState: Ember.on("init", function () {
+    var state = this.get("localStorage").get(STATE_STORAGE_KEY);
+
+    if(state === undefined || state === null) {
+      state = true;
+    }
     Ember.run.later(this, function () {
-      this.set("active", this.get("localStorage").get(STATE_STORAGE_KEY));
+      this.set("active", state);
     });
   }),
   stateObserver: Ember.observer("active", function () {

http://git-wip-us.apache.org/repos/asf/tez/blob/628f8b85/tez-ui2/src/main/webapp/app/styles/app.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/app.less b/tez-ui2/src/main/webapp/app/styles/app.less
index 11c611c..a832446 100644
--- a/tez-ui2/src/main/webapp/app/styles/app.less
+++ b/tez-ui2/src/main/webapp/app/styles/app.less
@@ -27,6 +27,7 @@
 @import "dags-page-search";
 @import "table-controls";
 @import "error-bar";
+@import "caller-info";
 
 // Modals
 @import "column-selector";

http://git-wip-us.apache.org/repos/asf/tez/blob/628f8b85/tez-ui2/src/main/webapp/app/styles/caller-info.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/caller-info.less b/tez-ui2/src/main/webapp/app/styles/caller-info.less
new file mode 100644
index 0000000..2dc78f1
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/styles/caller-info.less
@@ -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.
+ */
+
+.caller-info {
+  .panel-info {
+    overflow: hidden;
+  }
+  .CodeMirror {
+    height: auto;
+  }
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/628f8b85/tez-ui2/src/main/webapp/app/styles/dags-page-search.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/dags-page-search.less b/tez-ui2/src/main/webapp/app/styles/dags-page-search.less
index ec64d11..25a470d 100644
--- a/tez-ui2/src/main/webapp/app/styles/dags-page-search.less
+++ b/tez-ui2/src/main/webapp/app/styles/dags-page-search.less
@@ -16,6 +16,39 @@
  * limitations under the License.
  */
 
+.dags-page-search {
+  text-align: justify;
+
+  margin-bottom: 5px;
+
+  .search-element {
+    display: inline-block;
+    width: 16.66%;
+
+    padding-left: 3px;
+
+    label {
+      margin-bottom: 2px;
+    }
+
+    select {
+      top: -1px;
+      position: relative;
+    }
+  }
+
+  .dag-name {
+    padding-left: 0px;
+  }
+}
+
+.all-dags-table {
+  .pagination-ui, .table-controls {
+    margin-top: -5px;
+    margin-bottom: 5px;
+  }
+}
+
 @media screen and (min-width: 1300px) {
   .dags-page-search{
     float: left;
@@ -32,19 +65,3 @@
     }
   }
 }
-
-.dags-page-search {
-  text-align: justify;
-
-
-  .search-element {
-    display: inline-block;
-    width: 16.66%;
-
-    padding-left: 3px;
-  }
-
-  .dag-name {
-    padding-left: 0px;
-  }
-}

http://git-wip-us.apache.org/repos/asf/tez/blob/628f8b85/tez-ui2/src/main/webapp/app/styles/page-layout.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/page-layout.less b/tez-ui2/src/main/webapp/app/styles/page-layout.less
index 0411fa0..ee62535 100644
--- a/tez-ui2/src/main/webapp/app/styles/page-layout.less
+++ b/tez-ui2/src/main/webapp/app/styles/page-layout.less
@@ -43,11 +43,13 @@ body, html {
         position: absolute;
         left: 70px;
         right: 20px;
-        top: 9px;
+        top: 6px;
 
         .breadcrumb {
           .no-border;
 
+          font-size: 1.2em;
+
           background-color: transparent;
           margin-bottom: 0px;
 
@@ -60,6 +62,7 @@ body, html {
         position: absolute;
         right: 0px;
         top: 0px;
+        height: 27px;
 
         span {
           .left-delim;
@@ -108,7 +111,7 @@ body, html {
 
     border-top: 1px @border-color solid;
 
-    font-size: .8em;
+    font-size: .9em;
 
     .ui-info {
       background-color: @white;

http://git-wip-us.apache.org/repos/asf/tez/blob/628f8b85/tez-ui2/src/main/webapp/app/styles/shared.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/shared.less b/tez-ui2/src/main/webapp/app/styles/shared.less
index a96636f..5f4b8f4 100644
--- a/tez-ui2/src/main/webapp/app/styles/shared.less
+++ b/tez-ui2/src/main/webapp/app/styles/shared.less
@@ -48,6 +48,8 @@ b {
   }
 }
 
-.CodeMirror {
-  height: auto;
+.em-table {
+  .em-progress-container {
+    padding-top: 1px;
+  }
 }

http://git-wip-us.apache.org/repos/asf/tez/blob/628f8b85/tez-ui2/src/main/webapp/config/build-info.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/config/build-info.js b/tez-ui2/src/main/webapp/config/build-info.js
new file mode 100644
index 0000000..ae2b33d
--- /dev/null
+++ b/tez-ui2/src/main/webapp/config/build-info.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.
+ */
+
+const POM_FILE = "../../../pom.xml";
+var fs = require('fs');
+
+function fetchVersion() {
+  try {
+    var fileData = fs.readFileSync(POM_FILE, 'ascii');
+    // Feel this is better than parsing the whole xml
+    return fileData.substring(fileData.indexOf("<version>") + 9, fileData.indexOf("</version>"));
+  }catch(e){}
+}
+
+module.exports = {
+  version: fetchVersion()
+};

http://git-wip-us.apache.org/repos/asf/tez/blob/628f8b85/tez-ui2/src/main/webapp/config/configs.env
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/config/configs.env b/tez-ui2/src/main/webapp/config/configs.env
index 60421fd..a0d2198 100644
--- a/tez-ui2/src/main/webapp/config/configs.env
+++ b/tez-ui2/src/main/webapp/config/configs.env
@@ -1,6 +1,31 @@
 ENV = {
   hosts: {
+    /*
+     * Timeline Server Address:
+     * By default TEZ UI looks for timeline server at http://localhost:8188, uncomment and change
+     * the following value for pointing to a different address.
+     */
     //timeline: "http://localhost:8188",
-    //rm: "http://localhost:8088"
-  }
+
+    /*
+     * Resource Manager Address:
+     * By default RM REST APIs are expected to be at http://localhost:8088, uncomment and change
+     * the following value to point to a different address.
+     */
+    //rm: "http://localhost:8088",
+
+    /*
+     * Resource Manager Web Proxy Address:
+     * Optional - By default, value configured as RM host will be taken as proxy address
+     * Use this configuration when RM web proxy is configured at a different address than RM.
+     */
+    //rmProxy: "http://localhost:8088",
+  },
+
+  /*
+   * Time Zone in which dates are displayed in the UI:
+   * If not set, local time zone will be used.
+   * Refer http://momentjs.com/timezone/docs/ for valid entries.
+   */
+  //timeZone: "UTC",
 };

http://git-wip-us.apache.org/repos/asf/tez/blob/628f8b85/tez-ui2/src/main/webapp/config/default-app-conf.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/config/default-app-conf.js b/tez-ui2/src/main/webapp/config/default-app-conf.js
index 084e9b7..c53e4d7 100644
--- a/tez-ui2/src/main/webapp/config/default-app-conf.js
+++ b/tez-ui2/src/main/webapp/config/default-app-conf.js
@@ -16,8 +16,10 @@
  * limitations under the License.
  */
 
+var buildInfo = require('./build-info');
+
 module.exports = { // Tez App configurations
-  buildVersion: "",
+  buildVersion: buildInfo.version || "",
   isStandalone: true, // Must be set false while running in wrapped mode
   rowLoadLimit: 9007199254740991,
   pollingInterval: 3000,

http://git-wip-us.apache.org/repos/asf/tez/blob/628f8b85/tez-ui2/src/main/webapp/config/environment.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/config/environment.js b/tez-ui2/src/main/webapp/config/environment.js
index c08549f..0c755ac 100644
--- a/tez-ui2/src/main/webapp/config/environment.js
+++ b/tez-ui2/src/main/webapp/config/environment.js
@@ -24,8 +24,7 @@ module.exports = function(environment) {
   var ENV = {
     modulePrefix: 'tez-ui',
     environment: environment,
-    baseURL: '/',
-    locationType: 'auto',
+    locationType: 'hash',
     EmberENV: {
       FEATURES: {
         // Here you can enable experimental features on an ember canary build


[44/45] tez git commit: TEZ-3058. Tez UI 2: Add download data functionality (sree)

Posted by sr...@apache.org.
TEZ-3058. Tez UI 2: Add download data functionality (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/c6ce4ec8
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/c6ce4ec8
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/c6ce4ec8

Branch: refs/heads/TEZ-2980
Commit: c6ce4ec8abf8e62e2c344308b43bb9f270d02bcb
Parents: 9c232cc
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Mon Feb 1 20:42:24 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:32:53 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |   1 +
 .../webapp/app/components/zip-download-modal.js |  43 ++
 .../src/main/webapp/app/initializers/hosts.js   |   1 +
 .../src/main/webapp/app/routes/application.js   |   3 +
 .../src/main/webapp/app/routes/dag/graphical.js |  10 +-
 tez-ui2/src/main/webapp/app/routes/dag/index.js |  22 +
 tez-ui2/src/main/webapp/app/styles/app.less     |   5 +-
 .../webapp/app/styles/zip-download-modal.less   |  30 ++
 .../templates/components/zip-download-modal.hbs |  36 ++
 .../src/main/webapp/app/templates/dag/index.hbs |   2 +-
 .../main/webapp/app/utils/download-dag-zip.js   | 407 +++++++++++++++++++
 tez-ui2/src/main/webapp/bower.json              |   5 +-
 tez-ui2/src/main/webapp/config/environment.js   |   1 +
 tez-ui2/src/main/webapp/ember-cli-build.js      |  13 +-
 tez-ui2/src/main/webapp/package.json            |   3 +
 .../components/zip-download-modal-test.js       |  46 +++
 .../tests/unit/routes/application-test.js       |   6 +
 .../tests/unit/utils/download-dag-zip-test.js   |  26 ++
 18 files changed, 651 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/c6ce4ec8/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index 653899c..e4ab014 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -30,3 +30,4 @@ ALL CHANGES:
   TEZ-3061. Tez UI 2: Display in-progress vertex table in DAG details
   TEZ-3069. Tez UI 2: Make error bar fully functional
   TEZ-3062. Tez UI 2: Integrate graphical view
+  TEZ-3058. Tez UI 2: Add download data functionality

http://git-wip-us.apache.org/repos/asf/tez/blob/c6ce4ec8/tez-ui2/src/main/webapp/app/components/zip-download-modal.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/components/zip-download-modal.js b/tez-ui2/src/main/webapp/app/components/zip-download-modal.js
new file mode 100644
index 0000000..c55b34e
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/components/zip-download-modal.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';
+
+export default Ember.Component.extend({
+  classNames: ['zip-download-modal'],
+  content: null,
+
+  _onSuccess: Ember.observer("content.downloader.succeeded", function () {
+    if(this.get("content.downloader.succeeded")) {
+      Ember.run.later(this, "close");
+    }
+  }),
+
+  close: function () {
+    Ember.$(".simple-modal").modal("hide");
+  },
+
+  actions: {
+    cancel: function () {
+      var downloader = this.get("content.downloader");
+      if(downloader) {
+        downloader.cancel();
+      }
+    }
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/c6ce4ec8/tez-ui2/src/main/webapp/app/initializers/hosts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/initializers/hosts.js b/tez-ui2/src/main/webapp/app/initializers/hosts.js
index 8791fc7..ec6f7a7 100644
--- a/tez-ui2/src/main/webapp/app/initializers/hosts.js
+++ b/tez-ui2/src/main/webapp/app/initializers/hosts.js
@@ -19,6 +19,7 @@
 export function initialize(application) {
   application.inject('controller', 'hosts', 'service:hosts');
   application.inject('adapter', 'hosts', 'service:hosts');
+  application.inject('route', 'hosts', 'service:hosts');
 }
 
 export default {

http://git-wip-us.apache.org/repos/asf/tez/blob/c6ce4ec8/tez-ui2/src/main/webapp/app/routes/application.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/application.js b/tez-ui2/src/main/webapp/app/routes/application.js
index 41ea3fb..99bed25 100644
--- a/tez-ui2/src/main/webapp/app/routes/application.js
+++ b/tez-ui2/src/main/webapp/app/routes/application.js
@@ -59,6 +59,9 @@ export default Ember.Route.extend({
         Ember.$(".simple-modal").modal();
       });
     },
+    closeModal: function () {
+      Ember.$(".simple-modal").modal("hide");
+    },
     destroyModal: function () {
       Ember.run.later(this, function () {
         this.disconnectOutlet({

http://git-wip-us.apache.org/repos/asf/tez/blob/c6ce4ec8/tez-ui2/src/main/webapp/app/routes/dag/graphical.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag/graphical.js b/tez-ui2/src/main/webapp/app/routes/dag/graphical.js
index 3d9550f..69d2de4 100644
--- a/tez-ui2/src/main/webapp/app/routes/dag/graphical.js
+++ b/tez-ui2/src/main/webapp/app/routes/dag/graphical.js
@@ -39,11 +39,13 @@ export default MultiAmPollsterRoute.extend({
     var loadedValue = this.get("loadedValue"),
         records = [];
 
-    loadedValue.forEach(function (record) {
-      records.push(record);
-    });
+    if(loadedValue) {
+      loadedValue.forEach(function (record) {
+        records.push(record);
+      });
 
-    this.set("polledRecords", records);
+      this.set("polledRecords", records);
+    }
     Ember.run.later(this, "setViewHeight", 100);
   }),
 

http://git-wip-us.apache.org/repos/asf/tez/blob/c6ce4ec8/tez-ui2/src/main/webapp/app/routes/dag/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag/index.js b/tez-ui2/src/main/webapp/app/routes/dag/index.js
index be60c1d..acabc58 100644
--- a/tez-ui2/src/main/webapp/app/routes/dag/index.js
+++ b/tez-ui2/src/main/webapp/app/routes/dag/index.js
@@ -19,6 +19,8 @@
 import Ember from 'ember';
 import SingleAmPollsterRoute from '../single-am-pollster';
 
+import downloadDAGZip from '../../utils/download-dag-zip';
+
 export default SingleAmPollsterRoute.extend({
   title: "DAG Details",
 
@@ -33,4 +35,24 @@ export default SingleAmPollsterRoute.extend({
     return this.get("loader").queryRecord('dag', this.modelFor("dag").get("id"), options);
   },
 
+  actions: {
+    downloadDagJson: function () {
+      var dag = this.get("loadedValue"),
+          downloader = downloadDAGZip(dag, {
+            batchSize: 500,
+            timelineHost: this.get("hosts.timeline"),
+            timelineNamespace: this.get("env.app.namespaces.webService.timeline")
+          }),
+          modalContent = Ember.Object.create({
+            dag: dag,
+            downloader: downloader
+          });
+
+      this.send("openModal", "zip-download-modal", {
+        title: "Download data",
+        content: modalContent
+      });
+    }
+  }
+
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/c6ce4ec8/tez-ui2/src/main/webapp/app/styles/app.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/app.less b/tez-ui2/src/main/webapp/app/styles/app.less
index cdeccd1..11c611c 100644
--- a/tez-ui2/src/main/webapp/app/styles/app.less
+++ b/tez-ui2/src/main/webapp/app/styles/app.less
@@ -26,9 +26,12 @@
 @import "tab-n-refresh";
 @import "dags-page-search";
 @import "table-controls";
-@import "column-selector";
 @import "error-bar";
 
+// Modals
+@import "column-selector";
+@import "zip-download-modal";
+
 // Pages
 @import "page-layout";
 @import "details-page";

http://git-wip-us.apache.org/repos/asf/tez/blob/c6ce4ec8/tez-ui2/src/main/webapp/app/styles/zip-download-modal.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/zip-download-modal.less b/tez-ui2/src/main/webapp/app/styles/zip-download-modal.less
new file mode 100644
index 0000000..4ed0fd2
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/styles/zip-download-modal.less
@@ -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.
+ */
+
+.zip-download-modal {
+  .message {
+    padding: 10px 15px;
+
+    .fa-spinner {
+      color: green;
+    }
+    .fa-exclamation-circle {
+      color: red;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/c6ce4ec8/tez-ui2/src/main/webapp/app/templates/components/zip-download-modal.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/components/zip-download-modal.hbs b/tez-ui2/src/main/webapp/app/templates/components/zip-download-modal.hbs
new file mode 100644
index 0000000..03b820e
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/components/zip-download-modal.hbs
@@ -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.
+}}
+
+<div class="message">
+  {{#if content.downloader.failed}}
+    <i class="fa fa-lg fa-exclamation-circle"></i>
+    Error downloading data!
+  {{else}}
+    <i class="fa fa-lg fa-spinner fa-spin"></i>
+    Downloading data for dag: <b>{{content.dag.entityID}}</b>
+  {{/if}}
+</div>
+
+
+<div class="form-actions">
+  {{#if content.downloader.failed}}
+    <button type="button" class="btn btn-primary" data-dismiss="modal" aria-label="Close">Ok</button>
+  {{else}}
+    <button type="button" class="btn" data-dismiss="modal" aria-label="Close" {{action "cancel"}}>Cancel</button>
+  {{/if}}
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/c6ce4ec8/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/index.hbs b/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
index d7e23fc..59bb6a9 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
@@ -26,7 +26,7 @@
     <tbody>
       <tr>
         <td colspan="2">
-          {{bs-button icon="fa fa-download" title="Download data" defaultText="Download data" type="info" clicked="downloadDagJson"}}
+          {{bs-button icon="fa fa-download" title="Download data" defaultText="Download data" type="info" action="downloadDagJson"}}
         </td>
       </tr>
       <tr>

http://git-wip-us.apache.org/repos/asf/tez/blob/c6ce4ec8/tez-ui2/src/main/webapp/app/utils/download-dag-zip.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/utils/download-dag-zip.js b/tez-ui2/src/main/webapp/app/utils/download-dag-zip.js
new file mode 100644
index 0000000..88ea9a4
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/utils/download-dag-zip.js
@@ -0,0 +1,407 @@
+/*global zip, saveAs*/
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES 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';
+
+zip.workerScriptsPath = "/assets/zip/";
+
+var IO = {
+  /* Allow queuing of downloads and then get a callback once all the downloads are done.
+   * sample usage.
+   * var downloader = IO.fileDownloader();
+   * downloader.queueItem({
+   *   url: 'http://....',
+   *   onItemFetched: function(data, context) {...},
+   *   context: {}, // context object gets passed back to the callback
+   * });
+   * downloader.queueItem({...}); //queue in other items
+   * downloader.finish(); // once all items are queued. items can be queued from
+   *                      // callbacks too. in that case the finish should be called
+   *                      // once all items are queued.
+   * downloader.then(successCallback).catch(failurecallback).finally(callback)
+   */
+  fileDownloader: function(options) {
+    var itemList = [],
+        opts = options || {},
+        numParallel = opts.numParallel || 5,
+        hasMoreInputs = true,
+        inProgress = 0,
+        hasFailed = false,
+        pendingRequests = {},
+        pendingRequestID = 0,
+        failureReason = 'Unknown',
+        deferredPromise = Ember.RSVP.defer();
+
+    function checkForCompletion() {
+      if (hasFailed) {
+        if (inProgress === 0) {
+          deferredPromise.reject("Unknown Error");
+        }
+        return;
+      }
+
+      if (hasMoreInputs || itemList.length > 0 || inProgress > 0) {
+        return;
+      }
+
+      deferredPromise.resolve();
+    }
+
+    function getRequestId() {
+      return "req_" + pendingRequestID++;
+    }
+
+    function abortPendingRequests() {
+      Ember.$.each(pendingRequests, function(idx, val) {
+        try {
+          val.abort("abort");
+        } catch(e) {}
+      });
+    }
+
+    function markFailed(reason) {
+      if (!hasFailed) {
+        hasFailed = true;
+        failureReason = reason;
+        abortPendingRequests();
+      }
+    }
+
+    function processNext() {
+      if (inProgress >= numParallel) {
+        Ember.Logger.debug(`delaying download as ${inProgress} of ${numParallel} is in progress`);
+        return;
+      }
+
+      if (itemList.length < 1) {
+        Ember.Logger.debug("no items to download");
+        checkForCompletion();
+        return;
+      }
+
+      inProgress++;
+      Ember.Logger.debug(`starting download ${inProgress}`);
+      var item = itemList.shift();
+
+      var xhr = Ember.$.ajax({
+        crossOrigin: true,
+        url: item.url,
+        dataType: 'json',
+        xhrFields: {
+          withCredentials: true
+        },
+      });
+      var reqID = getRequestId();
+      pendingRequests[reqID] = xhr;
+
+      xhr.done(function(data/*, statusText, xhr*/) {
+        delete pendingRequests[reqID];
+
+        if (Ember.$.isFunction(item.onItemFetched)) {
+          try {
+            item.onItemFetched(data, item.context);
+          } catch (e) {
+            markFailed(e || 'failed to process data');
+            inProgress--;
+            checkForCompletion();
+            return;
+          }
+        }
+
+        inProgress--;
+        processNext();
+      }).fail(function(xhr, statusText/*, errorObject*/) {
+        delete pendingRequests[reqID];
+        markFailed(statusText);
+        inProgress--;
+        checkForCompletion();
+      });
+    }
+
+    return DS.PromiseObject.create({
+      promise: deferredPromise.promise,
+
+      queueItems: function(options) {
+        options.forEach(this.queueItem);
+      },
+
+      queueItem: function(option) {
+        itemList.push(option);
+        processNext();
+      },
+
+      finish: function() {
+        hasMoreInputs = false;
+        checkForCompletion();
+      },
+
+      cancel: function() {
+        markFailed("User cancelled");
+        checkForCompletion();
+      }
+    });
+  },
+
+
+  /*
+   * allows to zip files and download that.
+   * usage:
+   * zipHelper = IO.zipHelper({
+   *   onProgress: function(filename, current, total) { ...},
+   *   onAdd: function(filename) {...}
+   * });
+   * zipHelper.addFile({name: filenameinsidezip, data: data);
+   * // add all files
+   * once all files are added call the close
+   * zipHelper.close(); // or .abort to abort zip
+   * zipHelper.then(function(zippedBlob) {
+   *   saveAs(filename, zippedBlob);
+   * }).catch(failureCallback);
+   */
+  zipHelper: function(options) {
+    var opts = options || {},
+        zipWriter,
+        completion = Ember.RSVP.defer(),
+        fileList = [],
+        completed = 0,
+        currentIdx = -1,
+        numFiles = 0,
+        hasMoreInputs = true,
+        inProgress = false,
+        hasFailed = false;
+
+    zip.createWriter(new zip.BlobWriter("application/zip"), function(writer) {
+      zipWriter = writer;
+      checkForCompletion();
+      nextFile();
+    });
+
+    function checkForCompletion() {
+      if (hasFailed) {
+        if (zipWriter) {
+          Ember.Logger.debug("aborting zipping. closing file.");
+          zipWriter.close(completion.reject);
+          zipWriter = null;
+        }
+      } else {
+        if (!hasMoreInputs && numFiles === completed) {
+          Ember.Logger.debug("completed zipping. closing file.");
+          zipWriter.close(completion.resolve);
+        }
+      }
+    }
+
+    function onProgress(current, total) {
+      if (Ember.$.isFunction(opts.onProgress)) {
+        opts.onProgress(fileList[currentIdx].name, current, total);
+      }
+    }
+
+    function onAdd(filename) {
+      if (Ember.$.isFunction(opts.onAdd)) {
+        opts.onAdd(filename);
+      }
+    }
+
+    function nextFile() {
+      if (hasFailed || completed === numFiles || inProgress) {
+        return;
+      }
+
+      currentIdx++;
+      var file = fileList[currentIdx];
+      inProgress = true;
+      onAdd(file.name);
+      zipWriter.add(file.name, new zip.TextReader(file.data), function() {
+        completed++;
+        inProgress = false;
+        if (currentIdx < numFiles - 1) {
+          nextFile();
+        }
+        checkForCompletion();
+      }, onProgress);
+    }
+
+    return DS.PromiseObject.create({
+      addFiles: function(files) {
+        files.forEach(this.addFile);
+      },
+
+      addFile: function(file) {
+        if (hasFailed) {
+          Ember.Logger.debug(`Skipping add of file ${file.name} as zip has been aborted`);
+          return;
+        }
+        numFiles++;
+        fileList.push(file);
+        if (zipWriter) {
+          Ember.Logger.debug("adding file from addFile: " + file.name);
+          nextFile();
+        }
+      },
+
+      close: function() {
+        hasMoreInputs = false;
+        checkForCompletion();
+      },
+
+      promise: completion.promise,
+
+      abort: function() {
+        hasFailed = true;
+        this.close();
+      }
+    });
+  }
+};
+
+export default function downloadDagZip(dag, options) {
+  var opts = options || {},
+      batchSize = opts.batchSize || 1000,
+      dagID = dag.get("entityID"),
+      baseurl = `${options.timelineHost}/${options.timelineNamespace}`,
+      itemsToDownload = [
+        {
+          url: getUrl('TEZ_APPLICATION', 'tez_' + dag.get("appID")),
+          context: { name: 'application', type: 'TEZ_APPLICATION' },
+          onItemFetched: processSingleItem
+        },
+        {
+          url: getUrl('TEZ_DAG_ID', dagID),
+          context: { name: 'dag', type: 'TEZ_DAG_ID' },
+          onItemFetched: processSingleItem
+        },
+        {
+          url: getUrl('TEZ_VERTEX_ID', dagID),
+          context: { name: 'vertices', type: 'TEZ_VERTEX_ID', part: 0 },
+          onItemFetched: processMultipleItems
+        },
+        {
+          url: getUrl('TEZ_TASK_ID', dagID),
+          context: { name: 'tasks', type: 'TEZ_TASK_ID', part: 0 },
+          onItemFetched: processMultipleItems
+        },
+        {
+          url: getUrl('TEZ_TASK_ATTEMPT_ID', dagID),
+          context: { name: 'task_attempts', type: 'TEZ_TASK_ATTEMPT_ID', part: 0 },
+          onItemFetched: processMultipleItems
+        }
+      ],
+      totalItemsToDownload = itemsToDownload.length,
+      numItemTypesToDownload = totalItemsToDownload,
+      downloader = IO.fileDownloader(),
+      zipHelper = IO.zipHelper({
+        onProgress: function(filename, current, total) {
+          Ember.Logger.debug(`${filename}: ${current} of ${total}`);
+        },
+        onAdd: function(filename) {
+          Ember.Logger.debug(`adding ${filename} to Zip`);
+        }
+      }),
+      downloaderProxy = Ember.Object.create({
+        percent: 0,
+        succeeded: false,
+        failed: false,
+        cancel: function() {
+          downloader.cancel();
+        }
+      });
+
+  function getUrl(type, dagID, fromID) {
+    var url,
+        queryBatchSize = batchSize + 1;
+
+    if (type === 'TEZ_DAG_ID' || type === 'TEZ_APPLICATION') {
+      url = `${baseurl}/${type}/${dagID}`;
+    } else {
+      url = `${baseurl}/${type}?primaryFilter=TEZ_DAG_ID:${dagID}&limit=${queryBatchSize}`;
+      if (!!fromID) {
+        url = `${url}&fromId=${fromID}`;
+      }
+    }
+    return url;
+  }
+
+  function checkIfAllDownloaded() {
+    numItemTypesToDownload--;
+
+    var remainingItems = totalItemsToDownload - numItemTypesToDownload;
+    downloaderProxy.set("percent", remainingItems / totalItemsToDownload);
+
+    if (numItemTypesToDownload === 0) {
+      downloader.finish();
+    }
+  }
+
+  function processSingleItem(data, context) {
+    var obj = {};
+    obj[context.name] = data;
+
+    zipHelper.addFile({name: `${context.name}.json`, data: JSON.stringify(obj, null, 2)});
+    checkIfAllDownloaded();
+  }
+
+  function processMultipleItems(data, context) {
+    var obj = {};
+    var nextBatchStart;
+
+    if (!Ember.$.isArray(data.entities)) {
+      throw "invalid data";
+    }
+
+    // need to handle no more entries , zero entries
+    if (data.entities.length > batchSize) {
+      nextBatchStart = data.entities.pop().entity;
+    }
+    obj[context.name] = data.entities;
+
+    zipHelper.addFile({name: `${context.name}_part_${context.part}.json`, data: JSON.stringify(obj, null, 2)});
+
+    if (!!nextBatchStart) {
+      context.part++;
+      downloader.queueItem({
+        url: getUrl(context.type, dagID, nextBatchStart),
+        context: context,
+        onItemFetched: processMultipleItems
+      });
+    } else {
+      checkIfAllDownloaded();
+    }
+  }
+
+  downloader.queueItems(itemsToDownload);
+
+  downloader.then(function() {
+    Ember.Logger.info('Finished download');
+    zipHelper.close();
+  }).catch(function(e) {
+    Ember.Logger.error('Failed to download: ' + e);
+    zipHelper.abort();
+  });
+
+  zipHelper.then(function(zippedBlob) {
+    saveAs(zippedBlob, `${dagID}.zip`);
+    downloaderProxy.set("succeeded", true);
+  }, function() {
+    Ember.Logger.error('zip Failed');
+    downloaderProxy.set("failed", true);
+  });
+
+  return downloaderProxy;
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/c6ce4ec8/tez-ui2/src/main/webapp/bower.json
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/bower.json b/tez-ui2/src/main/webapp/bower.json
index eb9569d..8d23c02 100644
--- a/tez-ui2/src/main/webapp/bower.json
+++ b/tez-ui2/src/main/webapp/bower.json
@@ -17,6 +17,9 @@
     "moment": "^2.8.0",
     "moment-timezone": "^0.5.0",
     "numeral": "1.5.3",
-    "snippet-ss": "~1.11.0"
+    "snippet-ss": "~1.11.0",
+    "jquery-mousewheel": "~3.1.13",
+    "FileSaver": "#230de7d",
+    "zip.js": "#1bead0a"
   }
 }

http://git-wip-us.apache.org/repos/asf/tez/blob/c6ce4ec8/tez-ui2/src/main/webapp/config/environment.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/config/environment.js b/tez-ui2/src/main/webapp/config/environment.js
index e5fc8ac..c08549f 100644
--- a/tez-ui2/src/main/webapp/config/environment.js
+++ b/tez-ui2/src/main/webapp/config/environment.js
@@ -37,6 +37,7 @@ module.exports = function(environment) {
 
     contentSecurityPolicy: {
       'connect-src': "* 'self'",
+      'child-src': "'self' 'unsafe-inline'",
       'style-src': "'self' 'unsafe-inline'",
       'script-src': "'self' 'unsafe-inline'"
     }

http://git-wip-us.apache.org/repos/asf/tez/blob/c6ce4ec8/tez-ui2/src/main/webapp/ember-cli-build.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/ember-cli-build.js b/tez-ui2/src/main/webapp/ember-cli-build.js
index d5cd31a..24c24fb 100644
--- a/tez-ui2/src/main/webapp/ember-cli-build.js
+++ b/tez-ui2/src/main/webapp/ember-cli-build.js
@@ -21,17 +21,23 @@
 
 var Funnel = require("broccoli-funnel");
 var EmberApp = require('ember-cli/lib/broccoli/ember-app');
+var MergeTrees = require('broccoli-merge-trees');
 
 module.exports = function(defaults) {
   var app = new EmberApp(defaults, {
     storeConfigInMeta: false
   });
 
-  var extraAssets = new Funnel('config', {
+  var configEnv = new Funnel('config', {
      srcDir: '/',
      include: ['*.env'],
      destDir: '/config'
   });
+  var zipWorker = new Funnel('bower_components/zip.js', {
+     srcDir: '/WebContent',
+     include: ['z-worker.js', 'deflate.js', 'inflate.js'],
+     destDir: '/assets/zip'
+  });
 
   app.import("bower_components/snippet-ss/less/force.less");
   app.import("bower_components/snippet-ss/less/effects.less");
@@ -43,5 +49,8 @@ module.exports = function(defaults) {
 
   app.import('bower_components/more-js/dist/more.js');
 
-  return app.toTree(extraAssets);
+  app.import('bower_components/FileSaver/FileSaver.js');
+  app.import('bower_components/zip.js/WebContent/zip.js');
+
+  return app.toTree(new MergeTrees([configEnv, zipWorker]));
 };

http://git-wip-us.apache.org/repos/asf/tez/blob/c6ce4ec8/tez-ui2/src/main/webapp/package.json
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/package.json b/tez-ui2/src/main/webapp/package.json
index e30d5bc..8fde220 100644
--- a/tez-ui2/src/main/webapp/package.json
+++ b/tez-ui2/src/main/webapp/package.json
@@ -23,6 +23,7 @@
   "devDependencies": {
     "bower": "^1.7.1",
     "broccoli-asset-rev": "^2.2.0",
+    "broccoli-merge-trees": "^1.1.1",
     "em-tgraph": "0.0.3",
     "ember-bootstrap": "0.5.1",
     "ember-cli": "1.13.13",
@@ -30,12 +31,14 @@
     "ember-cli-auto-register": "^1.1.0",
     "ember-cli-babel": "^5.1.5",
     "ember-cli-content-security-policy": "0.4.0",
+    "ember-cli-d3": "1.1.2",
     "ember-cli-dependency-checker": "^1.1.0",
     "ember-cli-font-awesome": "1.4.0",
     "ember-cli-htmlbars-inline-precompile": "^0.3.1",
     "ember-cli-inject-live-reload": "^1.3.1",
     "ember-cli-jquery-ui": "0.0.20",
     "ember-cli-moment-shim": "0.7.3",
+    "ember-cli-mousewheel": "0.1.5",
     "ember-cli-numeral": "0.1.2",
     "ember-cli-qunit": "^1.0.4",
     "ember-cli-release": "0.2.8",

http://git-wip-us.apache.org/repos/asf/tez/blob/c6ce4ec8/tez-ui2/src/main/webapp/tests/integration/components/zip-download-modal-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/integration/components/zip-download-modal-test.js b/tez-ui2/src/main/webapp/tests/integration/components/zip-download-modal-test.js
new file mode 100644
index 0000000..cd9a61a
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/integration/components/zip-download-modal-test.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 { moduleForComponent, test } from 'ember-qunit';
+import hbs from 'htmlbars-inline-precompile';
+
+moduleForComponent('zip-download-modal', 'Integration | Component | zip download modal', {
+  integration: true
+});
+
+test('Basic creation test', function(assert) {
+  var testID = "dag_a",
+      expectedMessage = "Downloading data for dag: " + testID;
+
+  this.set("content", {
+    dag: {
+      entityID: testID
+    }
+  });
+
+  this.render(hbs`{{zip-download-modal content=content}}`);
+  assert.equal(this.$(".message").text().trim(), expectedMessage);
+
+  // Template block usage:" + EOL +
+  this.render(hbs`
+    {{#zip-download-modal content=content}}
+      template block text
+    {{/zip-download-modal}}
+  `);
+  assert.equal(this.$(".message").text().trim(), expectedMessage);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/c6ce4ec8/tez-ui2/src/main/webapp/tests/unit/routes/application-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/application-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/application-test.js
index 695b72f..e441e49 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/application-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/application-test.js
@@ -30,6 +30,12 @@ test('Basic creation test', function(assert) {
   assert.ok(route.pageReset);
   assert.ok(route.actions.didTransition);
   assert.ok(route.actions.bubbleBreadcrumbs);
+
+  assert.ok(route.actions.error);
+
+  assert.ok(route.actions.openModal);
+  assert.ok(route.actions.closeModal);
+  assert.ok(route.actions.destroyModal);
 });
 
 test('Test didTransition action', function(assert) {

http://git-wip-us.apache.org/repos/asf/tez/blob/c6ce4ec8/tez-ui2/src/main/webapp/tests/unit/utils/download-dag-zip-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/utils/download-dag-zip-test.js b/tez-ui2/src/main/webapp/tests/unit/utils/download-dag-zip-test.js
new file mode 100644
index 0000000..0fe8c5f
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/utils/download-dag-zip-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 downloadDagZip from '../../../utils/download-dag-zip';
+import { module, test } from 'qunit';
+
+module('Unit | Utility | download dag zip');
+
+test('Basic creation test', function(assert) {
+  assert.ok(downloadDagZip);
+});


[21/45] tez git commit: TEZ-3048. Tez UI 2: Make PhantomJS a local dependency for build tests (sree)

Posted by sr...@apache.org.
TEZ-3048. Tez UI 2: Make PhantomJS a local dependency for build tests (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/a42b6f6c
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/a42b6f6c
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/a42b6f6c

Branch: refs/heads/TEZ-2980
Commit: a42b6f6ca8cf065380c9f474f955ec9672416848
Parents: e893e94
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Tue Jan 19 12:50:29 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:32:15 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                 | 1 +
 tez-ui2/src/main/webapp/package.json | 5 +++--
 2 files changed, 4 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/a42b6f6c/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index 366396f..65fdcb5 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -18,3 +18,4 @@ ALL CHANGES:
   TEZ-3040. Tez UI 2: Create Vertex details page & sub tables
   TEZ-3041. Tez UI 2: Create Task & Attempt details page with sub tables
   TEZ-3045. Tez UI 2: Create application details page with DAGs tab
+  TEZ-3048. Tez UI 2: Make PhantomJS a local dependency for build tests

http://git-wip-us.apache.org/repos/asf/tez/blob/a42b6f6c/tez-ui2/src/main/webapp/package.json
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/package.json b/tez-ui2/src/main/webapp/package.json
index a5b29db..ec84b18 100644
--- a/tez-ui2/src/main/webapp/package.json
+++ b/tez-ui2/src/main/webapp/package.json
@@ -48,9 +48,10 @@
   },
   "dependencies": {
     "broccoli-funnel": "^1.0.1",
-    "em-table": "0.3.7",
     "em-helpers": "0.5.7",
+    "em-table": "0.3.7",
     "ember-cli-htmlbars": "^1.0.1",
-    "ember-cli-less": "^1.4.0"
+    "ember-cli-less": "^1.4.0",
+    "phantomjs": "^1.9.19"
   }
 }


[45/45] tez git commit: TEZ-3088. Tez UI 2: Licenses of all the packages used by Tez Ui must be documented (sree)

Posted by sr...@apache.org.
TEZ-3088. Tez UI 2: Licenses of all the packages used by Tez Ui must be documented (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/32bcb39b
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/32bcb39b
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/32bcb39b

Branch: refs/heads/TEZ-2980
Commit: 32bcb39b427a47314a562ac6f99f73b943535122
Parents: 69ae05e
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Wed Feb 10 23:12:27 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:32:53 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |  1 +
 tez-ui2/src/main/resources/META-INF/LICENSE.txt | 45 ++++++++++++--------
 tez-ui2/src/main/webapp/bower.json              | 19 +++++----
 tez-ui2/src/main/webapp/package.json            | 43 ++++++++++---------
 4 files changed, 60 insertions(+), 48 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/32bcb39b/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index ec8bc05..9d949ca 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -35,3 +35,4 @@ ALL CHANGES:
   TEZ-3080. Tez UI 2: Ensure UI 2 is in-line with UI 1
   TEZ-3092. Tez UI 2: Tuneups & Improvements
   TEZ-3095. Tez UI 2: Tuneups & Improvements
+  TEZ-3088. Tez UI 2: Licenses of all the packages used by Tez Ui must be documented

http://git-wip-us.apache.org/repos/asf/tez/blob/32bcb39b/tez-ui2/src/main/resources/META-INF/LICENSE.txt
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/resources/META-INF/LICENSE.txt b/tez-ui2/src/main/resources/META-INF/LICENSE.txt
index 4f0c9d4..25a1ca1 100644
--- a/tez-ui2/src/main/resources/META-INF/LICENSE.txt
+++ b/tez-ui2/src/main/resources/META-INF/LICENSE.txt
@@ -215,20 +215,30 @@ licenses.
 
 The Apache TEZ tez-ui bundles the following files under the MIT License:
 
- - antiscroll v1.0.0 (https://github.com/LearnBoost/antiscroll) - Copyright (c) 2011 Guillermo Rauch <gu...@learnboost.com>
- - bootstrap v3.3.1 (http://getbootstrap.com) - Copyright (c) 2011-2014 Twitter, Inc
- - ember v1.7.0 (http://emberjs.com/) - Copyright (c) 2014 Yehuda Katz, Tom Dale and Ember.js contributors
- - ember-data v1.0.0-beta.11 (https://github.com/emberjs/data) - Copyright (C) 2011-2014 Tilde, Inc. and contributors, Portions Copyright (C) 2011 LivingSocial Inc.
- - ember-json-mapper v1.0.0 (https://github.com/onechiporenko/ember-json-mapper) - Copyright (c) 2014 onechiporenko
- - font-awesome css/less files v4.2.0 (http://fontawesome.io/) - Created by Dave Gandy
- - handlebars v1.3.0 (http://handlebarsjs.com/) - Copyright (C) 2011-2014 by Yehuda Katz
- - jquery v1.10.2 (http://jquery.org) - Copyright 2005, 2014 jQuery Foundation and other contributors
- - jquery-mousewheel v3.1.12 (https://github.com/jquery/jquery-mousewheel) - Copyright 2006, 2014 jQuery Foundation and other contributors, https://jquery.org/
- - jquery-ui v1.11 (http://jqueryui.com/) - Copyright 2014 jQuery Foundation and other contributors
- - moment v2.10.6 (http://momentjs.com/) - Copyright (c) 2011-2015 Tim Wood, Iskren Chernev, Moment.js contributors
- - moment-timezone v0.4.0 (http://momentjs.com/timezone/) - Copyright (c) 2014 Tim Wood
- - FileSaver.js master branch #24b303f49213b905ec9062b708f7cd43d56a5dde (https://github.com/eligrey/FileSaver.js) authors : Eli Grey.
- - CodeMirror 5.2.0 (https://codemirror.net/) authors: Copyright (C) 2015 by Marijn Haverbeke <ma...@gmail.com> and others
+ - ember v2.2.0 (http://emberjs.com/) - Copyright (c) 2014 Yehuda Katz, Tom Dale and Ember.js contributors
+ - ember-data v2.1.0 (https://github.com/emberjs/data) - Copyright (C) 2011-2014 Tilde, Inc. and contributors, Portions Copyright (C) 2011 LivingSocial Inc.
+ - ember-resolver v2.0.3 (https://github.com/ember-cli/ember-resolver) - Copyright (c) 2013 Stefan Penner and Ember App Kit Contributors
+ - bootstrap v3.3.6 (http://getbootstrap.com) - Copyright (c) 2011-2014 Twitter, Inc
+ - jquery v2.1.4 (http://jquery.org) - Copyright 2005, 2014 jQuery Foundation and other contributors
+ - jquery-ui v1.11.4 (http://jqueryui.com/) - Copyright 2014 jQuery Foundation and other contributors
+ - jquery-mousewheel v3.1.13 (https://github.com/jquery/jquery-mousewheel) - Copyright 2006, 2014 jQuery Foundation and other contributors, https://jquery.org/
+ - CodeMirror 5.11.0 (https://codemirror.net/) - Copyright (C) 2015 by Marijn Haverbeke <ma...@gmail.com> and others
+ - FileSaver.js master branch #230de7d (https://github.com/eligrey/FileSaver.js) - Authored by Eli Grey
+ - moment v2.11.1 (http://momentjs.com/) - Copyright (c) 2011-2015 Tim Wood, Iskren Chernev, Moment.js contributors
+ - moment-timezone v0.5.0 (http://momentjs.com/timezone/) - Copyright (c) 2014 Tim Wood
+ - font-awesome css/less files v4.5.0 (http://fontawesome.io/) - Created by Dave Gandy
+ - ember-bootstrap v0.5.1 (https://github.com/kaliber5/ember-bootstrap) - Copyright 2015 kaliber5 GmbH.
+ - snippet-ss v1.11.0 (https://github.com/sreenaths/snippet-ss)
+ - em-tgraph v0.0.3 (https://github.com/sreenaths/em-tgraph)
+ - em-table v0.3.10 (https://github.com/sreenaths/em-table)
+ - em-helpers v0.5.8 (https://github.com/sreenaths/em-helpers)
+ - ember-cli-app-version v1.0.0 (https://github.com/EmberSherpa/ember-cli-app-version) - Authored by Taras Mankovski <ta...@gmail.com>
+ - ember-cli-auto-register v1.1.0 (https://github.com/williamsbdev/ember-cli-auto-register) - Copyright © 2015 Brandon Williams http://williamsbdev.com
+ - ember-cli-content-security-policy v0.4.0 (https://github.com/rwjblue/ember-cli-content-security-policy)
+ - ember-cli-d3 v1.1.2 (https://github.com/ming-codes/ember-cli-d3) - Authored by Ming Liu
+ - ember-cli-font-awesome v1.4.0 (https://github.com/martndemus/ember-cli-font-awesome) - Authored by Marten Schilstra <ma...@martenschilstra.nl>
+ - ember-cli-jquery-ui 0.0.20 (https://github.com/gaurav0/ember-cli-jquery-ui) - Authored by Gaurav Munjal
+ - normalize.css v3.0.3 (github.com/necolas/normalize.css) - By Nicolas Gallagher & Jonathan Neal
 
 All rights reserved.
 
@@ -257,9 +267,8 @@ THE SOFTWARE.
 The Apache Tez tez-ui bundles the following files under BSD licenses:
 
 (3-clause BSD license)
- - D3 v3.4.11 (http://d3js.org/) - Copyright (c) 2010-2014, Michael Bostock
- - ember-table v0.2.2 (https://github.com/Addepar/ember-table) - Copyright © 2012 Addepar, Inc. All Rights Reserved.
- - zip.js master branch #bfd76c66293305faaf9fcbb65b5ff7fe2dbe621a (https://github.com/gildas-lormeau/zip.js)
+ - D3 v3.5.14 (http://d3js.org/) - Copyright (c) 2010-2014, Michael Bostock
+ - zip.js master branch #1bead0a (https://github.com/gildas-lormeau/zip.js)
 
 All rights reserved.
 
@@ -295,7 +304,7 @@ POSSIBILITY OF SUCH DAMAGE.
 The Apache Tez tez-ui bundles the following fonts under the
 SIL Open Font License v1.1 (OFT) - http://scripts.sil.org/OFL
 
- - font-awesome fonts v4.2.0 (http://fontawesome.io/) - Created by Dave Gandy
+ - font-awesome fonts v4.5.0 (http://fontawesome.io/) - Created by Dave Gandy
 
 SIL OPEN FONT LICENSE
 

http://git-wip-us.apache.org/repos/asf/tez/blob/32bcb39b/tez-ui2/src/main/webapp/bower.json
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/bower.json b/tez-ui2/src/main/webapp/bower.json
index f0fec1a..87e53ba 100644
--- a/tez-ui2/src/main/webapp/bower.json
+++ b/tez-ui2/src/main/webapp/bower.json
@@ -9,18 +9,19 @@
     "ember-qunit": "0.4.16",
     "ember-qunit-notifications": "0.1.0",
     "loader.js": "3.3.0",
-    "qunit": "~1.19.0",
-    "more-js": "*",
-    "bootstrap": "~3.3.5",
-    "font-awesome": "~4.5.0",
+    "qunit": "1.19.0",
+    "more-js": "0.8.2",
+    "bootstrap": "3.3.6",
+    "font-awesome": "4.5.0",
+    "jquery": "2.1.4",
     "jquery-ui": "1.11.4",
-    "moment": "^2.8.0",
-    "moment-timezone": "^0.5.0",
+    "moment": "2.11.1",
+    "moment-timezone": "0.5.0",
     "numeral": "1.5.3",
-    "snippet-ss": "~1.11.0",
-    "jquery-mousewheel": "~3.1.13",
+    "snippet-ss": "1.11.0",
+    "jquery-mousewheel": "3.1.13",
     "FileSaver": "#230de7d",
     "zip.js": "#1bead0a",
-    "codemirror": "~5.11.0"
+    "codemirror": "5.11.0"
   }
 }

http://git-wip-us.apache.org/repos/asf/tez/blob/32bcb39b/tez-ui2/src/main/webapp/package.json
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/package.json b/tez-ui2/src/main/webapp/package.json
index db2cc77..1393e90 100644
--- a/tez-ui2/src/main/webapp/package.json
+++ b/tez-ui2/src/main/webapp/package.json
@@ -1,6 +1,7 @@
 {
   "name": "tez-ui",
   "version": "0.2.0",
+  "license": "Apache-2.0",
   "description": "Apache Tez UI",
   "private": true,
   "directories": {
@@ -21,41 +22,41 @@
     "node": ">= 0.10.0"
   },
   "devDependencies": {
-    "bower": "^1.7.1",
-    "broccoli-asset-rev": "^2.2.0",
-    "broccoli-merge-trees": "^1.1.1",
-    "em-tgraph": "0.0.3",
+    "bower": "1.7.7",
+    "broccoli-asset-rev": "2.4.2",
+    "broccoli-funnel": "1.0.1",
+    "broccoli-merge-trees": "1.1.1",
     "ember-bootstrap": "0.5.1",
     "ember-cli": "1.13.13",
-    "ember-cli-app-version": "^1.0.0",
-    "ember-cli-auto-register": "^1.1.0",
-    "ember-cli-babel": "^5.1.5",
+    "ember-cli-app-version": "1.0.0",
+    "ember-cli-auto-register": "1.1.0",
+    "ember-cli-babel": "5.1.6",
     "ember-cli-content-security-policy": "0.4.0",
     "ember-cli-d3": "1.1.2",
-    "ember-cli-dependency-checker": "^1.1.0",
+    "ember-cli-dependency-checker": "1.2.0",
     "ember-cli-font-awesome": "1.4.0",
-    "ember-cli-htmlbars-inline-precompile": "^0.3.1",
-    "ember-cli-inject-live-reload": "^1.3.1",
+    "ember-cli-htmlbars": "1.0.2",
+    "ember-cli-htmlbars-inline-precompile": "0.3.1",
+    "ember-cli-inject-live-reload": "1.4.0",
     "ember-cli-jquery-ui": "0.0.20",
+    "ember-cli-less": "1.5.3",
     "ember-cli-moment-shim": "0.7.3",
     "ember-cli-mousewheel": "0.1.5",
     "ember-cli-numeral": "0.1.2",
-    "ember-cli-qunit": "^1.0.4",
+    "ember-cli-qunit": "1.2.1",
     "ember-cli-release": "0.2.8",
-    "ember-cli-sri": "^1.2.0",
-    "ember-cli-test-info": "^1.0.0",
-    "ember-cli-uglify": "^1.2.0",
+    "ember-cli-sri": "1.2.1",
+    "ember-cli-test-info": "1.0.0",
+    "ember-cli-uglify": "1.2.0",
     "ember-data": "2.1.0",
-    "ember-disable-proxy-controllers": "^1.0.1",
-    "ember-export-application-global": "^1.0.4",
-    "ember-resolver": "^2.0.3"
+    "ember-disable-proxy-controllers": "1.0.1",
+    "ember-export-application-global": "1.0.5",
+    "ember-resolver": "2.0.3",
+    "phantomjs": "1.9.19"
   },
   "dependencies": {
-    "broccoli-funnel": "^1.0.1",
     "em-helpers": "0.5.8",
     "em-table": "0.3.10",
-    "ember-cli-htmlbars": "^1.0.1",
-    "ember-cli-less": "^1.4.0",
-    "phantomjs": "^1.9.19"
+    "em-tgraph": "0.0.3"
   }
 }


[18/45] tez git commit: TEZ-3041. Tez UI 2: Create Task & Attempt details page with sub tables (sree)

Posted by sr...@apache.org.
TEZ-3041. Tez UI 2: Create Task & Attempt details page with sub tables (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/70c6b5fa
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/70c6b5fa
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/70c6b5fa

Branch: refs/heads/TEZ-2980
Commit: 70c6b5fa029796f4d4c65db3d9270c81f3959f89
Parents: 68dc2f5
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Tue Jan 19 01:31:55 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:32:15 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |  1 +
 .../src/main/webapp/app/controllers/attempt.js  | 53 +++++++++++++
 .../webapp/app/controllers/attempt/index.js     | 22 ++++++
 .../main/webapp/app/controllers/dag/attempts.js | 20 ++++-
 .../main/webapp/app/controllers/dag/tasks.js    | 10 ++-
 tez-ui2/src/main/webapp/app/controllers/task.js | 51 ++++++++++++
 .../webapp/app/controllers/task/attempts.js     | 81 ++++++++++++++++++++
 .../main/webapp/app/controllers/task/index.js   | 22 ++++++
 .../webapp/app/controllers/vertex/attempts.js   | 20 ++++-
 .../main/webapp/app/controllers/vertex/tasks.js | 10 ++-
 tez-ui2/src/main/webapp/app/router.js           |  6 +-
 tez-ui2/src/main/webapp/app/routes/attempt.js   | 31 ++++++++
 .../src/main/webapp/app/routes/attempt/index.js | 33 ++++++++
 tez-ui2/src/main/webapp/app/routes/task.js      | 31 ++++++++
 .../src/main/webapp/app/routes/task/attempts.js | 35 +++++++++
 .../src/main/webapp/app/routes/task/index.js    | 33 ++++++++
 .../src/main/webapp/app/templates/attempt.hbs   | 20 +++++
 .../main/webapp/app/templates/attempt/index.hbs | 65 ++++++++++++++++
 tez-ui2/src/main/webapp/app/templates/task.hbs  | 20 +++++
 .../main/webapp/app/templates/task/attempts.hbs | 33 ++++++++
 .../main/webapp/app/templates/task/index.hbs    | 57 ++++++++++++++
 .../tests/unit/controllers/attempt-test.js      | 36 +++++++++
 .../unit/controllers/attempt/index-test.js      | 34 ++++++++
 .../webapp/tests/unit/controllers/task-test.js  | 36 +++++++++
 .../unit/controllers/task/attempts-test.js      | 36 +++++++++
 .../tests/unit/controllers/task/index-test.js   | 34 ++++++++
 .../webapp/tests/unit/routes/attempt-test.js    | 32 ++++++++
 .../tests/unit/routes/attempt/index-test.js     | 45 +++++++++++
 .../main/webapp/tests/unit/routes/task-test.js  | 32 ++++++++
 .../tests/unit/routes/task/attempts-test.js     | 45 +++++++++++
 .../webapp/tests/unit/routes/task/index-test.js | 45 +++++++++++
 31 files changed, 1022 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/70c6b5fa/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index 3389c46..354816e 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -16,3 +16,4 @@ ALL CHANGES:
   TEZ-3038. Tez UI 2: Create DAG details page
   TEZ-3039. Tez UI 2: Create all sub-pages for DAG
   TEZ-3040. Tez UI 2: Create Vertex details page & sub tables
+  TEZ-3041. Tez UI 2: Create Task & Attempt details page with sub tables

http://git-wip-us.apache.org/repos/asf/tez/blob/70c6b5fa/tez-ui2/src/main/webapp/app/controllers/attempt.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/attempt.js b/tez-ui2/src/main/webapp/app/controllers/attempt.js
new file mode 100644
index 0000000..f17e317
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/attempt.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 Ember from 'ember';
+
+import AbstractController from './abstract';
+
+export default AbstractController.extend({
+  breadcrumbs: Ember.computed("model.dag", function () {
+    var dagName = this.get("model.dag.name"),
+        vertexName = this.get("model.vertexName"),
+        taskIndex = this.get("model.taskIndex"),
+        attemptNo = this.get("model.index");
+
+    return [{
+      text: `DAG [ ${dagName} ]`,
+      routeName: "dag.index",
+      model: this.get("model.dagID")
+    },{
+      text: `Vertex [ ${vertexName} ]`,
+      routeName: "vertex.index",
+      model: this.get("model.vertexID")
+    },{
+      text: `Task [ ${taskIndex} ]`,
+      routeName: "task.index",
+      model: this.get("model.taskID")
+    },{
+      text: `Attempt [ ${attemptNo} ]`,
+      routeName: "attempt.index",
+      model: this.get("model.entityID")
+    }];
+  }),
+
+  tabs: [{
+    text: "Attempt Details",
+    routeName: "attempt.index"
+  }]
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/70c6b5fa/tez-ui2/src/main/webapp/app/controllers/attempt/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/attempt/index.js b/tez-ui2/src/main/webapp/app/controllers/attempt/index.js
new file mode 100644
index 0000000..9745328
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/attempt/index.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 PageController from '../page';
+
+export default PageController.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/70c6b5fa/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js b/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
index c2e3950..d9cb9e9 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
@@ -28,11 +28,27 @@ export default TablePageController.extend({
   columns: ColumnDefinition.make([{
     id: 'index',
     headerTitle: 'Attempt No',
-    contentPath: 'index'
+    contentPath: 'index',
+    cellComponentName: 'em-table-linked-cell',
+    getCellContent: function (row) {
+      return {
+        routeName: "attempt",
+        model: row.get("entityID"),
+        text: row.get("index")
+      };
+    }
   },{
     id: 'taskIndex',
     headerTitle: 'Task Index',
-    contentPath: 'taskIndex'
+    contentPath: 'taskIndex',
+    cellComponentName: 'em-table-linked-cell',
+    getCellContent: function (row) {
+      return {
+        routeName: "task",
+        model: row.get("taskID"),
+        text: row.get("taskIndex")
+      };
+    }
   },{
     id: 'vertexName',
     headerTitle: 'Vertex Index',

http://git-wip-us.apache.org/repos/asf/tez/blob/70c6b5fa/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js b/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
index 4721b81..1a5c776 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
@@ -28,7 +28,15 @@ export default TablePageController.extend({
   columns: ColumnDefinition.make([{
     id: 'index',
     headerTitle: 'Task Index',
-    contentPath: 'index'
+    contentPath: 'index',
+    cellComponentName: 'em-table-linked-cell',
+    getCellContent: function (row) {
+      return {
+        routeName: "task",
+        model: row.get("entityID"),
+        text: row.get("index")
+      };
+    }
   },{
     id: 'vertexName',
     headerTitle: 'Vertex Name',

http://git-wip-us.apache.org/repos/asf/tez/blob/70c6b5fa/tez-ui2/src/main/webapp/app/controllers/task.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/task.js b/tez-ui2/src/main/webapp/app/controllers/task.js
new file mode 100644
index 0000000..5b2510c
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/task.js
@@ -0,0 +1,51 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 AbstractController from './abstract';
+
+export default AbstractController.extend({
+  breadcrumbs: Ember.computed("model.dag", function () {
+    var dagName = this.get("model.dag.name"),
+        vertexName = this.get("model.vertexName"),
+        taskIndex = this.get("model.index");
+
+    return [{
+      text: `DAG [ ${dagName} ]`,
+      routeName: "dag.index",
+      model: this.get("model.dagID")
+    },{
+      text: `Vertex [ ${vertexName} ]`,
+      routeName: "vertex.index",
+      model: this.get("model.vertexID")
+    },{
+      text: `Task [ ${taskIndex} ]`,
+      routeName: "task.index",
+      model: this.get("model.entityID")
+    }];
+  }),
+
+  tabs: [{
+    text: "Task Details",
+    routeName: "task.index"
+  }, {
+    text: "Task Attempts",
+    routeName: "task.attempts"
+  }]
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/70c6b5fa/tez-ui2/src/main/webapp/app/controllers/task/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/task/attempts.js b/tez-ui2/src/main/webapp/app/controllers/task/attempts.js
new file mode 100644
index 0000000..5b97033
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/task/attempts.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 TablePageController from '../table-page';
+import ColumnDefinition from 'em-table/utils/column-definition';
+
+export default TablePageController.extend({
+  breadcrumbs: [{
+    text: "Task Attempts",
+    routeName: "task.attempts",
+  }],
+
+  columns: ColumnDefinition.make([{
+    id: 'index',
+    headerTitle: 'Attempt No',
+    contentPath: 'index',
+    cellComponentName: 'em-table-linked-cell',
+    getCellContent: function (row) {
+      return {
+        routeName: "attempt",
+        model: row.get("entityID"),
+        text: row.get("index")
+      };
+    }
+  },{
+    id: 'status',
+    headerTitle: 'Status',
+    contentPath: 'status',
+    cellComponentName: 'em-table-status-cell'
+  },{
+    id: 'progress',
+    headerTitle: 'Progress',
+    contentPath: 'progress',
+    cellComponentName: 'em-table-progress-cell',
+    observePath: true
+  },{
+    id: 'startTime',
+    headerTitle: 'Start Time',
+    contentPath: 'startTime',
+    cellDefinition: {
+      type: 'date'
+    }
+  },{
+    id: 'endTime',
+    headerTitle: 'End Time',
+    contentPath: 'endTime',
+    cellDefinition: {
+      type: 'date'
+    }
+  },{
+    id: 'duration',
+    headerTitle: 'Duration',
+    contentPath: 'duration',
+    cellDefinition: {
+      type: 'duration'
+    }
+  },{
+    id: 'containerID',
+    headerTitle: 'Container',
+    contentPath: 'containerID'
+  },{
+    id: 'nodeID',
+    headerTitle: 'Node',
+    contentPath: 'nodeID'
+  }])
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/70c6b5fa/tez-ui2/src/main/webapp/app/controllers/task/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/task/index.js b/tez-ui2/src/main/webapp/app/controllers/task/index.js
new file mode 100644
index 0000000..9745328
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/task/index.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 PageController from '../page';
+
+export default PageController.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/70c6b5fa/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js b/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js
index 61a6a63..b6a4389 100644
--- a/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js
+++ b/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js
@@ -28,11 +28,27 @@ export default TablePageController.extend({
   columns: ColumnDefinition.make([{
     id: 'index',
     headerTitle: 'Attempt No',
-    contentPath: 'index'
+    contentPath: 'index',
+    cellComponentName: 'em-table-linked-cell',
+    getCellContent: function (row) {
+      return {
+        routeName: "attempt",
+        model: row.get("entityID"),
+        text: row.get("index")
+      };
+    }
   },{
     id: 'taskIndex',
     headerTitle: 'Task Index',
-    contentPath: 'taskIndex'
+    contentPath: 'taskIndex',
+    cellComponentName: 'em-table-linked-cell',
+    getCellContent: function (row) {
+      return {
+        routeName: "task",
+        model: row.get("taskID"),
+        text: row.get("taskIndex")
+      };
+    }
   },{
     id: 'status',
     headerTitle: 'Status',

http://git-wip-us.apache.org/repos/asf/tez/blob/70c6b5fa/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.js b/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.js
index ce67150..f35a022 100644
--- a/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.js
+++ b/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.js
@@ -28,7 +28,15 @@ export default TablePageController.extend({
   columns: ColumnDefinition.make([{
     id: 'index',
     headerTitle: 'Task Index',
-    contentPath: 'index'
+    contentPath: 'index',
+    cellComponentName: 'em-table-linked-cell',
+    getCellContent: function (row) {
+      return {
+        routeName: "task",
+        model: row.get("entityID"),
+        text: row.get("index")
+      };
+    }
   },{
     id: 'status',
     headerTitle: 'Status',

http://git-wip-us.apache.org/repos/asf/tez/blob/70c6b5fa/tez-ui2/src/main/webapp/app/router.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/router.js b/tez-ui2/src/main/webapp/app/router.js
index e80c817..e907cc7 100644
--- a/tez-ui2/src/main/webapp/app/router.js
+++ b/tez-ui2/src/main/webapp/app/router.js
@@ -30,11 +30,15 @@ Router.map(function() {
     this.route('tasks');
     this.route('attempts');
   });
-  this.route('app', {path: '/app/:app_id'});
   this.route('vertex', {path: '/vertex/:vertex_id'}, function() {
     this.route('tasks');
     this.route('attempts');
   });
+  this.route('task', {path: '/task/:task_id'}, function() {
+    this.route('attempts');
+  });
+  this.route('attempt', {path: '/attempt/:attempt_id'}, function () {});
+  this.route('app', {path: '/app/:app_id'}, function () {});
 });
 
 export default Router;

http://git-wip-us.apache.org/repos/asf/tez/blob/70c6b5fa/tez-ui2/src/main/webapp/app/routes/attempt.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/attempt.js b/tez-ui2/src/main/webapp/app/routes/attempt.js
new file mode 100644
index 0000000..71be6d2
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/attempt.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 AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+  title: "Vertex",
+
+  loaderQueryParams: {
+    id: "attempt_id"
+  },
+
+  model: function (params) {
+    return this.get("loader").queryRecord('attempt', this.queryFromParams(params).id);
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/70c6b5fa/tez-ui2/src/main/webapp/app/routes/attempt/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/attempt/index.js b/tez-ui2/src/main/webapp/app/routes/attempt/index.js
new file mode 100644
index 0000000..f88737d
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/attempt/index.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';
+import AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  title: "DAG Details",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (/*value, query*/) {
+    return this.get("loader").queryRecord('attempt', this.modelFor("attempt").id);
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/70c6b5fa/tez-ui2/src/main/webapp/app/routes/task.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/task.js b/tez-ui2/src/main/webapp/app/routes/task.js
new file mode 100644
index 0000000..42809c9
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/task.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 AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+  title: "Vertex",
+
+  loaderQueryParams: {
+    id: "task_id"
+  },
+
+  model: function (params) {
+    return this.get("loader").queryRecord('task', this.queryFromParams(params).id);
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/70c6b5fa/tez-ui2/src/main/webapp/app/routes/task/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/task/attempts.js b/tez-ui2/src/main/webapp/app/routes/task/attempts.js
new file mode 100644
index 0000000..bc7af27
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/task/attempts.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({
+  title: "Task Attempts",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (/*value, query*/) {
+    return this.get("loader").query('attempt', {
+      taskID: this.modelFor("task").id
+    });
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/70c6b5fa/tez-ui2/src/main/webapp/app/routes/task/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/task/index.js b/tez-ui2/src/main/webapp/app/routes/task/index.js
new file mode 100644
index 0000000..fd76df9
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/task/index.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';
+import AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  title: "DAG Details",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (/*value, query*/) {
+    return this.get("loader").queryRecord('task', this.modelFor("task").id);
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/70c6b5fa/tez-ui2/src/main/webapp/app/templates/attempt.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/attempt.hbs b/tez-ui2/src/main/webapp/app/templates/attempt.hbs
new file mode 100644
index 0000000..308b905
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/attempt.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.
+}}
+
+{{tab-n-refresh tabs=tabs}}
+{{outlet}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/70c6b5fa/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs b/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs
new file mode 100644
index 0000000..cf83afe
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs
@@ -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.
+}}
+
+{{#if loaded}}
+  <table class='detail-list'>
+    <thead>
+      <tr>
+        <th colspan=2>Details</th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>Task Attempt ID</td>
+        <td>{{model.entityID}}</td>
+      </tr>
+      <tr>
+        <td>Task ID</td>
+        <td>{{model.taskID}}</td>
+      </tr>
+      <tr>
+        <td>Container ID</td>
+        <td>{{model.containerID}}</td>
+      </tr>
+      <tr>
+        <td>Node ID</td>
+        <td>{{model.nodeID}}</td>
+      </tr>
+      <tr>
+        <td>Status</td>
+        <td>
+          {{em-table-status-cell content=model.status}}
+        </td>
+      </tr>
+      <tr>
+        <td>Start Time</td>
+        <td>{{txt model.startTime type="date"}}</td>
+      </tr>
+      <tr>
+        <td>End Time</td>
+        <td>{{txt model.endTime type="date"}}</td>
+      </tr>
+      <tr>
+        <td>Duration</td>
+        <td>{{txt model.duration type="duration"}}</td>
+      </tr>
+    </tbody>
+  </table>
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/70c6b5fa/tez-ui2/src/main/webapp/app/templates/task.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/task.hbs b/tez-ui2/src/main/webapp/app/templates/task.hbs
new file mode 100644
index 0000000..308b905
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/task.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.
+}}
+
+{{tab-n-refresh tabs=tabs}}
+{{outlet}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/70c6b5fa/tez-ui2/src/main/webapp/app/templates/task/attempts.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/task/attempts.hbs b/tez-ui2/src/main/webapp/app/templates/task/attempts.hbs
new file mode 100644
index 0000000..cdb28aa
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/task/attempts.hbs
@@ -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.
+}}
+
+{{#if loaded}}
+  {{em-table
+  columns=columns
+  rows=model
+
+  definition=definition
+
+  searchAction="searchChanged"
+  sortAction="sortChanged"
+  rowAction="rowsChanged"
+  pageAction="pageChanged"
+  }}
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/70c6b5fa/tez-ui2/src/main/webapp/app/templates/task/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/task/index.hbs b/tez-ui2/src/main/webapp/app/templates/task/index.hbs
new file mode 100644
index 0000000..b559203
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/task/index.hbs
@@ -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.
+}}
+
+{{#if loaded}}
+  <table class='detail-list'>
+    <thead>
+      <tr>
+        <th colspan=2>Details</th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>Task ID</td>
+        <td>{{model.entityID}}</td>
+      </tr>
+      <tr>
+        <td>Vertex ID</td>
+        <td>{{model.vertexID}}</td>
+      </tr>
+      <tr>
+        <td>Status</td>
+        <td>
+          {{em-table-status-cell content=model.status}}
+        </td>
+      </tr>
+      <tr>
+        <td>Start Time</td>
+        <td>{{txt model.startTime type="date"}}</td>
+      </tr>
+      <tr>
+        <td>End Time</td>
+        <td>{{txt model.endTime type="date"}}</td>
+      </tr>
+      <tr>
+        <td>Duration</td>
+        <td>{{txt model.duration type="duration"}}</td>
+      </tr>
+    </tbody>
+  </table>
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/70c6b5fa/tez-ui2/src/main/webapp/tests/unit/controllers/attempt-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/attempt-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/attempt-test.js
new file mode 100644
index 0000000..32c6347
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/attempt-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:attempt', 'Unit | Controller | vertex', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+  assert.ok(controller.tabs);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/70c6b5fa/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/index-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/index-test.js
new file mode 100644
index 0000000..b20e402
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/index-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:attempt/index', 'Unit | Controller | vertex/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/70c6b5fa/tez-ui2/src/main/webapp/tests/unit/controllers/task-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/task-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/task-test.js
new file mode 100644
index 0000000..f59817e
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/task-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:task', 'Unit | Controller | vertex', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+  assert.ok(controller.tabs);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/70c6b5fa/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.js
new file mode 100644
index 0000000..bf389da
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:task/attempts', 'Unit | Controller | vertex/attempts', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+  assert.ok(controller.columns);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/70c6b5fa/tez-ui2/src/main/webapp/tests/unit/controllers/task/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/task/index-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/task/index-test.js
new file mode 100644
index 0000000..e3014ae
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/task/index-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:task/index', 'Unit | Controller | vertex/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/70c6b5fa/tez-ui2/src/main/webapp/tests/unit/routes/attempt-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/attempt-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/attempt-test.js
new file mode 100644
index 0000000..dbfe590
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/attempt-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:attempt', 'Unit | Route | vertex', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.loaderQueryParams);
+  assert.ok(route.model);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/70c6b5fa/tez-ui2/src/main/webapp/tests/unit/routes/attempt/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/attempt/index-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/attempt/index-test.js
new file mode 100644
index 0000000..8576090
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/attempt/index-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:attempt/index', 'Unit | Route | vertex/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+  assert.ok(route.load);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/70c6b5fa/tez-ui2/src/main/webapp/tests/unit/routes/task-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/task-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/task-test.js
new file mode 100644
index 0000000..af802b8
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/task-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:task', 'Unit | Route | vertex', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.loaderQueryParams);
+  assert.ok(route.model);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/70c6b5fa/tez-ui2/src/main/webapp/tests/unit/routes/task/attempts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/task/attempts-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/task/attempts-test.js
new file mode 100644
index 0000000..1209012
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/task/attempts-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:task/attempts', 'Unit | Route | vertex/attempts', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+  assert.ok(route.load);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/70c6b5fa/tez-ui2/src/main/webapp/tests/unit/routes/task/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/task/index-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/task/index-test.js
new file mode 100644
index 0000000..8f4f6b9
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/task/index-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:task/index', 'Unit | Route | vertex/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+  assert.ok(route.load);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});


[09/45] tez git commit: TEZ-3019. Tez UI 2: Replace BaseURL with Host (sree)

Posted by sr...@apache.org.
TEZ-3019. Tez UI 2: Replace BaseURL with Host (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/ec0a5927
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/ec0a5927
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/ec0a5927

Branch: refs/heads/TEZ-2980
Commit: ec0a5927a8e301e8a84f96ca71a33be5ab462dde
Parents: d6bb483
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Tue Dec 29 23:00:20 2015 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:31:59 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                                |  1 +
 tez-ui2/src/main/webapp/app/services/hosts.js       |  8 ++++----
 .../src/main/webapp/app/templates/application.hbs   |  4 +++-
 tez-ui2/src/main/webapp/config/configs.env          |  4 ++--
 .../main/webapp/tests/unit/services/hosts-test.js   | 16 ++++++++--------
 5 files changed, 18 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/ec0a5927/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index e792420..5143309 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -3,3 +3,4 @@ ALL CHANGES:
   TEZ-3016. Tez UI 2: Make bower dependency silent
   TEZ-2983. Tez UI 2: Get ember initializers functional
   TEZ-3018. Tez UI 2: Add config.env
+  TEZ-3019. Tez UI 2: Replace BaseURL with Host

http://git-wip-us.apache.org/repos/asf/tez/blob/ec0a5927/tez-ui2/src/main/webapp/app/services/hosts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/services/hosts.js b/tez-ui2/src/main/webapp/app/services/hosts.js
index 7ffdc29..f549f2c 100644
--- a/tez-ui2/src/main/webapp/app/services/hosts.js
+++ b/tez-ui2/src/main/webapp/app/services/hosts.js
@@ -54,14 +54,14 @@ export default Ember.Service.extend({
     return url;
   },
 
-  timelineBaseURL: Ember.computed(function () {
+  timeline: Ember.computed(function () {
     var ENV = window.ENV;
-    return this.normalizeURL((ENV && ENV.timelineBaseURL) || environment.hosts.timeline);
+    return this.normalizeURL((ENV && ENV.timelineHost) || environment.hosts.timeline);
   }),
 
-  rmBaseURL: Ember.computed(function () {
+  rm: Ember.computed(function () {
     var ENV = window.ENV;
-    return this.normalizeURL((ENV && ENV.rmBaseURL) || environment.hosts.RM);
+    return this.normalizeURL((ENV && ENV.rmHost) || environment.hosts.RM);
   }),
 
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/ec0a5927/tez-ui2/src/main/webapp/app/templates/application.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/application.hbs b/tez-ui2/src/main/webapp/app/templates/application.hbs
index c1c380d..d1154b1 100644
--- a/tez-ui2/src/main/webapp/app/templates/application.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/application.hbs
@@ -20,4 +20,6 @@
 
 {{outlet}}
 
-{{hosts.timelineBaseURL}}
+Timeline: {{hosts.timeline}}
+<br/>
+RM: {{hosts.rm}}

http://git-wip-us.apache.org/repos/asf/tez/blob/ec0a5927/tez-ui2/src/main/webapp/config/configs.env
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/config/configs.env b/tez-ui2/src/main/webapp/config/configs.env
index 6e12286..5f5ec17 100644
--- a/tez-ui2/src/main/webapp/config/configs.env
+++ b/tez-ui2/src/main/webapp/config/configs.env
@@ -1,4 +1,4 @@
 ENV = {
-  //timelineBaseURL: "http://localhost:8188",
-  //rmBaseURL: "http://localhost:8088"
+  //timelineHost: "http://localhost:8188",
+  //rmHost: "http://localhost:8088"
 };

http://git-wip-us.apache.org/repos/asf/tez/blob/ec0a5927/tez-ui2/src/main/webapp/tests/unit/services/hosts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/services/hosts-test.js b/tez-ui2/src/main/webapp/tests/unit/services/hosts-test.js
index b130a2c..51b558c 100644
--- a/tez-ui2/src/main/webapp/tests/unit/services/hosts-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/services/hosts-test.js
@@ -57,20 +57,20 @@ test('Test correctProtocol with protocol=file:', function(assert) {
   assert.equal(service.correctProtocol("https://localhost:8088", "file:"), "https://localhost:8088");
 });
 
-test('Test base URLs', function(assert) {
+test('Test host URLs', function(assert) {
   let service = this.subject();
 
-  assert.equal(service.get("timelineBaseURL"), "http://localhost:8188");
-  assert.equal(service.get("rmBaseURL"), "http://localhost:8088");
+  assert.equal(service.get("timeline"), "http://localhost:8188");
+  assert.equal(service.get("rm"), "http://localhost:8088");
 });
 
-test('Test base URLs with ENV set', function(assert) {
+test('Test host URLs with ENV set', function(assert) {
   let service = this.subject();
 
   window.ENV = {
-    timelineBaseURL: "https://localhost:3333",
-    rmBaseURL: "https://localhost:4444"
+    timelineHost: "https://localhost:3333",
+    rmHost: "https://localhost:4444"
   };
-  assert.equal(service.get("timelineBaseURL"), "http://localhost:3333");
-  assert.equal(service.get("rmBaseURL"), "http://localhost:4444");
+  assert.equal(service.get("timeline"), "http://localhost:3333");
+  assert.equal(service.get("rm"), "http://localhost:4444");
 });


[42/45] tez git commit: TEZ-3084. Tez UI 2: Display caller type and info (sree)

Posted by sr...@apache.org.
TEZ-3084. Tez UI 2: Display caller type and info (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/94599693
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/94599693
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/94599693

Branch: refs/heads/TEZ-2980
Commit: 94599693c05d276df850f10dffdedcc8d275e9e6
Parents: c6ce4ec
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Tue Feb 2 01:41:24 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:32:53 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |  1 +
 .../src/main/webapp/app/adapters/timeline.js    |  2 +-
 .../main/webapp/app/components/caller-info.js   | 76 ++++++++++++++++++++
 .../webapp/app/components/dags-page-search.js   |  4 +-
 .../src/main/webapp/app/controllers/app/dags.js |  4 +-
 tez-ui2/src/main/webapp/app/controllers/dags.js | 18 +++--
 tez-ui2/src/main/webapp/app/models/dag.js       |  6 +-
 tez-ui2/src/main/webapp/app/routes/dags.js      | 14 ++--
 tez-ui2/src/main/webapp/app/serializers/dag.js  | 27 ++++++-
 .../app/templates/components/caller-info.hbs    | 24 +++++++
 .../templates/components/dags-page-search.hbs   |  6 +-
 .../src/main/webapp/app/templates/dag/index.hbs |  4 ++
 tez-ui2/src/main/webapp/bower.json              |  3 +-
 tez-ui2/src/main/webapp/ember-cli-build.js      |  5 ++
 .../integration/components/caller-info-test.js  | 42 +++++++++++
 15 files changed, 212 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/94599693/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index e4ab014..38f474a 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -31,3 +31,4 @@ ALL CHANGES:
   TEZ-3069. Tez UI 2: Make error bar fully functional
   TEZ-3062. Tez UI 2: Integrate graphical view
   TEZ-3058. Tez UI 2: Add download data functionality
+  TEZ-3084. Tez UI 2: Display caller type and info

http://git-wip-us.apache.org/repos/asf/tez/blob/94599693/tez-ui2/src/main/webapp/app/adapters/timeline.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/timeline.js b/tez-ui2/src/main/webapp/app/adapters/timeline.js
index 82faed8..1a341f7 100644
--- a/tez-ui2/src/main/webapp/app/adapters/timeline.js
+++ b/tez-ui2/src/main/webapp/app/adapters/timeline.js
@@ -37,7 +37,7 @@ export default AbstractAdapter.extend({
     dagName: 'dagName',
     user: "user",
     status: "status",
-    contextID: "callerId"
+    callerID: "callerId"
   },
 
   stringifyFilters: function (filters) {

http://git-wip-us.apache.org/repos/asf/tez/blob/94599693/tez-ui2/src/main/webapp/app/components/caller-info.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/components/caller-info.js b/tez-ui2/src/main/webapp/app/components/caller-info.js
new file mode 100644
index 0000000..3680049
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/components/caller-info.js
@@ -0,0 +1,76 @@
+/*global CodeMirror*/
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Must be convert into an ember addon
+
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+
+  type: null,
+  info: null,
+
+  codeMirror: null,
+
+  mode: Ember.computed("type", function () {
+    switch(this.get("type")) {
+      case 'Hive':
+        return 'text/x-hive';
+      case 'Pig':
+        return 'text/x-pig';
+      default:
+        return 'text/x-sql';
+    }
+  }),
+
+  _init:  Ember.on('didInsertElement', function() {
+    var element  = Ember.$(this.get('element')).find('textarea')[0],
+        codeMirror = CodeMirror.fromTextArea(element, {
+          theme: 'default',
+          indentUnit: 2,
+          smartIndent: true,
+          tabSize: 4,
+          electricChars: true,
+          lineWrapping: true,
+          lineNumbers: true,
+          readOnly: true,
+          autofocus: false,
+          dragDrop: false,
+        });
+
+    this.set('codeMirror', codeMirror);
+
+    this._modeChanged();
+    this._infoChanged();
+  }),
+
+  _modeChanged: Ember.observer("mode", function() {
+    this.get('codeMirror').setOption("mode", this.get("mode"));
+  }),
+
+  _infoChanged: Ember.observer("info", function() {
+    var codeMirror = this.get('codeMirror'),
+        info = this.get('info') || '';
+
+    if (this.get('codeMirror').getValue() !== info) {
+      codeMirror.setValue(info);
+    }
+  })
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/94599693/tez-ui2/src/main/webapp/app/components/dags-page-search.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/components/dags-page-search.js b/tez-ui2/src/main/webapp/app/components/dags-page-search.js
index c9c01e3..f95a901 100644
--- a/tez-ui2/src/main/webapp/app/components/dags-page-search.js
+++ b/tez-ui2/src/main/webapp/app/components/dags-page-search.js
@@ -37,8 +37,8 @@ export default Ember.Component.extend({
     appIDChanged: function (value) {
       this.get('targetObject.targetObject').send('searchChanged', 'appID', value);
     },
-    contextIDChanged: function (value) {
-      this.get('targetObject.targetObject').send('searchChanged', 'contextID', value);
+    callerIDChanged: function (value) {
+      this.get('targetObject.targetObject').send('searchChanged', 'callerID', value);
     },
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/94599693/tez-ui2/src/main/webapp/app/controllers/app/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/app/dags.js b/tez-ui2/src/main/webapp/app/controllers/app/dags.js
index b3e855a..6510e93 100644
--- a/tez-ui2/src/main/webapp/app/controllers/app/dags.js
+++ b/tez-ui2/src/main/webapp/app/controllers/app/dags.js
@@ -83,9 +83,9 @@ export default MultiTableController.extend({
     headerTitle: 'Queue',
     contentPath: 'queue'
   },{
-    id: 'contextID',
+    id: 'callerID',
     headerTitle: 'Context ID',
-    contentPath: 'contextID'
+    contentPath: 'callerID'
   },{
     id: 'logs',
     headerTitle: 'Logs',

http://git-wip-us.apache.org/repos/asf/tez/blob/94599693/tez-ui2/src/main/webapp/app/controllers/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dags.js b/tez-ui2/src/main/webapp/app/controllers/dags.js
index 021a1e0..1a760d1 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dags.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dags.js
@@ -24,27 +24,27 @@ import TableDefinition from 'em-table/utils/table-definition';
 
 export default TableController.extend({
 
-  queryParams: ["dagName", "dagID", "submitter", "status", "appID", "contextID", "pageNo"],
+  queryParams: ["dagName", "dagID", "submitter", "status", "appID", "callerID", "pageNo"],
   dagName: "",
   dagID: "",
   submitter: "",
   status: "",
   appID: "",
-  contextID: "",
+  callerID: "",
   pageNo: 1,
 
   breadcrumbs: [],
 
   headerComponentNames: ['dags-page-search', 'table-controls', 'dags-pagination-ui'],
 
-  definition: Ember.computed("dagName", "dagID", "submitter", "status", "appID", "contextID", "pageNo", function () {
+  definition: Ember.computed("dagName", "dagID", "submitter", "status", "appID", "callerID", "pageNo", function () {
     return TableDefinition.create({
       dagName: this.get("dagName"),
       dagID: this.get("dagID"),
       submitter: this.get("submitter"),
       status: this.get("status"),
       appID: this.get("appID"),
-      contextID: this.get("contextID"),
+      callerID: this.get("callerID"),
 
       pageNum: this.get("pageNo"),
       rowCountOptions: [5, 10, 25, 50, 100, 250, 500]
@@ -121,9 +121,13 @@ export default TableController.extend({
     headerTitle: 'Queue',
     contentPath: 'queue'
   },{
-    id: 'contextID',
-    headerTitle: 'Context ID',
-    contentPath: 'contextID'
+    id: 'callerID',
+    headerTitle: 'Caller ID',
+    contentPath: 'callerID'
+  },{
+    id: 'callerType',
+    headerTitle: 'Caller Type',
+    contentPath: 'callerType'
   },{
     id: 'logs',
     headerTitle: 'Logs',

http://git-wip-us.apache.org/repos/asf/tez/blob/94599693/tez-ui2/src/main/webapp/app/models/dag.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/dag.js b/tez-ui2/src/main/webapp/app/models/dag.js
index 4c4cd96..7114a7c 100644
--- a/tez-ui2/src/main/webapp/app/models/dag.js
+++ b/tez-ui2/src/main/webapp/app/models/dag.js
@@ -44,7 +44,6 @@ export default AMTimelineModel.extend({
   name: DS.attr("string"),
 
   submitter: DS.attr("string"),
-  contextID: DS.attr("string"),
 
   // Serialize when required
   vertices: DS.attr('object'),
@@ -58,4 +57,9 @@ export default AMTimelineModel.extend({
   }),
 
   vertexIdNameMap: DS.attr("object"),
+
+  callerID: DS.attr("string"),
+  callerType: DS.attr("string"),
+  callerInfo: DS.attr("string"),
+
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/94599693/tez-ui2/src/main/webapp/app/routes/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dags.js b/tez-ui2/src/main/webapp/app/routes/dags.js
index 45fd25d..4902460 100644
--- a/tez-ui2/src/main/webapp/app/routes/dags.js
+++ b/tez-ui2/src/main/webapp/app/routes/dags.js
@@ -31,7 +31,7 @@ export default AbstractRoute.extend({
     submitter: REFRESH,
     status: REFRESH,
     appID: REFRESH,
-    contextID: REFRESH,
+    callerID: REFRESH,
     pageNo: REFRESH,
 
     rowCount: REFRESH,
@@ -43,7 +43,7 @@ export default AbstractRoute.extend({
     user: "submitter",
     status: "status",
     appID: "appID",
-    contextID: "contextID",
+    callerID: "callerID",
 
     pageNo: "pageNo",
     limit: "rowCount",
@@ -62,7 +62,7 @@ export default AbstractRoute.extend({
       submitter: query.submitter,
       status: query.status,
       appID: query.appID,
-      contextID: query.contextID
+      callerID: query.callerID
     };
 
     return records.filter(function (record) {
@@ -90,7 +90,13 @@ export default AbstractRoute.extend({
     }
 
     return loader.then(function (records) {
-      return that.filterRecords(records, query);
+      records = that.filterRecords(records, query);
+      records.forEach(function (record) {
+        if(record.get("status") === "RUNNING") {
+          that.get("loader").loadNeed(record, "am", {reload: true});
+        }
+      });
+      return records;
     });
   },
 

http://git-wip-us.apache.org/repos/asf/tez/blob/94599693/tez-ui2/src/main/webapp/app/serializers/dag.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/dag.js b/tez-ui2/src/main/webapp/app/serializers/dag.js
index f7d2f21..b5cc42c 100644
--- a/tez-ui2/src/main/webapp/app/serializers/dag.js
+++ b/tez-ui2/src/main/webapp/app/serializers/dag.js
@@ -107,7 +107,6 @@ export default TimelineSerializer.extend({
     name: 'primaryfilters.dagName.0',
 
     submitter: 'primaryfilters.user.0',
-    contextID: 'primaryfilters.callerId.0',
 
     atsStatus: getStatus,
     // progress
@@ -125,6 +124,28 @@ export default TimelineSerializer.extend({
     // queue
     containerLogs: getContainerLogs,
 
-    vertexIdNameMap: getIdNameMap
-  }
+    vertexIdNameMap: getIdNameMap,
+
+    callerID: 'primaryfilters.callerId.0',
+    callerType: 'callerType',
+    callerInfo: 'callerInfo',
+  },
+
+  extractAttributes: function (modelClass, resourceHash) {
+    var data = resourceHash.data,
+        dagInfo = Ember.get(resourceHash, "data.otherinfo.dagPlan.dagInfo");
+
+    if(dagInfo) {
+      let infoObj = {};
+      try{
+        infoObj = JSON.parse(dagInfo);
+      }catch(e){}
+
+      data.callerType = Ember.get(infoObj, "context");
+      data.callerInfo = Ember.get(infoObj, "description") || Ember.get(dagInfo, "blob") || dagInfo;
+    }
+
+    return this._super(modelClass, resourceHash);
+  },
+
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/94599693/tez-ui2/src/main/webapp/app/templates/components/caller-info.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/components/caller-info.hbs b/tez-ui2/src/main/webapp/app/templates/components/caller-info.hbs
new file mode 100644
index 0000000..72a52db
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/components/caller-info.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.
+}}
+
+<div class="panel panel-info">
+  <div class="panel-heading">
+    Additional Info from {{type}}
+  </div>
+  <textarea></textarea>
+</div>

http://git-wip-us.apache.org/repos/asf/tez/blob/94599693/tez-ui2/src/main/webapp/app/templates/components/dags-page-search.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/components/dags-page-search.hbs b/tez-ui2/src/main/webapp/app/templates/components/dags-page-search.hbs
index 0c118e4..94015dc 100644
--- a/tez-ui2/src/main/webapp/app/templates/components/dags-page-search.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/components/dags-page-search.hbs
@@ -63,12 +63,12 @@
         value={{tableDefinition.appID}}
         onchange={{action "appIDChanged" value="target.value"}}>
   </div><div class="search-element">
-    <label for="pwd">Context ID:</label>
+    <label for="pwd">Caller ID:</label>
     <input
         type="text"
         class="form-control input-sm"
         placeholder="Search..."
-        value={{tableDefinition.contextID}}
-        onchange={{action "contextIDChanged" value="target.value"}}>
+        value={{tableDefinition.callerID}}
+        onchange={{action "callerIDChanged" value="target.value"}}>
   </div>
 </div>

http://git-wip-us.apache.org/repos/asf/tez/blob/94599693/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/index.hbs b/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
index 59bb6a9..7ea00c5 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
@@ -74,6 +74,10 @@
     </tbody>
   </table>
 
+  {{#if model.callerInfo}}
+    {{caller-info type=model.callerType info=model.callerInfo}}
+  {{/if}}
+
   {{outlet}}
 
 {{else}}

http://git-wip-us.apache.org/repos/asf/tez/blob/94599693/tez-ui2/src/main/webapp/bower.json
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/bower.json b/tez-ui2/src/main/webapp/bower.json
index 8d23c02..f0fec1a 100644
--- a/tez-ui2/src/main/webapp/bower.json
+++ b/tez-ui2/src/main/webapp/bower.json
@@ -20,6 +20,7 @@
     "snippet-ss": "~1.11.0",
     "jquery-mousewheel": "~3.1.13",
     "FileSaver": "#230de7d",
-    "zip.js": "#1bead0a"
+    "zip.js": "#1bead0a",
+    "codemirror": "~5.11.0"
   }
 }

http://git-wip-us.apache.org/repos/asf/tez/blob/94599693/tez-ui2/src/main/webapp/ember-cli-build.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/ember-cli-build.js b/tez-ui2/src/main/webapp/ember-cli-build.js
index 24c24fb..6068ee4 100644
--- a/tez-ui2/src/main/webapp/ember-cli-build.js
+++ b/tez-ui2/src/main/webapp/ember-cli-build.js
@@ -52,5 +52,10 @@ module.exports = function(defaults) {
   app.import('bower_components/FileSaver/FileSaver.js');
   app.import('bower_components/zip.js/WebContent/zip.js');
 
+  app.import('bower_components/codemirror/lib/codemirror.js');
+  app.import('bower_components/codemirror/mode/sql/sql.js');
+  app.import('bower_components/codemirror/mode/pig/pig.js');
+  app.import('bower_components/codemirror/lib/codemirror.css');
+
   return app.toTree(new MergeTrees([configEnv, zipWorker]));
 };

http://git-wip-us.apache.org/repos/asf/tez/blob/94599693/tez-ui2/src/main/webapp/tests/integration/components/caller-info-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/integration/components/caller-info-test.js b/tez-ui2/src/main/webapp/tests/integration/components/caller-info-test.js
new file mode 100644
index 0000000..20f787c
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/integration/components/caller-info-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 { moduleForComponent, test } from 'ember-qunit';
+import hbs from 'htmlbars-inline-precompile';
+
+moduleForComponent('caller-info', 'Integration | Component | caller info', {
+  integration: true
+});
+
+test('Basic creation test', function(assert) {
+  var testType = "Typ",
+      heading = "Additional Info from " + testType;
+
+  this.set("type", testType);
+
+  this.render(hbs`{{caller-info type=type}}`);
+  assert.equal(this.$(".panel-heading").text().trim(), heading);
+
+  // Template block usage:" + EOL +
+  this.render(hbs`
+    {{#caller-info type=type}}
+      template block text
+    {{/caller-info}}
+  `);
+  assert.equal(this.$(".panel-heading").text().trim(), heading);
+});


[14/45] tez git commit: TEZ-3027. Tez UI 2: Add header and footer elements (sree)

Posted by sr...@apache.org.
TEZ-3027. Tez UI 2: Add header and footer elements (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/27000ab2
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/27000ab2
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/27000ab2

Branch: refs/heads/TEZ-2980
Commit: 27000ab2b88f0ad1190542fdb1e34e31dee3fbd1
Parents: 0213e55
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Sat Jan 9 13:18:01 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:32:15 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |   1 +
 .../main/webapp/app/controllers/application.js  |  38 +++++
 tez-ui2/src/main/webapp/app/index.html          |   2 +
 .../src/main/webapp/app/initializers/jquery.js  |  26 ++--
 .../src/main/webapp/app/routes/application.js   |  35 +++++
 tez-ui2/src/main/webapp/app/services/env.js     |   7 +
 tez-ui2/src/main/webapp/app/styles/app.less     |  15 +-
 tez-ui2/src/main/webapp/app/styles/colors.less  |  44 ++++++
 .../src/main/webapp/app/styles/page-layout.less | 150 +++++++++++++++++++
 tez-ui2/src/main/webapp/app/styles/shared.less  |  32 ++++
 tez-ui2/src/main/webapp/app/styles/tooltip.less |  24 +++
 .../main/webapp/app/templates/application.hbs   |  49 +++++-
 tez-ui2/src/main/webapp/bower.json              |   8 +-
 .../src/main/webapp/config/default-app-conf.js  |   6 +
 tez-ui2/src/main/webapp/config/environment.js   |   3 +-
 tez-ui2/src/main/webapp/ember-cli-build.js      |   4 +-
 tez-ui2/src/main/webapp/package.json            |   4 +
 .../webapp/public/assets/images/favicon.png     | Bin 0 -> 1416 bytes
 .../main/webapp/public/assets/images/logo.png   | Bin 0 -> 77160 bytes
 .../tests/unit/controllers/application-test.js  |  45 ++++++
 .../tests/unit/routes/application-test.js       |  59 ++++++++
 .../main/webapp/tests/unit/services/env-test.js |   7 +
 22 files changed, 528 insertions(+), 31 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/27000ab2/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index 28584a8..355e7d6 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -11,3 +11,4 @@ ALL CHANGES:
   TEZ-3023. Tez UI 2: Abstract adapter and route
   TEZ-3022. Tez UI 2: Add serializer & adapter for timeline server
   TEZ-3026. Tez UI 2: Add adapters for RM & AM
+  TEZ-3027. Tez UI 2: Add header and footer elements

http://git-wip-us.apache.org/repos/asf/tez/blob/27000ab2/tez-ui2/src/main/webapp/app/controllers/application.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/application.js b/tez-ui2/src/main/webapp/app/controllers/application.js
new file mode 100644
index 0000000..24db40a
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/application.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';
+
+const BREADCRUMB_PREFIX = [{
+  text: "All DAGs",
+  routeName: 'application'
+}];
+
+export default Ember.Controller.extend({
+  breadcrumbs: null,
+  prefixedBreadcrumbs: Ember.computed("breadcrumbs", function () {
+    var prefix = BREADCRUMB_PREFIX,
+    breadcrumbs = this.get('breadcrumbs');
+
+    if(Array.isArray(breadcrumbs)) {
+      prefix = prefix.concat(breadcrumbs);
+    }
+
+    return prefix;
+  })
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/27000ab2/tez-ui2/src/main/webapp/app/index.html
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/index.html b/tez-ui2/src/main/webapp/app/index.html
index 2108d0f..3f82152 100644
--- a/tez-ui2/src/main/webapp/app/index.html
+++ b/tez-ui2/src/main/webapp/app/index.html
@@ -27,6 +27,8 @@
 
     {{content-for 'head'}}
 
+    <link rel="shortcut icon" href="assets/images/favicon.png" type="image/x-icon">
+
     <link rel="stylesheet" href="assets/vendor.css">
     <link rel="stylesheet" href="assets/tez-ui.css">
 

http://git-wip-us.apache.org/repos/asf/tez/blob/27000ab2/tez-ui2/src/main/webapp/app/initializers/jquery.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/initializers/jquery.js b/tez-ui2/src/main/webapp/app/initializers/jquery.js
index b0c52eb..2c34b1d 100644
--- a/tez-ui2/src/main/webapp/app/initializers/jquery.js
+++ b/tez-ui2/src/main/webapp/app/initializers/jquery.js
@@ -1,5 +1,3 @@
-/*global $*/
-
 /**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -18,23 +16,21 @@
  * limitations under the License.
  */
 
-import environment from '../config/environment';
+import Ember from 'ember';
 
 export function initialize(/* application */) {
-  if(environment.environment !== 'test') {
-    $(document).tooltip({
-      delay: 20,
-      tooltipClass: 'generic-tooltip'
-    });
+  Ember.$(document).tooltip({
+    delay: 20,
+    tooltipClass: 'generic-tooltip'
+  });
 
-    $.ajaxPrefilter(function(options, originalOptions, jqXHR) {
-      jqXHR.requestOptions = originalOptions;
-    });
+  Ember.$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
+    jqXHR.requestOptions = originalOptions;
+  });
 
-    $.ajaxSetup({
-      cache: false
-    });
-  }
+  Ember.$.ajaxSetup({
+    cache: false
+  });
 }
 
 export default {

http://git-wip-us.apache.org/repos/asf/tez/blob/27000ab2/tez-ui2/src/main/webapp/app/routes/application.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/application.js b/tez-ui2/src/main/webapp/app/routes/application.js
new file mode 100644
index 0000000..1540107
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/application.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';
+
+export default Ember.Route.extend({
+
+  pageReset: function () {
+    Ember.$(document).tooltip("close");
+  },
+
+  actions: {
+    didTransition: function(/* transition */) {
+      this.pageReset();
+    },
+    pageChanged: function (breadcrumbs) {
+      this.set("controller.breadcrumbs", breadcrumbs);
+    }
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/27000ab2/tez-ui2/src/main/webapp/app/services/env.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/services/env.js b/tez-ui2/src/main/webapp/app/services/env.js
index bd7dde7..78193ee 100644
--- a/tez-ui2/src/main/webapp/app/services/env.js
+++ b/tez-ui2/src/main/webapp/app/services/env.js
@@ -42,9 +42,16 @@ export default Ember.Service.extend({
       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;
+  },
+
   app: Ember.computed("ENV.APP", function () {
     return this.get("ENV.APP");
   })

http://git-wip-us.apache.org/repos/asf/tez/blob/27000ab2/tez-ui2/src/main/webapp/app/styles/app.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/app.less b/tez-ui2/src/main/webapp/app/styles/app.less
index 8a21537..4c3b89d 100644
--- a/tez-ui2/src/main/webapp/app/styles/app.less
+++ b/tez-ui2/src/main/webapp/app/styles/app.less
@@ -16,9 +16,12 @@
  * limitations under the License.
  */
 
-.generic-tooltip {
-  padding: 3px 5px !important;
-  background: rgba(0,0,0,.8) !important;
-  color: white !important;
-  border: none !important;
-}
+// External imports
+@import "../../bower_components/snippet-ss/less/index";
+
+@import "colors";
+@import "shared";
+
+@import "tooltip";
+
+@import "page-layout";

http://git-wip-us.apache.org/repos/asf/tez/blob/27000ab2/tez-ui2/src/main/webapp/app/styles/colors.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/colors.less b/tez-ui2/src/main/webapp/app/styles/colors.less
new file mode 100644
index 0000000..af470ff
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/styles/colors.less
@@ -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.
+ */
+
+// Colors
+@logo-orange: #D27A22;
+
+@bg-lite: #f5f5f5;
+@bg-liter: #f5f5f5;
+@bg-red-light: #FFE6E6;
+
+@bg-grey: #f0f0f0;
+
+@border-lite: #e5e5e5;
+@border-color: #dcdcdc;
+
+@white: #fff;
+
+@text-color: rgb(70, 70, 70);
+@text-red: red;
+@text-light: #BBBBBB;
+@text-green: green;
+
+@top-nav-bg-color-from: #d5d5d5;
+@top-nav-bg-color-to: #f0f0f0;
+
+@success-color: limegreen;
+@error-color: crimson;
+@warning-color: orange;
+@unknown-color: crimson;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/27000ab2/tez-ui2/src/main/webapp/app/styles/page-layout.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/page-layout.less b/tez-ui2/src/main/webapp/app/styles/page-layout.less
new file mode 100644
index 0000000..ef00b40
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/styles/page-layout.less
@@ -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.
+ */
+
+@import "colors";
+@import "../../bower_components/snippet-ss/less/no";
+
+body, html, body > .ember-view {
+  height: 100%;
+  overflow: visible;
+  color: @text-color;
+
+  .san-helvetica;
+}
+body, html {
+  min-width: 1024px;
+}
+
+// Styles used in both standalone and wrapped modes
+.standalone, .wrapped {
+
+  .lr-margin {
+    margin: 0px 30px;
+  }
+
+  .header, .footer {
+    .content {
+      position: relative;
+
+      .breadcrumb-container {
+        position: absolute;
+        left: 70px;
+        right: 20px;
+        top: 9px;
+
+        .breadcrumb {
+          .no-border;
+
+          background-color: transparent;
+          margin-bottom: 0px;
+        }
+      }
+
+      .ui-info {
+        position: absolute;
+        right: 0px;
+        top: 0px;
+
+        span {
+          .left-delim;
+        }
+        span:first-child {
+          .no-border;
+        }
+      }
+    }
+  }
+
+  .header {
+    background-color: @bg-lite;
+
+    height: 40px;
+    border-bottom: 1px @border-color solid;
+    margin-bottom: 10px;
+
+    a.logo {
+      img {
+        margin-top: 2px;
+        height: 34px;
+        width: 70px;
+      }
+      &:hover {
+        text-decoration: none;
+      }
+    }
+
+    .ui-info {
+      background-color: @bg-lite;
+      margin-top: 10px;
+
+      .fa::before {
+        font-size: 20px;
+      }
+    }
+  }
+
+  .footer {
+    background-color: @white;
+    color: @text-color;
+
+    padding: 10px 0px;
+    margin: 0px;
+
+    border-top: 1px @border-color solid;
+
+    font-size: .8em;
+
+    .ui-info {
+      background-color: @white;
+    }
+  }
+}
+
+// TEZ UI in stand alone mode
+.standalone {
+  height: 100%;
+
+  a, .pagination > li > a, .btn-default, .clickable {
+    color: @logo-orange;
+  }
+
+  .footer, .footer-frame {
+    height: 40px;
+  }
+
+  .footer-pusher {
+    min-height: 100%;
+    height: auto !important;
+    height: 100%;
+    margin: 0 auto -40px; // Must be same as footer & footer-frame
+  }
+}
+
+// TEZ UI wrapped in a host like Ambari
+.wrapped {
+  .header {
+    border: 1px @border-lite solid;
+    border-radius: 5px;
+  }
+  .footer {
+    display: none;
+  }
+}
+
+
+

http://git-wip-us.apache.org/repos/asf/tez/blob/27000ab2/tez-ui2/src/main/webapp/app/styles/shared.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/shared.less b/tez-ui2/src/main/webapp/app/styles/shared.less
new file mode 100644
index 0000000..7fd4db9
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/styles/shared.less
@@ -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 "colors";
+
+b {
+  font-weight: bold;
+}
+.horizontal-half {
+  width: 50%;
+}
+
+.left-delim {
+  border-left: 1px solid @border-color;
+  margin-left: 5px;
+  padding-left: 5px;
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/27000ab2/tez-ui2/src/main/webapp/app/styles/tooltip.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/tooltip.less b/tez-ui2/src/main/webapp/app/styles/tooltip.less
new file mode 100644
index 0000000..8a21537
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/styles/tooltip.less
@@ -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.
+ */
+
+.generic-tooltip {
+  padding: 3px 5px !important;
+  background: rgba(0,0,0,.8) !important;
+  color: white !important;
+  border: none !important;
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/27000ab2/tez-ui2/src/main/webapp/app/templates/application.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/application.hbs b/tez-ui2/src/main/webapp/app/templates/application.hbs
index d1154b1..5d1df11 100644
--- a/tez-ui2/src/main/webapp/app/templates/application.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/application.hbs
@@ -16,10 +16,49 @@
  * limitations under the License.
 }}
 
-<h2 id="title">Welcome to Ember</h2>
+<div class="{{if env.app.isStandalone 'standalone' 'wrapped'}} {{if env.ENV.isIE 'ie'}}">
+  <div class="footer-pusher">
 
-{{outlet}}
+    <div class="header">
+      <div class="lr-margin content">
+        {{#link-to 'application' class="logo"}}
+          <img src="assets/images/logo.png" width="70px"/>
+          <span>{{unbound App.env.version}}</span>
+        {{/link-to}}
 
-Timeline: {{hosts.timeline}}
-<br/>
-RM: {{hosts.rm}}
+        <div class="breadcrumb-container">
+          {{em-breadcrumbs items=prefixedBreadcrumbs}}
+        </div>
+
+        <div class="ui-info">
+          {{#if env.app.buildVersion}}
+            <span>Version <b>{{env.app.buildVersion}}</b></span>
+          {{/if}}
+          <span>
+            <a href={{env.app.hrefs.help}} target="_blank">
+              <i class="fa fa-question-circle"></i>
+            </a>
+          </span>
+        </div>
+      </div>
+    </div>
+
+    <div class="lr-margin">
+      {{outlet}}
+    </div>
+    <div class="footer-frame"> </div>
+  </div>
+
+  <div class="footer">
+    <div class="lr-margin content">
+      <a href={{env.app.hrefs.license}} target="_blank">
+        Licensed under the Apache License, Version 2.0.
+      </a>
+      <div class="ui-info">
+        {{#if env.app.timezone}}
+          <span>Timezone <b>{{env.app.timezone}}</b></span>
+        {{/if}}
+      </div>
+    </div>
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/tez/blob/27000ab2/tez-ui2/src/main/webapp/bower.json
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/bower.json b/tez-ui2/src/main/webapp/bower.json
index 98402b3..550ce85 100644
--- a/tez-ui2/src/main/webapp/bower.json
+++ b/tez-ui2/src/main/webapp/bower.json
@@ -8,10 +8,12 @@
     "ember-load-initializers": "0.1.7",
     "ember-qunit": "0.4.16",
     "ember-qunit-notifications": "0.1.0",
-    "jquery": "^1.11.3",
     "loader.js": "3.3.0",
     "qunit": "~1.19.0",
-    "jquery-ui": "~1.11.4",
-    "more-js": "*"
+    "more-js": "*",
+    "bootstrap": "~3.3.5",
+    "snippet-ss": "*",
+    "font-awesome": "~4.5.0",
+    "jquery-ui": "1.11.4"
   }
 }

http://git-wip-us.apache.org/repos/asf/tez/blob/27000ab2/tez-ui2/src/main/webapp/config/default-app-conf.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/config/default-app-conf.js b/tez-ui2/src/main/webapp/config/default-app-conf.js
index 31a946f..e3d9076 100644
--- a/tez-ui2/src/main/webapp/config/default-app-conf.js
+++ b/tez-ui2/src/main/webapp/config/default-app-conf.js
@@ -17,6 +17,8 @@
  */
 
 module.exports = { // Tez App configurations
+  buildVersion: "",
+  isStandalone: true, // Must be set false while running in wrapped mode
   hosts: {
     timeline: 'localhost:8188',
     rm: 'localhost:8088',
@@ -43,5 +45,9 @@ module.exports = { // Tez App configurations
 
       tezApp: 'TEZ_APPLICATION'
     }
+  },
+  hrefs: {
+    help: "https://tez.apache.org/tez_ui_user_data.html",
+    license: "http://www.apache.org/licenses/LICENSE-2.0"
   }
 };

http://git-wip-us.apache.org/repos/asf/tez/blob/27000ab2/tez-ui2/src/main/webapp/config/environment.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/config/environment.js b/tez-ui2/src/main/webapp/config/environment.js
index 4201f9a..b102c8f 100644
--- a/tez-ui2/src/main/webapp/config/environment.js
+++ b/tez-ui2/src/main/webapp/config/environment.js
@@ -36,7 +36,8 @@ module.exports = function(environment) {
     APP: DEFAULT_APP_CONF,
 
     contentSecurityPolicy: {
-      'connect-src': "* 'self'"
+      'connect-src': "* 'self'",
+      'style-src': "'self' 'unsafe-inline'"
     }
   };
 

http://git-wip-us.apache.org/repos/asf/tez/blob/27000ab2/tez-ui2/src/main/webapp/ember-cli-build.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/ember-cli-build.js b/tez-ui2/src/main/webapp/ember-cli-build.js
index c68e22b..ac5eea9 100644
--- a/tez-ui2/src/main/webapp/ember-cli-build.js
+++ b/tez-ui2/src/main/webapp/ember-cli-build.js
@@ -23,7 +23,9 @@ var Funnel = require("broccoli-funnel");
 var EmberApp = require('ember-cli/lib/broccoli/ember-app');
 
 module.exports = function(defaults) {
-  var app = new EmberApp(defaults, {});
+  var app = new EmberApp(defaults, {
+    storeConfigInMeta: false
+  });
 
   var extraAssets = new Funnel('config', {
      srcDir: '/',

http://git-wip-us.apache.org/repos/asf/tez/blob/27000ab2/tez-ui2/src/main/webapp/package.json
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/package.json b/tez-ui2/src/main/webapp/package.json
index c5ab3d0..33a27a6 100644
--- a/tez-ui2/src/main/webapp/package.json
+++ b/tez-ui2/src/main/webapp/package.json
@@ -23,14 +23,17 @@
   "devDependencies": {
     "bower": "^1.7.1",
     "broccoli-asset-rev": "^2.2.0",
+    "ember-bootstrap": "0.5.1",
     "ember-cli": "1.13.13",
     "ember-cli-app-version": "^1.0.0",
     "ember-cli-auto-register": "^1.1.0",
     "ember-cli-babel": "^5.1.5",
     "ember-cli-content-security-policy": "0.4.0",
     "ember-cli-dependency-checker": "^1.1.0",
+    "ember-cli-font-awesome": "1.4.0",
     "ember-cli-htmlbars-inline-precompile": "^0.3.1",
     "ember-cli-inject-live-reload": "^1.3.1",
+    "ember-cli-jquery-ui": "0.0.20",
     "ember-cli-qunit": "^1.0.4",
     "ember-cli-release": "0.2.8",
     "ember-cli-sri": "^1.2.0",
@@ -43,6 +46,7 @@
   },
   "dependencies": {
     "broccoli-funnel": "^1.0.1",
+    "em-helpers": "^0.5.2",
     "ember-cli-htmlbars": "^1.0.1",
     "ember-cli-less": "^1.4.0"
   }

http://git-wip-us.apache.org/repos/asf/tez/blob/27000ab2/tez-ui2/src/main/webapp/public/assets/images/favicon.png
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/public/assets/images/favicon.png b/tez-ui2/src/main/webapp/public/assets/images/favicon.png
new file mode 100644
index 0000000..4762bdf
Binary files /dev/null and b/tez-ui2/src/main/webapp/public/assets/images/favicon.png differ

http://git-wip-us.apache.org/repos/asf/tez/blob/27000ab2/tez-ui2/src/main/webapp/public/assets/images/logo.png
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/public/assets/images/logo.png b/tez-ui2/src/main/webapp/public/assets/images/logo.png
new file mode 100644
index 0000000..f29455a
Binary files /dev/null and b/tez-ui2/src/main/webapp/public/assets/images/logo.png differ

http://git-wip-us.apache.org/repos/asf/tez/blob/27000ab2/tez-ui2/src/main/webapp/tests/unit/controllers/application-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/application-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/application-test.js
new file mode 100644
index 0000000..6fe69df
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/application-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:application', 'Unit | Controller | application', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject();
+
+  assert.ok(controller.prefixedBreadcrumbs);
+});
+
+test('prefixedBreadcrumbs test', function(assert) {
+  let controller = this.subject(),
+      prefixedBreadcrumbs,
+      testText = "foo";
+
+  controller.breadcrumbs = [{
+    text: testText
+  }];
+  prefixedBreadcrumbs = controller.get("prefixedBreadcrumbs");
+
+  assert.equal(prefixedBreadcrumbs.length, 2);
+  assert.equal(prefixedBreadcrumbs[0].text, "All DAGs");
+  assert.equal(prefixedBreadcrumbs[1].text, testText);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/27000ab2/tez-ui2/src/main/webapp/tests/unit/routes/application-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/application-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/application-test.js
new file mode 100644
index 0000000..fbf515b
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/application-test.js
@@ -0,0 +1,59 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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:application', 'Unit | Route | application', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.pageReset);
+  assert.ok(route.actions.didTransition);
+  assert.ok(route.actions.pageChanged);
+});
+
+test('Test didTransition action', function(assert) {
+  let route = this.subject();
+
+  assert.expect(1);
+
+  route.pageReset = function () {
+    assert.ok(true);
+  };
+
+  route.send("didTransition");
+});
+
+test('Test pageChanged action', function(assert) {
+  let route = this.subject(),
+      testController = {
+        breadcrumbs: null
+      },
+      testBreadcrumbs = [{}];
+
+  route.controller = testController;
+
+  assert.notOk(route.get("controller.breadcrumbs"));
+  route.send("pageChanged", testBreadcrumbs);
+  assert.equal(route.get("controller.breadcrumbs"), testBreadcrumbs);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/27000ab2/tez-ui2/src/main/webapp/tests/unit/services/env-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/services/env-test.js b/tez-ui2/src/main/webapp/tests/unit/services/env-test.js
index 5064fc3..ca17f85 100644
--- a/tez-ui2/src/main/webapp/tests/unit/services/env-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/services/env-test.js
@@ -32,6 +32,7 @@ test('Basic creation test', function(assert) {
   assert.ok(service.ENV);
   assert.ok(service.collateConfigs);
   assert.ok(service.app);
+  assert.ok(service.setComputedENVs);
 });
 
 test('collateConfigs test', function(assert) {
@@ -64,6 +65,12 @@ test('app computed property test', function(assert) {
   assert.equal(service.get("app.b"), ENV.b);
 });
 
+test('setComputedENVs test', function(assert) {
+  let service = this.subject();
+
+  assert.equal(service.ENV.isIE, false);
+});
+
 test('Validate config/default-app-conf.js', function(assert) {
   let service = this.subject();
 


[13/45] tez git commit: TEZ-3038. Tez UI 2: Create DAG details page (sree)

Posted by sr...@apache.org.
TEZ-3038. Tez UI 2: Create DAG details page (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/a0ba39cb
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/a0ba39cb
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/a0ba39cb

Branch: refs/heads/TEZ-2980
Commit: a0ba39cbc150870ede7ebb80719889c4624d08c8
Parents: d34cbe0
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Mon Jan 18 15:28:53 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:32:15 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |  1 +
 .../main/webapp/app/components/tab-n-refresh.js | 44 +++++++++++
 .../src/main/webapp/app/controllers/abstract.js | 42 ++++++++++
 tez-ui2/src/main/webapp/app/controllers/dag.js  | 47 +++++++++++
 .../main/webapp/app/controllers/dag/attempts.js | 26 ++++++
 .../main/webapp/app/controllers/dag/index.js    | 22 ++++++
 .../main/webapp/app/controllers/dag/tasks.js    | 26 ++++++
 .../main/webapp/app/controllers/dag/vertices.js | 26 ++++++
 tez-ui2/src/main/webapp/app/controllers/dags.js | 25 +++---
 tez-ui2/src/main/webapp/app/controllers/page.js | 30 +++++++
 .../main/webapp/app/controllers/table-page.js   |  8 +-
 tez-ui2/src/main/webapp/app/mixins/name.js      | 30 +++++++
 tez-ui2/src/main/webapp/app/router.js           |  6 ++
 tez-ui2/src/main/webapp/app/routes/abstract.js  | 49 ++++++++++--
 tez-ui2/src/main/webapp/app/routes/app.js       | 22 ++++++
 .../src/main/webapp/app/routes/application.js   |  9 ++-
 tez-ui2/src/main/webapp/app/routes/dag.js       | 31 ++++++++
 .../src/main/webapp/app/routes/dag/attempts.js  | 29 +++++++
 tez-ui2/src/main/webapp/app/routes/dag/index.js | 34 ++++++++
 tez-ui2/src/main/webapp/app/routes/dag/tasks.js | 29 +++++++
 .../src/main/webapp/app/routes/dag/vertices.js  | 29 +++++++
 tez-ui2/src/main/webapp/app/routes/dags.js      | 17 ++++
 tez-ui2/src/main/webapp/app/styles/app.less     |  3 +
 .../main/webapp/app/styles/details-page.less    | 49 ++++++++++++
 .../src/main/webapp/app/styles/page-layout.less |  3 +
 tez-ui2/src/main/webapp/app/styles/shared.less  |  8 ++
 .../main/webapp/app/styles/tab-n-refresh.less   | 42 ++++++++++
 tez-ui2/src/main/webapp/app/templates/app.hbs   | 19 +++++
 .../app/templates/components/tab-n-refresh.hbs  | 42 ++++++++++
 tez-ui2/src/main/webapp/app/templates/dag.hbs   | 20 +++++
 .../main/webapp/app/templates/dag/attempts.hbs  | 19 +++++
 .../src/main/webapp/app/templates/dag/index.hbs | 83 ++++++++++++++++++++
 .../src/main/webapp/app/templates/dag/tasks.hbs | 19 +++++
 .../main/webapp/app/templates/dag/vertices.hbs  | 19 +++++
 .../components/tab-n-refresh-test.js            | 50 ++++++++++++
 .../tests/unit/controllers/abstract-test.js     | 74 +++++++++++++++++
 .../webapp/tests/unit/controllers/dag-test.js   | 36 +++++++++
 .../tests/unit/controllers/dag/attempts-test.js | 35 +++++++++
 .../tests/unit/controllers/dag/index-test.js    | 34 ++++++++
 .../tests/unit/controllers/dag/tasks-test.js    | 35 +++++++++
 .../tests/unit/controllers/dag/vertices-test.js | 35 +++++++++
 .../webapp/tests/unit/controllers/dags-test.js  |  5 +-
 .../webapp/tests/unit/controllers/page-test.js  | 49 ++++++++++++
 .../tests/unit/controllers/table-page-test.js   |  6 +-
 .../main/webapp/tests/unit/mixins/name-test.js  | 44 +++++++++++
 .../webapp/tests/unit/routes/abstract-test.js   | 62 ++++++++++++++-
 .../main/webapp/tests/unit/routes/app-test.js   | 29 +++++++
 .../tests/unit/routes/application-test.js       |  6 +-
 .../main/webapp/tests/unit/routes/dag-test.js   | 32 ++++++++
 .../tests/unit/routes/dag/attempts-test.js      | 44 +++++++++++
 .../webapp/tests/unit/routes/dag/index-test.js  | 46 +++++++++++
 .../webapp/tests/unit/routes/dag/tasks-test.js  | 44 +++++++++++
 .../tests/unit/routes/dag/vertices-test.js      | 44 +++++++++++
 .../main/webapp/tests/unit/routes/dags-test.js  |  2 +
 54 files changed, 1584 insertions(+), 36 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index 9fcb0ef..925dc7f 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -13,3 +13,4 @@ ALL CHANGES:
   TEZ-3026. Tez UI 2: Add adapters for RM & AM
   TEZ-3027. Tez UI 2: Add header and footer elements
   TEZ-2986. Tez UI 2: Implement All DAGs page
+  TEZ-3038. Tez UI 2: Create DAG details page

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/components/tab-n-refresh.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/components/tab-n-refresh.js b/tez-ui2/src/main/webapp/app/components/tab-n-refresh.js
new file mode 100644
index 0000000..3f05371
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/components/tab-n-refresh.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.Component.extend({
+  init: function () {
+    this._super();
+    this.setApplication();
+  },
+
+  setApplication: function () {
+    var application = this.get("targetObject.container").lookup('controller:application');
+    this.set("application", application);
+  },
+
+  normalizedTabs: Ember.computed("tabs", "application.currentPath", function () {
+    var tabs = this.get("tabs"),
+        activeRouteName = this.get("application.currentPath");
+
+    return tabs.map(function (tab) {
+      return {
+        text: tab.text,
+        routeName: tab.routeName,
+        active: tab.routeName === activeRouteName
+      };
+    });
+  })
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/controllers/abstract.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/abstract.js b/tez-ui2/src/main/webapp/app/controllers/abstract.js
new file mode 100644
index 0000000..c077914
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/abstract.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 NameMixin from '../mixins/name';
+
+export default Ember.Controller.extend(NameMixin, {
+  // Must be set by inheriting classes
+  breadcrumbs: null,
+
+  init: function () {
+    this._super();
+    Ember.run.later(this, "setBreadcrumbs");
+  },
+
+  crumbObserver: Ember.observer("breadcrumbs", function () {
+    Ember.run.later(this, "setBreadcrumbs");
+  }),
+
+  setBreadcrumbs: function () {
+    var crumbs = {},
+        name = this.get("name");
+    crumbs[name] = this.get("breadcrumbs");
+    this.send("setBreadcrumbs", crumbs);
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/controllers/dag.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag.js b/tez-ui2/src/main/webapp/app/controllers/dag.js
new file mode 100644
index 0000000..f54d8cf
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/dag.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 Ember from 'ember';
+
+import AbstractController from './abstract';
+
+export default AbstractController.extend({
+  breadcrumbs: Ember.computed("model", function () {
+    var name = this.get("model.name");
+
+    return [{
+      text: `DAG [${name}]`,
+      routeName: "dag.index",
+      model: this.get("model.entityID")
+    }];
+  }),
+
+  tabs: [{
+    text: "DAG Details",
+    routeName: "dag.index"
+  }, {
+    text: "All Vertices",
+    routeName: "dag.vertices"
+  }, {
+    text: "All Tasks",
+    routeName: "dag.tasks"
+  }, {
+    text: "All Attempts",
+    routeName: "dag.attempts"
+  }]
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js b/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
new file mode 100644
index 0000000..d5efc50
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/attempts.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 PageController from '../page';
+
+export default PageController.extend({
+  breadcrumbs: [{
+    text: "All Attempts",
+    routeName: "dag.attempts",
+  }]
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/controllers/dag/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/index.js b/tez-ui2/src/main/webapp/app/controllers/dag/index.js
new file mode 100644
index 0000000..9745328
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/index.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 PageController from '../page';
+
+export default PageController.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js b/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
new file mode 100644
index 0000000..e83df5d
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/tasks.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 PageController from '../page';
+
+export default PageController.extend({
+  breadcrumbs: [{
+    text: "All Tasks",
+    routeName: "dag.tasks",
+  }]
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js b/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
new file mode 100644
index 0000000..e001652
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/vertices.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 PageController from '../page';
+
+export default PageController.extend({
+  breadcrumbs: [{
+    text: "All Vertices",
+    routeName: "dag.vertices",
+  }]
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/controllers/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dags.js b/tez-ui2/src/main/webapp/app/controllers/dags.js
index 900b03d..354f4f8 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dags.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dags.js
@@ -16,17 +16,25 @@
  * limitations under the License.
  */
 
-import Ember from 'ember';
-
 import TablePageController from './table-page';
 import ColumnDefinition from 'em-table/utils/column-definition';
 
 export default TablePageController.extend({
 
+  breadcrumbs: [],
+
   columns: ColumnDefinition.make([{
     id: 'dagName',
     headerTitle: 'Dag Name',
-    contentPath: 'name'
+    contentPath: 'name',
+    cellComponentName: 'em-table-linked-cell',
+    getCellContent: function (row) {
+      return {
+        routeName: "dag",
+        model: row.get("entityID"),
+        text: row.get("name")
+      };
+    }
   },{
     id: 'entityID',
     headerTitle: 'Id',
@@ -89,15 +97,4 @@ export default TablePageController.extend({
     }
   }]),
 
-  _loadObserver: Ember.on("init", Ember.observer("rowCount", function () {
-    var that = this,
-        query = {
-          limit: this.get("rowCount")
-        };
-
-    Ember.run.later(function () {
-      that.send("loadData", query);
-    });
-  }))
-
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/controllers/page.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/page.js b/tez-ui2/src/main/webapp/app/controllers/page.js
new file mode 100644
index 0000000..84882a8
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/page.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 AbstractController from './abstract';
+
+export default AbstractController.extend({
+  // Must be set from route
+  isLoading: false,
+
+  loaded: Ember.computed("model", "isLoading", function () {
+    return this.get("model") && !this.get("isLoading");
+  }),
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/controllers/table-page.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/table-page.js b/tez-ui2/src/main/webapp/app/controllers/table-page.js
index c807393..14219d9 100644
--- a/tez-ui2/src/main/webapp/app/controllers/table-page.js
+++ b/tez-ui2/src/main/webapp/app/controllers/table-page.js
@@ -16,9 +16,9 @@
  * limitations under the License.
  */
 
-import Ember from 'ember';
+import PageController from './page';
 
-export default Ember.Controller.extend({
+export default PageController.extend({
   queryParams: ["rowCount", "searchText", "sortColumnId", "sortOrder", "pageNo"],
   rowCount: 10,
   searchText: "",
@@ -26,10 +26,6 @@ export default Ember.Controller.extend({
   sortOrder: "",
   pageNo: 1,
 
-  loaded: Ember.computed("model", "isLoading", function () {
-    return this.get("model") && !this.get("isLoading");
-  }),
-
   actions: {
     searchChanged: function (searchText) {
       this.set("searchText", searchText);

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/mixins/name.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/mixins/name.js b/tez-ui2/src/main/webapp/app/mixins/name.js
new file mode 100644
index 0000000..fe0c524
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/mixins/name.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';
+
+export default Ember.Mixin.create({
+
+  name: Ember.computed(function () {
+    var name = this.toString();
+    name = name.substr(0, name.indexOf("::"));
+    name = name.substr(name.indexOf(":") + 1);
+    return name;
+  }),
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/router.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/router.js b/tez-ui2/src/main/webapp/app/router.js
index 3aca665..d94a837 100644
--- a/tez-ui2/src/main/webapp/app/router.js
+++ b/tez-ui2/src/main/webapp/app/router.js
@@ -25,6 +25,12 @@ const Router = Ember.Router.extend({
 
 Router.map(function() {
   this.route('dags', { path: '/' });
+  this.route('dag', {path: '/dag/:dag_id'}, function() {
+    this.route('vertices');
+    this.route('tasks');
+    this.route('attempts');
+  });
+  this.route('app', {path: '/app/:app_id'});
 });
 
 export default Router;

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/routes/abstract.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/abstract.js b/tez-ui2/src/main/webapp/app/routes/abstract.js
index 8696b67..1624bea 100644
--- a/tez-ui2/src/main/webapp/app/routes/abstract.js
+++ b/tez-ui2/src/main/webapp/app/routes/abstract.js
@@ -1,3 +1,4 @@
+/*global more*/
 /**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -19,14 +20,40 @@
 import Ember from 'ember';
 import LoaderService from '../services/loader';
 import UnlinkedPromise from '../errors/unlinked-promise';
+import NameMixin from '../mixins/name';
 
-export default Ember.Route.extend({
+var MoreObject = more.Object;
+
+export default Ember.Route.extend(NameMixin, {
   title: null, // Must be set by inheriting class
 
   isLoading: false,
   currentPromiseId: null,
   loadedValue: null,
 
+  isLeafRoute: false,
+  breadcrumbs: null,
+  childCrumbs: null,
+
+  loaderQueryParams: {},
+
+  model: function(params/*, transition*/) {
+    Ember.run.later(this, "loadData", this.queryFromParams(params));
+  },
+
+  queryFromParams: function (params) {
+    var query = {};
+
+    MoreObject.forEach(this.get("loaderQueryParams"), function (name, paramKey) {
+      var value = Ember.get(params, paramKey);
+      if(value) {
+        query[name] = value;
+      }
+    });
+
+    return query;
+  },
+
   setDocTitle: function () {
     Ember.$(document).attr('title', this.get('title'));
   },
@@ -78,7 +105,7 @@ export default Ember.Route.extend({
     return value;
   },
 
-  _setControllerModel: Ember.observer("_controller", "loadedValue", function () {
+  _setControllerModel: Ember.observer("loadedValue", function () {
     var controller = this.get("controller");
     if(controller) {
       controller.set("model", this.get("loadedValue"));
@@ -93,11 +120,21 @@ export default Ember.Route.extend({
     }));
   },
 
+  startCrumbBubble: function () {
+    this.send("bubbleBreadcrumbs", []);
+  },
+
   actions: {
-    loadData: function (query) {
-      // To be on the safer side
-      Ember.run.once(this, "loadData", query);
+    setBreadcrumbs: function (crumbs) {
+      var name = this.get("name");
+      if(crumbs && crumbs[name]) {
+        this.set("breadcrumbs", crumbs[name]);
+      }
+      return true;
+    },
+    bubbleBreadcrumbs: function (crumbs) {
+      crumbs.unshift.apply(crumbs, this.get("breadcrumbs"));
+      return true;
     }
   }
-
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/routes/app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/app.js b/tez-ui2/src/main/webapp/app/routes/app.js
new file mode 100644
index 0000000..8719170
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/app.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({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/routes/application.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/application.js b/tez-ui2/src/main/webapp/app/routes/application.js
index 1540107..8da6a31 100644
--- a/tez-ui2/src/main/webapp/app/routes/application.js
+++ b/tez-ui2/src/main/webapp/app/routes/application.js
@@ -19,16 +19,21 @@
 import Ember from 'ember';
 
 export default Ember.Route.extend({
+  title: "Application",
 
   pageReset: function () {
-    Ember.$(document).tooltip("close");
+    Ember.$(document).tooltip("destroy");
+    Ember.$(document).tooltip({
+      delay: 20,
+      tooltipClass: 'generic-tooltip'
+    });
   },
 
   actions: {
     didTransition: function(/* transition */) {
       this.pageReset();
     },
-    pageChanged: function (breadcrumbs) {
+    bubbleBreadcrumbs: function (breadcrumbs) {
       this.set("controller.breadcrumbs", breadcrumbs);
     }
   }

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/routes/dag.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag.js b/tez-ui2/src/main/webapp/app/routes/dag.js
new file mode 100644
index 0000000..71ff019
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/dag.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 AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+  title: "DAG",
+
+  loaderQueryParams: {
+    id: "dag_id"
+  },
+
+  model: function (params) {
+    return this.get("loader").queryRecord('dag', this.queryFromParams(params).id);
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/routes/dag/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag/attempts.js b/tez-ui2/src/main/webapp/app/routes/dag/attempts.js
new file mode 100644
index 0000000..5de1cab
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/dag/attempts.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';
+import AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  title: "DAG Details",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/routes/dag/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag/index.js b/tez-ui2/src/main/webapp/app/routes/dag/index.js
new file mode 100644
index 0000000..90929d0
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/dag/index.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({
+  title: "DAG Details",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (/*value, query*/) {
+    return this.get("loader").queryRecord('dag', this.modelFor("dag").id);
+  },
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/routes/dag/tasks.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag/tasks.js b/tez-ui2/src/main/webapp/app/routes/dag/tasks.js
new file mode 100644
index 0000000..5de1cab
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/dag/tasks.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';
+import AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  title: "DAG Details",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/routes/dag/vertices.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag/vertices.js b/tez-ui2/src/main/webapp/app/routes/dag/vertices.js
new file mode 100644
index 0000000..5de1cab
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/dag/vertices.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';
+import AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  title: "DAG Details",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/routes/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dags.js b/tez-ui2/src/main/webapp/app/routes/dags.js
index b4b9070..ecd1b00 100644
--- a/tez-ui2/src/main/webapp/app/routes/dags.js
+++ b/tez-ui2/src/main/webapp/app/routes/dags.js
@@ -16,11 +16,28 @@
  * limitations under the License.
  */
 
+import Ember from 'ember';
+
 import AbstractRoute from './abstract';
 
 export default AbstractRoute.extend({
   title: "All DAGs",
 
+  queryParams: {
+    rowCount: {
+      refreshModel: true
+    }
+  },
+
+  loaderQueryParams: {
+    rowCount: "rowCount"
+  },
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
   load: function (value, query) {
     return this.get("loader").query('dag', query);
   }

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/styles/app.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/app.less b/tez-ui2/src/main/webapp/app/styles/app.less
index 082c785..bdf9480 100644
--- a/tez-ui2/src/main/webapp/app/styles/app.less
+++ b/tez-ui2/src/main/webapp/app/styles/app.less
@@ -21,4 +21,7 @@
 
 @import "tooltip";
 
+@import "tab-n-refresh";
+
 @import "page-layout";
+@import "details-page";

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/styles/details-page.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/details-page.less b/tez-ui2/src/main/webapp/app/styles/details-page.less
new file mode 100644
index 0000000..8c85d1f
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/styles/details-page.less
@@ -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.
+ */
+
+.detail-list {
+  table-layout: fixed;
+  white-space: nowrap;
+
+  .progress {
+    margin-bottom: 0px;
+  }
+
+  tr {
+    margin: 0px 0px 0px 15px;
+    overflow: hidden;
+  }
+
+  thead {
+    background-color: @bg-lite;
+    font-weight: bold;
+  }
+
+  td {
+    padding: 0px 20px 0px 0px;
+  }
+
+  td:first-child {
+    width:120px;
+  }
+
+  th, td {
+    border: 1px solid @border-lite;
+    padding: 5px;
+  }
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/styles/page-layout.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/page-layout.less b/tez-ui2/src/main/webapp/app/styles/page-layout.less
index aacb731..c3530ff 100644
--- a/tez-ui2/src/main/webapp/app/styles/page-layout.less
+++ b/tez-ui2/src/main/webapp/app/styles/page-layout.less
@@ -50,6 +50,9 @@ body, html {
 
           background-color: transparent;
           margin-bottom: 0px;
+
+          .active {
+          }
         }
       }
 

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/styles/shared.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/shared.less b/tez-ui2/src/main/webapp/app/styles/shared.less
index 7fd4db9..db79db4 100644
--- a/tez-ui2/src/main/webapp/app/styles/shared.less
+++ b/tez-ui2/src/main/webapp/app/styles/shared.less
@@ -30,3 +30,11 @@ b {
   margin-left: 5px;
   padding-left: 5px;
 }
+
+.align-checknradio {
+  input[type=checkbox], input[type=radio] {
+    vertical-align: middle;
+    position: relative;
+    bottom: .2em;
+  }
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/styles/tab-n-refresh.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/tab-n-refresh.less b/tez-ui2/src/main/webapp/app/styles/tab-n-refresh.less
new file mode 100644
index 0000000..698f8f3
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/styles/tab-n-refresh.less
@@ -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 "./shared";
+
+.tab-n-refresh {
+  margin-bottom: 10px;
+  position: relative;
+
+  .refresh-ui {
+    position: absolute;
+    right: 0px;
+    top: -10px;
+
+    .text-elements {
+      display: inline-block;
+      position: relative;
+
+      line-height: 18px;
+      top: 12px;
+      text-align: right;
+      font-size: .95em;
+
+      .align-checknradio;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/templates/app.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/app.hbs b/tez-ui2/src/main/webapp/app/templates/app.hbs
new file mode 100644
index 0000000..c1a05b4
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/app.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.
+}}
+
+{{outlet}}

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs b/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs
new file mode 100644
index 0000000..4075c54
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs
@@ -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.
+}}
+
+<ul class="nav nav-tabs tab-n-refresh">
+  {{#each normalizedTabs as |tab|}}
+    <li class="{{if tab.active 'active'}}">
+      {{#link-to tab.routeName}}
+        {{tab.text}}
+      {{/link-to}}
+    </li>
+  {{/each}}
+  <span class="refresh-ui">
+    <span class="text-elements">
+      {{input type="checkbox" name="autoEnabled" checked=autoEnabled}}
+      Auto Refresh
+      <br/>
+      {{#if displayTime}}
+        Last refreshed at <b>{{displayTime}}</b>
+      {{else}}
+        Load time not available!
+      {{/if}}
+    </span>
+    <button type="button" class="btn btn-success">
+      <i class='fa fa-refresh'></i> Refresh
+    </button>
+  </span>
+</ul>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/templates/dag.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag.hbs b/tez-ui2/src/main/webapp/app/templates/dag.hbs
new file mode 100644
index 0000000..308b905
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/dag.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.
+}}
+
+{{tab-n-refresh tabs=tabs}}
+{{outlet}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/templates/dag/attempts.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/attempts.hbs b/tez-ui2/src/main/webapp/app/templates/dag/attempts.hbs
new file mode 100644
index 0000000..63840f5
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/dag/attempts.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.
+}}
+
+Attempts
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/index.hbs b/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
new file mode 100644
index 0000000..2811a35
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
@@ -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.
+}}
+
+{{#if loaded}}
+  <table class='detail-list'>
+    <thead>
+      <tr>
+        <th colspan=2>Details</th>
+      </tr>
+    </thead>
+    <tbody>
+    <tr>
+      <td colspan="2">
+        {{bs-button icon="fa fa-download" title="Download data" defaultText="Download data" type="info" clicked="downloadDagJson"}}
+      </td>
+    </tr>
+    <tr>
+      <td>Application ID</td>
+      <td>
+        {{#link-to 'app' model.appID class='ember-table-content'}}
+          {{model.appID}}
+        {{/link-to}}
+      </td>
+    </tr>
+    <tr>
+      <td>ID</td>
+      <td>{{model.entityID}}</td>
+    </tr>
+    <tr>
+      <td>Submitter</td>
+      <td>{{model.user}}</td>
+    </tr>
+    <tr>
+      <td>Status</td>
+      <td>
+        {{em-table-status-cell content=model.status}}
+        {{#if progressStr}} {{bs-badge content=progressStr}}{{/if}}
+        {{#if hasFailedTasks}}
+          [ <a href='{{unbound failedTasksLink}}'>Failed Tasks</a> ]
+        {{/if}}
+        {{#if hasFailedTaskAttempts}}
+          [ <a href='{{unbound failedTaskAttemptsLink}}'>Failed TaskAttempts</a> ]
+        {{/if}}
+      </td>
+    </tr>
+    <tr>
+      <td>Start Time</td>
+      <td>{{txt model.startTime type="date"}}</td>
+    </tr>
+    <tr>
+      <td>End Time</td>
+      <td>{{txt model.endTime type="date"}}</td>
+    </tr>
+    <tr>
+      <td>Duration</td>
+      <td>{{txt model.duration type="duration"}}</td>
+    </tr>
+    <tr>
+      <td>Logs</td>
+      <td>
+        {{em-table-linked-cell content=model.containerLogs}}
+      </td>
+    </tr>
+    </tbody>
+  </table>
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/templates/dag/tasks.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/tasks.hbs b/tez-ui2/src/main/webapp/app/templates/dag/tasks.hbs
new file mode 100644
index 0000000..daee5b5
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/dag/tasks.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.
+}}
+
+Tasks
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/app/templates/dag/vertices.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/vertices.hbs b/tez-ui2/src/main/webapp/app/templates/dag/vertices.hbs
new file mode 100644
index 0000000..7f0bd85
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/dag/vertices.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.
+}}
+
+Vertices
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/tests/integration/components/tab-n-refresh-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/integration/components/tab-n-refresh-test.js b/tez-ui2/src/main/webapp/tests/integration/components/tab-n-refresh-test.js
new file mode 100644
index 0000000..e45b461
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/integration/components/tab-n-refresh-test.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 { moduleForComponent, test } from 'ember-qunit';
+import hbs from 'htmlbars-inline-precompile';
+
+moduleForComponent('tab-n-refresh', 'Integration | Component | tab n refresh', {
+  integration: true
+});
+
+test('Basic creation test', function(assert) {
+  var testTabs = [{
+    text: "Tab 1",
+    routeName: "route_1",
+  },{
+    text: "Tab 2",
+    routeName: "route_2",
+  }];
+
+  this.set("tabs", testTabs);
+
+  this.render(hbs`{{tab-n-refresh tabs=tabs}}`);
+
+  assert.equal(this.$("button").text().trim(), 'Refresh');
+  assert.equal($(this.$("li")[0]).text().trim(), testTabs[0].text);
+  assert.equal($(this.$("li")[1]).text().trim(), testTabs[1].text);
+
+  this.render(hbs`
+    {{#tab-n-refresh tabs=tabs}}
+      template block text
+    {{/tab-n-refresh}}
+  `);
+
+  assert.equal(this.$("button").text().trim(), 'Refresh');
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/tests/unit/controllers/abstract-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/abstract-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/abstract-test.js
new file mode 100644
index 0000000..640e1e5
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/abstract-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 Ember from 'ember';
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:abstract', 'Unit | Controller | abstract', {
+  // Specify the other units that are required for this test.
+  // needs: ['route:abstract']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller.name);
+  assert.ok(controller.crumbObserver);
+  assert.ok(controller.setBreadcrumbs);
+});
+
+test('init test', function(assert) {
+  assert.expect(1);
+
+  this.subject({
+    send: function (name) {
+      assert.equal(name, "setBreadcrumbs");
+    }
+  });
+});
+
+test('crumbObserver test', function(assert) {
+  assert.expect(1 + 1); // Init and fired
+
+  let controller = this.subject({
+    send: function (name) {
+      assert.equal(name, "setBreadcrumbs");
+    }
+  });
+
+  controller.set("breadcrumbs", []);
+});
+
+test('setBreadcrumbs test', function(assert) {
+  let testName = "Abc", // Because all controllers are pointing to the leaf rout
+      testBreadCrumbs = [];
+
+  assert.expect(3);
+  this.subject({
+    name: testName,
+    breadcrumbs: testBreadCrumbs,
+    send: function (name, crumbs) {
+      assert.equal(name, "setBreadcrumbs");
+      assert.ok(crumbs.hasOwnProperty(testName));
+      assert.equal(crumbs[testName], testBreadCrumbs);
+    }
+  });
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/tests/unit/controllers/dag-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag-test.js
new file mode 100644
index 0000000..304321e
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:dag', 'Unit | Controller | dag', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+  assert.ok(controller.tabs);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js
new file mode 100644
index 0000000..1908e69
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:dag/attempts', 'Unit | Controller | dag/attempts', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/tests/unit/controllers/dag/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/index-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/index-test.js
new file mode 100644
index 0000000..0b64e86
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/index-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:dag/index', 'Unit | Controller | dag/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js
new file mode 100644
index 0000000..9d22331
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:dag/tasks', 'Unit | Controller | dag/tasks', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
new file mode 100644
index 0000000..ca6d3d9
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:dag/vertices', 'Unit | Controller | dag/vertices', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js
index 51ea9fe..ddf6c44 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js
@@ -24,16 +24,15 @@ moduleFor('controller:dags', 'Unit | Controller | dags', {
 });
 
 test('Basic creation test', function(assert) {
-  assert.expect(2 + 3);
+  assert.expect(2 + 2);
 
   let controller = this.subject({
     send: function (name, query) {
-      assert.equal(name, "loadData");
+      assert.equal(name, "setBreadcrumbs");
       assert.ok(query);
     }
   });
 
   assert.ok(controller);
   assert.ok(controller.columns);
-  assert.ok(controller._loadObserver);
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/tests/unit/controllers/page-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/page-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/page-test.js
new file mode 100644
index 0000000..ffbdd60
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/page-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 Ember from 'ember';
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:page', 'Unit | Controller | page', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.loaded);
+
+  assert.equal(controller.isLoading, false);
+});
+
+test('loaded test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.notOk(controller.get("loaded"));
+  controller.set("model", true);
+  assert.ok(controller.get("loaded"));
+  controller.set("isLoading", true);
+  assert.notOk(controller.get("loaded"));
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/tests/unit/controllers/table-page-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/table-page-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/table-page-test.js
index efe3f7e..4c41a20 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/table-page-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/table-page-test.js
@@ -16,6 +16,8 @@
  * limitations under the License.
  */
 
+import Ember from 'ember';
+
 import { moduleFor, test } from 'ember-qunit';
 
 moduleFor('controller:table-page', 'Unit | Controller | table page', {
@@ -24,7 +26,9 @@ moduleFor('controller:table-page', 'Unit | Controller | table page', {
 });
 
 test('Basic creation test', function(assert) {
-  let controller = this.subject();
+  let controller = this.subject({
+    send: Ember.K
+  });
 
   assert.ok(controller);
   assert.ok(controller.queryParams);

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/tests/unit/mixins/name-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/mixins/name-test.js b/tez-ui2/src/main/webapp/tests/unit/mixins/name-test.js
new file mode 100644
index 0000000..aedd0cd
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/mixins/name-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 Ember from 'ember';
+import NameMixin from '../../../mixins/name';
+import { module, test } from 'qunit';
+
+module('Unit | Mixin | name');
+
+test('Basic creation', function(assert) {
+  let NameObject = Ember.Object.extend(NameMixin);
+  let subject = NameObject.create();
+
+  assert.ok(subject);
+  assert.ok(subject.name);
+});
+
+test('name test', function(assert) {
+  let NameObject = Ember.Object.extend(NameMixin),
+      testName = "ts";
+
+  let subject = NameObject.create({
+    toString: function () {
+      return `<tez-ui@test:${testName}::ember427>`;
+    }
+  });
+
+  assert.equal(subject.get("name"), testName);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js
index 222a19e..e1e446a 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js
@@ -31,6 +31,11 @@ test('Basic creation test', function(assert) {
   let route = this.subject();
 
   assert.ok(route);
+
+  assert.ok(route.loaderQueryParams);
+  assert.ok(route.model);
+  assert.ok(route.queryFromParams);
+
   assert.ok(route.setDocTitle);
   assert.ok(route.setupController);
 
@@ -46,7 +51,28 @@ test('Basic creation test', function(assert) {
   assert.ok(route._setControllerModel);
   assert.ok(route.setLoader);
 
-  assert.ok(route.actions.loadData);
+  assert.ok(route.actions.setBreadcrumbs);
+  assert.ok(route.actions.bubbleBreadcrumbs);
+});
+
+test('queryFromParams test', function(assert) {
+  let route = this.subject({
+    loaderQueryParams: {
+      id: "a_id",
+      b: "b"
+    }
+  }),
+  testParam = {
+    a: 1,
+    a_id: 2,
+    b: 3,
+    b_id: 4
+  };
+
+  assert.deepEqual(route.queryFromParams(testParam), {
+    id: 2,
+    b: 3
+  });
 });
 
 test('checkAndCall test', function(assert) {
@@ -208,3 +234,37 @@ test('setLoader test', function(assert) {
   assert.equal(route.get("loader.store"), route.get("store"));
   assert.equal(route.get("loader.container"), route.get("container"));
 });
+
+test('actions.setBreadcrumbs test', function(assert) {
+  let testName = "ts",
+      route = this.subject({
+        name: testName
+      }),
+      testCrumbs = {};
+
+  // Because all controllers are pointing to the leaf rout
+  testCrumbs[testName] = testCrumbs;
+
+  route.send("setBreadcrumbs", testCrumbs);
+  assert.equal(route.get("breadcrumbs"), testCrumbs);
+
+  route.send("setBreadcrumbs", {});
+  assert.equal(route.get("breadcrumbs"), testCrumbs);
+
+  route.send("setBreadcrumbs", null);
+  assert.equal(route.get("breadcrumbs"), testCrumbs);
+});
+
+test('actions.bubbleBreadcrumbs test', function(assert) {
+  let testName = "ts",
+      route = this.subject({
+        name: testName
+      }),
+      existingCrumbs = [1, 2],
+      testCrumbs = [1, 2];
+
+  route.set("breadcrumbs", existingCrumbs);
+
+  route.send("bubbleBreadcrumbs", testCrumbs);
+  assert.equal(testCrumbs.length, 2 + 2);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/tests/unit/routes/app-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/app-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/app-test.js
new file mode 100644
index 0000000..8e361ea
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/app-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:app', 'Unit | Route | app', {
+  // 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);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/tests/unit/routes/application-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/application-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/application-test.js
index fbf515b..695b72f 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/application-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/application-test.js
@@ -29,7 +29,7 @@ test('Basic creation test', function(assert) {
   assert.ok(route);
   assert.ok(route.pageReset);
   assert.ok(route.actions.didTransition);
-  assert.ok(route.actions.pageChanged);
+  assert.ok(route.actions.bubbleBreadcrumbs);
 });
 
 test('Test didTransition action', function(assert) {
@@ -44,7 +44,7 @@ test('Test didTransition action', function(assert) {
   route.send("didTransition");
 });
 
-test('Test pageChanged action', function(assert) {
+test('Test bubbleBreadcrumbs action', function(assert) {
   let route = this.subject(),
       testController = {
         breadcrumbs: null
@@ -54,6 +54,6 @@ test('Test pageChanged action', function(assert) {
   route.controller = testController;
 
   assert.notOk(route.get("controller.breadcrumbs"));
-  route.send("pageChanged", testBreadcrumbs);
+  route.send("bubbleBreadcrumbs", testBreadcrumbs);
   assert.equal(route.get("controller.breadcrumbs"), testBreadcrumbs);
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/tests/unit/routes/dag-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/dag-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/dag-test.js
new file mode 100644
index 0000000..dc1c012
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/dag-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:dag', 'Unit | Route | dag', {
+  // 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);
+  assert.ok(route.loaderQueryParams);
+  assert.ok(route.model);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/tests/unit/routes/dag/attempts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/dag/attempts-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/dag/attempts-test.js
new file mode 100644
index 0000000..f997891
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/dag/attempts-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('route:dag/attempts', 'Unit | Route | dag/attempts', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/tests/unit/routes/dag/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/dag/index-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/dag/index-test.js
new file mode 100644
index 0000000..aef7031
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/dag/index-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:dag/index', 'Unit | Route | dag/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+  assert.ok(route.load);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});
+

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/tests/unit/routes/dag/tasks-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/dag/tasks-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/dag/tasks-test.js
new file mode 100644
index 0000000..3e283ca
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/dag/tasks-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('route:dag/tasks', 'Unit | Route | dag/tasks', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/tests/unit/routes/dag/vertices-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/dag/vertices-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/dag/vertices-test.js
new file mode 100644
index 0000000..e55e184
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/dag/vertices-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('route:dag/vertices', 'Unit | Route | dag/vertices', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a0ba39cb/tez-ui2/src/main/webapp/tests/unit/routes/dags-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/dags-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/dags-test.js
index 3dabfe4..8b99a7f 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/dags-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/dags-test.js
@@ -28,5 +28,7 @@ test('Basic creation test', function(assert) {
 
   assert.ok(route);
   assert.ok(route.title);
+  assert.ok(route.loaderQueryParams);
+  assert.ok(route.setupController);
   assert.ok(route.load);
 });


[08/45] tez git commit: TEZ-3020. Tez UI 2: Add entity blueprint (sree)

Posted by sr...@apache.org.
TEZ-3020. Tez UI 2: Add entity blueprint (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/72a10602
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/72a10602
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/72a10602

Branch: refs/heads/TEZ-2980
Commit: 72a10602bf08076a1a5fd292601ba45314fb07c4
Parents: 95c13aa
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Wed Dec 30 20:51:21 2015 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:31:59 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |  1 +
 tez-ui2/src/main/webapp/app/entities/entity.js  | 22 +++++++++++
 .../main/webapp/app/initializers/entities.js    | 28 ++++++++++++++
 tez-ui2/src/main/webapp/blueprints/.jshintrc    |  6 +++
 .../files/tests/unit/entities/__name__-test.js  | 30 +++++++++++++++
 .../main/webapp/blueprints/entity-test/index.js | 35 +++++++++++++++++
 .../entity/files/app/entities/__name__.js       | 22 +++++++++++
 .../src/main/webapp/blueprints/entity/index.js  | 31 +++++++++++++++
 tez-ui2/src/main/webapp/package.json            |  2 +
 .../tests/unit/initializers/entities-test.js    | 40 ++++++++++++++++++++
 10 files changed, 217 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/72a10602/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index e3fece1..da361d6 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -5,3 +5,4 @@ ALL CHANGES:
   TEZ-3018. Tez UI 2: Add config.env
   TEZ-3019. Tez UI 2: Replace BaseURL with Host
   TEZ-2984. Tez UI 2: Create abstract classes
+  TEZ-3020. Tez UI 2: Add entity blueprint

http://git-wip-us.apache.org/repos/asf/tez/blob/72a10602/tez-ui2/src/main/webapp/app/entities/entity.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/entities/entity.js b/tez-ui2/src/main/webapp/app/entities/entity.js
new file mode 100644
index 0000000..3d858c8
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/entities/entity.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.ObjectProxy.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/72a10602/tez-ui2/src/main/webapp/app/initializers/entities.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/initializers/entities.js b/tez-ui2/src/main/webapp/app/initializers/entities.js
new file mode 100644
index 0000000..86d796c
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/initializers/entities.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 registerWithContainer from "ember-cli-auto-register/register";
+
+export function initialize(application) {
+  registerWithContainer("entity", application);
+}
+
+export default {
+  name: 'entities',
+  initialize
+};

http://git-wip-us.apache.org/repos/asf/tez/blob/72a10602/tez-ui2/src/main/webapp/blueprints/.jshintrc
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/blueprints/.jshintrc b/tez-ui2/src/main/webapp/blueprints/.jshintrc
new file mode 100644
index 0000000..33f4f6f
--- /dev/null
+++ b/tez-ui2/src/main/webapp/blueprints/.jshintrc
@@ -0,0 +1,6 @@
+{
+  "predef": [
+    "console"
+  ],
+  "strict": false
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/72a10602/tez-ui2/src/main/webapp/blueprints/entity-test/files/tests/unit/entities/__name__-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/blueprints/entity-test/files/tests/unit/entities/__name__-test.js b/tez-ui2/src/main/webapp/blueprints/entity-test/files/tests/unit/entities/__name__-test.js
new file mode 100644
index 0000000..179c5e5
--- /dev/null
+++ b/tez-ui2/src/main/webapp/blueprints/entity-test/files/tests/unit/entities/__name__-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('entitie:<%= dasherizedModuleName %>', '<%= friendlyTestDescription %>', {
+  // Specify the other units that are required for this test.
+  // needs: ['entitie:foo']
+});
+
+// Replace this with your real tests.
+test('it exists', function(assert) {
+  let adapter = this.subject();
+  assert.ok(adapter);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/72a10602/tez-ui2/src/main/webapp/blueprints/entity-test/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/blueprints/entity-test/index.js b/tez-ui2/src/main/webapp/blueprints/entity-test/index.js
new file mode 100644
index 0000000..d89d9cd
--- /dev/null
+++ b/tez-ui2/src/main/webapp/blueprints/entity-test/index.js
@@ -0,0 +1,35 @@
+/*jshint node:true*/
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var testInfo = require('ember-cli-test-info');
+
+module.exports = {
+  description: 'Generate an entity unit test.',
+
+  locals: function(options) {
+    return {
+      friendlyTestDescription: testInfo.description(options.entity.name, "Unit", "Entity")
+    };
+  },
+
+  // afterInstall: function(options) {
+  //   // Perform extra work here.
+  // }
+};

http://git-wip-us.apache.org/repos/asf/tez/blob/72a10602/tez-ui2/src/main/webapp/blueprints/entity/files/app/entities/__name__.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/blueprints/entity/files/app/entities/__name__.js b/tez-ui2/src/main/webapp/blueprints/entity/files/app/entities/__name__.js
new file mode 100644
index 0000000..334868e
--- /dev/null
+++ b/tez-ui2/src/main/webapp/blueprints/entity/files/app/entities/__name__.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 Entity from './entity';
+
+export default Entity.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/72a10602/tez-ui2/src/main/webapp/blueprints/entity/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/blueprints/entity/index.js b/tez-ui2/src/main/webapp/blueprints/entity/index.js
new file mode 100644
index 0000000..24e25ef
--- /dev/null
+++ b/tez-ui2/src/main/webapp/blueprints/entity/index.js
@@ -0,0 +1,31 @@
+/*jshint node:true*/
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 = {
+  description: 'Generate and entity',
+
+  locals: function(options) {
+    return {};
+  }
+
+  // afterInstall: function(options) {
+  //   // Perform extra work here.
+  // }
+};

http://git-wip-us.apache.org/repos/asf/tez/blob/72a10602/tez-ui2/src/main/webapp/package.json
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/package.json b/tez-ui2/src/main/webapp/package.json
index da85316..c5ab3d0 100644
--- a/tez-ui2/src/main/webapp/package.json
+++ b/tez-ui2/src/main/webapp/package.json
@@ -25,6 +25,7 @@
     "broccoli-asset-rev": "^2.2.0",
     "ember-cli": "1.13.13",
     "ember-cli-app-version": "^1.0.0",
+    "ember-cli-auto-register": "^1.1.0",
     "ember-cli-babel": "^5.1.5",
     "ember-cli-content-security-policy": "0.4.0",
     "ember-cli-dependency-checker": "^1.1.0",
@@ -33,6 +34,7 @@
     "ember-cli-qunit": "^1.0.4",
     "ember-cli-release": "0.2.8",
     "ember-cli-sri": "^1.2.0",
+    "ember-cli-test-info": "^1.0.0",
     "ember-cli-uglify": "^1.2.0",
     "ember-data": "2.1.0",
     "ember-disable-proxy-controllers": "^1.0.1",

http://git-wip-us.apache.org/repos/asf/tez/blob/72a10602/tez-ui2/src/main/webapp/tests/unit/initializers/entities-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/initializers/entities-test.js b/tez-ui2/src/main/webapp/tests/unit/initializers/entities-test.js
new file mode 100644
index 0000000..ea54a11
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/initializers/entities-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 EntitiesInitializer from '../../../initializers/entities';
+import { module, test } from 'qunit';
+
+let application;
+
+module('Unit | Initializer | entities', {
+  beforeEach() {
+    Ember.run(function() {
+      application = Ember.Application.create();
+      application.deferReadiness();
+    });
+  }
+});
+
+// Replace this with your real tests.
+test('it works', function(assert) {
+  EntitiesInitializer.initialize(application);
+
+  // you would normally confirm the results of the initializer here
+  assert.ok(true);
+});


[03/45] tez git commit: TEZ-3016. Tez UI 2: Make bower dependency silent (sree)

Posted by sr...@apache.org.
TEZ-3016. Tez UI 2: Make bower dependency silent (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/0c9601a6
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/0c9601a6
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/0c9601a6

Branch: refs/heads/TEZ-2980
Commit: 0c9601a609347cbd6fb92a3ce1a7029773ced02f
Parents: d072f3d
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Tue Dec 29 14:58:28 2015 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:31:58 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                 | 1 +
 tez-ui2/README.md                    | 1 -
 tez-ui2/src/main/webapp/README.md    | 1 -
 tez-ui2/src/main/webapp/package.json | 9 +++++----
 4 files changed, 6 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/0c9601a6/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index 7130897..cb91f25 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -1,2 +1,3 @@
 ALL CHANGES:
   TEZ-2982. Tez UI: Create tez-ui2 directory and get a basic dummy page working in ember 2.2
+  TEZ-3016. Tez UI 2: Make bower dependency silent

http://git-wip-us.apache.org/repos/asf/tez/blob/0c9601a6/tez-ui2/README.md
----------------------------------------------------------------------
diff --git a/tez-ui2/README.md b/tez-ui2/README.md
index a10f460..e4ce2f5 100644
--- a/tez-ui2/README.md
+++ b/tez-ui2/README.md
@@ -11,7 +11,6 @@ You will need the following things properly installed on your computer.
 
 * [Git](http://git-scm.com/)
 * [Node.js](http://nodejs.org/) (with NPM)
-* [Bower](http://bower.io/)
 * [Ember CLI](http://www.ember-cli.com/)
 * [PhantomJS](http://phantomjs.org/)
 

http://git-wip-us.apache.org/repos/asf/tez/blob/0c9601a6/tez-ui2/src/main/webapp/README.md
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/README.md b/tez-ui2/src/main/webapp/README.md
index 291e05f..fb8128e 100644
--- a/tez-ui2/src/main/webapp/README.md
+++ b/tez-ui2/src/main/webapp/README.md
@@ -11,7 +11,6 @@ You will need the following things properly installed on your computer.
 
 * [Git](http://git-scm.com/)
 * [Node.js](http://nodejs.org/) (with NPM)
-* [Bower](http://bower.io/)
 * [Ember CLI](http://www.ember-cli.com/)
 * [PhantomJS](http://phantomjs.org/)
 

http://git-wip-us.apache.org/repos/asf/tez/blob/0c9601a6/tez-ui2/src/main/webapp/package.json
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/package.json b/tez-ui2/src/main/webapp/package.json
index 7e474e3..38c76da 100644
--- a/tez-ui2/src/main/webapp/package.json
+++ b/tez-ui2/src/main/webapp/package.json
@@ -11,16 +11,17 @@
     "build": "ember build",
     "start": "ember server",
     "test": "ember test",
-    "postinstall": "bower install"
+    "postinstall": "./node_modules/bower/bin/bower install"
   },
-  "repository" : {
-    "type" : "git",
-    "url" : "https://git-wip-us.apache.org/repos/asf/tez.git"
+  "repository": {
+    "type": "git",
+    "url": "https://git-wip-us.apache.org/repos/asf/tez.git"
   },
   "engines": {
     "node": ">= 0.10.0"
   },
   "devDependencies": {
+    "bower": "^1.7.1",
     "broccoli-asset-rev": "^2.2.0",
     "ember-cli": "1.13.13",
     "ember-cli-app-version": "^1.0.0",


[33/45] tez git commit: TEZ-3064. Tez UI 2: Add All DAGs filters (sree)

Posted by sr...@apache.org.
TEZ-3064. Tez UI 2: Add All DAGs filters (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/7040bbda
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/7040bbda
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/7040bbda

Branch: refs/heads/TEZ-2980
Commit: 7040bbda2c456cedb700d9d13c73589664ae327a
Parents: 5e4d542
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Thu Jan 21 19:20:43 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:32:52 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |  1 +
 .../src/main/webapp/app/adapters/timeline.js    |  7 +-
 .../webapp/app/components/dags-page-search.js   | 44 ++++++++++
 .../webapp/app/components/dags-pagination-ui.js | 92 ++++++++++++++++++++
 .../main/webapp/app/components/tab-n-refresh.js |  4 +-
 .../src/main/webapp/app/controllers/app/dags.js |  4 +-
 tez-ui2/src/main/webapp/app/controllers/dags.js | 39 ++++++++-
 tez-ui2/src/main/webapp/app/models/dag.js       |  2 +-
 tez-ui2/src/main/webapp/app/models/timeline.js  |  2 +-
 tez-ui2/src/main/webapp/app/routes/dags.js      | 62 +++++++++++--
 tez-ui2/src/main/webapp/app/serializers/dag.js  |  2 +-
 tez-ui2/src/main/webapp/app/styles/app.less     |  1 +
 .../webapp/app/styles/dags-page-search.less     | 50 +++++++++++
 .../main/webapp/app/styles/tab-n-refresh.less   |  2 +
 .../templates/components/dags-page-search.hbs   | 74 ++++++++++++++++
 .../templates/components/dags-pagination-ui.hbs | 27 ++++++
 .../app/templates/components/tab-n-refresh.hbs  |  8 +-
 tez-ui2/src/main/webapp/app/templates/dags.hbs  |  6 +-
 .../components/dags-page-search-test.js         | 45 ++++++++++
 .../components/dags-pagination-ui-test.js       | 47 ++++++++++
 .../webapp/tests/unit/controllers/dags-test.js  |  7 +-
 .../main/webapp/tests/unit/routes/dags-test.js  | 24 +++++
 22 files changed, 531 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/7040bbda/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index 6a2b343..e34c0fd 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -23,3 +23,4 @@ ALL CHANGES:
   TEZ-3043. Tez UI 2: Create configurations page
   TEZ-3049. Tez UI 2: Add column selector
   TEZ-3050. Tez UI 2: Add counter columns
+  TEZ-3064. Tez UI 2: Add All DAGs filters

http://git-wip-us.apache.org/repos/asf/tez/blob/7040bbda/tez-ui2/src/main/webapp/app/adapters/timeline.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/timeline.js b/tez-ui2/src/main/webapp/app/adapters/timeline.js
index 6e06c7b..93e83cb 100644
--- a/tez-ui2/src/main/webapp/app/adapters/timeline.js
+++ b/tez-ui2/src/main/webapp/app/adapters/timeline.js
@@ -31,7 +31,12 @@ export default AbstractAdapter.extend({
     taskID: 'TEZ_TASK_ID',
     attemptID: 'TEZ_TASK_ATTEMPT_ID',
     hiveQueryID: 'HIVE_QUERY_ID',
-    appID: 'applicationId'
+    appID: 'applicationId',
+
+    dagName: 'dagName',
+    user: "user",
+    status: "status",
+    contextID: "callerId"
   },
 
   stringifyFilters: function (filters) {

http://git-wip-us.apache.org/repos/asf/tez/blob/7040bbda/tez-ui2/src/main/webapp/app/components/dags-page-search.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/components/dags-page-search.js b/tez-ui2/src/main/webapp/app/components/dags-page-search.js
new file mode 100644
index 0000000..c9c01e3
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/components/dags-page-search.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.Component.extend({
+  classNames: ['dags-page-search'],
+
+  actions: {
+    dagNameChanged: function (value) {
+      this.get('targetObject.targetObject').send('searchChanged', 'dagName', value);
+    },
+    dagIDChanged: function (value) {
+      this.get('targetObject.targetObject').send('searchChanged', 'dagID', value);
+    },
+    submitterChanged: function (value) {
+      this.get('targetObject.targetObject').send('searchChanged', 'submitter', value);
+    },
+    statusChanged: function (value) {
+      this.get('targetObject.targetObject').send('searchChanged', 'status', value);
+    },
+    appIDChanged: function (value) {
+      this.get('targetObject.targetObject').send('searchChanged', 'appID', value);
+    },
+    contextIDChanged: function (value) {
+      this.get('targetObject.targetObject').send('searchChanged', 'contextID', value);
+    },
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/7040bbda/tez-ui2/src/main/webapp/app/components/dags-pagination-ui.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/components/dags-pagination-ui.js b/tez-ui2/src/main/webapp/app/components/dags-pagination-ui.js
new file mode 100644
index 0000000..bedb6cb
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/components/dags-pagination-ui.js
@@ -0,0 +1,92 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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({
+  tableDefinition: null,
+  dataProcessor: null,
+
+  classNames: ['pagination-ui'],
+  isVisible: Ember.computed.alias('tableDefinition.enablePagination'),
+
+  atFirst: Ember.computed('tableDefinition.pageNum', function () {
+    return this.get('tableDefinition.pageNum') === 1;
+  }),
+
+  atLast: Ember.computed('tableDefinition.pageNum', 'dataProcessor.totalPages', function () {
+    return this.get('tableDefinition.pageNum') === this.get('dataProcessor.totalPages');
+  }),
+
+  rowCountOptions: Ember.computed('tableDefinition.rowCountOptions', 'tableDefinition.rowCount', function () {
+    var options = this.get('tableDefinition.rowCountOptions'),
+        rowCount = this.get('tableDefinition.rowCount');
+
+    return options.map(function (option) {
+      return {
+        value: option,
+        selected: option === rowCount
+      };
+    });
+  }),
+
+  _possiblePages: Ember.computed('tableDefinition.pageNum', 'dataProcessor.totalPages', function () {
+    var pageNum = this.get('tableDefinition.pageNum'),
+        totalPages = this.get('dataProcessor.totalPages'),
+        possiblePages = [],
+        startPage = 1,
+        endPage = totalPages,
+        delta = 0;
+
+    if(totalPages > 5) {
+      startPage = pageNum - 2;
+      endPage = pageNum + 2;
+
+      if(startPage < 1) {
+        delta = 1 - startPage;
+      }
+      else if(endPage > totalPages) {
+        delta = totalPages - endPage;
+      }
+
+      startPage += delta;
+      endPage += delta;
+    }
+
+    while(startPage <= endPage) {
+      possiblePages.push({
+        isCurrent: startPage === pageNum,
+        pageNum: startPage++
+      });
+    }
+
+    return possiblePages;
+  }),
+
+  actions: {
+    rowSelected: function (value) {
+      value = parseInt(value);
+      if(this.get('tableDefinition.rowCount') !== value) {
+        this.get('parentView').send('rowChanged', value);
+      }
+    },
+    changePage: function (value) {
+      this.get('parentView').send('pageChanged', value);
+    }
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/7040bbda/tez-ui2/src/main/webapp/app/components/tab-n-refresh.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/components/tab-n-refresh.js b/tez-ui2/src/main/webapp/app/components/tab-n-refresh.js
index 3f05371..555418e 100644
--- a/tez-ui2/src/main/webapp/app/components/tab-n-refresh.js
+++ b/tez-ui2/src/main/webapp/app/components/tab-n-refresh.js
@@ -24,13 +24,15 @@ export default Ember.Component.extend({
     this.setApplication();
   },
 
+  autoRefreshEnabled: true,
+
   setApplication: function () {
     var application = this.get("targetObject.container").lookup('controller:application');
     this.set("application", application);
   },
 
   normalizedTabs: Ember.computed("tabs", "application.currentPath", function () {
-    var tabs = this.get("tabs"),
+    var tabs = this.get("tabs") || [],
         activeRouteName = this.get("application.currentPath");
 
     return tabs.map(function (tab) {

http://git-wip-us.apache.org/repos/asf/tez/blob/7040bbda/tez-ui2/src/main/webapp/app/controllers/app/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/app/dags.js b/tez-ui2/src/main/webapp/app/controllers/app/dags.js
index 04f8f43..547c4ee 100644
--- a/tez-ui2/src/main/webapp/app/controllers/app/dags.js
+++ b/tez-ui2/src/main/webapp/app/controllers/app/dags.js
@@ -42,9 +42,9 @@ export default TablePageController.extend({
     headerTitle: 'Id',
     contentPath: 'entityID'
   },{
-    id: 'user',
+    id: 'submitter',
     headerTitle: 'Submitter',
-    contentPath: 'user'
+    contentPath: 'submitter'
   },{
     id: 'status',
     headerTitle: 'Status',

http://git-wip-us.apache.org/repos/asf/tez/blob/7040bbda/tez-ui2/src/main/webapp/app/controllers/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dags.js b/tez-ui2/src/main/webapp/app/controllers/dags.js
index 7d5f1d9..d35d8f7 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dags.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dags.js
@@ -16,13 +16,41 @@
  * limitations under the License.
  */
 
+import Ember from 'ember';
+
 import TablePageController from './table-page';
 import ColumnDefinition from 'em-table/utils/column-definition';
+import TableDefinition from 'em-table/utils/table-definition';
 
 export default TablePageController.extend({
 
+  queryParams: ["dagName", "dagID", "submitter", "status", "appID", "contextID", "pageNo"],
+  dagName: "",
+  dagID: "",
+  submitter: "",
+  status: "",
+  appID: "",
+  contextID: "",
+  pageNo: 1,
+
   breadcrumbs: [],
 
+  headerComponentNames: ['dags-page-search', 'table-controls', 'dags-pagination-ui'],
+
+  definition: Ember.computed("dagName", "dagID", "submitter", "status", "appID", "contextID", "pageNo", function () {
+    return TableDefinition.create({
+      dagName: this.get("dagName"),
+      dagID: this.get("dagID"),
+      submitter: this.get("submitter"),
+      status: this.get("status"),
+      appID: this.get("appID"),
+      contextID: this.get("contextID"),
+
+      pageNum: this.get("pageNo"),
+      rowCountOptions: [5, 10, 25, 50, 100, 250, 500]
+    });
+  }),
+
   columns: ColumnDefinition.make([{
     id: 'name',
     headerTitle: 'Dag Name',
@@ -40,9 +68,9 @@ export default TablePageController.extend({
     headerTitle: 'Id',
     contentPath: 'entityID'
   },{
-    id: 'user',
+    id: 'submitter',
     headerTitle: 'Submitter',
-    contentPath: 'user'
+    contentPath: 'submitter'
   },{
     id: 'status',
     headerTitle: 'Status',
@@ -107,5 +135,12 @@ export default TablePageController.extend({
 
   getCounterColumns: function () {
     return this._super().concat(this.get('env.app.tables.defaultColumns.dagCounters'));
+  },
+
+  actions: {
+    searchChanged: function (propertyName, value) {
+      this.set(propertyName, value);
+    },
   }
+
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/7040bbda/tez-ui2/src/main/webapp/app/models/dag.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/dag.js b/tez-ui2/src/main/webapp/app/models/dag.js
index 2efb65f..e0a4b55 100644
--- a/tez-ui2/src/main/webapp/app/models/dag.js
+++ b/tez-ui2/src/main/webapp/app/models/dag.js
@@ -40,7 +40,7 @@ import TimelineModel from './timeline';
 export default TimelineModel.extend({
   name: DS.attr("string"),
 
-  user: DS.attr("string"),
+  submitter: DS.attr("string"),
   contextID: DS.attr("string"),
 
   domain: DS.attr("string"),

http://git-wip-us.apache.org/repos/asf/tez/blob/7040bbda/tez-ui2/src/main/webapp/app/models/timeline.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/timeline.js b/tez-ui2/src/main/webapp/app/models/timeline.js
index 6f9ddb7..cdd8d22 100644
--- a/tez-ui2/src/main/webapp/app/models/timeline.js
+++ b/tez-ui2/src/main/webapp/app/models/timeline.js
@@ -67,7 +67,7 @@ export default AbstractModel.extend({
   counterGroups: DS.attr('object'),
   counterHash: Ember.computed("counterGroups", function () {
     var counterHash = {},
-        counterGroups = this.get("counterGroups");
+        counterGroups = this.get("counterGroups") || [];
 
     counterGroups.forEach(function (group) {
       var counters = group.counters,

http://git-wip-us.apache.org/repos/asf/tez/blob/7040bbda/tez-ui2/src/main/webapp/app/routes/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dags.js b/tez-ui2/src/main/webapp/app/routes/dags.js
index ecd1b00..b9484be 100644
--- a/tez-ui2/src/main/webapp/app/routes/dags.js
+++ b/tez-ui2/src/main/webapp/app/routes/dags.js
@@ -20,17 +20,33 @@ import Ember from 'ember';
 
 import AbstractRoute from './abstract';
 
+const REFRESH = {refreshModel: true};
+
 export default AbstractRoute.extend({
   title: "All DAGs",
 
   queryParams: {
-    rowCount: {
-      refreshModel: true
-    }
+    dagName: REFRESH,
+    dagID: REFRESH,
+    submitter: REFRESH,
+    status: REFRESH,
+    appID: REFRESH,
+    contextID: REFRESH,
+    pageNo: REFRESH,
+
+    rowCount: REFRESH,
   },
 
   loaderQueryParams: {
-    rowCount: "rowCount"
+    dagName: "dagName",
+    dagID: "dagID",
+    user: "submitter",
+    status: "status",
+    appID: "appID",
+    contextID: "contextID",
+
+    pageNo: "pageNo",
+    limit: "rowCount",
   },
 
   setupController: function (controller, model) {
@@ -38,7 +54,43 @@ export default AbstractRoute.extend({
     Ember.run.later(this, "startCrumbBubble");
   },
 
+  // Client side filtering to ensure that records are relevant after status correction
+  filterRecords: function (records, query) {
+    query = {
+      name: query.dagName,
+      entityID: query.dagID,
+      submitter: query.submitter,
+      status: query.status,
+      appID: query.appID,
+      contextID: query.contextID
+    };
+
+    return records.filter(function (record) {
+      for(var propName in query) {
+        if(query[propName] && query[propName] !== record.get(propName)) {
+          return false;
+        }
+      }
+      return true;
+    });
+  },
+
   load: function (value, query) {
-    return this.get("loader").query('dag', query);
+    var loader,
+        that = this;
+
+    if(query.dagID) {
+      that.set("loadedRecords", []);
+      loader = this.get("loader").queryRecord('dag', query.dagID).then(function (record) {
+        return [record];
+      });
+    }
+    else {
+      loader = this.get("loader").query('dag', query);
+    }
+
+    return loader.then(function (records) {
+      return that.filterRecords(records, query);
+    });
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/7040bbda/tez-ui2/src/main/webapp/app/serializers/dag.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/dag.js b/tez-ui2/src/main/webapp/app/serializers/dag.js
index 00113e4..9da7bb5 100644
--- a/tez-ui2/src/main/webapp/app/serializers/dag.js
+++ b/tez-ui2/src/main/webapp/app/serializers/dag.js
@@ -106,7 +106,7 @@ export default TimelineSerializer.extend({
   maps: {
     name: 'primaryfilters.dagName.0',
 
-    user: 'primaryfilters.user.0',
+    submitter: 'primaryfilters.user.0',
     contextID: 'primaryfilters.callerId.0',
 
     atsStatus: getStatus,

http://git-wip-us.apache.org/repos/asf/tez/blob/7040bbda/tez-ui2/src/main/webapp/app/styles/app.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/app.less b/tez-ui2/src/main/webapp/app/styles/app.less
index d697ba7..758d1ab 100644
--- a/tez-ui2/src/main/webapp/app/styles/app.less
+++ b/tez-ui2/src/main/webapp/app/styles/app.less
@@ -22,6 +22,7 @@
 @import "tooltip";
 
 @import "tab-n-refresh";
+@import "dags-page-search";
 
 @import "page-layout";
 @import "details-page";

http://git-wip-us.apache.org/repos/asf/tez/blob/7040bbda/tez-ui2/src/main/webapp/app/styles/dags-page-search.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/dags-page-search.less b/tez-ui2/src/main/webapp/app/styles/dags-page-search.less
new file mode 100644
index 0000000..2fa0216
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/styles/dags-page-search.less
@@ -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.
+ */
+
+@media screen and (min-width: 1500px) {
+  .dags-page-search{
+    float: left;
+    width: 1000px;
+
+    .form-group {
+      margin-bottom: 0px;
+    }
+  }
+
+  .all-dags-table {
+    .pagination-ui, .table-controls {
+      margin-top: 21px;
+    }
+  }
+}
+
+.dags-page-search {
+  text-align: justify;
+
+
+  .search-element {
+    display: inline-block;
+    width: 16.66%;
+
+    padding-left: 3px;
+  }
+
+  .dag-name {
+    padding-left: 0px;
+  }
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/7040bbda/tez-ui2/src/main/webapp/app/styles/tab-n-refresh.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/tab-n-refresh.less b/tez-ui2/src/main/webapp/app/styles/tab-n-refresh.less
index 698f8f3..ab930f2 100644
--- a/tez-ui2/src/main/webapp/app/styles/tab-n-refresh.less
+++ b/tez-ui2/src/main/webapp/app/styles/tab-n-refresh.less
@@ -22,6 +22,8 @@
   margin-bottom: 10px;
   position: relative;
 
+  height: 42px;
+
   .refresh-ui {
     position: absolute;
     right: 0px;

http://git-wip-us.apache.org/repos/asf/tez/blob/7040bbda/tez-ui2/src/main/webapp/app/templates/components/dags-page-search.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/components/dags-page-search.hbs b/tez-ui2/src/main/webapp/app/templates/components/dags-page-search.hbs
new file mode 100644
index 0000000..0c118e4
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/components/dags-page-search.hbs
@@ -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.
+}}
+
+<div class="form-group">
+  <div class="search-element dag-name">
+    <label for="pwd">DAG Name:</label>
+    <input
+        type="text"
+        class="form-control input-sm"
+        placeholder="Search..."
+        value={{tableDefinition.dagName}}
+        onchange={{action "dagNameChanged" value="target.value"}}>
+  </div><div class="search-element">
+    <label for="pwd">ID:</label>
+    <input
+        type="text"
+        class="form-control input-sm"
+        placeholder="Search..."
+        value={{tableDefinition.dagID}}
+        onchange={{action "dagIDChanged" value="target.value"}}>
+  </div><div class="search-element">
+    <label for="pwd">Submitter:</label>
+    <input
+        type="text"
+        class="form-control input-sm"
+        placeholder="Search..."
+        value={{tableDefinition.submitter}}
+        onchange={{action "submitterChanged" value="target.value"}}>
+  </div><div class="search-element">
+    <label for="pwd">Status:</label>
+    <select
+        class="form-control input-sm"
+        value={{tableDefinition.status}}
+        onchange={{action "statusChanged" value="target.value"}}>
+      <option value="">All</option>
+      <option value="SUBMITTED">Submitted</option>
+      <option value="RUNNING">Running</option>
+      <option value="SUCCEEDED">Succeeded</option>
+      <option value="FAILED">Failed</option>
+      <option value="ERROR">Error</option>
+    </select>
+  </div><div class="search-element">
+    <label for="pwd">Application ID:</label>
+    <input
+        type="text"
+        class="form-control input-sm"
+        placeholder="Search..."
+        value={{tableDefinition.appID}}
+        onchange={{action "appIDChanged" value="target.value"}}>
+  </div><div class="search-element">
+    <label for="pwd">Context ID:</label>
+    <input
+        type="text"
+        class="form-control input-sm"
+        placeholder="Search..."
+        value={{tableDefinition.contextID}}
+        onchange={{action "contextIDChanged" value="target.value"}}>
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/tez/blob/7040bbda/tez-ui2/src/main/webapp/app/templates/components/dags-pagination-ui.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/components/dags-pagination-ui.hbs b/tez-ui2/src/main/webapp/app/templates/components/dags-pagination-ui.hbs
new file mode 100644
index 0000000..60b3bee
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/components/dags-pagination-ui.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.
+}}
+
+<div class='row-select'>
+  <select class="form-control" onchange={{action "rowSelected" value="target.value"}}>
+    {{#each rowCountOptions as |option|}}
+      <option value={{option.value}} selected={{option.selected}}>
+        {{option.value}} Rows
+      </option>
+    {{/each}}
+  </select>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/7040bbda/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs b/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs
index 4075c54..6b9c822 100644
--- a/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs
@@ -26,9 +26,11 @@
   {{/each}}
   <span class="refresh-ui">
     <span class="text-elements">
-      {{input type="checkbox" name="autoEnabled" checked=autoEnabled}}
-      Auto Refresh
-      <br/>
+      <span class="auto-refresh {{unless autoRefreshEnabled 'no-visible'}}">
+        {{input type="checkbox" name="autoEnabled" checked=autoEnabled}}
+        Auto Refresh
+        <br/>
+      </span>
       {{#if displayTime}}
         Last refreshed at <b>{{displayTime}}</b>
       {{else}}

http://git-wip-us.apache.org/repos/asf/tez/blob/7040bbda/tez-ui2/src/main/webapp/app/templates/dags.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dags.hbs b/tez-ui2/src/main/webapp/app/templates/dags.hbs
index 1fd0eef..3e64a7e 100644
--- a/tez-ui2/src/main/webapp/app/templates/dags.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dags.hbs
@@ -16,15 +16,19 @@
  * limitations under the License.
 }}
 
+{{tab-n-refresh tabs=tabs autoRefreshEnabled=false}}
+
 {{#if loaded}}
   {{em-table
     columns=visibleColumns
     rows=model
     rowCount=rowCount
 
+    classNames="all-dags-table"
+
     headerComponentNames=headerComponentNames
 
-    enableSearch=false
+    definition=definition
     enableSort=false
 
     searchAction="searchChanged"

http://git-wip-us.apache.org/repos/asf/tez/blob/7040bbda/tez-ui2/src/main/webapp/tests/integration/components/dags-page-search-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/integration/components/dags-page-search-test.js b/tez-ui2/src/main/webapp/tests/integration/components/dags-page-search-test.js
new file mode 100644
index 0000000..def7413
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/integration/components/dags-page-search-test.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 { moduleForComponent, test } from 'ember-qunit';
+import hbs from 'htmlbars-inline-precompile';
+
+moduleForComponent('dags-page-search', 'Integration | Component | dags page search', {
+  integration: true
+});
+
+test('Basic creation test', function(assert) {
+
+  // Set any properties with this.set('myProperty', 'value');
+  // Handle any actions with this.on('myAction', function(val) { ... });" + EOL + EOL +
+
+  this.render(hbs`{{dags-page-search}}`);
+
+  assert.equal(this.$("input").length, 5);
+  assert.equal(this.$("select").length, 1);
+
+  // Template block usage:" + EOL +
+  this.render(hbs`
+    {{#dags-page-search}}
+      template block text
+    {{/dags-page-search}}
+  `);
+
+  assert.equal(this.$("input").length, 5);
+  assert.equal(this.$("select").length, 1);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/7040bbda/tez-ui2/src/main/webapp/tests/integration/components/dags-pagination-ui-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/integration/components/dags-pagination-ui-test.js b/tez-ui2/src/main/webapp/tests/integration/components/dags-pagination-ui-test.js
new file mode 100644
index 0000000..b4c192a
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/integration/components/dags-pagination-ui-test.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 { moduleForComponent, test } from 'ember-qunit';
+import hbs from 'htmlbars-inline-precompile';
+
+moduleForComponent('dags-pagination-ui', 'Integration | Component | dags pagination ui', {
+  integration: true
+});
+
+test('Basic creation test', function(assert) {
+
+  // Set any properties with this.set('myProperty', 'value');
+  // Handle any actions with this.on('myAction', function(val) { ... });" + EOL + EOL +
+
+  this.set("rowCountOptions", {
+    rowCountOptions: [1, 2]
+  });
+
+  this.render(hbs`{{dags-pagination-ui rowCountOptions=rowCountOptions}}`);
+
+  assert.equal(this.$('select').length, 1);
+
+  // Template block usage:" + EOL +
+  this.render(hbs`
+    {{#dags-pagination-ui rowCountOptions=rowCountOptions}}
+      template block text
+    {{/dags-pagination-ui}}
+  `);
+
+  assert.equal(this.$('select').length, 1);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/7040bbda/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js
index 21dbc96..996dd39 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js
@@ -26,7 +26,7 @@ moduleFor('controller:dags', 'Unit | Controller | dags', {
 });
 
 test('Basic creation test', function(assert) {
-  assert.expect(2 + 3);
+  assert.expect(2 + 3 + 4);
 
   let controller = this.subject({
     initVisibleColumns: Ember.K,
@@ -39,4 +39,9 @@ test('Basic creation test', function(assert) {
   assert.ok(controller);
   assert.ok(controller.columns);
   assert.ok(controller.getCounterColumns);
+
+  assert.ok(controller.queryParams);
+  assert.ok(controller.headerComponentNames);
+  assert.ok(controller.definition);
+  assert.ok(controller.actions.searchChanged);
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/7040bbda/tez-ui2/src/main/webapp/tests/unit/routes/dags-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/dags-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/dags-test.js
index 8b99a7f..baadf16 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/dags-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/dags-test.js
@@ -16,6 +16,7 @@
  * limitations under the License.
  */
 
+import Ember from 'ember';
 import { moduleFor, test } from 'ember-qunit';
 
 moduleFor('route:dags', 'Unit | Route | dags', {
@@ -28,7 +29,30 @@ test('Basic creation test', function(assert) {
 
   assert.ok(route);
   assert.ok(route.title);
+
+  assert.ok(route.queryParams);
   assert.ok(route.loaderQueryParams);
   assert.ok(route.setupController);
   assert.ok(route.load);
+
+  assert.ok(route.filterRecords);
+});
+
+test('filterRecords test', function(assert) {
+  let route = this.subject(),
+      testRecords = [Ember.Object.create({
+        name: "test"
+      }), Ember.Object.create({
+
+      }),Ember.Object.create({
+        name: "notest"
+      })],
+      testQuery = {
+        dagName: "test"
+      };
+
+  let filteredRecords = route.filterRecords(testRecords, testQuery);
+
+  assert.equal(filteredRecords.length, 1);
+  assert.equal(filteredRecords[0].name, "test");
 });


[02/45] tez git commit: TEZ-2983. Tez UI 2: Get ember initializers functional (sree)

Posted by sr...@apache.org.
TEZ-2983. Tez UI 2: Get ember initializers functional (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/1e5a3154
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/1e5a3154
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/1e5a3154

Branch: refs/heads/TEZ-2980
Commit: 1e5a3154f5db0c3c90dbc3449ea4870599c6fbc9
Parents: 0c9601a
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Tue Dec 29 20:32:23 2015 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:31:58 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |  1 +
 .../src/main/webapp/app/initializers/hosts.js   | 27 +++++++++
 .../src/main/webapp/app/initializers/jquery.js  | 43 +++++++++++++++
 .../webapp/app/initializers/object-transform.js | 37 +++++++++++++
 tez-ui2/src/main/webapp/app/services/hosts.js   | 58 ++++++++++++++++++++
 tez-ui2/src/main/webapp/app/styles/app.less     | 23 ++++++++
 tez-ui2/src/main/webapp/bower.json              |  3 +-
 tez-ui2/src/main/webapp/config/environment.js   | 23 ++++++++
 tez-ui2/src/main/webapp/ember-cli-build.js      | 22 ++++++++
 .../tests/unit/initializers/hosts-test.js       | 38 +++++++++++++
 .../tests/unit/initializers/jquery-test.js      | 38 +++++++++++++
 .../unit/initializers/object-transform-test.js  | 38 +++++++++++++
 .../webapp/tests/unit/services/hosts-test.js    | 42 ++++++++++++++
 13 files changed, 392 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/1e5a3154/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index cb91f25..4a4edaf 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -1,3 +1,4 @@
 ALL CHANGES:
   TEZ-2982. Tez UI: Create tez-ui2 directory and get a basic dummy page working in ember 2.2
   TEZ-3016. Tez UI 2: Make bower dependency silent
+  TEZ-2983. Tez UI 2: Get ember initializers functional

http://git-wip-us.apache.org/repos/asf/tez/blob/1e5a3154/tez-ui2/src/main/webapp/app/initializers/hosts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/initializers/hosts.js b/tez-ui2/src/main/webapp/app/initializers/hosts.js
new file mode 100644
index 0000000..8791fc7
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/initializers/hosts.js
@@ -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.
+ */
+
+export function initialize(application) {
+  application.inject('controller', 'hosts', 'service:hosts');
+  application.inject('adapter', 'hosts', 'service:hosts');
+}
+
+export default {
+  name: 'hosts',
+  initialize
+};

http://git-wip-us.apache.org/repos/asf/tez/blob/1e5a3154/tez-ui2/src/main/webapp/app/initializers/jquery.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/initializers/jquery.js b/tez-ui2/src/main/webapp/app/initializers/jquery.js
new file mode 100644
index 0000000..b0c52eb
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/initializers/jquery.js
@@ -0,0 +1,43 @@
+/*global $*/
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import environment from '../config/environment';
+
+export function initialize(/* application */) {
+  if(environment.environment !== 'test') {
+    $(document).tooltip({
+      delay: 20,
+      tooltipClass: 'generic-tooltip'
+    });
+
+    $.ajaxPrefilter(function(options, originalOptions, jqXHR) {
+      jqXHR.requestOptions = originalOptions;
+    });
+
+    $.ajaxSetup({
+      cache: false
+    });
+  }
+}
+
+export default {
+  name: 'jquery',
+  initialize
+};

http://git-wip-us.apache.org/repos/asf/tez/blob/1e5a3154/tez-ui2/src/main/webapp/app/initializers/object-transform.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/initializers/object-transform.js b/tez-ui2/src/main/webapp/app/initializers/object-transform.js
new file mode 100644
index 0000000..57502cf
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/initializers/object-transform.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 DS from "ember-data";
+
+export function initialize(application) {
+  application.register('transform:object', DS.Transform.extend({
+    deserialize: function(serialized) {
+      return Ember.none(serialized) ? {} : serialized;
+    },
+
+    serialized: function(deserialized) {
+      return Ember.none(deserialized) ? {} : deserialized;
+    }
+  }));
+}
+
+export default {
+  name: 'object-transform',
+  initialize
+};

http://git-wip-us.apache.org/repos/asf/tez/blob/1e5a3154/tez-ui2/src/main/webapp/app/services/hosts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/services/hosts.js b/tez-ui2/src/main/webapp/app/services/hosts.js
new file mode 100644
index 0000000..5bdc6d1
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/services/hosts.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 environment from '../config/environment';
+
+export default Ember.Service.extend({
+
+  correctProtocol: function (url) {
+    var proto = window.location.protocol;
+
+    if(proto === "file:") {
+      proto = "http:";
+    }
+
+    if(url.match("://")) {
+      url = url.substr(url.indexOf("://") + 3);
+    }
+
+    return proto + "//" + url;
+  },
+
+  normalizeURL: function (url) {
+    url = this.correctProtocol(url);
+
+    // Remove trailing slash
+    if(url && url.charAt(url.length - 1) === '/') {
+      url = url.slice(0, -1);
+    }
+    return url;
+  },
+
+  timelineBaseURL: Ember.computed(function () {
+    // Todo: Use global ENV if available
+    // Todo: Use loaded host if protocol is != file
+    return this.normalizeURL(environment.hosts.timeline);
+  }),
+
+  rmBaseURL: Ember.computed(function () {
+    return this.normalizeURL(environment.hosts.RM);
+  }),
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/1e5a3154/tez-ui2/src/main/webapp/app/styles/app.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/app.less b/tez-ui2/src/main/webapp/app/styles/app.less
index 8b13789..8a21537 100644
--- a/tez-ui2/src/main/webapp/app/styles/app.less
+++ b/tez-ui2/src/main/webapp/app/styles/app.less
@@ -1 +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.
+ */
 
+.generic-tooltip {
+  padding: 3px 5px !important;
+  background: rgba(0,0,0,.8) !important;
+  color: white !important;
+  border: none !important;
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/1e5a3154/tez-ui2/src/main/webapp/bower.json
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/bower.json b/tez-ui2/src/main/webapp/bower.json
index fb312cb..b6c7ca5 100644
--- a/tez-ui2/src/main/webapp/bower.json
+++ b/tez-ui2/src/main/webapp/bower.json
@@ -10,6 +10,7 @@
     "ember-qunit-notifications": "0.1.0",
     "jquery": "^1.11.3",
     "loader.js": "3.3.0",
-    "qunit": "~1.19.0"
+    "qunit": "~1.19.0",
+    "jquery-ui": "~1.11.4"
   }
 }

http://git-wip-us.apache.org/repos/asf/tez/blob/1e5a3154/tez-ui2/src/main/webapp/config/environment.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/config/environment.js b/tez-ui2/src/main/webapp/config/environment.js
index 9243b2b..e061066 100644
--- a/tez-ui2/src/main/webapp/config/environment.js
+++ b/tez-ui2/src/main/webapp/config/environment.js
@@ -1,5 +1,23 @@
 /* jshint node: true */
 
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 = function(environment) {
   var ENV = {
     modulePrefix: 'tez-ui',
@@ -16,6 +34,11 @@ module.exports = function(environment) {
     APP: {
       // Here you can pass flags/options to your application instance
       // when it is created
+    },
+
+    hosts: {
+      timeline: 'localhost:8188',
+      RM: 'localhost:8088'
     }
   };
 

http://git-wip-us.apache.org/repos/asf/tez/blob/1e5a3154/tez-ui2/src/main/webapp/ember-cli-build.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/ember-cli-build.js b/tez-ui2/src/main/webapp/ember-cli-build.js
index 2537ce2..9f33b64 100644
--- a/tez-ui2/src/main/webapp/ember-cli-build.js
+++ b/tez-ui2/src/main/webapp/ember-cli-build.js
@@ -1,5 +1,24 @@
 /*jshint node:true*/
 /* global require, module */
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 var EmberApp = require('ember-cli/lib/broccoli/ember-app');
 
 module.exports = function(defaults) {
@@ -20,5 +39,8 @@ module.exports = function(defaults) {
   // please specify an object with the list of modules as keys
   // along with the exports of each module as its value.
 
+  app.import('bower_components/jquery-ui/jquery-ui.js');
+  app.import('bower_components/jquery-ui/ui/tooltip.js');
+
   return app.toTree();
 };

http://git-wip-us.apache.org/repos/asf/tez/blob/1e5a3154/tez-ui2/src/main/webapp/tests/unit/initializers/hosts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/initializers/hosts-test.js b/tez-ui2/src/main/webapp/tests/unit/initializers/hosts-test.js
new file mode 100644
index 0000000..5244c77
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/initializers/hosts-test.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 HostsInitializer from '../../../initializers/hosts';
+import { module, test } from 'qunit';
+
+let application;
+
+module('Unit | Initializer | hosts', {
+  beforeEach() {
+    Ember.run(function() {
+      application = Ember.Application.create();
+      application.deferReadiness();
+    });
+  }
+});
+
+test('it works', function(assert) {
+  HostsInitializer.initialize(application);
+
+  assert.ok(true);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/1e5a3154/tez-ui2/src/main/webapp/tests/unit/initializers/jquery-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/initializers/jquery-test.js b/tez-ui2/src/main/webapp/tests/unit/initializers/jquery-test.js
new file mode 100644
index 0000000..e30f427
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/initializers/jquery-test.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 JqueryInitializer from '../../../initializers/jquery';
+import { module, test } from 'qunit';
+
+let application;
+
+module('Unit | Initializer | jquery', {
+  beforeEach() {
+    Ember.run(function() {
+      application = Ember.Application.create();
+      application.deferReadiness();
+    });
+  }
+});
+
+test('it works', function(assert) {
+  JqueryInitializer.initialize(application);
+
+  assert.ok(true);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/1e5a3154/tez-ui2/src/main/webapp/tests/unit/initializers/object-transform-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/initializers/object-transform-test.js b/tez-ui2/src/main/webapp/tests/unit/initializers/object-transform-test.js
new file mode 100644
index 0000000..a52a7bd
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/initializers/object-transform-test.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 ObjectTransformInitializer from '../../../initializers/object-transform';
+import { module, test } from 'qunit';
+
+let application;
+
+module('Unit | Initializer | object transform', {
+  beforeEach() {
+    Ember.run(function() {
+      application = Ember.Application.create();
+      application.deferReadiness();
+    });
+  }
+});
+
+test('it works', function(assert) {
+  ObjectTransformInitializer.initialize(application);
+
+  assert.ok(true);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/1e5a3154/tez-ui2/src/main/webapp/tests/unit/services/hosts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/services/hosts-test.js b/tez-ui2/src/main/webapp/tests/unit/services/hosts-test.js
new file mode 100644
index 0000000..8136ae4
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/services/hosts-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('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('Test creation', function(assert) {
+  let service = this.subject();
+  assert.ok(service);
+});
+
+test('Test correctProtocol', function(assert) {
+  let service = this.subject();
+
+  //No correction
+  assert.equal(service.correctProtocol("http://localhost:8088"), "http://localhost:8088");
+
+  // Correction
+  assert.equal(service.correctProtocol("localhost:8088"), "http://localhost:8088");
+  assert.equal(service.correctProtocol("https://localhost:8088"), "http://localhost:8088");
+  assert.equal(service.correctProtocol("file://localhost:8088"), "http://localhost:8088");
+});


[05/45] tez git commit: TEZ-3022. Tez UI 2: Add serializer & adapter for timeline server (sree)

Posted by sr...@apache.org.
TEZ-3022. Tez UI 2: Add serializer & adapter for timeline server (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/e2fbcc4c
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/e2fbcc4c
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/e2fbcc4c

Branch: refs/heads/TEZ-2980
Commit: e2fbcc4c24baf043a43b71bce9037da12dff534d
Parents: a0dd70c
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Tue Jan 5 00:07:05 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:31:59 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |  1 +
 .../src/main/webapp/app/adapters/timeline.js    | 23 +++++++++++
 tez-ui2/src/main/webapp/app/routes/abstract.js  |  1 +
 .../src/main/webapp/app/serializers/timeline.js | 25 ++++++++++++
 .../src/main/webapp/config/default-app-conf.js  | 12 ++++++
 .../webapp/tests/unit/adapters/timeline-test.js | 31 +++++++++++++++
 .../tests/unit/serializers/timeline-test.js     | 40 ++++++++++++++++++++
 7 files changed, 133 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/e2fbcc4c/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index 0eb31bf..c8f9d0f 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -9,3 +9,4 @@ ALL CHANGES:
   TEZ-2985. Tez UI 2: Create loader and entity classes
   TEZ-3021. Tez UI 2: Add env service & initializer
   TEZ-3023. Tez UI 2: Abstract adapter and route
+  TEZ-3022. Tez UI 2: Add serializer & adapter for timeline server

http://git-wip-us.apache.org/repos/asf/tez/blob/e2fbcc4c/tez-ui2/src/main/webapp/app/adapters/timeline.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/timeline.js b/tez-ui2/src/main/webapp/app/adapters/timeline.js
new file mode 100644
index 0000000..aba7e1e
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/adapters/timeline.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.
+ */
+
+import AbstractAdapter from './abstract';
+
+export default AbstractAdapter.extend({
+  serverName: "timeline",
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/e2fbcc4c/tez-ui2/src/main/webapp/app/routes/abstract.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/abstract.js b/tez-ui2/src/main/webapp/app/routes/abstract.js
index d0f3c3d..3191762 100644
--- a/tez-ui2/src/main/webapp/app/routes/abstract.js
+++ b/tez-ui2/src/main/webapp/app/routes/abstract.js
@@ -80,6 +80,7 @@ export default Ember.Route.extend({
   setValue: function (value) {
     this.set('loadedValue', value);
     this.set('isLoading', false);
+    return value;
   },
 
   _setControllerModel: Ember.observer("_controller", "loadedValue", function () {

http://git-wip-us.apache.org/repos/asf/tez/blob/e2fbcc4c/tez-ui2/src/main/webapp/app/serializers/timeline.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/timeline.js b/tez-ui2/src/main/webapp/app/serializers/timeline.js
new file mode 100644
index 0000000..8963dc2
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/serializers/timeline.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 LoaderSerializer from './loader';
+
+export default LoaderSerializer.extend({
+  extractArrayPayload: function (payload) {
+    return payload.entities;
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/e2fbcc4c/tez-ui2/src/main/webapp/config/default-app-conf.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/config/default-app-conf.js b/tez-ui2/src/main/webapp/config/default-app-conf.js
index c8f6dd9..51a2e81 100644
--- a/tez-ui2/src/main/webapp/config/default-app-conf.js
+++ b/tez-ui2/src/main/webapp/config/default-app-conf.js
@@ -35,4 +35,16 @@ module.exports = { // Tez App configurations
       cluster: 'cluster'
     },
   },
+  paths: {
+    timeline: {
+      dag: 'TEZ_DAG_ID',
+      vertex: 'TEZ_VERTEX_ID',
+      task: 'TEZ_TASK_ID',
+      taskAttempt: 'TEZ_TASK_ATTEMPT_ID',
+
+      hiveQuery: 'HIVE_QUERY_ID',
+
+      tezApp: 'TEZ_APPLICATION'
+    }
+  }
 };

http://git-wip-us.apache.org/repos/asf/tez/blob/e2fbcc4c/tez-ui2/src/main/webapp/tests/unit/adapters/timeline-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/timeline-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/timeline-test.js
new file mode 100644
index 0000000..9b1a8de
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/adapters/timeline-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('adapter:timeline', 'Unit | Adapter | timeline', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let adapter = this.subject();
+
+  assert.ok(adapter);
+  assert.equal(adapter.serverName, "timeline");
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/e2fbcc4c/tez-ui2/src/main/webapp/tests/unit/serializers/timeline-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/serializers/timeline-test.js b/tez-ui2/src/main/webapp/tests/unit/serializers/timeline-test.js
new file mode 100644
index 0000000..53f0b06
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/serializers/timeline-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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('serializer:timeline', 'Unit | Serializer | timeline', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:timeline']
+});
+
+test('Basic creation test', function(assert) {
+  let serializer = this.subject();
+
+  assert.ok(serializer);
+  assert.ok(serializer.extractArrayPayload);
+});
+
+test('extractArrayPayload test', function(assert) {
+  let serializer = this.subject(),
+      testPayload = {
+        entities: []
+      };
+
+  assert.equal(serializer.extractArrayPayload(testPayload), testPayload.entities);
+});


[43/45] tez git commit: TEZ-3095. Tez UI 2: Tuneups & Improvements (sree)

Posted by sr...@apache.org.
TEZ-3095. Tez UI 2: Tuneups & Improvements (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/69ae05e8
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/69ae05e8
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/69ae05e8

Branch: refs/heads/TEZ-2980
Commit: 69ae05e89f319c0138a110de9d16264e62a41fb7
Parents: 628f8b8
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Thu Feb 4 21:54:53 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:32:53 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |  1 +
 .../webapp/app/components/date-formatter.js     | 30 +++++++
 .../main/webapp/app/components/stats-link.js    | 33 ++++++++
 .../src/main/webapp/app/controllers/app/dags.js |  8 +-
 .../main/webapp/app/controllers/dag/attempts.js |  8 +-
 .../webapp/app/controllers/dag/graphical.js     | 12 +--
 .../webapp/app/controllers/dag/index/index.js   | 58 ++++++++++++-
 .../main/webapp/app/controllers/dag/tasks.js    |  8 +-
 .../main/webapp/app/controllers/dag/vertices.js | 12 +--
 tez-ui2/src/main/webapp/app/controllers/dags.js |  8 +-
 .../src/main/webapp/app/controllers/table.js    | 32 ++++++-
 .../webapp/app/controllers/task/attempts.js     |  8 +-
 .../webapp/app/controllers/vertex/attempts.js   |  8 +-
 .../main/webapp/app/controllers/vertex/tasks.js |  8 +-
 tez-ui2/src/main/webapp/app/entities/entity.js  |  4 +-
 tez-ui2/src/main/webapp/app/index.html          |  2 +-
 tez-ui2/src/main/webapp/app/models/task.js      |  2 +
 tez-ui2/src/main/webapp/app/models/vertex-am.js |  2 +-
 tez-ui2/src/main/webapp/app/models/vertex.js    | 10 +--
 .../src/main/webapp/app/routes/am-pollster.js   |  2 +-
 .../src/main/webapp/app/routes/application.js   |  6 ++
 tez-ui2/src/main/webapp/app/serializers/task.js |  2 +
 .../main/webapp/app/serializers/vertex-am.js    |  2 +-
 .../src/main/webapp/app/serializers/vertex.js   |  2 +-
 tez-ui2/src/main/webapp/app/styles/app.less     |  1 +
 .../main/webapp/app/styles/column-selector.less |  2 +-
 .../main/webapp/app/styles/date-formatter.less  | 21 +++++
 .../main/webapp/app/styles/details-page.less    |  1 +
 .../src/main/webapp/app/templates/app/index.hbs |  7 +-
 .../main/webapp/app/templates/attempt/index.hbs |  4 +-
 .../app/templates/components/date-formatter.hbs | 19 +++++
 .../app/templates/components/stats-link.hbs     | 25 ++++++
 .../app/templates/components/tab-n-refresh.hbs  |  2 +-
 .../src/main/webapp/app/templates/dag/index.hbs |  8 +-
 .../webapp/app/templates/dag/index/index.hbs    | 42 +++++++++
 .../main/webapp/app/templates/simple-modal.hbs  |  2 +
 .../main/webapp/app/templates/task/index.hbs    | 17 +++-
 .../main/webapp/app/templates/vertex/index.hbs  | 89 ++++++--------------
 tez-ui2/src/main/webapp/package.json            |  2 +-
 .../components/date-formatter-test.js           | 40 +++++++++
 .../integration/components/stats-link-test.js   | 38 +++++++++
 .../tests/unit/controllers/app/dags-test.js     |  1 +
 .../tests/unit/controllers/dag/attempts-test.js |  1 +
 .../unit/controllers/dag/graphical-test.js      |  1 +
 .../unit/controllers/dag/index/index-test.js    |  1 +
 .../tests/unit/controllers/dag/tasks-test.js    |  1 +
 .../tests/unit/controllers/dag/vertices-test.js |  1 +
 .../webapp/tests/unit/controllers/dags-test.js  |  1 +
 .../tests/unit/controllers/multi-table-test.js  |  1 +
 .../webapp/tests/unit/controllers/table-test.js |  1 +
 .../unit/controllers/task/attempts-test.js      |  1 +
 .../unit/controllers/vertex/attempts-test.js    |  1 +
 .../tests/unit/controllers/vertex/tasks-test.js |  1 +
 .../webapp/tests/unit/models/vertex-test.js     |  2 +-
 54 files changed, 449 insertions(+), 153 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index bc74ffd..ec8bc05 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -34,3 +34,4 @@ ALL CHANGES:
   TEZ-3084. Tez UI 2: Display caller type and info
   TEZ-3080. Tez UI 2: Ensure UI 2 is in-line with UI 1
   TEZ-3092. Tez UI 2: Tuneups & Improvements
+  TEZ-3095. Tez UI 2: Tuneups & Improvements

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/components/date-formatter.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/components/date-formatter.js b/tez-ui2/src/main/webapp/app/components/date-formatter.js
new file mode 100644
index 0000000..da21383
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/components/date-formatter.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';
+
+export default Ember.Component.extend({
+
+  classNames: ["date-formatter"],
+
+  content: null,
+
+  env: Ember.inject.service('env'),
+  timeZone: Ember.computed.oneWay('env.app.timeZone'),
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/components/stats-link.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/components/stats-link.js b/tez-ui2/src/main/webapp/app/components/stats-link.js
new file mode 100644
index 0000000..0fb56df
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/components/stats-link.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.Component.extend({
+  value: null,
+  routeName: null,
+  statsType: null,
+
+  searchText: Ember.computed.oneWay("statsType"),
+  _statsType: Ember.computed("statsType", function () {
+    var type = this.get("statsType");
+    if(type) {
+      return Ember.String.capitalize(type.toLowerCase());
+    }
+  })
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/controllers/app/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/app/dags.js b/tez-ui2/src/main/webapp/app/controllers/app/dags.js
index 6510e93..e0c5e68 100644
--- a/tez-ui2/src/main/webapp/app/controllers/app/dags.js
+++ b/tez-ui2/src/main/webapp/app/controllers/app/dags.js
@@ -61,16 +61,12 @@ export default MultiTableController.extend({
     id: 'startTime',
     headerTitle: 'Start Time',
     contentPath: 'startTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'endTime',
     headerTitle: 'End Time',
     contentPath: 'endTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'duration',
     headerTitle: 'Duration',

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js b/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
index 94bca3e..71559f8 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
@@ -77,16 +77,12 @@ export default MultiTableController.extend({
     id: 'startTime',
     headerTitle: 'Start Time',
     contentPath: 'startTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'endTime',
     headerTitle: 'End Time',
     contentPath: 'endTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'duration',
     headerTitle: 'Duration',

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/controllers/dag/graphical.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/graphical.js b/tez-ui2/src/main/webapp/app/controllers/dag/graphical.js
index a6e42c3..86d534a 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag/graphical.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/graphical.js
@@ -62,16 +62,12 @@ export default MultiTableController.extend({
     id: 'startTime',
     headerTitle: 'Start Time',
     contentPath: 'startTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'endTime',
     headerTitle: 'End Time',
     contentPath: 'endTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'duration',
     headerTitle: 'Duration',
@@ -83,9 +79,7 @@ export default MultiTableController.extend({
     id: 'firstTaskStartTime',
     headerTitle: 'First Task Start Time',
     contentPath: 'firstTaskStartTime',
-    cellDefinition: {
-     type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'totalTasks',
     headerTitle: 'Tasks',

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/controllers/dag/index/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/index/index.js b/tez-ui2/src/main/webapp/app/controllers/dag/index/index.js
index 8dc27a5..2937a2b 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag/index/index.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/index/index.js
@@ -16,6 +16,8 @@
  * limitations under the License.
  */
 
+import Ember from 'ember';
+
 import MultiTableController from '../../multi-table';
 import ColumnDefinition from 'em-table/utils/column-definition';
 
@@ -50,9 +52,9 @@ export default MultiTableController.extend({
     contentPath: 'totalTasks',
     observePath: true
   },{
-    id: 'successfulTasks',
-    headerTitle: 'Successful Tasks',
-    contentPath: 'successfulTasks',
+    id: 'succeededTasks',
+    headerTitle: 'Succeeded Tasks',
+    contentPath: 'succeededTasks',
     observePath: true
   },{
     id: 'runningTasks',
@@ -74,6 +76,54 @@ export default MultiTableController.extend({
     headerTitle: 'Killed Task Attempts',
     contentPath: 'killedTaskAttempts',
     observePath: true
-  }])
+  }]),
+
+  stats: Ember.computed("model.@each.loadTime", function () {
+    var vertices = this.get("model");
+
+    if(vertices) {
+      let succeededVertices = 0,
+          succeededTasks = 0,
+          totalTasks =0,
+
+          failedTasks = 0,
+          killedTasks = 0,
+          failedTaskAttempts = 0,
+          killedTaskAttempts = 0;
+
+      vertices.forEach(function (vertex) {
+        if(vertex.get("status") === "SUCCEEDED") {
+          succeededVertices++;
+        }
+
+        succeededTasks += vertex.get("succeededTasks");
+        totalTasks += vertex.get("totalTasks");
+
+        failedTasks += vertex.get("failedTasks");
+        killedTasks += vertex.get("killedTasks");
+
+        failedTaskAttempts += vertex.get("failedTaskAttempts");
+        killedTaskAttempts += vertex.get("killedTaskAttempts");
+      });
+
+      return {
+        succeededVertices: succeededVertices,
+        totalVertices: vertices.get("length"),
+
+        succeededTasks: succeededTasks,
+        totalTasks: totalTasks,
+
+        failedTasks: failedTasks,
+        killedTasks: killedTasks,
+
+        failedTaskAttempts: failedTaskAttempts,
+        killedTaskAttempts: killedTaskAttempts
+      };
+    }
+  }),
+
+  beforeSort: function () {
+    return true;
+  }
 
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js b/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
index 58e0163..113d37e 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
@@ -65,16 +65,12 @@ export default MultiTableController.extend({
     id: 'startTime',
     headerTitle: 'Start Time',
     contentPath: 'startTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'endTime',
     headerTitle: 'End Time',
     contentPath: 'endTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'duration',
     headerTitle: 'Duration',

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js b/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
index 1b9f136..f42a667 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
@@ -57,16 +57,12 @@ export default MultiTableController.extend({
     id: 'startTime',
     headerTitle: 'Start Time',
     contentPath: 'startTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'endTime',
     headerTitle: 'End Time',
     contentPath: 'endTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'duration',
     headerTitle: 'Duration',
@@ -78,9 +74,7 @@ export default MultiTableController.extend({
     id: 'firstTaskStartTime',
     headerTitle: 'First Task Start Time',
     contentPath: 'firstTaskStartTime',
-    cellDefinition: {
-     type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'totalTasks',
     headerTitle: 'Tasks',

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/controllers/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dags.js b/tez-ui2/src/main/webapp/app/controllers/dags.js
index 1a760d1..0365987 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dags.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dags.js
@@ -87,16 +87,12 @@ export default TableController.extend({
     id: 'startTime',
     headerTitle: 'Start Time',
     contentPath: 'startTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'endTime',
     headerTitle: 'End Time',
     contentPath: 'endTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'duration',
     headerTitle: 'Duration',

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/controllers/table.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/table.js b/tez-ui2/src/main/webapp/app/controllers/table.js
index 0891e8d..ca2bae8 100644
--- a/tez-ui2/src/main/webapp/app/controllers/table.js
+++ b/tez-ui2/src/main/webapp/app/controllers/table.js
@@ -43,6 +43,8 @@ export default AbstractController.extend({
   columnSelectorTitle: 'Column Selector',
   columnSelectorMessage: "",
 
+  polling: Ember.inject.service("pollster"),
+
   definition: Ember.computed(function () {
     return TableDefinition.create({
       rowCount: this.get("rowCount"),
@@ -69,11 +71,37 @@ export default AbstractController.extend({
     this.set('visibleColumnIDs', visibleColumnIDs);
   })),
 
+  beforeSort: function (columnDefinition) {
+    if(this.get("polling.isReady")) {
+      let columnName = columnDefinition.get("headerTitle");
+      switch(columnDefinition.get("contentPath")) {
+        case "counterGroupsHash":
+          columnName = "Counters";
+          /* falls through */
+        case "status":
+        case "progress":
+          this.send("openModal", {
+            title: "Cannot sort!",
+            content: `Sorting on ${columnName} is disabled for running DAGs!`
+          });
+          return false;
+      }
+    }
+    return true;
+  },
+
   allColumns: Ember.computed("columns", function () {
     var columns = this.get("columns"),
-        counters = this.getCounterColumns();
+        counters = this.getCounterColumns(),
+        beforeSort = this.get("beforeSort").bind(this);
+
+    columns = columns.concat(CounterColumnDefinition.make(counters));
+
+    columns.forEach(function (column) {
+      column.set("beforeSort", beforeSort);
+    });
 
-    return columns.concat(CounterColumnDefinition.make(counters));
+    return columns;
   }),
 
   visibleColumns: Ember.computed('visibleColumnIDs', 'allColumns', function() {

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/controllers/task/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/task/attempts.js b/tez-ui2/src/main/webapp/app/controllers/task/attempts.js
index 472d04f..696b09d 100644
--- a/tez-ui2/src/main/webapp/app/controllers/task/attempts.js
+++ b/tez-ui2/src/main/webapp/app/controllers/task/attempts.js
@@ -55,16 +55,12 @@ export default MultiTableController.extend(AutoCounterColumn, {
     id: 'startTime',
     headerTitle: 'Start Time',
     contentPath: 'startTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'endTime',
     headerTitle: 'End Time',
     contentPath: 'endTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'duration',
     headerTitle: 'Duration',

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js b/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js
index 34a067f..9806458 100644
--- a/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js
+++ b/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js
@@ -67,16 +67,12 @@ export default MultiTableController.extend(AutoCounterColumn, {
     id: 'startTime',
     headerTitle: 'Start Time',
     contentPath: 'startTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'endTime',
     headerTitle: 'End Time',
     contentPath: 'endTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'duration',
     headerTitle: 'Duration',

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.js b/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.js
index ea02d61..ed26173 100644
--- a/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.js
+++ b/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.js
@@ -55,16 +55,12 @@ export default MultiTableController.extend(AutoCounterColumn, {
     id: 'startTime',
     headerTitle: 'Start Time',
     contentPath: 'startTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'endTime',
     headerTitle: 'End Time',
     contentPath: 'endTime',
-    cellDefinition: {
-      type: 'date'
-    }
+    cellComponentName: 'date-formatter',
   },{
     id: 'duration',
     headerTitle: 'Duration',

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/entities/entity.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/entities/entity.js b/tez-ui2/src/main/webapp/app/entities/entity.js
index f763dcf..8280558 100644
--- a/tez-ui2/src/main/webapp/app/entities/entity.js
+++ b/tez-ui2/src/main/webapp/app/entities/entity.js
@@ -98,15 +98,15 @@ var Entity = Ember.Object.extend(NameMixin, {
     );
 
     needLoader.then(function (model) {
-      parentModel.refreshLoadTime();
       parentModel.set(needOptions.name, model);
+      parentModel.refreshLoadTime();
       return model;
     });
 
     if(needOptions.silent) {
       needLoader = needLoader.catch(function () {
-        parentModel.refreshLoadTime();
         parentModel.set(needOptions.name, null);
+        parentModel.refreshLoadTime();
       });
     }
 

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/index.html
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/index.html b/tez-ui2/src/main/webapp/app/index.html
index 3f82152..757d663 100644
--- a/tez-ui2/src/main/webapp/app/index.html
+++ b/tez-ui2/src/main/webapp/app/index.html
@@ -37,7 +37,7 @@
   <body>
     {{content-for 'body'}}
 
-    <script src="config/configs.env"></script>
+    <script src="config/configs.env" integrity=""></script>
 
     <script src="assets/vendor.js"></script>
     <script src="assets/tez-ui.js"></script>

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/models/task.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/task.js b/tez-ui2/src/main/webapp/app/models/task.js
index 4db732e..b2e7f71 100644
--- a/tez-ui2/src/main/webapp/app/models/task.js
+++ b/tez-ui2/src/main/webapp/app/models/task.js
@@ -61,4 +61,6 @@ export default AMTimelineModel.extend({
 
   dagID: DS.attr('string'),
   dag: DS.attr('object'), // Auto-loaded by need
+
+  failedTaskAttempts: DS.attr('number'),
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/models/vertex-am.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/vertex-am.js b/tez-ui2/src/main/webapp/app/models/vertex-am.js
index 54339b2..69d2346 100644
--- a/tez-ui2/src/main/webapp/app/models/vertex-am.js
+++ b/tez-ui2/src/main/webapp/app/models/vertex-am.js
@@ -23,7 +23,7 @@ import AMModel from './am';
 export default AMModel.extend({
 
   totalTasks: DS.attr("number"),
-  successfulTasks: DS.attr("number"),
+  succeededTasks: DS.attr("number"),
   runningTasks: DS.attr("number"),
   pendingTasks: DS.attr("number"),
   failedTaskAttempts: DS.attr("number"),

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/models/vertex.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/vertex.js b/tez-ui2/src/main/webapp/app/models/vertex.js
index 1f4365b..647241f 100644
--- a/tez-ui2/src/main/webapp/app/models/vertex.js
+++ b/tez-ui2/src/main/webapp/app/models/vertex.js
@@ -64,13 +64,13 @@ export default AMTimelineModel.extend({
 
   totalTasks: DS.attr('number'),
   _failedTasks: DS.attr('number'),
-  _successfulTasks: DS.attr('number'),
+  _succeededTasks: DS.attr('number'),
   _killedTasks: DS.attr('number'),
   failedTasks: Ember.computed("am.failedTasks", "_failedTasks",
     valueComputerFactory("am.failedTasks", "_failedTasks")
   ),
-  successfulTasks: Ember.computed("am.successfulTasks", "_successfulTasks",
-    valueComputerFactory("am.successfulTasks", "_successfulTasks")
+  succeededTasks: Ember.computed("am.succeededTasks", "_succeededTasks",
+    valueComputerFactory("am.succeededTasks", "_succeededTasks")
   ),
   killedTasks: Ember.computed("am.killedTasks", "_killedTasks",
     valueComputerFactory("am.killedTasks", "_killedTasks")
@@ -83,12 +83,12 @@ export default AMTimelineModel.extend({
     }
     return  runningTasks;
   }),
-  pendingTasks: Ember.computed("totalTasks", "successfulTasks", "runningTasks", function () {
+  pendingTasks: Ember.computed("totalTasks", "succeededTasks", "runningTasks", function () {
     var pendingTasks = null,
         runningTasks = this.get("runningTasks"),
         totalTasks = this.get("totalTasks");
     if(totalTasks!== null && runningTasks !== null) {
-      pendingTasks = totalTasks - this.get("successfulTasks") - runningTasks;
+      pendingTasks = totalTasks - this.get("succeededTasks") - runningTasks;
     }
     return pendingTasks;
   }),

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/routes/am-pollster.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/am-pollster.js b/tez-ui2/src/main/webapp/app/routes/am-pollster.js
index 6752ffd..35d6611 100644
--- a/tez-ui2/src/main/webapp/app/routes/am-pollster.js
+++ b/tez-ui2/src/main/webapp/app/routes/am-pollster.js
@@ -51,7 +51,7 @@ export default PollsterRoute.extend({
       }
     }, function (error) {
       that.send("error", error);
-      Ember.run.later(that, "reload", this.get("polling.interval") * 3);
+      Ember.run.later(that, "reload", that.get("polling.interval") * 3);
     });
   },
 

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/routes/application.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/application.js b/tez-ui2/src/main/webapp/app/routes/application.js
index 99bed25..039e329 100644
--- a/tez-ui2/src/main/webapp/app/routes/application.js
+++ b/tez-ui2/src/main/webapp/app/routes/application.js
@@ -45,6 +45,12 @@ export default Ember.Route.extend({
     // Modal window actions
     openModal: function (componentName, options) {
       options = options || {};
+
+      if(typeof componentName === "object") {
+        options = componentName;
+        componentName = null;
+      }
+
       this.render(options.modalName || "simple-modal", {
         into: 'application',
         outlet: 'modal',

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/serializers/task.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/task.js b/tez-ui2/src/main/webapp/app/serializers/task.js
index 7918e89..3c57be2 100644
--- a/tez-ui2/src/main/webapp/app/serializers/task.js
+++ b/tez-ui2/src/main/webapp/app/serializers/task.js
@@ -22,5 +22,7 @@ export default TimelineSerializer.extend({
   maps: {
     vertexID: 'primaryfilters.TEZ_VERTEX_ID.0',
     dagID: 'primaryfilters.TEZ_DAG_ID.0',
+
+    failedTaskAttempts: 'otherinfo.numFailedTaskAttempts'
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/serializers/vertex-am.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/vertex-am.js b/tez-ui2/src/main/webapp/app/serializers/vertex-am.js
index e3b7eaf..ba160d2 100644
--- a/tez-ui2/src/main/webapp/app/serializers/vertex-am.js
+++ b/tez-ui2/src/main/webapp/app/serializers/vertex-am.js
@@ -22,7 +22,7 @@ export default AMSerializer.extend({
   payloadNamespace: "vertices",
 
   maps: {
-    successfulTasks: "succeededTasks",
+    succeededTasks: "succeededTasks",
     runningTasks: "runningTasks",
     failedTaskAttempts: "failedTaskAttempts",
     killedTaskAttempts: "killedTaskAttempts",

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/serializers/vertex.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/vertex.js b/tez-ui2/src/main/webapp/app/serializers/vertex.js
index bf074f1..eac6808 100644
--- a/tez-ui2/src/main/webapp/app/serializers/vertex.js
+++ b/tez-ui2/src/main/webapp/app/serializers/vertex.js
@@ -34,7 +34,7 @@ export default TimelineSerializer.extend({
 
     totalTasks: 'otherinfo.numTasks',
     _failedTasks: 'otherinfo.numFailedTasks',
-    _successfulTasks: 'otherinfo.numSucceededTasks',
+    _succeededTasks: 'otherinfo.numSucceededTasks',
     _killedTasks: 'otherinfo.numKilledTasks',
 
     _failedTaskAttempts: 'otherinfo.numFailedTaskAttempts',

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/styles/app.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/app.less b/tez-ui2/src/main/webapp/app/styles/app.less
index a832446..88dc47a 100644
--- a/tez-ui2/src/main/webapp/app/styles/app.less
+++ b/tez-ui2/src/main/webapp/app/styles/app.less
@@ -28,6 +28,7 @@
 @import "table-controls";
 @import "error-bar";
 @import "caller-info";
+@import "date-formatter";
 
 // Modals
 @import "column-selector";

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/styles/column-selector.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/column-selector.less b/tez-ui2/src/main/webapp/app/styles/column-selector.less
index c83bdde..eb61128 100644
--- a/tez-ui2/src/main/webapp/app/styles/column-selector.less
+++ b/tez-ui2/src/main/webapp/app/styles/column-selector.less
@@ -40,7 +40,7 @@
     .options {
       .force-scrollbar;
 
-      max-height: 500px;
+      max-height: 450px;
       overflow: auto;
     }
 

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/styles/date-formatter.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/date-formatter.less b/tez-ui2/src/main/webapp/app/styles/date-formatter.less
new file mode 100644
index 0000000..a817bec
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/styles/date-formatter.less
@@ -0,0 +1,21 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+.date-formatter {
+  display: inline;
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/styles/details-page.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/details-page.less b/tez-ui2/src/main/webapp/app/styles/details-page.less
index b3b1a16..dccec06 100644
--- a/tez-ui2/src/main/webapp/app/styles/details-page.less
+++ b/tez-ui2/src/main/webapp/app/styles/details-page.less
@@ -20,6 +20,7 @@
 
 .detail-list {
   display: inline-block;
+  vertical-align: top;
 
   margin: 0 10px 10px 0;
 

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/templates/app/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/app/index.hbs b/tez-ui2/src/main/webapp/app/templates/app/index.hbs
index feaee3a..bf77bf1 100644
--- a/tez-ui2/src/main/webapp/app/templates/app/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/app/index.hbs
@@ -35,11 +35,11 @@
       </tr>
       <tr>
         <td>Start Time</td>
-        <td>{{txt model.app.startTime type="date"}}</td>
+        <td>{{date-formatter content=model.startTime}}</td>
       </tr>
       <tr>
         <td>End Time</td>
-        <td>{{txt model.app.endTime type="date"}}</td>
+        <td>{{date-formatter content=model.endTime}}</td>
       </tr>
       <tr>
         <td>Duration</td>
@@ -47,6 +47,7 @@
       </tr>
       </tbody>
     </table>
+
     <table class='detail-list'>
       <thead>
       <tr>
@@ -76,8 +77,8 @@
       </tr>
       </tbody>
     </table>
-    <br/>
   {{/if}}
+
   <table class='detail-list'>
     <thead>
       <tr>

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs b/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs
index a8be79f..e652cde 100644
--- a/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs
@@ -50,11 +50,11 @@
       </tr>
       <tr>
         <td>Start Time</td>
-        <td>{{txt model.startTime type="date"}}</td>
+        <td>{{date-formatter content=model.startTime}}</td>
       </tr>
       <tr>
         <td>End Time</td>
-        <td>{{txt model.endTime type="date"}}</td>
+        <td>{{date-formatter content=model.endTime}}</td>
       </tr>
       <tr>
         <td>Duration</td>

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/templates/components/date-formatter.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/components/date-formatter.hbs b/tez-ui2/src/main/webapp/app/templates/components/date-formatter.hbs
new file mode 100644
index 0000000..0f740cb
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/components/date-formatter.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.
+}}
+
+{{txt content type="date" timeZone=timeZone}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/templates/components/stats-link.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/components/stats-link.hbs b/tez-ui2/src/main/webapp/app/templates/components/stats-link.hbs
new file mode 100644
index 0000000..0d91ae9
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/components/stats-link.hbs
@@ -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.
+}}
+
+{{#if value}}
+  {{#link-to routeName (query-params searchText=searchText)}}
+    {{txt value type="number"}} {{_statsType}}
+  {{/link-to}}
+{{else}}
+  {{txt value type="number"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs b/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs
index 9d80c6a..e489f00 100644
--- a/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs
@@ -32,7 +32,7 @@
         <br/>
       </span>
       {{#if loadTime}}
-        Last refreshed at <b>{{txt loadTime type="date"}}</b>
+        Last refreshed at <b>{{date-formatter content=loadTime}}</b>
       {{else}}
         Load time not available!
       {{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/index.hbs b/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
index 0003a64..9bc6a80 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
@@ -42,6 +42,10 @@
         <td>{{model.entityID}}</td>
       </tr>
       <tr>
+        <td>Name</td>
+        <td>{{model.name}}</td>
+      </tr>
+      <tr>
         <td>Submitter</td>
         <td>{{model.submitter}}</td>
       </tr>
@@ -55,11 +59,11 @@
       </tr>
       <tr>
         <td>Start Time</td>
-        <td>{{txt model.startTime type="date"}}</td>
+        <td>{{date-formatter content=model.startTime}}</td>
       </tr>
       <tr>
         <td>End Time</td>
-        <td>{{txt model.endTime type="date"}}</td>
+        <td>{{date-formatter content=model.endTime}}</td>
       </tr>
       <tr>
         <td>Duration</td>

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/templates/dag/index/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/index/index.hbs b/tez-ui2/src/main/webapp/app/templates/dag/index/index.hbs
index 1321b9f..02c88da 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag/index/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag/index/index.hbs
@@ -17,6 +17,48 @@
 }}
 
 {{#if loaded}}
+  <table class='detail-list'>
+    <thead>
+    <tr>
+      <th colspan=2>Stats</th>
+    </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>Succeeded Vertices</td>
+        <td>{{stats-link value=stats.succeededVertices routeName="dag.vertices" statsType="SUCCEEDED"}}</td>
+      </tr>
+      <tr>
+        <td>Total Vertices</td>
+        <td>{{stats.totalVertices}}</td>
+      </tr>
+      <tr>
+        <td>Succeeded Tasks</td>
+        <td>{{stats-link value=stats.succeededTasks routeName="dag.tasks" statsType="SUCCEEDED"}}</td>
+      </tr>
+      <tr>
+        <td>Total Tasks</td>
+        <td>{{stats.totalTasks}}</td>
+      </tr>
+      <tr>
+        <td>Failed Tasks</td>
+        <td>{{stats-link value=stats.failedTasks routeName="dag.tasks" statsType="FAILED"}}</td>
+      </tr>
+      <tr>
+        <td>Killed Tasks</td>
+        <td>{{stats-link value=stats.killedTasks routeName="dag.tasks" statsType="KILLED"}}</td>
+      </tr>
+      <tr>
+        <td>Failed Task Attempts</td>
+        <td>{{stats-link value=stats.failedTaskAttempts routeName="dag.attempts" statsType="FAILED"}}</td>
+      </tr>
+      <tr>
+        <td>Killed Task Attempts</td>
+        <td>{{stats-link value=stats.killedTaskAttempts routeName="dag.attempts" statsType="KILLED"}}</td>
+      </tr>
+    </tbody>
+  </table>
+
   {{em-table
   columns=visibleColumns
   rows=model

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/templates/simple-modal.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/simple-modal.hbs b/tez-ui2/src/main/webapp/app/templates/simple-modal.hbs
index 59b3aaa..71fdb90 100644
--- a/tez-ui2/src/main/webapp/app/templates/simple-modal.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/simple-modal.hbs
@@ -27,6 +27,8 @@
       </div>
       {{#if model.componentName}}
         {{component model.componentName content=model.content targetObject=model.targetObject}}
+      {{else}}
+        <div class="modal-body">{{model.content}}</div>
       {{/if}}
     </div>
   </div>

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/templates/task/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/task/index.hbs b/tez-ui2/src/main/webapp/app/templates/task/index.hbs
index c4b0a5a..3bcecad 100644
--- a/tez-ui2/src/main/webapp/app/templates/task/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/task/index.hbs
@@ -42,11 +42,11 @@
       </tr>
       <tr>
         <td>Start Time</td>
-        <td>{{txt model.startTime type="date"}}</td>
+        <td>{{date-formatter content=model.startTime}}</td>
       </tr>
       <tr>
         <td>End Time</td>
-        <td>{{txt model.endTime type="date"}}</td>
+        <td>{{date-formatter content=model.endTime}}</td>
       </tr>
       <tr>
         <td>Duration</td>
@@ -54,6 +54,19 @@
       </tr>
     </tbody>
   </table>
+  <table class='detail-list'>
+    <thead>
+    <tr>
+      <th colspan=2>Stats</th>
+    </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>Failed Task Attempts</td>
+        <td>{{stats-link value=model.failedTaskAttempts routeName="vertex.attempts" statsType="FAILED"}}</td>
+      </tr>
+    </tbody>
+  </table>
 
   {{#if model.diagnostics}}
     <div class="panel panel-danger">

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs b/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs
index cac5c92..2955882 100644
--- a/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs
@@ -20,7 +20,7 @@
   <table class='detail-list'>
     <thead>
       <tr>
-        <th colspan=2>Description</th>
+        <th colspan=2>Details</th>
       </tr>
     </thead>
     <tbody>
@@ -36,18 +36,6 @@
         <td>Processor Class</td>
         <td>{{model.processorClassName}}</td>
       </tr>
-    </tbody>
-  </table>
-
-  <br/>
-
-  <table class='detail-list'>
-    <thead>
-      <tr>
-        <th colspan=2>Details</th>
-      </tr>
-    </thead>
-    <tbody>
       <tr>
         <td>Status</td>
         <td>{{em-table-status-cell content=model.status}}</td>
@@ -58,82 +46,59 @@
       </tr>
       <tr>
         <td>Start Time</td>
-        <td>{{txt model.startTime type="date"}}</td>
+        <td>{{date-formatter content=model.startTime}}</td>
       </tr>
       <tr>
         <td>End Time</td>
-        <td>{{txt model.endTime type="date"}}</td>
+        <td>{{date-formatter content=model.endTime}}</td>
       </tr>
       <tr>
         <td>Duration</td>
         <td>{{txt model.duration type="duration"}}</td>
       </tr>
-      <tr>
-        <td>First Task Start Time</td>
-        <td>
-          {{txt model.firstTaskStartTime type="date"}}
-          {{#if firstTasksToStart}}
-            [{{em-table-linked-cell content=firstTasksToStart}}]
-          {{/if}}
-        </td>
-      </tr>
-      <tr>
-        <td>Last Task Finish Time</td>
-        <td>
-          {{txt model.lastTaskFinishTime type="date"}}
-          {{#if lastTasksToFinish}}
-            [{{em-table-linked-cell content=lastTasksToFinish}}]
-          {{/if}}
-        </td>
-      </tr>
     </tbody>
   </table>
 
-  <br/>
-
   <table class='detail-list'>
     <thead>
       <tr>
-        <th colspan=2>Tasks of this Vertex</th>
+        <th colspan=2>Stats</th>
       </tr>
     </thead>
     <tbody>
       <tr>
         <td>Total Tasks</td>
-          <td>
-            <a href="{{pathname}}/tasks">{{txt model.totalTasks type="number"}} Tasks</a>
-          </td>
+        <td>{{txt model.totalTasks type="number"}}</td>
       </tr>
       <tr>
-        <td>Successful Tasks</td>
-        {{#if model.successfulTasks}}
-          <td>
-            <a href="{{pathname}}/tasks?searchText=SUCCEEDED">{{txt model.successfulTasks type="number"}} Succeeded</a>
-          </td>
-        {{else}}
-          <td>{{txt model.successfulTasks type="number"}}</td>
-        {{/if}}
+        <td>Succeeded Tasks</td>
+        <td>{{stats-link value=model.succeededTasks routeName="vertex.tasks" statsType="SUCCEEDED"}}</td>
       </tr>
       <tr>
         <td>Failed Tasks</td>
-        {{#if model.failedTasks}}
-          <td>
-            <a href="{{pathname}}/tasks?searchText=FAILED">{{txt model.failedTasks type="number"}} Failed</a>
-          </td>
-        {{else}}
-          <td>{{txt model.failedTasks type="number"}}</td>
-        {{/if}}
+        <td>{{stats-link value=model.failedTasks routeName="vertex.tasks" statsType="FAILED"}}</td>
       </tr>
       <tr>
         <td>Killed Tasks</td>
-        {{#if model.killedTasks}}
-          <td>
-            <a href="{{pathname}}/tasks?searchText=KILLED">{{txt model.killedTasks type="number"}} Killed</a>
-          </td>
-        {{else}}
-          <td>{{txt model.killedTasks type="number"}}</td>
-        {{/if}}
-
+        <td>{{stats-link value=model.killedTasks routeName="vertex.tasks" statsType="KILLED"}}</td>
+      </tr>
+      <tr>
+        <td>First Task Start Time</td>
+        <td>
+          {{date-formatter content=model.firstTaskStartTime}}
+          {{#if firstTasksToStart}}
+            [{{em-table-linked-cell content=firstTasksToStart}}]
+          {{/if}}
+        </td>
+      </tr>
+      <tr>
+        <td>Last Task Finish Time</td>
+        <td>
+          {{date-formatter content=model.lastTaskFinishTime}}
+          {{#if lastTasksToFinish}}
+            [{{em-table-linked-cell content=lastTasksToFinish}}]
+          {{/if}}
+        </td>
       </tr>
       <tr>
         <td>Average Duration</td>

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/package.json
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/package.json b/tez-ui2/src/main/webapp/package.json
index 8fde220..db2cc77 100644
--- a/tez-ui2/src/main/webapp/package.json
+++ b/tez-ui2/src/main/webapp/package.json
@@ -53,7 +53,7 @@
   "dependencies": {
     "broccoli-funnel": "^1.0.1",
     "em-helpers": "0.5.8",
-    "em-table": "0.3.9",
+    "em-table": "0.3.10",
     "ember-cli-htmlbars": "^1.0.1",
     "ember-cli-less": "^1.4.0",
     "phantomjs": "^1.9.19"

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/tests/integration/components/date-formatter-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/integration/components/date-formatter-test.js b/tez-ui2/src/main/webapp/tests/integration/components/date-formatter-test.js
new file mode 100644
index 0000000..dad41f9
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/integration/components/date-formatter-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 { moduleForComponent, test } from 'ember-qunit';
+import hbs from 'htmlbars-inline-precompile';
+
+moduleForComponent('date-formatter', 'Integration | Component | em table date-formatter cell', {
+  integration: true
+});
+
+test('Basic creation test', function(assert) {
+
+  this.render(hbs`{{date-formatter}}`);
+
+  assert.equal(this.$().text().trim(), 'Not Available!');
+
+  // Template block usage:" + EOL +
+  this.render(hbs`
+    {{#date-formatter}}
+      template block text
+    {{/date-formatter}}
+  `);
+
+  assert.equal(this.$().text().trim(), 'Not Available!');
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/tests/integration/components/stats-link-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/integration/components/stats-link-test.js b/tez-ui2/src/main/webapp/tests/integration/components/stats-link-test.js
new file mode 100644
index 0000000..ad2dc7b
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/integration/components/stats-link-test.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 { moduleForComponent, test } from 'ember-qunit';
+import hbs from 'htmlbars-inline-precompile';
+
+moduleForComponent('stats-link', 'Integration | Component | stats link', {
+  integration: true
+});
+
+test('Basic creation test', function(assert) {
+
+  this.render(hbs`{{stats-link}}`);
+  assert.equal(this.$().text().trim(), 'Not Available!');
+
+  // Template block usage:" + EOL +
+  this.render(hbs`
+    {{#stats-link}}
+      template block text
+    {{/stats-link}}
+  `);
+  assert.equal(this.$().text().trim(), 'Not Available!');
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js
index 402b629..53cf7f2 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js
@@ -28,6 +28,7 @@ moduleFor('controller:app/dags', 'Unit | Controller | app/dags', {
 test('Basic creation test', function(assert) {
   let controller = this.subject({
     send: Ember.K,
+    beforeSort: {bind: Ember.K},
     initVisibleColumns: Ember.K,
     getCounterColumns: Ember.K
   });

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js
index f0aeeb9..f1d3d01 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js
@@ -28,6 +28,7 @@ moduleFor('controller:dag/attempts', 'Unit | Controller | dag/attempts', {
 test('Basic creation test', function(assert) {
   let controller = this.subject({
     send: Ember.K,
+    beforeSort: {bind: Ember.K},
     initVisibleColumns: Ember.K,
     getCounterColumns: function () {
       return [];

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/tests/unit/controllers/dag/graphical-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/graphical-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/graphical-test.js
index cb9ab66..6b7ecb6 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/graphical-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/graphical-test.js
@@ -28,6 +28,7 @@ moduleFor('controller:dag/graphical', 'Unit | Controller | dag/graphical', {
 test('Basic creation test', function(assert) {
   let controller = this.subject({
     send: Ember.K,
+    beforeSort: {bind: Ember.K},
     initVisibleColumns: Ember.K,
     getCounterColumns: function () {
       return [];

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/tests/unit/controllers/dag/index/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/index/index-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/index/index-test.js
index 956eee3..166ee6b 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/index/index-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/index/index-test.js
@@ -28,6 +28,7 @@ moduleFor('controller:dag/index/index', 'Unit | Controller | dag/index/index', {
 test('Basic creation test', function(assert) {
   let controller = this.subject({
     send: Ember.K,
+    beforeSort: {bind: Ember.K},
     initVisibleColumns: Ember.K,
     getCounterColumns: function () {
       return [];

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js
index 474c61a..a288244 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js
@@ -28,6 +28,7 @@ moduleFor('controller:dag/tasks', 'Unit | Controller | dag/tasks', {
 test('Basic creation test', function(assert) {
   let controller = this.subject({
     send: Ember.K,
+    beforeSort: {bind: Ember.K},
     initVisibleColumns: Ember.K,
     getCounterColumns: function () {
       return [];

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
index d0b32f3..fa7bec0 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
@@ -28,6 +28,7 @@ moduleFor('controller:dag/vertices', 'Unit | Controller | dag/vertices', {
 test('Basic creation test', function(assert) {
   let controller = this.subject({
     send: Ember.K,
+    beforeSort: {bind: Ember.K},
     initVisibleColumns: Ember.K,
     getCounterColumns: function () {
       return [];

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js
index 996dd39..98f2815 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js
@@ -30,6 +30,7 @@ test('Basic creation test', function(assert) {
 
   let controller = this.subject({
     initVisibleColumns: Ember.K,
+    beforeSort: {bind: Ember.K},
     send: function (name, query) {
       assert.equal(name, "setBreadcrumbs");
       assert.ok(query);

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/tests/unit/controllers/multi-table-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/multi-table-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/multi-table-test.js
index d4ab10f..27e32fc 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/multi-table-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/multi-table-test.js
@@ -27,6 +27,7 @@ moduleFor('controller:multi-table', 'Unit | Controller | multi table', {
 test('Basic creation test', function(assert) {
   let controller = this.subject({
     send: Ember.K,
+    beforeSort: {bind: Ember.K},
     initVisibleColumns: Ember.K,
     localStorage: Ember.Object.create(),
     getCounterColumns: function () {

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/tests/unit/controllers/table-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/table-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/table-test.js
index 360b6a9..110fec2 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/table-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/table-test.js
@@ -48,6 +48,7 @@ test('Basic creation test', function(assert) {
   assert.ok(controller.storageID);
   assert.ok(controller.initVisibleColumns);
 
+  assert.ok(controller.beforeSort);
   assert.ok(controller.columns);
   assert.ok(controller.allColumns);
   assert.ok(controller.visibleColumns);

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.js
index b2006de..4db8dac 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.js
@@ -28,6 +28,7 @@ moduleFor('controller:task/attempts', 'Unit | Controller | task/attempts', {
 test('Basic creation test', function(assert) {
   let controller = this.subject({
     send: Ember.K,
+    beforeSort: {bind: Ember.K},
     initVisibleColumns: Ember.K,
     getCounterColumns: function () {
       return [];

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/attempts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/attempts-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/attempts-test.js
index eb68055..142fa58 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/attempts-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/attempts-test.js
@@ -28,6 +28,7 @@ moduleFor('controller:vertex/attempts', 'Unit | Controller | vertex/attempts', {
 test('Basic creation test', function(assert) {
   let controller = this.subject({
     send: Ember.K,
+    beforeSort: {bind: Ember.K},
     initVisibleColumns: Ember.K,
     getCounterColumns: function () {
       return [];

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/tasks-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/tasks-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/tasks-test.js
index 9aae299..6949ba5 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/tasks-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/tasks-test.js
@@ -28,6 +28,7 @@ moduleFor('controller:vertex/tasks', 'Unit | Controller | vertex/tasks', {
 test('Basic creation test', function(assert) {
   let controller = this.subject({
     send: Ember.K,
+    beforeSort: {bind: Ember.K},
     initVisibleColumns: Ember.K,
     getCounterColumns: function () {
       return [];

http://git-wip-us.apache.org/repos/asf/tez/blob/69ae05e8/tez-ui2/src/main/webapp/tests/unit/models/vertex-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/vertex-test.js b/tez-ui2/src/main/webapp/tests/unit/models/vertex-test.js
index 9ca049a..86cd472 100644
--- a/tez-ui2/src/main/webapp/tests/unit/models/vertex-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/models/vertex-test.js
@@ -54,7 +54,7 @@ test('pendingTasks test', function(assert) {
     model.set("totalTasks", null);
     assert.equal(model.get("pendingTasks"), null);
     model.set("totalTasks", 2);
-    model.set("_successfulTasks", 1);
+    model.set("_succeededTasks", 1);
     model.set("status", "SUCCEEDED");
     assert.equal(model.get("pendingTasks"), 1);
   });


[19/45] tez git commit: TEZ-3040. Tez UI 2: Create Vertex details page & sub tables (sree)

Posted by sr...@apache.org.
TEZ-3040. Tez UI 2: Create Vertex details page & sub tables (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/68dc2f5d
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/68dc2f5d
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/68dc2f5d

Branch: refs/heads/TEZ-2980
Commit: 68dc2f5de7eba7fbfe5c4403befdf8bfb2418b00
Parents: a1c3622
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Tue Jan 19 00:23:31 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:32:15 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |   1 +
 tez-ui2/src/main/webapp/app/controllers/dag.js  |   4 +-
 .../main/webapp/app/controllers/dag/attempts.js |  12 +-
 .../main/webapp/app/controllers/dag/tasks.js    |  10 +-
 .../main/webapp/app/controllers/dag/vertices.js |  12 ++
 .../src/main/webapp/app/controllers/vertex.js   |  49 +++++++
 .../webapp/app/controllers/vertex/attempts.js   |  77 +++++++++++
 .../main/webapp/app/controllers/vertex/index.js |  22 ++++
 .../main/webapp/app/controllers/vertex/tasks.js |  65 ++++++++++
 tez-ui2/src/main/webapp/app/models/vertex.js    |  20 ++-
 tez-ui2/src/main/webapp/app/router.js           |   4 +
 .../src/main/webapp/app/routes/dag/attempts.js  |   2 +-
 tez-ui2/src/main/webapp/app/routes/vertex.js    |  31 +++++
 .../main/webapp/app/routes/vertex/attempts.js   |  35 +++++
 .../src/main/webapp/app/routes/vertex/index.js  |  33 +++++
 .../src/main/webapp/app/routes/vertex/tasks.js  |  35 +++++
 .../src/main/webapp/app/serializers/vertex.js   |  11 +-
 .../src/main/webapp/app/styles/page-layout.less |   5 +-
 .../src/main/webapp/app/templates/dag/index.hbs |  97 +++++++-------
 .../src/main/webapp/app/templates/vertex.hbs    |  20 +++
 .../webapp/app/templates/vertex/attempts.hbs    |  33 +++++
 .../main/webapp/app/templates/vertex/index.hbs  | 130 +++++++++++++++++++
 .../main/webapp/app/templates/vertex/tasks.hbs  |  33 +++++
 .../tests/unit/controllers/vertex-test.js       |  36 +++++
 .../unit/controllers/vertex/attempts-test.js    |  36 +++++
 .../tests/unit/controllers/vertex/index-test.js |  34 +++++
 .../tests/unit/controllers/vertex/tasks-test.js |  36 +++++
 .../webapp/tests/unit/routes/vertex-test.js     |  32 +++++
 .../tests/unit/routes/vertex/attempts-test.js   |  45 +++++++
 .../tests/unit/routes/vertex/index-test.js      |  45 +++++++
 .../tests/unit/routes/vertex/tasks-test.js      |  45 +++++++
 31 files changed, 987 insertions(+), 63 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/68dc2f5d/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index 372369a..3389c46 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -15,3 +15,4 @@ ALL CHANGES:
   TEZ-2986. Tez UI 2: Implement All DAGs page
   TEZ-3038. Tez UI 2: Create DAG details page
   TEZ-3039. Tez UI 2: Create all sub-pages for DAG
+  TEZ-3040. Tez UI 2: Create Vertex details page & sub tables

http://git-wip-us.apache.org/repos/asf/tez/blob/68dc2f5d/tez-ui2/src/main/webapp/app/controllers/dag.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag.js b/tez-ui2/src/main/webapp/app/controllers/dag.js
index f54d8cf..732a0df 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag.js
@@ -25,7 +25,7 @@ export default AbstractController.extend({
     var name = this.get("model.name");
 
     return [{
-      text: `DAG [${name}]`,
+      text: `DAG [ ${name} ]`,
       routeName: "dag.index",
       model: this.get("model.entityID")
     }];
@@ -41,7 +41,7 @@ export default AbstractController.extend({
     text: "All Tasks",
     routeName: "dag.tasks"
   }, {
-    text: "All Attempts",
+    text: "All Task Attempts",
     routeName: "dag.attempts"
   }]
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/68dc2f5d/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js b/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
index 1ffc00c..c2e3950 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
@@ -21,7 +21,7 @@ import ColumnDefinition from 'em-table/utils/column-definition';
 
 export default TablePageController.extend({
   breadcrumbs: [{
-    text: "All Attempts",
+    text: "All Task Attempts",
     routeName: "dag.attempts",
   }],
 
@@ -36,7 +36,15 @@ export default TablePageController.extend({
   },{
     id: 'vertexName',
     headerTitle: 'Vertex Index',
-    contentPath: 'vertexName'
+    contentPath: 'vertexName',
+    cellComponentName: 'em-table-linked-cell',
+    getCellContent: function (row) {
+      return {
+        routeName: "vertex",
+        model: row.get("vertexID"),
+        text: row.get("vertexName")
+      };
+    }
   },{
     id: 'status',
     headerTitle: 'Status',

http://git-wip-us.apache.org/repos/asf/tez/blob/68dc2f5d/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js b/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
index 7c91deb..4721b81 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
@@ -32,7 +32,15 @@ export default TablePageController.extend({
   },{
     id: 'vertexName',
     headerTitle: 'Vertex Name',
-    contentPath: 'vertexName'
+    contentPath: 'vertexName',
+    cellComponentName: 'em-table-linked-cell',
+    getCellContent: function (row) {
+      return {
+        routeName: "vertex",
+        model: row.get("vertexID"),
+        text: row.get("vertexName")
+      };
+    }
   },{
     id: 'status',
     headerTitle: 'Status',

http://git-wip-us.apache.org/repos/asf/tez/blob/68dc2f5d/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js b/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
index 7bdc229..b20a558 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
@@ -29,6 +29,14 @@ export default TablePageController.extend({
     id: 'name',
     headerTitle: 'Vertex Name',
     contentPath: 'name',
+    cellComponentName: 'em-table-linked-cell',
+    getCellContent: function (row) {
+      return {
+        routeName: "vertex",
+        model: row.get("entityID"),
+        text: row.get("name")
+      };
+    }
   },{
     id: 'entityID',
     headerTitle: 'Vertex Id',
@@ -73,6 +81,10 @@ export default TablePageController.extend({
      type: 'date'
     }
   },{
+    id: 'totalTasks',
+    headerTitle: 'Tasks',
+    contentPath: 'totalTasks',
+  },{
     id: 'processorClassName',
     headerTitle: 'Processor Class',
     contentPath: 'processorClassName',

http://git-wip-us.apache.org/repos/asf/tez/blob/68dc2f5d/tez-ui2/src/main/webapp/app/controllers/vertex.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/vertex.js b/tez-ui2/src/main/webapp/app/controllers/vertex.js
new file mode 100644
index 0000000..946eaa5
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/vertex.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 Ember from 'ember';
+
+import AbstractController from './abstract';
+
+export default AbstractController.extend({
+  breadcrumbs: Ember.computed("model.dag", function () {
+    var dagName = this.get("model.dag.name"),
+        vertexName = this.get("model.name");
+
+    return [{
+      text: `DAG [ ${dagName} ]`,
+      routeName: "dag.index",
+      model: this.get("model.dagID")
+    },{
+      text: `Vertex [ ${vertexName} ]`,
+      routeName: "vertex.index",
+      model: this.get("model.vertexID")
+    }];
+  }),
+
+  tabs: [{
+    text: "Vertex Details",
+    routeName: "vertex.index"
+  }, {
+    text: "Tasks",
+    routeName: "vertex.tasks"
+  }, {
+    text: "Task Attempts",
+    routeName: "vertex.attempts"
+  }]
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/68dc2f5d/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js b/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js
new file mode 100644
index 0000000..61a6a63
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js
@@ -0,0 +1,77 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import TablePageController from '../table-page';
+import ColumnDefinition from 'em-table/utils/column-definition';
+
+export default TablePageController.extend({
+  breadcrumbs: [{
+    text: "Task Attempts",
+    routeName: "vertex.attempts",
+  }],
+
+  columns: ColumnDefinition.make([{
+    id: 'index',
+    headerTitle: 'Attempt No',
+    contentPath: 'index'
+  },{
+    id: 'taskIndex',
+    headerTitle: 'Task Index',
+    contentPath: 'taskIndex'
+  },{
+    id: 'status',
+    headerTitle: 'Status',
+    contentPath: 'status',
+    cellComponentName: 'em-table-status-cell'
+  },{
+    id: 'progress',
+    headerTitle: 'Progress',
+    contentPath: 'progress',
+    cellComponentName: 'em-table-progress-cell',
+    observePath: true
+  },{
+    id: 'startTime',
+    headerTitle: 'Start Time',
+    contentPath: 'startTime',
+    cellDefinition: {
+      type: 'date'
+    }
+  },{
+    id: 'endTime',
+    headerTitle: 'End Time',
+    contentPath: 'endTime',
+    cellDefinition: {
+      type: 'date'
+    }
+  },{
+    id: 'duration',
+    headerTitle: 'Duration',
+    contentPath: 'duration',
+    cellDefinition: {
+      type: 'duration'
+    }
+  },{
+    id: 'containerID',
+    headerTitle: 'Container',
+    contentPath: 'containerID'
+  },{
+    id: 'nodeID',
+    headerTitle: 'Node',
+    contentPath: 'nodeID'
+  }])
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/68dc2f5d/tez-ui2/src/main/webapp/app/controllers/vertex/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/vertex/index.js b/tez-ui2/src/main/webapp/app/controllers/vertex/index.js
new file mode 100644
index 0000000..9745328
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/vertex/index.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 PageController from '../page';
+
+export default PageController.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/68dc2f5d/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.js b/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.js
new file mode 100644
index 0000000..ce67150
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.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 TablePageController from '../table-page';
+import ColumnDefinition from 'em-table/utils/column-definition';
+
+export default TablePageController.extend({
+  breadcrumbs: [{
+    text: "Tasks",
+    routeName: "vertex.tasks",
+  }],
+
+  columns: ColumnDefinition.make([{
+    id: 'index',
+    headerTitle: 'Task Index',
+    contentPath: 'index'
+  },{
+    id: 'status',
+    headerTitle: 'Status',
+    contentPath: 'status',
+    cellComponentName: 'em-table-status-cell'
+  },{
+    id: 'progress',
+    headerTitle: 'Progress',
+    contentPath: 'progress',
+    cellComponentName: 'em-table-progress-cell',
+    observePath: true
+  },{
+    id: 'startTime',
+    headerTitle: 'Start Time',
+    contentPath: 'startTime',
+    cellDefinition: {
+      type: 'date'
+    }
+  },{
+    id: 'endTime',
+    headerTitle: 'End Time',
+    contentPath: 'endTime',
+    cellDefinition: {
+      type: 'date'
+    }
+  },{
+    id: 'duration',
+    headerTitle: 'Duration',
+    contentPath: 'duration',
+    cellDefinition: {
+      type: 'duration'
+    }
+  }])
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/68dc2f5d/tez-ui2/src/main/webapp/app/models/vertex.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/vertex.js b/tez-ui2/src/main/webapp/app/models/vertex.js
index dcdb0f2..4192771 100644
--- a/tez-ui2/src/main/webapp/app/models/vertex.js
+++ b/tez-ui2/src/main/webapp/app/models/vertex.js
@@ -38,13 +38,22 @@ import TimelineModel from './timeline';
 */
 
 export default TimelineModel.extend({
+  needs: {
+    dag: {
+      type: "dag",
+      idKey: "dagID",
+      silent: true
+    }
+  },
+
   name: DS.attr('string'),
 
   firstTaskStartTime: DS.attr('number'),
+  lastTaskFinishTime: DS.attr('number'),
 
-  numTasks: DS.attr('number'),
+  totalTasks: DS.attr('number'),
   failedTasks: DS.attr('number'),
-  sucessfulTasks: DS.attr('number'),
+  successfulTasks: DS.attr('number'),
   killedTasks: DS.attr('number'),
 
   runningTasks: Ember.computed("status", function () {
@@ -57,5 +66,12 @@ export default TimelineModel.extend({
   failedTaskAttempts: DS.attr('number'),
   killedTaskAttempts: DS.attr('number'),
 
+  minDuration: DS.attr('number'),
+  maxDuration: DS.attr('number'),
+  avgDuration: DS.attr('number'),
+
   processorClassName: DS.attr('string'),
+
+  dagID: DS.attr('string'),
+  dag: DS.attr('object'), // Auto-loaded by need
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/68dc2f5d/tez-ui2/src/main/webapp/app/router.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/router.js b/tez-ui2/src/main/webapp/app/router.js
index d94a837..e80c817 100644
--- a/tez-ui2/src/main/webapp/app/router.js
+++ b/tez-ui2/src/main/webapp/app/router.js
@@ -31,6 +31,10 @@ Router.map(function() {
     this.route('attempts');
   });
   this.route('app', {path: '/app/:app_id'});
+  this.route('vertex', {path: '/vertex/:vertex_id'}, function() {
+    this.route('tasks');
+    this.route('attempts');
+  });
 });
 
 export default Router;

http://git-wip-us.apache.org/repos/asf/tez/blob/68dc2f5d/tez-ui2/src/main/webapp/app/routes/dag/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag/attempts.js b/tez-ui2/src/main/webapp/app/routes/dag/attempts.js
index 3a05867..f438b95 100644
--- a/tez-ui2/src/main/webapp/app/routes/dag/attempts.js
+++ b/tez-ui2/src/main/webapp/app/routes/dag/attempts.js
@@ -20,7 +20,7 @@ import Ember from 'ember';
 import AbstractRoute from '../abstract';
 
 export default AbstractRoute.extend({
-  title: "All Attempts",
+  title: "All Task Attempts",
 
   setupController: function (controller, model) {
     this._super(controller, model);

http://git-wip-us.apache.org/repos/asf/tez/blob/68dc2f5d/tez-ui2/src/main/webapp/app/routes/vertex.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/vertex.js b/tez-ui2/src/main/webapp/app/routes/vertex.js
new file mode 100644
index 0000000..2a38001
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/vertex.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 AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+  title: "Vertex",
+
+  loaderQueryParams: {
+    id: "vertex_id"
+  },
+
+  model: function (params) {
+    return this.get("loader").queryRecord('vertex', this.queryFromParams(params).id);
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/68dc2f5d/tez-ui2/src/main/webapp/app/routes/vertex/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/vertex/attempts.js b/tez-ui2/src/main/webapp/app/routes/vertex/attempts.js
new file mode 100644
index 0000000..cead8a2
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/vertex/attempts.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({
+  title: "Task Attempts",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (/*value, query*/) {
+    return this.get("loader").query('attempt', {
+      vertexID: this.modelFor("vertex").id
+    });
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/68dc2f5d/tez-ui2/src/main/webapp/app/routes/vertex/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/vertex/index.js b/tez-ui2/src/main/webapp/app/routes/vertex/index.js
new file mode 100644
index 0000000..d05e5f6
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/vertex/index.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';
+import AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  title: "DAG Details",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (/*value, query*/) {
+    return this.get("loader").queryRecord('vertex', this.modelFor("vertex").id);
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/68dc2f5d/tez-ui2/src/main/webapp/app/routes/vertex/tasks.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/vertex/tasks.js b/tez-ui2/src/main/webapp/app/routes/vertex/tasks.js
new file mode 100644
index 0000000..e959fef
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/vertex/tasks.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({
+  title: "All Tasks",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (/*value, query*/) {
+    return this.get("loader").query('task', {
+      vertexID: this.modelFor("vertex").id
+    });
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/68dc2f5d/tez-ui2/src/main/webapp/app/serializers/vertex.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/vertex.js b/tez-ui2/src/main/webapp/app/serializers/vertex.js
index 88ee5d3..7c36074 100644
--- a/tez-ui2/src/main/webapp/app/serializers/vertex.js
+++ b/tez-ui2/src/main/webapp/app/serializers/vertex.js
@@ -30,15 +30,22 @@ export default TimelineSerializer.extend({
     name: 'otherinfo.vertexName',
 
     firstTaskStartTime: 'otherinfo.stats.firstTaskStartTime',
+    lastTaskFinishTime: 'otherinfo.stats.lastTaskFinishTime',
 
-    numTasks: 'otherinfo.numTasks',
+    totalTasks: 'otherinfo.numTasks',
     failedTasks: 'otherinfo.numFailedTasks',
-    sucessfulTasks: 'otherinfo.numSucceededTasks',
+    successfulTasks: 'otherinfo.numSucceededTasks',
     killedTasks: 'otherinfo.numKilledTasks',
 
     failedTaskAttempts: 'otherinfo.numFailedTaskAttempts',
     killedTaskAttempts: 'otherinfo.numKilledTaskAttempts',
 
+    minDuration:  'otherinfo.stats.minTaskDuration',
+    maxDuration:  'otherinfo.stats.maxTaskDuration',
+    avgDuration:  'otherinfo.stats.avgTaskDuration',
+
     processorClassName: getProcessorClass,
+
+    dagID: 'primaryfilters.TEZ_DAG_ID.0',
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/68dc2f5d/tez-ui2/src/main/webapp/app/styles/page-layout.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/page-layout.less b/tez-ui2/src/main/webapp/app/styles/page-layout.less
index c3530ff..5a49abc 100644
--- a/tez-ui2/src/main/webapp/app/styles/page-layout.less
+++ b/tez-ui2/src/main/webapp/app/styles/page-layout.less
@@ -124,7 +124,10 @@ body, html {
     color: @logo-orange;
   }
 
-  .footer, .footer-frame {
+  .footer-frame {
+    height: 60px;
+  }
+  .footer {
     height: 40px;
   }
 

http://git-wip-us.apache.org/repos/asf/tez/blob/68dc2f5d/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/index.hbs b/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
index 2811a35..1bd3c21 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
@@ -24,58 +24,51 @@
       </tr>
     </thead>
     <tbody>
-    <tr>
-      <td colspan="2">
-        {{bs-button icon="fa fa-download" title="Download data" defaultText="Download data" type="info" clicked="downloadDagJson"}}
-      </td>
-    </tr>
-    <tr>
-      <td>Application ID</td>
-      <td>
-        {{#link-to 'app' model.appID class='ember-table-content'}}
-          {{model.appID}}
-        {{/link-to}}
-      </td>
-    </tr>
-    <tr>
-      <td>ID</td>
-      <td>{{model.entityID}}</td>
-    </tr>
-    <tr>
-      <td>Submitter</td>
-      <td>{{model.user}}</td>
-    </tr>
-    <tr>
-      <td>Status</td>
-      <td>
-        {{em-table-status-cell content=model.status}}
-        {{#if progressStr}} {{bs-badge content=progressStr}}{{/if}}
-        {{#if hasFailedTasks}}
-          [ <a href='{{unbound failedTasksLink}}'>Failed Tasks</a> ]
-        {{/if}}
-        {{#if hasFailedTaskAttempts}}
-          [ <a href='{{unbound failedTaskAttemptsLink}}'>Failed TaskAttempts</a> ]
-        {{/if}}
-      </td>
-    </tr>
-    <tr>
-      <td>Start Time</td>
-      <td>{{txt model.startTime type="date"}}</td>
-    </tr>
-    <tr>
-      <td>End Time</td>
-      <td>{{txt model.endTime type="date"}}</td>
-    </tr>
-    <tr>
-      <td>Duration</td>
-      <td>{{txt model.duration type="duration"}}</td>
-    </tr>
-    <tr>
-      <td>Logs</td>
-      <td>
-        {{em-table-linked-cell content=model.containerLogs}}
-      </td>
-    </tr>
+      <tr>
+        <td colspan="2">
+          {{bs-button icon="fa fa-download" title="Download data" defaultText="Download data" type="info" clicked="downloadDagJson"}}
+        </td>
+      </tr>
+      <tr>
+        <td>Application ID</td>
+        <td>
+          {{#link-to 'app' model.appID class='ember-table-content'}}
+            {{model.appID}}
+          {{/link-to}}
+        </td>
+      </tr>
+      <tr>
+        <td>ID</td>
+        <td>{{model.entityID}}</td>
+      </tr>
+      <tr>
+        <td>Submitter</td>
+        <td>{{model.user}}</td>
+      </tr>
+      <tr>
+        <td>Status</td>
+        <td>
+          {{em-table-status-cell content=model.status}}
+        </td>
+      </tr>
+      <tr>
+        <td>Start Time</td>
+        <td>{{txt model.startTime type="date"}}</td>
+      </tr>
+      <tr>
+        <td>End Time</td>
+        <td>{{txt model.endTime type="date"}}</td>
+      </tr>
+      <tr>
+        <td>Duration</td>
+        <td>{{txt model.duration type="duration"}}</td>
+      </tr>
+      <tr>
+        <td>Logs</td>
+        <td>
+          {{em-table-linked-cell content=model.containerLogs}}
+        </td>
+      </tr>
     </tbody>
   </table>
 {{else}}

http://git-wip-us.apache.org/repos/asf/tez/blob/68dc2f5d/tez-ui2/src/main/webapp/app/templates/vertex.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/vertex.hbs b/tez-ui2/src/main/webapp/app/templates/vertex.hbs
new file mode 100644
index 0000000..308b905
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/vertex.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.
+}}
+
+{{tab-n-refresh tabs=tabs}}
+{{outlet}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/68dc2f5d/tez-ui2/src/main/webapp/app/templates/vertex/attempts.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/vertex/attempts.hbs b/tez-ui2/src/main/webapp/app/templates/vertex/attempts.hbs
new file mode 100644
index 0000000..cdb28aa
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/vertex/attempts.hbs
@@ -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.
+}}
+
+{{#if loaded}}
+  {{em-table
+  columns=columns
+  rows=model
+
+  definition=definition
+
+  searchAction="searchChanged"
+  sortAction="sortChanged"
+  rowAction="rowsChanged"
+  pageAction="pageChanged"
+  }}
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/68dc2f5d/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs b/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs
new file mode 100644
index 0000000..8183842
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs
@@ -0,0 +1,130 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 loaded}}
+  <table class='detail-list'>
+    <thead>
+      <tr>
+        <th colspan=2>Description</th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>Vertex ID</td>
+        <td>{{model.entityID}}</td>
+      </tr>
+      <tr>
+        <td>Vertex Name</td>
+        <td>{{model.name}}</td>
+      </tr>
+      <tr>
+        <td>Processor Class</td>
+        <td>{{model.processorClassName}}</td>
+      </tr>
+    </tbody>
+  </table>
+
+  <br/>
+
+  <table class='detail-list'>
+    <thead>
+      <tr>
+        <th colspan=2>Details</th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>Status</td>
+        <td>{{em-table-status-cell content=model.status}}</td>
+      </tr>
+      <tr>
+        <td>Start Time</td>
+        <td>{{txt model.startTime type="date"}}</td>
+      </tr>
+      <tr>
+        <td>End Time</td>
+        <td>{{txt model.endTime type="date"}}</td>
+      </tr>
+      <tr>
+        <td>Duration</td>
+        <td>{{txt model.duration type="duration"}}</td>
+      </tr>
+      <tr>
+        <td>First Task Start Time</td>
+        <td>
+          {{txt model.firstTaskStartTime type="date"}}
+        </td>
+      </tr>
+      <tr>
+        <td>Last Task Finish Time</td>
+        <td>
+          {{txt model.lastTaskFinishTime type="date"}}
+        </td>
+      </tr>
+    </tbody>
+  </table>
+
+  <br/>
+
+  <table class='detail-list'>
+    <thead>
+      <tr>
+        <th colspan=2>Tasks of this Vertex</th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>Total Tasks</td>
+        <td>{{txt model.totalTasks type="number"}}</td>
+      </tr>
+      <tr>
+        <td>Successful Tasks</td>
+        <td>{{txt model.successfulTasks type="number"}}</td>
+      </tr>
+      <tr>
+        <td>Failed Tasks</td>
+        <td>{{txt model.failedTasks type="number"}}</td>
+      </tr>
+      <tr>
+        <td>Killed Tasks</td>
+        <td>{{txt model.killedTasks type="number"}}</td>
+      </tr>
+      <tr>
+        <td>Average Duration</td>
+        <td>
+          {{txt model.avgDuration type="duration"}}
+        </td>
+      </tr>
+      <tr>
+        <td>Minimum Duration</td>
+        <td>
+          {{txt model.minDuration type="duration"}}
+        </td>
+      </tr>
+      <tr>
+        <td>Maximum Duration</td>
+        <td>
+          {{txt model.maxDuration type="duration"}}
+        </td>
+      </tr>
+    </tbody>
+  </table>
+
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/68dc2f5d/tez-ui2/src/main/webapp/app/templates/vertex/tasks.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/vertex/tasks.hbs b/tez-ui2/src/main/webapp/app/templates/vertex/tasks.hbs
new file mode 100644
index 0000000..cdb28aa
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/vertex/tasks.hbs
@@ -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.
+}}
+
+{{#if loaded}}
+  {{em-table
+  columns=columns
+  rows=model
+
+  definition=definition
+
+  searchAction="searchChanged"
+  sortAction="sortChanged"
+  rowAction="rowsChanged"
+  pageAction="pageChanged"
+  }}
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/68dc2f5d/tez-ui2/src/main/webapp/tests/unit/controllers/vertex-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex-test.js
new file mode 100644
index 0000000..0061f74
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:vertex', 'Unit | Controller | vertex', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+  assert.ok(controller.tabs);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/68dc2f5d/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/attempts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/attempts-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/attempts-test.js
new file mode 100644
index 0000000..933096e
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/attempts-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:vertex/attempts', 'Unit | Controller | vertex/attempts', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+  assert.ok(controller.columns);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/68dc2f5d/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/index-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/index-test.js
new file mode 100644
index 0000000..e9b46b5
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/index-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:vertex/index', 'Unit | Controller | vertex/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/68dc2f5d/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/tasks-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/tasks-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/tasks-test.js
new file mode 100644
index 0000000..a449dc2
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/tasks-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:vertex/tasks', 'Unit | Controller | vertex/tasks', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+  assert.ok(controller.columns);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/68dc2f5d/tez-ui2/src/main/webapp/tests/unit/routes/vertex-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/vertex-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/vertex-test.js
new file mode 100644
index 0000000..79cef72
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/vertex-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:vertex', 'Unit | Route | vertex', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.loaderQueryParams);
+  assert.ok(route.model);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/68dc2f5d/tez-ui2/src/main/webapp/tests/unit/routes/vertex/attempts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/vertex/attempts-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/vertex/attempts-test.js
new file mode 100644
index 0000000..9ba3cf0
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/vertex/attempts-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:vertex/attempts', 'Unit | Route | vertex/attempts', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+  assert.ok(route.load);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/68dc2f5d/tez-ui2/src/main/webapp/tests/unit/routes/vertex/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/vertex/index-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/vertex/index-test.js
new file mode 100644
index 0000000..cc7e9de
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/vertex/index-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:vertex/index', 'Unit | Route | vertex/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+  assert.ok(route.load);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/68dc2f5d/tez-ui2/src/main/webapp/tests/unit/routes/vertex/tasks-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/vertex/tasks-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/vertex/tasks-test.js
new file mode 100644
index 0000000..e70434f
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/vertex/tasks-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:vertex/tasks', 'Unit | Route | vertex/tasks', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+  assert.ok(route.load);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});


[15/45] tez git commit: TEZ-3026. Tez UI 2: Add adapters for RM & AM (sree)

Posted by sr...@apache.org.
TEZ-3026. Tez UI 2: Add adapters for RM & AM (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/0213e55d
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/0213e55d
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/0213e55d

Branch: refs/heads/TEZ-2980
Commit: 0213e55d90735f64bda46051647d109a26d2c823
Parents: e2fbcc4
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Wed Jan 6 18:25:29 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:32:15 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |  1 +
 .../src/main/webapp/app/adapters/abstract.js    | 11 +++----
 tez-ui2/src/main/webapp/app/adapters/am.js      | 25 ++++++++++++++++
 tez-ui2/src/main/webapp/app/adapters/rm.js      | 25 ++++++++++++++++
 .../src/main/webapp/app/adapters/timeline.js    |  2 ++
 tez-ui2/src/main/webapp/app/services/env.js     | 24 +++++++--------
 tez-ui2/src/main/webapp/app/services/hosts.js   |  6 ++--
 .../src/main/webapp/config/default-app-conf.js  | 11 +++----
 .../webapp/tests/unit/adapters/abstract-test.js | 28 ++++++++++++++++++
 .../main/webapp/tests/unit/adapters/am-test.js  | 31 ++++++++++++++++++++
 .../main/webapp/tests/unit/adapters/rm-test.js  | 31 ++++++++++++++++++++
 .../main/webapp/tests/unit/services/env-test.js | 29 ++++++++++--------
 12 files changed, 179 insertions(+), 45 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/0213e55d/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index c8f9d0f..28584a8 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -10,3 +10,4 @@ ALL CHANGES:
   TEZ-3021. Tez UI 2: Add env service & initializer
   TEZ-3023. Tez UI 2: Abstract adapter and route
   TEZ-3022. Tez UI 2: Add serializer & adapter for timeline server
+  TEZ-3026. Tez UI 2: Add adapters for RM & AM

http://git-wip-us.apache.org/repos/asf/tez/blob/0213e55d/tez-ui2/src/main/webapp/app/adapters/abstract.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/abstract.js b/tez-ui2/src/main/webapp/app/adapters/abstract.js
index b412a46..6cb701b 100644
--- a/tez-ui2/src/main/webapp/app/adapters/abstract.js
+++ b/tez-ui2/src/main/webapp/app/adapters/abstract.js
@@ -28,15 +28,12 @@ export default LoaderAdapter.extend({
     return this.get(`hosts.${serverName}`);
   }),
   namespace: Ember.computed("serverName", function () {
-    var serverName = this.get("serverName"),
-        env = this.get("env");
-    return env.getAppConfig(`namespaces.webService.${serverName}`);
+    var serverName = this.get("serverName");
+    return this.get(`env.app.namespaces.webService.${serverName}`);
   }),
   pathTypeHash: Ember.computed("serverName", function () {
-    var serverName = this.get("serverName"),
-        env = this.get("env");
-
-    return env.getAppConfig(`paths.${serverName}`);
+    var serverName = this.get("serverName");
+    return this.get(`env.app.paths.${serverName}`);
   }),
 
   ajaxOptions: function(url, method, options) {

http://git-wip-us.apache.org/repos/asf/tez/blob/0213e55d/tez-ui2/src/main/webapp/app/adapters/am.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/am.js b/tez-ui2/src/main/webapp/app/adapters/am.js
new file mode 100644
index 0000000..f80cdd5
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/adapters/am.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 AbstractAdapter from './abstract';
+
+export default AbstractAdapter.extend({
+  serverName: "am",
+
+  // Any am specific adapter changes must be added here
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/0213e55d/tez-ui2/src/main/webapp/app/adapters/rm.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/rm.js b/tez-ui2/src/main/webapp/app/adapters/rm.js
new file mode 100644
index 0000000..b87c77d
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/adapters/rm.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 AbstractAdapter from './abstract';
+
+export default AbstractAdapter.extend({
+  serverName: "rm",
+
+  // Any rm specific adapter changes must be added here
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/0213e55d/tez-ui2/src/main/webapp/app/adapters/timeline.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/timeline.js b/tez-ui2/src/main/webapp/app/adapters/timeline.js
index aba7e1e..454cbc9 100644
--- a/tez-ui2/src/main/webapp/app/adapters/timeline.js
+++ b/tez-ui2/src/main/webapp/app/adapters/timeline.js
@@ -20,4 +20,6 @@ import AbstractAdapter from './abstract';
 
 export default AbstractAdapter.extend({
   serverName: "timeline",
+
+  // Any timeline specific adapter changes must be added here
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/0213e55d/tez-ui2/src/main/webapp/app/services/env.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/services/env.js b/tez-ui2/src/main/webapp/app/services/env.js
index 397293d..bd7dde7 100644
--- a/tez-ui2/src/main/webapp/app/services/env.js
+++ b/tez-ui2/src/main/webapp/app/services/env.js
@@ -24,32 +24,28 @@ import environment from '../config/environment';
 var MoreObject = more.Object;
 
 export default Ember.Service.extend({
-  _configs: null,
+  ENV: null,
 
   init: function () {
     this.collateConfigs();
   },
 
   collateConfigs: function () {
-    var configs = {},
+    var collatedENV = {
+          APP: {}
+        },
         ENV = window.ENV;
 
-    MoreObject.merge(configs, environment);
+    MoreObject.merge(collatedENV, environment);
 
     if(ENV) {
-      MoreObject.merge(configs.APP, ENV);
+      MoreObject.merge(collatedENV.APP, ENV);
     }
 
-    this.set("_configs", configs);
+    this.set("ENV", collatedENV);
   },
 
-  getConfig: function (path) {
-    var configs = this.get("_configs");
-    return Ember.get(configs, path);
-  },
-
-  getAppConfig: function (path) {
-    var configs = this.get("_configs.APP");
-    return Ember.get(configs, path);
-  }
+  app: Ember.computed("ENV.APP", function () {
+    return this.get("ENV.APP");
+  })
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/0213e55d/tez-ui2/src/main/webapp/app/services/hosts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/services/hosts.js b/tez-ui2/src/main/webapp/app/services/hosts.js
index 07de04d..a3dc1f3 100644
--- a/tez-ui2/src/main/webapp/app/services/hosts.js
+++ b/tez-ui2/src/main/webapp/app/services/hosts.js
@@ -56,13 +56,11 @@ export default Ember.Service.extend({
   },
 
   timeline: Ember.computed(function () {
-    var env = this.get("env");
-    return this.normalizeURL(env.getAppConfig("hosts.timeline"));
+    return this.normalizeURL(this.get("env.app.hosts.timeline"));
   }),
 
   rm: Ember.computed(function () {
-    var env = this.get("env");
-    return this.normalizeURL(env.getAppConfig("hosts.rm"));
+    return this.normalizeURL(this.get("env.app.hosts.rm"));
   }),
 
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/0213e55d/tez-ui2/src/main/webapp/config/default-app-conf.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/config/default-app-conf.js b/tez-ui2/src/main/webapp/config/default-app-conf.js
index 51a2e81..31a946f 100644
--- a/tez-ui2/src/main/webapp/config/default-app-conf.js
+++ b/tez-ui2/src/main/webapp/config/default-app-conf.js
@@ -24,15 +24,12 @@ module.exports = { // Tez App configurations
   namespaces: {
     webService: {
       timeline: 'ws/v1/timeline',
-      history: 'ws/v1/applicationhistory',
-      am: {
-        v1: 'proxy/__app_id__/ws/v1/tez',
-        v2: 'proxy/__app_id__/ws/v2/tez',
-      },
-      cluster: 'ws/v1/cluster',
+      appHistory: 'ws/v1/applicationhistory',
+      rm: 'ws/v1/cluster',
+      am: 'proxy/{app_id}/ws/v{version}/tez',
     },
     web: {
-      cluster: 'cluster'
+      rm: 'cluster'
     },
   },
   paths: {

http://git-wip-us.apache.org/repos/asf/tez/blob/0213e55d/tez-ui2/src/main/webapp/tests/unit/adapters/abstract-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/abstract-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/abstract-test.js
index bc00679..5ff39e7 100644
--- a/tez-ui2/src/main/webapp/tests/unit/adapters/abstract-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/adapters/abstract-test.js
@@ -37,6 +37,34 @@ test('Basic creation test', function(assert) {
   assert.ok(adapter.pathForType);
 });
 
+test('host, namespace & pathTypeHash test', function(assert) {
+  let adapter = this.subject(),
+      testServerName = "sn",
+      testHosts = {
+        sn: "foo.bar",
+      },
+      testENV = {
+        app: {
+          namespaces: {
+            webService: {
+              sn: "ws"
+            }
+          },
+          paths: {
+            sn: "path"
+          }
+        }
+      };
+
+  adapter.hosts = testHosts;
+  adapter.env = testENV;
+  adapter.set("serverName", testServerName);
+
+  assert.equal(adapter.get("host"), testHosts.sn);
+  assert.equal(adapter.get("namespace"), testENV.app.namespaces.webService.sn);
+  assert.equal(adapter.get("pathTypeHash"), testENV.app.paths.sn);
+});
+
 test('ajaxOptions test', function(assert) {
   let adapter = this.subject(),
       testUrl = "foo.bar",

http://git-wip-us.apache.org/repos/asf/tez/blob/0213e55d/tez-ui2/src/main/webapp/tests/unit/adapters/am-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/am-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/am-test.js
new file mode 100644
index 0000000..a452467
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/adapters/am-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('adapter:am', 'Unit | Adapter | am', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let adapter = this.subject();
+
+  assert.ok(adapter);
+  assert.equal(adapter.serverName, "am");
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/0213e55d/tez-ui2/src/main/webapp/tests/unit/adapters/rm-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/rm-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/rm-test.js
new file mode 100644
index 0000000..0b0445e
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/adapters/rm-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('adapter:rm', 'Unit | Adapter | rm', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let adapter = this.subject();
+
+  assert.ok(adapter);
+  assert.equal(adapter.serverName, "rm");
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/0213e55d/tez-ui2/src/main/webapp/tests/unit/services/env-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/services/env-test.js b/tez-ui2/src/main/webapp/tests/unit/services/env-test.js
index a8a064b..5064fc3 100644
--- a/tez-ui2/src/main/webapp/tests/unit/services/env-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/services/env-test.js
@@ -29,9 +29,9 @@ test('Basic creation test', function(assert) {
   let service = this.subject();
 
   assert.ok(service);
+  assert.ok(service.ENV);
   assert.ok(service.collateConfigs);
-  assert.ok(service.getConfig);
-  assert.ok(service.getAppConfig);
+  assert.ok(service.app);
 });
 
 test('collateConfigs test', function(assert) {
@@ -46,25 +46,28 @@ test('collateConfigs test', function(assert) {
 
   service.collateConfigs();
 
-  APP = service._configs.APP;
+  APP = service.get("app");
   assert.equal(APP.a, 1, "Test window.ENV merge onto environment.APP");
   assert.equal(APP.b, 22);
 });
 
-test('getConfig test', function(assert) {
-  let service = this.subject();
+test('app computed property test', function(assert) {
+  let service = this.subject(),
+      ENV = {
+        b: 2
+      };
 
-  window.ENV = {};
-  environment.a = 11;
+  window.ENV = ENV;
+  environment.APP.a = 11;
   service.collateConfigs();
-  assert.equal(service.getConfig("a"), environment.a);
+  assert.equal(service.get("app.a"), environment.APP.a);
+  assert.equal(service.get("app.b"), ENV.b);
 });
 
-test('getAppConfig test', function(assert) {
+test('Validate config/default-app-conf.js', function(assert) {
   let service = this.subject();
 
-  window.ENV = {};
-  environment.APP.a = 11;
-  service.collateConfigs();
-  assert.equal(service.getAppConfig("a"), environment.APP.a);
+  assert.equal(service.get("app.hosts.timeline"), "localhost:8188");
+  assert.equal(service.get("app.namespaces.webService.timeline"), "ws/v1/timeline");
+  assert.equal(service.get("app.paths.timeline.dag"), "TEZ_DAG_ID");
 });


[17/45] tez git commit: TEZ-2986. Tez UI 2: Implement All DAGs page (sree)

Posted by sr...@apache.org.
TEZ-2986. Tez UI 2: Implement All DAGs page (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/d34cbe07
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/d34cbe07
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/d34cbe07

Branch: refs/heads/TEZ-2980
Commit: d34cbe07aca9591dfb979a05822cac0d4212649e
Parents: 27000ab
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Fri Jan 15 17:29:30 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:32:15 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |   1 +
 tez-ui2/src/main/webapp/app/adapters/ahs-app.js |  27 ++++
 tez-ui2/src/main/webapp/app/adapters/dag.js     |  22 ++++
 .../app/components/em-table-status-cell.js      |  63 ++++++++++
 tez-ui2/src/main/webapp/app/controllers/dags.js | 103 +++++++++++++++
 .../main/webapp/app/controllers/table-page.js   |  51 ++++++++
 tez-ui2/src/main/webapp/app/entities/entity.js  |  30 ++---
 .../webapp/app/initializers/object-transform.js |  37 ------
 tez-ui2/src/main/webapp/app/models/abstract.js  |   2 +
 tez-ui2/src/main/webapp/app/models/ahs-app.js   |  39 ++++++
 tez-ui2/src/main/webapp/app/models/dag.js       |  51 ++++++++
 tez-ui2/src/main/webapp/app/models/timeline.js  |  85 +++++++++++++
 tez-ui2/src/main/webapp/app/router.js           |  19 +++
 tez-ui2/src/main/webapp/app/routes/abstract.js  |  34 ++---
 tez-ui2/src/main/webapp/app/routes/dags.js      |  27 ++++
 .../src/main/webapp/app/serializers/ahs-app.js  |  51 ++++++++
 tez-ui2/src/main/webapp/app/serializers/dag.js  | 111 +++++++++++++++++
 .../src/main/webapp/app/serializers/loader.js   |  17 ++-
 .../src/main/webapp/app/serializers/timeline.js |   2 +
 tez-ui2/src/main/webapp/app/styles/app.less     |   3 -
 .../src/main/webapp/app/styles/page-layout.less |   2 -
 .../components/em-table-status-cell.hbs         |  23 ++++
 tez-ui2/src/main/webapp/app/templates/dags.hbs  |  35 ++++++
 .../app/templates/partials/loading-anim.hbs     |  24 ++++
 .../src/main/webapp/app/transforms/object.js    |  29 +++++
 tez-ui2/src/main/webapp/bower.json              |   5 +-
 tez-ui2/src/main/webapp/package.json            |   5 +-
 .../main/webapp/tests/helpers/destroy-app.js    |  18 +++
 .../tests/helpers/module-for-acceptance.js      |  18 +++
 .../src/main/webapp/tests/helpers/resolver.js   |  18 +++
 .../src/main/webapp/tests/helpers/start-app.js  |  18 +++
 tez-ui2/src/main/webapp/tests/index.html        |  18 +++
 .../components/em-table-status-cell-test.js     |  55 ++++++++
 tez-ui2/src/main/webapp/tests/test-helper.js    |  18 +++
 .../webapp/tests/unit/adapters/ahs-app-test.js  |  34 +++++
 .../main/webapp/tests/unit/adapters/dag-test.js |  30 +++++
 .../webapp/tests/unit/controllers/dags-test.js  |  39 ++++++
 .../tests/unit/controllers/table-page-test.js   |  42 +++++++
 .../webapp/tests/unit/entities/entity-test.js   | 118 +++++++++++++++---
 .../unit/initializers/object-transform-test.js  |  38 ------
 .../webapp/tests/unit/models/ahs-app-test.js    |  29 +++++
 .../main/webapp/tests/unit/models/dag-test.js   |  39 ++++++
 .../webapp/tests/unit/models/timeline-test.js   | 124 +++++++++++++++++++
 .../webapp/tests/unit/routes/abstract-test.js   |  37 +++---
 .../main/webapp/tests/unit/routes/dags-test.js  |  32 +++++
 .../tests/unit/serializers/ahs-app-test.js      |  34 +++++
 .../webapp/tests/unit/serializers/dag-test.js   | 109 ++++++++++++++++
 .../webapp/tests/unit/transforms/object-test.js |  30 +++++
 48 files changed, 1646 insertions(+), 150 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index 355e7d6..9fcb0ef 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -12,3 +12,4 @@ ALL CHANGES:
   TEZ-3022. Tez UI 2: Add serializer & adapter for timeline server
   TEZ-3026. Tez UI 2: Add adapters for RM & AM
   TEZ-3027. Tez UI 2: Add header and footer elements
+  TEZ-2986. Tez UI 2: Implement All DAGs page

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/app/adapters/ahs-app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/ahs-app.js b/tez-ui2/src/main/webapp/app/adapters/ahs-app.js
new file mode 100644
index 0000000..0e7556a
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/adapters/ahs-app.js
@@ -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.
+ */
+
+import Ember from 'ember';
+import TimelineAdapter from './timeline';
+
+export default TimelineAdapter.extend({
+  namespace: Ember.computed.alias("env.app.namespaces.webService.appHistory"),
+  pathForType: function() {
+    return "apps";
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/app/adapters/dag.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/dag.js b/tez-ui2/src/main/webapp/app/adapters/dag.js
new file mode 100644
index 0000000..b47e05f
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/adapters/dag.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 TimelineAdapter from './timeline';
+
+export default TimelineAdapter.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/app/components/em-table-status-cell.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/components/em-table-status-cell.js b/tez-ui2/src/main/webapp/app/components/em-table-status-cell.js
new file mode 100644
index 0000000..bfa74e1
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/components/em-table-status-cell.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';
+
+export default Ember.Component.extend({
+
+  content: null,
+
+  statusTypes: {
+    // Basic types
+    "default": "default",
+    "primary": "primary",
+    "success": "success",
+    "info": "info",
+    "warning": "warning",
+    "danger": "danger",
+
+    // Extended types
+    "new": "default",
+    "inited": "primary",
+    "initializing": "primary",
+    "scheduled": "primary",
+    "start_wait": "primary",
+    "running": "info",
+    "succeeded": "success",
+    "failed": "warning",
+    "fail_in_progress": "warning",
+    "killed": "danger",
+    "kill_wait": "warning",
+    "kill_in_progress": "warning",
+    "error": "danger",
+    "terminating": "warning",
+    "committing": "info",
+  },
+
+  statusType: Ember.computed("content", function () {
+    var content = this.get("content"),
+        statusType;
+
+    if(content) {
+      content = content.toString().toLowerCase();
+      statusType = this.get(`statusTypes.${content}`) || 'default';
+    }
+
+    return statusType;
+  })
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/app/controllers/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dags.js b/tez-ui2/src/main/webapp/app/controllers/dags.js
new file mode 100644
index 0000000..900b03d
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/dags.js
@@ -0,0 +1,103 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 TablePageController from './table-page';
+import ColumnDefinition from 'em-table/utils/column-definition';
+
+export default TablePageController.extend({
+
+  columns: ColumnDefinition.make([{
+    id: 'dagName',
+    headerTitle: 'Dag Name',
+    contentPath: 'name'
+  },{
+    id: 'entityID',
+    headerTitle: 'Id',
+    contentPath: 'entityID'
+  },{
+    id: 'user',
+    headerTitle: 'Submitter',
+    contentPath: 'user'
+  },{
+    id: 'status',
+    headerTitle: 'Status',
+    contentPath: 'status',
+    cellComponentName: 'em-table-status-cell'
+  },{
+    id: 'progress',
+    headerTitle: 'Progress',
+    contentPath: 'progress',
+    cellComponentName: 'em-table-progress-cell',
+    observePath: true
+  },{
+    id: 'startTime',
+    headerTitle: 'Start Time',
+    contentPath: 'startTime',
+    cellDefinition: {
+      type: 'date'
+    }
+  },{
+    id: 'endTime',
+    headerTitle: 'End Time',
+    contentPath: 'endTime',
+    cellDefinition: {
+      type: 'date'
+    }
+  },{
+    id: 'duration',
+    headerTitle: 'Duration',
+    contentPath: 'duration',
+    cellDefinition: {
+      type: 'duration'
+    }
+  },{
+    id: 'appID',
+    headerTitle: 'Application Id',
+    contentPath: 'appID'
+  },{
+    id: 'queue',
+    headerTitle: 'Queue',
+    contentPath: 'queue'
+  },{
+    id: 'contextID',
+    headerTitle: 'Context ID',
+    contentPath: 'contextID'
+  },{
+    id: 'logs',
+    headerTitle: 'Logs',
+    contentPath: 'containerLogs',
+    cellComponentName: "em-table-linked-cell",
+    cellDefinition: {
+      target: "_blank"
+    }
+  }]),
+
+  _loadObserver: Ember.on("init", Ember.observer("rowCount", function () {
+    var that = this,
+        query = {
+          limit: this.get("rowCount")
+        };
+
+    Ember.run.later(function () {
+      that.send("loadData", query);
+    });
+  }))
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/app/controllers/table-page.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/table-page.js b/tez-ui2/src/main/webapp/app/controllers/table-page.js
new file mode 100644
index 0000000..c807393
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/table-page.js
@@ -0,0 +1,51 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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({
+  queryParams: ["rowCount", "searchText", "sortColumnId", "sortOrder", "pageNo"],
+  rowCount: 10,
+  searchText: "",
+  sortColumnId: "",
+  sortOrder: "",
+  pageNo: 1,
+
+  loaded: Ember.computed("model", "isLoading", function () {
+    return this.get("model") && !this.get("isLoading");
+  }),
+
+  actions: {
+    searchChanged: function (searchText) {
+      this.set("searchText", searchText);
+    },
+    sortChanged: function (sortColumnId, sortOrder) {
+      this.setProperties({
+        sortColumnId,
+        sortOrder
+      });
+    },
+    rowsChanged: function (rowCount) {
+      // Change to rows action in em-table
+      this.set("rowCount", rowCount);
+    },
+    pageChanged: function (pageNum) {
+      this.set("pageNum", pageNum);
+    },
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/app/entities/entity.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/entities/entity.js b/tez-ui2/src/main/webapp/app/entities/entity.js
index 4d524fe..c11c6d1 100644
--- a/tez-ui2/src/main/webapp/app/entities/entity.js
+++ b/tez-ui2/src/main/webapp/app/entities/entity.js
@@ -36,25 +36,19 @@ export default Ember.Object.extend({
   },
 
   normalizeNeed: function(name, options) {
-    var attrName = name,
-        attrType = name,
-        idKey = options,
-        lazy = false;
+    var need = {
+      name: name,
+      type: name,
+      idKey: options,
+      lazy: false,
+      silent: false
+    };
 
     if(typeof options === 'object') {
-      attrType = options.type || attrType;
-      idKey = options.idKey || idKey;
-      if(options.lazy) {
-        lazy = true;
-      }
+      return Ember.Object.create(need, options);
     }
 
-    return {
-      name: attrName,
-      type: attrType,
-      idKey: idKey,
-      lazy: lazy
-    };
+    return Ember.Object.create(need);
   },
 
   loadNeeds: function (loader, parentModel) {
@@ -71,6 +65,12 @@ export default Ember.Object.extend({
           parentModel.set(need.name, model);
         });
 
+        if(need.silent) {
+          needLoader = needLoader.catch(function () {
+            parentModel.set(need.name, null);
+          });
+        }
+
         if(!need.lazy) {
           needLoaders.push(needLoader);
         }

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/app/initializers/object-transform.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/initializers/object-transform.js b/tez-ui2/src/main/webapp/app/initializers/object-transform.js
deleted file mode 100644
index 57502cf..0000000
--- a/tez-ui2/src/main/webapp/app/initializers/object-transform.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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";
-
-export function initialize(application) {
-  application.register('transform:object', DS.Transform.extend({
-    deserialize: function(serialized) {
-      return Ember.none(serialized) ? {} : serialized;
-    },
-
-    serialized: function(deserialized) {
-      return Ember.none(deserialized) ? {} : deserialized;
-    }
-  }));
-}
-
-export default {
-  name: 'object-transform',
-  initialize
-};

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/app/models/abstract.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/abstract.js b/tez-ui2/src/main/webapp/app/models/abstract.js
index 2191d18..0dd084d 100644
--- a/tez-ui2/src/main/webapp/app/models/abstract.js
+++ b/tez-ui2/src/main/webapp/app/models/abstract.js
@@ -21,6 +21,8 @@ import DS from 'ember-data';
 export default DS.Model.extend({
   timeStamp: null,
 
+  mergedProperties: ["needs"],
+
   refreshTimestamp: function () {
     this.set('timeStamp', new Date());
   },

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/app/models/ahs-app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/ahs-app.js b/tez-ui2/src/main/webapp/app/models/ahs-app.js
new file mode 100644
index 0000000..8f4a153
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/models/ahs-app.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 AbstractModel from './abstract';
+
+export default AbstractModel.extend({
+  attemptID: DS.attr('string'),
+
+  name: DS.attr('string'),
+  queue: DS.attr('string'),
+  user: DS.attr('string'),
+  type: DS.attr('string'),
+
+  status: DS.attr('string'),
+  finalStatus: DS.attr('string'),
+
+  startedTime: DS.attr('number'),
+  elapsedTime: DS.attr('number'),
+  finishedTime: DS.attr('number'),
+  submittedTime: DS.attr('number'),
+
+  diagnostics: DS.attr('string'),
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/app/models/dag.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/dag.js b/tez-ui2/src/main/webapp/app/models/dag.js
new file mode 100644
index 0000000..4e9ff7c
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/models/dag.js
@@ -0,0 +1,51 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 TimelineModel from './timeline';
+/*
+  Inherited properties
+
+  entityID - String
+  appID - Computed from entityID
+
+  status - String
+  progress - Computed from status
+
+  startTime - Number
+  endTime - Number
+  duration - Computed from start & end times
+
+  counterGroups - Array
+  counterHash - Computed from counterGroups
+*/
+
+export default TimelineModel.extend({
+  name: DS.attr("string"),
+
+  user: DS.attr("string"),
+  contextID: DS.attr("string"),
+
+  domain: DS.attr("string"),
+  containerLogs: DS.attr("object"),
+  queue: Ember.computed("app", function () {
+    return this.get("app.queue");
+  }),
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/app/models/timeline.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/timeline.js b/tez-ui2/src/main/webapp/app/models/timeline.js
new file mode 100644
index 0000000..6f9ddb7
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/models/timeline.js
@@ -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.
+ */
+
+import DS from 'ember-data';
+import Ember from 'ember';
+
+import AbstractModel from './abstract';
+
+export default AbstractModel.extend({
+
+  needs:{
+    app: {
+      type: "AhsApp",
+      idKey: "appID",
+      silent: true
+    }
+  },
+
+  entityID: DS.attr("string"),
+  appID: Ember.computed("entityID", function () {
+    var idParts = this.get("entityID").split("_");
+    return `application_${idParts[1]}_${idParts[2]}`;
+  }),
+  app: DS.attr("object"), // Either RMApp or AHSApp
+
+  atsStatus: DS.attr("string"),
+  status: Ember.computed("atsStatus", "app.status", function () {
+    var status = this.get("atsStatus"),
+        yarnStatus = this.get("app.status");
+
+    if (status !== 'RUNNING' || (yarnStatus !== 'FINISHED' && yarnStatus !== 'KILLED' && yarnStatus !== 'FAILED')) {
+      return status;
+    }
+
+    if (yarnStatus === 'KILLED' || yarnStatus === 'FAILED') {
+      return yarnStatus;
+    }
+
+    return this.get("app.finalStatus");
+  }),
+  progress: Ember.computed("status", function () {
+    return this.get("status") === "SUCCEEDED" ? 1 : null;
+  }),
+
+  startTime: DS.attr("number"),
+  endTime: DS.attr("number"),
+  duration: Ember.computed("startTime", "endTime", function () {
+    var duration = this.get("endTime") - this.get("startTime");
+    return duration > 0 ? duration : null;
+  }),
+
+  counterGroups: DS.attr('object'),
+  counterHash: Ember.computed("counterGroups", function () {
+    var counterHash = {},
+        counterGroups = this.get("counterGroups");
+
+    counterGroups.forEach(function (group) {
+      var counters = group.counters,
+          groupHash;
+
+      groupHash = counterHash[group.counterGroupName] = counterHash[group.counterGroupName] || {};
+
+      counters.forEach(function (counter) {
+        groupHash[counter.counterName] = counter.counterValue;
+      });
+    });
+
+    return counterHash;
+  })
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/app/router.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/router.js b/tez-ui2/src/main/webapp/app/router.js
index 3bba78e..3aca665 100644
--- a/tez-ui2/src/main/webapp/app/router.js
+++ b/tez-ui2/src/main/webapp/app/router.js
@@ -1,3 +1,21 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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';
 
@@ -6,6 +24,7 @@ const Router = Ember.Router.extend({
 });
 
 Router.map(function() {
+  this.route('dags', { path: '/' });
 });
 
 export default Router;

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/app/routes/abstract.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/abstract.js b/tez-ui2/src/main/webapp/app/routes/abstract.js
index 3191762..8696b67 100644
--- a/tez-ui2/src/main/webapp/app/routes/abstract.js
+++ b/tez-ui2/src/main/webapp/app/routes/abstract.js
@@ -27,8 +27,6 @@ export default Ember.Route.extend({
   currentPromiseId: null,
   loadedValue: null,
 
-  queryParams: null,
-
   setDocTitle: function () {
     Ember.$(document).attr('title', this.get('title'));
   },
@@ -38,35 +36,31 @@ export default Ember.Route.extend({
     this.setDocTitle();
   },
 
-  beforeModel: function (transition) {
-    this.set('queryParams', transition.queryParams);
-    return this._super(transition);
-  },
-
-  checkAndCall: function (id, functionName, value) {
+  checkAndCall: function (id, functionName, query, value) {
     if(id === this.get("currentPromiseId")) {
-      return this[functionName](value);
+      return this[functionName](value, query);
     }
     else {
       throw new UnlinkedPromise();
     }
   },
 
-  loadData: Ember.observer("queryParams", function () {
+  loadData: function (query) {
     var promiseId = Math.random();
 
     this.set('currentPromiseId', promiseId);
 
     return Ember.RSVP.resolve().
-      then(this.checkAndCall.bind(this, promiseId, "setLoading")).
-      then(this.checkAndCall.bind(this, promiseId, "beforeLoad")).
-      then(this.checkAndCall.bind(this, promiseId, "load")).
-      then(this.checkAndCall.bind(this, promiseId, "afterLoad")).
-      then(this.checkAndCall.bind(this, promiseId, "setValue"));
-  }),
+      then(this.checkAndCall.bind(this, promiseId, "setLoading", query)).
+      then(this.checkAndCall.bind(this, promiseId, "beforeLoad", query)).
+      then(this.checkAndCall.bind(this, promiseId, "load", query)).
+      then(this.checkAndCall.bind(this, promiseId, "afterLoad", query)).
+      then(this.checkAndCall.bind(this, promiseId, "setValue", query));
+  },
 
   setLoading: function () {
     this.set('isLoading', true);
+    this.set('controller.isLoading', true);
   },
   beforeLoad: function (value) {
     return value;
@@ -80,6 +74,7 @@ export default Ember.Route.extend({
   setValue: function (value) {
     this.set('loadedValue', value);
     this.set('isLoading', false);
+    this.set('controller.isLoading', false);
     return value;
   },
 
@@ -96,6 +91,13 @@ export default Ember.Route.extend({
       store: this.get("store"),
       container: this.get("container")
     }));
+  },
+
+  actions: {
+    loadData: function (query) {
+      // To be on the safer side
+      Ember.run.once(this, "loadData", query);
+    }
   }
 
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/app/routes/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dags.js b/tez-ui2/src/main/webapp/app/routes/dags.js
new file mode 100644
index 0000000..b4b9070
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/dags.js
@@ -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.
+ */
+
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+  title: "All DAGs",
+
+  load: function (value, query) {
+    return this.get("loader").query('dag', query);
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/app/serializers/ahs-app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/ahs-app.js b/tez-ui2/src/main/webapp/app/serializers/ahs-app.js
new file mode 100644
index 0000000..10825b2
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/serializers/ahs-app.js
@@ -0,0 +1,51 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 LoaderSerializer from './loader';
+
+export default LoaderSerializer.extend({
+  primaryKey: 'appId',
+
+  extractArrayPayload: function (payload) {
+    return payload.app;
+  },
+
+  maps: {
+    entityID: 'appId',
+    attemptID: function(source) {
+      // while an attempt is in progress the attempt id contains a '-'
+      return (Ember.get(source, 'currentAppAttemptId') || '').replace('-','');
+    },
+
+    name: 'name',
+    queue: 'queue',
+    user: 'user',
+    type: 'type',
+
+    status: 'appState',
+    finalStatus: 'finalAppStatus',
+
+    startedTime: 'startedTime',
+    elapsedTime: 'elapsedTime',
+    finishedTime: 'finishedTime',
+    submittedTime: 'submittedTime',
+
+    diagnostics: 'otherinfo.diagnostics',
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/app/serializers/dag.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/dag.js b/tez-ui2/src/main/webapp/app/serializers/dag.js
new file mode 100644
index 0000000..35c53ba
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/serializers/dag.js
@@ -0,0 +1,111 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 TimelineSerializer from './timeline';
+
+function getStatus(source) {
+  var status = Ember.get(source, 'otherinfo.status') || Ember.get(source, 'primaryfilters.status.0'),
+      event = source.events;
+
+  if(!status && event) {
+    if(event.findBy('eventtype', 'DAG_STARTED')) {
+      status = 'RUNNING';
+    }
+  }
+
+  return status;
+}
+
+function getStartTime(source) {
+  var time = Ember.get(source, 'otherinfo.startTime'),
+      event = source.events;
+
+  if(!time && event) {
+    event = event.findBy('eventtype', 'DAG_STARTED');
+    if(event) {
+      time = event.timestamp;
+    }
+  }
+
+  return time;
+}
+
+function getEndTime(source) {
+  var time = Ember.get(source, 'otherinfo.endTime'),
+      event = source.events;
+
+  if(!time && event) {
+    event = event.findBy('eventtype', 'DAG_FINISHED');
+    if(event) {
+      time = event.timestamp;
+    }
+  }
+
+  return time;
+}
+
+function getContainerLogs(source) {
+  var containerLogs = [],
+      otherinfo = Ember.get(source, 'otherinfo');
+
+  if(!otherinfo) {
+    return undefined;
+  }
+
+  for (var key in otherinfo) {
+    if (key.indexOf('inProgressLogsURL_') === 0) {
+      let logs = Ember.get(source, 'otherinfo.' + key);
+      if (logs.indexOf('http') !== 0) {
+        logs = 'http://' + logs;
+      }
+      let attemptID = key.substring(18);
+      containerLogs.push({
+        text : attemptID,
+        href: logs
+      });
+    }
+  }
+
+  return containerLogs;
+}
+
+export default TimelineSerializer.extend({
+  maps: {
+    entityID: 'entity',
+    name: 'primaryfilters.dagName.0',
+
+    user: 'primaryfilters.user.0',
+    contextID: 'primaryfilters.callerId.0',
+
+    atsStatus: getStatus,
+    // progress
+
+    startTime: getStartTime,
+    endTime: getEndTime,
+    // duration
+
+    appID: 'otherinfo.applicationId',
+    domain: 'domain',
+    // queue
+    containerLogs: getContainerLogs,
+
+    counterGroups: 'otherinfo.counters.counterGroups'
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/app/serializers/loader.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/loader.js b/tez-ui2/src/main/webapp/app/serializers/loader.js
index 9c97886..82899f6 100644
--- a/tez-ui2/src/main/webapp/app/serializers/loader.js
+++ b/tez-ui2/src/main/webapp/app/serializers/loader.js
@@ -1,3 +1,4 @@
+/*global more*/
 /**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -19,12 +20,22 @@
 import Ember from 'ember';
 import DS from 'ember-data';
 
+var MoreObject = more.Object;
+
 // TODO - Move to more js
 function mapObject(hash, map) {
   var mappedObject = Ember.Object.create();
-  for (var key in map) {
-    mappedObject.set(key, Ember.get(hash, map[key]));
-  }
+  MoreObject.forEach(map, function (key, value) {
+    if(MoreObject.isString(value)) {
+      mappedObject.set(key, Ember.get(hash, value));
+    }
+    else if (MoreObject.isFunction(value)) {
+      mappedObject.set(key, value(hash));
+    }
+    else {
+      Ember.assert("Unknown mapping value");
+    }
+  });
   return mappedObject;
 }
 

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/app/serializers/timeline.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/timeline.js b/tez-ui2/src/main/webapp/app/serializers/timeline.js
index 8963dc2..27f1894 100644
--- a/tez-ui2/src/main/webapp/app/serializers/timeline.js
+++ b/tez-ui2/src/main/webapp/app/serializers/timeline.js
@@ -19,6 +19,8 @@
 import LoaderSerializer from './loader';
 
 export default LoaderSerializer.extend({
+  primaryKey: 'entity',
+
   extractArrayPayload: function (payload) {
     return payload.entities;
   }

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/app/styles/app.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/app.less b/tez-ui2/src/main/webapp/app/styles/app.less
index 4c3b89d..082c785 100644
--- a/tez-ui2/src/main/webapp/app/styles/app.less
+++ b/tez-ui2/src/main/webapp/app/styles/app.less
@@ -16,9 +16,6 @@
  * limitations under the License.
  */
 
-// External imports
-@import "../../bower_components/snippet-ss/less/index";
-
 @import "colors";
 @import "shared";
 

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/app/styles/page-layout.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/page-layout.less b/tez-ui2/src/main/webapp/app/styles/page-layout.less
index ef00b40..aacb731 100644
--- a/tez-ui2/src/main/webapp/app/styles/page-layout.less
+++ b/tez-ui2/src/main/webapp/app/styles/page-layout.less
@@ -23,8 +23,6 @@ body, html, body > .ember-view {
   height: 100%;
   overflow: visible;
   color: @text-color;
-
-  .san-helvetica;
 }
 body, html {
   min-width: 1024px;

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/app/templates/components/em-table-status-cell.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/components/em-table-status-cell.hbs b/tez-ui2/src/main/webapp/app/templates/components/em-table-status-cell.hbs
new file mode 100644
index 0000000..f720178
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/components/em-table-status-cell.hbs
@@ -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.
+}}
+
+{{#if content}}
+  <span class="label label-{{statusType}}">{{content}}</span>
+{{else}}
+  <span class="txt-message"> Not Available! </span>
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/app/templates/dags.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dags.hbs b/tez-ui2/src/main/webapp/app/templates/dags.hbs
new file mode 100644
index 0000000..ddbc72a
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/dags.hbs
@@ -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.
+}}
+
+{{#if loaded}}
+  {{em-table
+    columns=columns
+    rows=model
+    rowCount=rowCount
+
+    enableSearch=false
+    enableSort=false
+
+    searchAction="searchChanged"
+    sortAction="sortChanged"
+    rowAction="rowsChanged"
+    pageAction="pageChanged"
+  }}
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/app/templates/partials/loading-anim.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/partials/loading-anim.hbs b/tez-ui2/src/main/webapp/app/templates/partials/loading-anim.hbs
new file mode 100644
index 0000000..0b3bb19
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/partials/loading-anim.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.
+}}
+
+<h3>Loading...</h3>
+
+<div class="progress">
+  <div class="progress-bar progress-bar-striped active" role="progressbar" style="width:100%">
+  </div>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/app/transforms/object.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/transforms/object.js b/tez-ui2/src/main/webapp/app/transforms/object.js
new file mode 100644
index 0000000..760f4f9
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/transforms/object.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 DS from 'ember-data';
+
+export default DS.Transform.extend({
+  deserialize(serialized) {
+    return serialized;
+  },
+
+  serialize(deserialized) {
+    return deserialized;
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/bower.json
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/bower.json b/tez-ui2/src/main/webapp/bower.json
index 550ce85..1448fd3 100644
--- a/tez-ui2/src/main/webapp/bower.json
+++ b/tez-ui2/src/main/webapp/bower.json
@@ -14,6 +14,9 @@
     "bootstrap": "~3.3.5",
     "snippet-ss": "*",
     "font-awesome": "~4.5.0",
-    "jquery-ui": "1.11.4"
+    "jquery-ui": "1.11.4",
+    "moment": "^2.8.0",
+    "moment-timezone": "^0.5.0",
+    "numeral": "1.5.3"
   }
 }

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/package.json
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/package.json b/tez-ui2/src/main/webapp/package.json
index 33a27a6..a5b29db 100644
--- a/tez-ui2/src/main/webapp/package.json
+++ b/tez-ui2/src/main/webapp/package.json
@@ -34,6 +34,8 @@
     "ember-cli-htmlbars-inline-precompile": "^0.3.1",
     "ember-cli-inject-live-reload": "^1.3.1",
     "ember-cli-jquery-ui": "0.0.20",
+    "ember-cli-moment-shim": "0.7.3",
+    "ember-cli-numeral": "0.1.2",
     "ember-cli-qunit": "^1.0.4",
     "ember-cli-release": "0.2.8",
     "ember-cli-sri": "^1.2.0",
@@ -46,7 +48,8 @@
   },
   "dependencies": {
     "broccoli-funnel": "^1.0.1",
-    "em-helpers": "^0.5.2",
+    "em-table": "0.3.7",
+    "em-helpers": "0.5.7",
     "ember-cli-htmlbars": "^1.0.1",
     "ember-cli-less": "^1.4.0"
   }

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/tests/helpers/destroy-app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/helpers/destroy-app.js b/tez-ui2/src/main/webapp/tests/helpers/destroy-app.js
index c3d4d1a..dfabf85 100644
--- a/tez-ui2/src/main/webapp/tests/helpers/destroy-app.js
+++ b/tez-ui2/src/main/webapp/tests/helpers/destroy-app.js
@@ -1,3 +1,21 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 function destroyApp(application) {

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/tests/helpers/module-for-acceptance.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/helpers/module-for-acceptance.js b/tez-ui2/src/main/webapp/tests/helpers/module-for-acceptance.js
index ed23003..05aa014 100644
--- a/tez-ui2/src/main/webapp/tests/helpers/module-for-acceptance.js
+++ b/tez-ui2/src/main/webapp/tests/helpers/module-for-acceptance.js
@@ -1,3 +1,21 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 import { module } from 'qunit';
 import startApp from '../helpers/start-app';
 import destroyApp from '../helpers/destroy-app';

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/tests/helpers/resolver.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/helpers/resolver.js b/tez-ui2/src/main/webapp/tests/helpers/resolver.js
index ebfb4e4..9c3d98c 100644
--- a/tez-ui2/src/main/webapp/tests/helpers/resolver.js
+++ b/tez-ui2/src/main/webapp/tests/helpers/resolver.js
@@ -1,3 +1,21 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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';
 

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/tests/helpers/start-app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/helpers/start-app.js b/tez-ui2/src/main/webapp/tests/helpers/start-app.js
index e098f1d..7b25773 100644
--- a/tez-ui2/src/main/webapp/tests/helpers/start-app.js
+++ b/tez-ui2/src/main/webapp/tests/helpers/start-app.js
@@ -1,3 +1,21 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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';

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/tests/index.html
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/index.html b/tez-ui2/src/main/webapp/tests/index.html
index b5205de..6b43939 100644
--- a/tez-ui2/src/main/webapp/tests/index.html
+++ b/tez-ui2/src/main/webapp/tests/index.html
@@ -1,3 +1,21 @@
+<!--
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+-->
+
 <!DOCTYPE html>
 <html>
   <head>

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/tests/integration/components/em-table-status-cell-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/integration/components/em-table-status-cell-test.js b/tez-ui2/src/main/webapp/tests/integration/components/em-table-status-cell-test.js
new file mode 100644
index 0000000..c2c6a45
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/integration/components/em-table-status-cell-test.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 { moduleForComponent, test } from 'ember-qunit';
+import hbs from 'htmlbars-inline-precompile';
+
+moduleForComponent('em-table-status-cell', 'Integration | Component | em table status cell', {
+  integration: true
+});
+
+test('Basic render test', function(assert) {
+
+  // Set any properties with this.set('myProperty', 'value');
+  // Handle any actions with this.on('myAction', function(val) { ... });" + EOL + EOL +
+
+  this.render(hbs`{{em-table-status-cell}}`);
+
+  assert.equal(this.$().text().trim(), 'Not Available!');
+
+  // Template block usage:" + EOL +
+  this.render(hbs`
+    {{#em-table-status-cell}}
+      template block text
+    {{/em-table-status-cell}}
+  `);
+
+  assert.equal(this.$().text().trim(), 'Not Available!');
+});
+
+test('Basic type test', function(assert) {
+  this.render(hbs`{{em-table-status-cell content="SUCCESS"}}`);
+  assert.equal(this.$().text().trim(), 'SUCCESS');
+  assert.equal(this.$("span")[0].className, 'label label-success');
+});
+
+test('Extended type test', function(assert) {
+  this.render(hbs`{{em-table-status-cell content="inited"}}`);
+  assert.equal(this.$().text().trim(), 'inited');
+  assert.equal(this.$("span")[0].className, 'label label-primary');
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/tests/test-helper.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/test-helper.js b/tez-ui2/src/main/webapp/tests/test-helper.js
index e6cfb70..96975ee 100644
--- a/tez-ui2/src/main/webapp/tests/test-helper.js
+++ b/tez-ui2/src/main/webapp/tests/test-helper.js
@@ -1,3 +1,21 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/tests/unit/adapters/ahs-app-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/ahs-app-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/ahs-app-test.js
new file mode 100644
index 0000000..e1aac04
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/adapters/ahs-app-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('adapter:ahs-app', 'Unit | Adapter | ahs app', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let adapter = this.subject();
+
+  assert.ok(adapter);
+  assert.ok(adapter.namespace);
+  assert.ok(adapter.pathForType);
+
+  assert.equal(adapter.pathForType(), "apps");
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/tests/unit/adapters/dag-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/dag-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/dag-test.js
new file mode 100644
index 0000000..33532b2
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/adapters/dag-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:dag', 'Unit | Adapter | dag', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let adapter = this.subject();
+
+  assert.ok(adapter);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.js
new file mode 100644
index 0000000..51ea9fe
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dags-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:dags', 'Unit | Controller | dags', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  assert.expect(2 + 3);
+
+  let controller = this.subject({
+    send: function (name, query) {
+      assert.equal(name, "loadData");
+      assert.ok(query);
+    }
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.columns);
+  assert.ok(controller._loadObserver);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/tests/unit/controllers/table-page-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/table-page-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/table-page-test.js
new file mode 100644
index 0000000..efe3f7e
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/table-page-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('controller:table-page', 'Unit | Controller | table page', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject();
+
+  assert.ok(controller);
+  assert.ok(controller.queryParams);
+
+  assert.equal(controller.rowCount, 10);
+  assert.equal(controller.searchText, "");
+  assert.equal(controller.sortColumnId, "");
+  assert.equal(controller.sortOrder, "");
+  assert.equal(controller.pageNo, 1);
+
+  assert.ok(controller.actions.searchChanged);
+  assert.ok(controller.actions.sortChanged);
+  assert.ok(controller.actions.rowsChanged);
+  assert.ok(controller.actions.pageChanged);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/tests/unit/entities/entity-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/entities/entity-test.js b/tez-ui2/src/main/webapp/tests/unit/entities/entity-test.js
index 23e349d..2129fb3 100644
--- a/tez-ui2/src/main/webapp/tests/unit/entities/entity-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/entities/entity-test.js
@@ -25,7 +25,7 @@ moduleFor('entitie:entity', 'Unit | Entity | entity', {
   // needs: ['entitie:foo']
 });
 
-test('Basic creation', function(assert) {
+test('Basic creation test', function(assert) {
   let adapter = this.subject();
 
   assert.ok(adapter);
@@ -34,7 +34,7 @@ test('Basic creation', function(assert) {
   assert.ok(adapter.loadNeeds);
 });
 
-test('loadRelations creation', function(assert) {
+test('loadRelations test', function(assert) {
   let adapter = this.subject(),
       testLoader = {},
       testModel = {},
@@ -69,39 +69,52 @@ test('loadRelations creation', function(assert) {
 
 });
 
-test('normalizeNeed creation', function(assert) {
-  let adapter = this.subject();
+test('normalizeNeed test', function(assert) {
+  let adapter = this.subject(),
+      expectedProperties = ["name", "type", "idKey", "lazy", "silent"];
 
-  assert.deepEqual(adapter.normalizeNeed("app", "appKey"), {
+  assert.deepEqual(adapter.normalizeNeed("app", "appKey").getProperties(expectedProperties), {
     name: "app",
     type: "app",
     idKey: "appKey",
-    lazy: false
+    lazy: false,
+    silent: false
   }, "Test 1");
 
-  assert.deepEqual(adapter.normalizeNeed( "app", { idKey: "appKey" }), {
+  assert.deepEqual(adapter.normalizeNeed( "app", { idKey: "appKey" }).getProperties(expectedProperties), {
     name: "app",
     type: "app",
     idKey: "appKey",
-    lazy: false
+    lazy: false,
+    silent: false
   }, "Test 2");
 
-  assert.deepEqual(adapter.normalizeNeed( "app", { type: "application", idKey: "appKey" }), {
+  assert.deepEqual(adapter.normalizeNeed( "app", { type: "application", idKey: "appKey" }).getProperties(expectedProperties), {
     name: "app",
     type: "application",
     idKey: "appKey",
-    lazy: false
+    lazy: false,
+    silent: false
   }, "Test 3");
 
-  assert.deepEqual(adapter.normalizeNeed( "app", { lazy: true, idKey: "appKey" }), {
+  assert.deepEqual(adapter.normalizeNeed( "app", { lazy: true, idKey: "appKey" }).getProperties(expectedProperties), {
     name: "app",
     type: "app",
     idKey: "appKey",
-    lazy: true
+    lazy: true,
+    silent: false
   }, "Test 4");
+
+  assert.deepEqual(adapter.normalizeNeed( "app", { silent: true, idKey: "appKey" }).getProperties(expectedProperties), {
+    name: "app",
+    type: "app",
+    idKey: "appKey",
+    lazy: false,
+    silent: true
+  }, "Test 5");
 });
 
-test('loadNeeds creation', function(assert) {
+test('loadNeeds basic test', function(assert) {
   let adapter = this.subject(),
       loader,
       testModel = Ember.Object.create({
@@ -115,7 +128,7 @@ test('loadNeeds creation', function(assert) {
 
   assert.expect(1 + 2 + 1);
 
-  assert.equal(adapter.loadNeeds(loader, Ember.Object.create()), null, "Model without needs");
+  assert.equal(adapter.loadNeeds(loader, Ember.Object.create()), undefined, "Model without needs");
 
   loader = {
     queryRecord: function (type, id) {
@@ -137,3 +150,80 @@ test('loadNeeds creation', function(assert) {
     assert.ok(true);
   });
 });
+
+test('loadNeeds silent=false test', function(assert) {
+  let adapter = this.subject(),
+      loader,
+      testModel = Ember.Object.create({
+        needs: {
+          app: {
+            idKey: "appID",
+            // silent: false - By default it's false
+          },
+        },
+        appID: 1,
+      }),
+      testErr = {};
+
+  assert.expect(1 + 1);
+
+  loader = {
+    queryRecord: function (type, id) {
+      assert.equal(id, testModel.get("appID"));
+      return Ember.RSVP.reject(testErr);
+    }
+  };
+  adapter.loadNeeds(loader, testModel).catch(function (err) {
+    assert.equal(err, testErr);
+  });
+});
+
+test('loadNeeds silent=true test', function(assert) {
+  let adapter = this.subject(),
+      loader,
+      testModel = Ember.Object.create({
+        needs: {
+          app: {
+            idKey: "appID",
+            silent: true
+          },
+        },
+        appID: 1,
+      });
+
+  assert.expect(1 + 1);
+
+  loader = {
+    queryRecord: function (type, id) {
+      assert.equal(id, testModel.get("appID"));
+      return Ember.RSVP.resolve();
+    }
+  };
+  adapter.loadNeeds(loader, testModel).then(function (val) {
+    assert.ok(val);
+  });
+});
+
+test('loadNeeds lazy=true test', function(assert) {
+  let adapter = this.subject(),
+      loader,
+      testModel = Ember.Object.create({
+        needs: {
+          app: {
+            idKey: "appID",
+            lazy: true
+          },
+        },
+        appID: 1,
+      });
+
+  assert.expect(1 + 1);
+
+  loader = {
+    queryRecord: function (type, id) {
+      assert.equal(id, testModel.get("appID"));
+      return Ember.RSVP.resolve();
+    }
+  };
+  assert.equal(adapter.loadNeeds(loader, testModel), undefined, "Model without needs");
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/tests/unit/initializers/object-transform-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/initializers/object-transform-test.js b/tez-ui2/src/main/webapp/tests/unit/initializers/object-transform-test.js
deleted file mode 100644
index a52a7bd..0000000
--- a/tez-ui2/src/main/webapp/tests/unit/initializers/object-transform-test.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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 ObjectTransformInitializer from '../../../initializers/object-transform';
-import { module, test } from 'qunit';
-
-let application;
-
-module('Unit | Initializer | object transform', {
-  beforeEach() {
-    Ember.run(function() {
-      application = Ember.Application.create();
-      application.deferReadiness();
-    });
-  }
-});
-
-test('it works', function(assert) {
-  ObjectTransformInitializer.initialize(application);
-
-  assert.ok(true);
-});

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/tests/unit/models/ahs-app-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/ahs-app-test.js b/tez-ui2/src/main/webapp/tests/unit/models/ahs-app-test.js
new file mode 100644
index 0000000..04b472a
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/models/ahs-app-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 { moduleForModel, test } from 'ember-qunit';
+
+moduleForModel('ahs-app', 'Unit | Model | ahs app', {
+  // Specify the other units that are required for this test.
+  needs: []
+});
+
+test('Basic creation test', function(assert) {
+  let model = this.subject();
+  assert.ok(!!model);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/tests/unit/models/dag-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/dag-test.js b/tez-ui2/src/main/webapp/tests/unit/models/dag-test.js
new file mode 100644
index 0000000..9b04398
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/models/dag-test.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';
+import { moduleForModel, test } from 'ember-qunit';
+
+moduleForModel('dag', 'Unit | Model | dag', {
+  // Specify the other units that are required for this test.
+  needs: []
+});
+
+test('Basic creation test', function(assert) {
+  let model = this.subject(),
+      testQueue = "TQ";
+
+  Ember.run(function () {
+    model.set("app", {
+      queue: testQueue
+    });
+
+    assert.ok(!!model);
+    assert.equal(model.get("queue"), testQueue);
+  });
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/tests/unit/models/timeline-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/timeline-test.js b/tez-ui2/src/main/webapp/tests/unit/models/timeline-test.js
new file mode 100644
index 0000000..fc52feb
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/models/timeline-test.js
@@ -0,0 +1,124 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 { moduleForModel, test } from 'ember-qunit';
+
+moduleForModel('timeline', 'Unit | Model | timeline', {
+  // 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.needs);
+
+  assert.ok(model.entityID);
+  assert.ok(model.appID);
+  assert.ok(model.app);
+
+  assert.ok(model.atsStatus);
+  assert.ok(model.status);
+  assert.ok(model.progress);
+
+  assert.ok(model.startTime);
+  assert.ok(model.endTime);
+  assert.ok(model.duration);
+
+  assert.ok(model.counterGroups);
+  assert.ok(model.counterHash);
+});
+
+test('appID test', function(assert) {
+  let model = this.subject();
+
+  Ember.run(function () {
+    model.set("entityID", "a_1_2_3");
+    assert.equal(model.get("appID"), "application_1_2");
+  });
+});
+
+test('status test', function(assert) {
+  let model = this.subject();
+
+  Ember.run(function () {
+    model.set("atsStatus", "RUNNING");
+    assert.equal(model.get("status"), "RUNNING");
+
+    model.set("app", {
+      status: "FAILED"
+    });
+    assert.equal(model.get("status"), "FAILED");
+  });
+});
+
+test('progress test', function(assert) {
+  let model = this.subject();
+
+  Ember.run(function () {
+    model.set("status", "RUNNING");
+    assert.equal(model.get("progress"), null);
+
+    model.set("status", "SUCCEEDED");
+    assert.equal(model.get("progress"), 1);
+  });
+});
+
+test('duration test', function(assert) {
+  let model = this.subject();
+
+  Ember.run(function () {
+    model.set("startTime", 100);
+    model.set("endTime", 200);
+    assert.equal(model.get("duration"), 100);
+  });
+});
+
+test('counterHash test', function(assert) {
+  let model = this.subject(),
+      testCounterGroup = [{
+        counterGroupName: "group_1",
+        counters: [{
+          counterName: "counter_1_1",
+          counterValue: "value_1_1"
+        },{
+          counterName: "counter_1_2",
+          counterValue: "value_1_2"
+        }]
+      },{
+        counterGroupName: "group_2",
+        counters: [{
+          counterName: "counter_2_1",
+          counterValue: "value_2_1"
+        },{
+          counterName: "counter_2_2",
+          counterValue: "value_2_2"
+        }]
+      }];
+
+  Ember.run(function () {
+    model.set("counterGroups", testCounterGroup);
+    assert.equal(model.get("counterHash.group_1.counter_1_1"), "value_1_1");
+    assert.equal(model.get("counterHash.group_1.counter_1_2"), "value_1_2");
+    assert.equal(model.get("counterHash.group_2.counter_2_1"), "value_2_1");
+    assert.equal(model.get("counterHash.group_2.counter_2_2"), "value_2_2");
+  });
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js
index 9513b91..222a19e 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js
@@ -33,7 +33,6 @@ test('Basic creation test', function(assert) {
   assert.ok(route);
   assert.ok(route.setDocTitle);
   assert.ok(route.setupController);
-  assert.ok(route.beforeModel);
 
   assert.ok(route.checkAndCall);
 
@@ -46,32 +45,26 @@ test('Basic creation test', function(assert) {
 
   assert.ok(route._setControllerModel);
   assert.ok(route.setLoader);
-});
-
-test('beforeModel test', function(assert) {
-  let route = this.subject(),
-      testQueryParams = {};
 
-  route.loadData = Ember.K;
-  assert.notOk(route.queryParams.queryParams);
-  route.beforeModel({queryParams: testQueryParams});
-  assert.equal(route.queryParams, testQueryParams);
+  assert.ok(route.actions.loadData);
 });
 
 test('checkAndCall test', function(assert) {
   let route = this.subject(),
-      testValue = {};
+      testValue = {},
+      testQuery = {};
 
-  assert.expect(2);
+  assert.expect(2 + 1);
 
-  route.testFunction = function (value) {
-    assert.equal(value, testValue, "Call with current id");
+  route.testFunction = function (value, query) {
+    assert.equal(value, testValue, "Value check for id 1");
+    assert.equal(query, testQuery, "Query check for id 1");
   };
   route.currentPromiseId = 1;
 
-  route.checkAndCall(1, "testFunction", testValue);
+  route.checkAndCall(1, "testFunction", testQuery, testValue);
   assert.throws(function () {
-    route.checkAndCall(2, "testFunction", testValue);
+    route.checkAndCall(2, "testFunction", testQuery, testValue);
   });
 });
 
@@ -79,10 +72,10 @@ test('loadData test - Hook sequence check', function(assert) {
   let route = this.subject();
 
   // Bind poilyfill
-  Function.prototype.bind = function (context, val1, val2) {
+  Function.prototype.bind = function (context, val1, val2, val3) {
     var that = this;
     return function (val) {
-      return that.call(context, val1, val2, val);
+      return that.call(context, val1, val2, val3, val);
     };
   };
 
@@ -118,10 +111,10 @@ test('loadData test - ID change check with exception throw', function(assert) {
   let route = this.subject();
 
   // Bind poilyfill
-  Function.prototype.bind = function (context, val1, val2) {
+  Function.prototype.bind = function (context, val1, val2, val3) {
     var that = this;
     return function (val) {
-      return that.call(context, val1, val2, val);
+      return that.call(context, val1, val2, val3, val);
     };
   };
 
@@ -160,6 +153,8 @@ test('loadData test - ID change check with exception throw', function(assert) {
 test('setLoading test', function(assert) {
   let route = this.subject();
 
+  route.controller = Ember.Object.create();
+
   assert.equal(route.get("isLoading"), false);
   route.setLoading();
   assert.equal(route.get("isLoading"), true);
@@ -178,6 +173,8 @@ test('setValue test', function(assert) {
   let route = this.subject(),
       testVal = {};
 
+  route.controller = Ember.Object.create();
+
   route.setLoading();
   assert.equal(route.get("loadedValue"), null);
   assert.equal(route.get("isLoading"), true);

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/tests/unit/routes/dags-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/dags-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/dags-test.js
new file mode 100644
index 0000000..3dabfe4
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/dags-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:dags', 'Unit | Route | dags', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.load);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/d34cbe07/tez-ui2/src/main/webapp/tests/unit/serializers/ahs-app-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/serializers/ahs-app-test.js b/tez-ui2/src/main/webapp/tests/unit/serializers/ahs-app-test.js
new file mode 100644
index 0000000..8e44179
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/serializers/ahs-app-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('serializer:ahs-app', 'Unit | Serializer | ahs app', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:timeline']
+});
+
+test('Basic creation test', function(assert) {
+  let serializer = this.subject();
+
+  assert.ok(serializer);
+  assert.ok(serializer.primaryKey);
+  assert.ok(serializer.extractArrayPayload);
+
+  assert.ok(serializer.maps);
+});


[40/45] tez git commit: TEZ-3080. Tez UI 2: Ensure UI 2 is in-line with UI 1 (sree)

Posted by sr...@apache.org.
TEZ-3080. Tez UI 2: Ensure UI 2 is in-line with UI 1 (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/08e55ceb
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/08e55ceb
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/08e55ceb

Branch: refs/heads/TEZ-2980
Commit: 08e55cebd77cd4f057c4ad428799f720f26971a7
Parents: 9459969
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Tue Feb 2 03:34:39 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:32:53 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |  1 +
 .../main/webapp/app/controllers/app/index.js    | 12 +++++
 .../main/webapp/app/controllers/vertex/index.js | 28 +++++++++++
 tez-ui2/src/main/webapp/app/models/timeline.js  |  5 +-
 tez-ui2/src/main/webapp/app/models/vertex.js    |  5 ++
 .../src/main/webapp/app/serializers/timeline.js | 14 ++++++
 .../src/main/webapp/app/serializers/vertex.js   |  5 ++
 .../main/webapp/app/styles/details-page.less    |  8 ++-
 tez-ui2/src/main/webapp/app/styles/shared.less  | 13 +++++
 .../src/main/webapp/app/templates/app/index.hbs |  4 +-
 .../main/webapp/app/templates/attempt/index.hbs | 12 +++++
 .../src/main/webapp/app/templates/dag/index.hbs | 11 ++++
 .../main/webapp/app/templates/task/index.hbs    | 12 +++++
 .../main/webapp/app/templates/vertex/index.hbs  | 53 ++++++++++++++++++--
 .../tests/unit/controllers/app/index-test.js    |  1 +
 15 files changed, 176 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/08e55ceb/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index 38f474a..b653e42 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -32,3 +32,4 @@ ALL CHANGES:
   TEZ-3062. Tez UI 2: Integrate graphical view
   TEZ-3058. Tez UI 2: Add download data functionality
   TEZ-3084. Tez UI 2: Display caller type and info
+  TEZ-3080. Tez UI 2: Ensure UI 2 is in-line with UI 1

http://git-wip-us.apache.org/repos/asf/tez/blob/08e55ceb/tez-ui2/src/main/webapp/app/controllers/app/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/app/index.js b/tez-ui2/src/main/webapp/app/controllers/app/index.js
index 9745328..cf199f8 100644
--- a/tez-ui2/src/main/webapp/app/controllers/app/index.js
+++ b/tez-ui2/src/main/webapp/app/controllers/app/index.js
@@ -16,7 +16,19 @@
  * limitations under the License.
  */
 
+import Ember from 'ember';
 import PageController from '../page';
 
 export default PageController.extend({
+
+  trackingURL: Ember.computed("model.appID", function () {
+    console.log(this.get("hosts.rm"));
+    return [
+      this.get("hosts.rm"),
+      this.get("env.app.namespaces.web.rm"),
+      "app",
+      this.get("model.appID")
+    ].join("/");
+  })
+
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/08e55ceb/tez-ui2/src/main/webapp/app/controllers/vertex/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/vertex/index.js b/tez-ui2/src/main/webapp/app/controllers/vertex/index.js
index 9745328..c14d113 100644
--- a/tez-ui2/src/main/webapp/app/controllers/vertex/index.js
+++ b/tez-ui2/src/main/webapp/app/controllers/vertex/index.js
@@ -16,7 +16,35 @@
  * limitations under the License.
  */
 
+import Ember from 'ember';
+
 import PageController from '../page';
 
+function taskLinkComputerFactory(name) {
+  return Ember.computed(name, function () {
+    var tasks = this.get(name);
+
+    if(tasks) {
+      return tasks.map(function (task) {
+        return {
+          routeName: 'task',
+          model: task,
+          text: task
+        };
+      });
+    }
+  });
+}
+
 export default PageController.extend({
+
+  pathname: Ember.computed(function() {
+    return window.location.pathname;
+  }).volatile(),
+
+  firstTasksToStart: taskLinkComputerFactory("model.firstTasksToStart"),
+  lastTasksToFinish: taskLinkComputerFactory("model.lastTasksToFinish"),
+  shortestDurationTasks: taskLinkComputerFactory("model.shortestDurationTasks"),
+  longestDurationTasks: taskLinkComputerFactory("model.longestDurationTasks"),
+
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/08e55ceb/tez-ui2/src/main/webapp/app/models/timeline.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/timeline.js b/tez-ui2/src/main/webapp/app/models/timeline.js
index 60157d3..ca82193 100644
--- a/tez-ui2/src/main/webapp/app/models/timeline.js
+++ b/tez-ui2/src/main/webapp/app/models/timeline.js
@@ -82,5 +82,8 @@ export default AbstractModel.extend({
     });
 
     return counterHash;
-  })
+  }),
+
+  diagnostics: DS.attr('string'),
+
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/08e55ceb/tez-ui2/src/main/webapp/app/models/vertex.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/vertex.js b/tez-ui2/src/main/webapp/app/models/vertex.js
index d8f1b43..1f4365b 100644
--- a/tez-ui2/src/main/webapp/app/models/vertex.js
+++ b/tez-ui2/src/main/webapp/app/models/vertex.js
@@ -106,6 +106,11 @@ export default AMTimelineModel.extend({
   maxDuration: DS.attr('number'),
   avgDuration: DS.attr('number'),
 
+  firstTasksToStart: DS.attr("object"),
+  lastTasksToFinish: DS.attr("object"),
+  shortestDurationTasks: DS.attr("object"),
+  longestDurationTasks: DS.attr("object"),
+
   processorClassName: DS.attr('string'),
 
   dagID: DS.attr('string'),

http://git-wip-us.apache.org/repos/asf/tez/blob/08e55ceb/tez-ui2/src/main/webapp/app/serializers/timeline.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/timeline.js b/tez-ui2/src/main/webapp/app/serializers/timeline.js
index 2f6a0d5..c258c64 100644
--- a/tez-ui2/src/main/webapp/app/serializers/timeline.js
+++ b/tez-ui2/src/main/webapp/app/serializers/timeline.js
@@ -16,8 +16,20 @@
  * limitations under the License.
  */
 
+import Ember from 'ember';
+
 import LoaderSerializer from './loader';
 
+function getDiagnostics(source) {
+  var diagnostics = Ember.get(source, 'otherinfo.diagnostics') || "";
+
+  diagnostics = diagnostics.replace(/\t/g, "&emsp;&emsp;");
+  diagnostics = diagnostics.replace(/\[/g, "<div>&#187; ");
+  diagnostics = diagnostics.replace(/\]/g, "</div>");
+
+  return diagnostics;
+}
+
 export default LoaderSerializer.extend({
   primaryKey: 'entity',
 
@@ -33,6 +45,8 @@ export default LoaderSerializer.extend({
     startTime: 'otherinfo.startTime',
     endTime: 'otherinfo.endTime',
 
+    diagnostics: getDiagnostics,
+
     _counterGroups: 'otherinfo.counters.counterGroups'
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/08e55ceb/tez-ui2/src/main/webapp/app/serializers/vertex.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/vertex.js b/tez-ui2/src/main/webapp/app/serializers/vertex.js
index 1f99f3a..bf074f1 100644
--- a/tez-ui2/src/main/webapp/app/serializers/vertex.js
+++ b/tez-ui2/src/main/webapp/app/serializers/vertex.js
@@ -44,6 +44,11 @@ export default TimelineSerializer.extend({
     maxDuration:  'otherinfo.stats.maxTaskDuration',
     avgDuration:  'otherinfo.stats.avgTaskDuration',
 
+    firstTasksToStart:  'otherinfo.stats.firstTasksToStart',
+    lastTasksToFinish:  'otherinfo.stats.lastTasksToFinish',
+    shortestDurationTasks:  'otherinfo.stats.shortestDurationTasks',
+    longestDurationTasks:  'otherinfo.stats.longestDurationTasks',
+
     processorClassName: getProcessorClass,
 
     dagID: 'primaryfilters.TEZ_DAG_ID.0',

http://git-wip-us.apache.org/repos/asf/tez/blob/08e55ceb/tez-ui2/src/main/webapp/app/styles/details-page.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/details-page.less b/tez-ui2/src/main/webapp/app/styles/details-page.less
index 4f65018..b3b1a16 100644
--- a/tez-ui2/src/main/webapp/app/styles/details-page.less
+++ b/tez-ui2/src/main/webapp/app/styles/details-page.less
@@ -16,13 +16,14 @@
  * limitations under the License.
  */
 
+@import "bower_components/snippet-ss/less/no";
+
 .detail-list {
   display: inline-block;
 
   margin: 0 10px 10px 0;
 
   table-layout: fixed;
-  white-space: nowrap;
 
   .progress {
     margin-bottom: 0px;
@@ -40,6 +41,11 @@
 
   td {
     padding: 0px 20px 0px 0px;
+    white-space: nowrap;
+
+    .ember-view {
+      display: inline;
+    }
   }
 
   td:first-child {

http://git-wip-us.apache.org/repos/asf/tez/blob/08e55ceb/tez-ui2/src/main/webapp/app/styles/shared.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/shared.less b/tez-ui2/src/main/webapp/app/styles/shared.less
index 0dc70f7..a96636f 100644
--- a/tez-ui2/src/main/webapp/app/styles/shared.less
+++ b/tez-ui2/src/main/webapp/app/styles/shared.less
@@ -38,3 +38,16 @@ b {
     bottom: .2em;
   }
 }
+
+.diagnostics {
+  padding: 10px;
+  white-space: pre-line;
+
+  div {
+    padding-left: 20px;
+  }
+}
+
+.CodeMirror {
+  height: auto;
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/08e55ceb/tez-ui2/src/main/webapp/app/templates/app/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/app/index.hbs b/tez-ui2/src/main/webapp/app/templates/app/index.hbs
index 3567f32..feaee3a 100644
--- a/tez-ui2/src/main/webapp/app/templates/app/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/app/index.hbs
@@ -55,8 +55,8 @@
       </thead>
       <tbody>
       <tr>
-        <td>Application ID</td>
-        <td>{{model.app.entityID}}</td>
+        <td>Application Tracking URL</td>
+        <td><a href={{trackingURL}} target="_blank">{{model.app.entityID}}</a></td>
       </tr>
       <tr>
         <td>Application Name</td>

http://git-wip-us.apache.org/repos/asf/tez/blob/08e55ceb/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs b/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs
index 1d77e25..a8be79f 100644
--- a/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs
@@ -62,6 +62,18 @@
       </tr>
     </tbody>
   </table>
+
+  {{#if model.diagnostics}}
+    <div class="panel panel-danger">
+      <div class="panel-heading">
+        Diagnostics
+      </div>
+      <div class="diagnostics">
+        {{{model.diagnostics}}}
+      </div>
+    </div>
+  {{/if}}
+
 {{else}}
   {{partial "loading"}}
 {{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/08e55ceb/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/index.hbs b/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
index 7ea00c5..0003a64 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
@@ -78,6 +78,17 @@
     {{caller-info type=model.callerType info=model.callerInfo}}
   {{/if}}
 
+  {{#if model.diagnostics}}
+    <div class="panel panel-danger">
+      <div class="panel-heading">
+        Diagnostics
+      </div>
+      <div class="diagnostics">
+        {{{model.diagnostics}}}
+      </div>
+    </div>
+  {{/if}}
+
   {{outlet}}
 
 {{else}}

http://git-wip-us.apache.org/repos/asf/tez/blob/08e55ceb/tez-ui2/src/main/webapp/app/templates/task/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/task/index.hbs b/tez-ui2/src/main/webapp/app/templates/task/index.hbs
index b9d98c8..c4b0a5a 100644
--- a/tez-ui2/src/main/webapp/app/templates/task/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/task/index.hbs
@@ -54,6 +54,18 @@
       </tr>
     </tbody>
   </table>
+
+  {{#if model.diagnostics}}
+    <div class="panel panel-danger">
+      <div class="panel-heading">
+        Diagnostics
+      </div>
+      <div class="diagnostics">
+        {{{model.diagnostics}}}
+      </div>
+    </div>
+  {{/if}}
+
 {{else}}
   {{partial "loading"}}
 {{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/08e55ceb/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs b/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs
index eb3a477..cac5c92 100644
--- a/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs
@@ -72,12 +72,18 @@
         <td>First Task Start Time</td>
         <td>
           {{txt model.firstTaskStartTime type="date"}}
+          {{#if firstTasksToStart}}
+            [{{em-table-linked-cell content=firstTasksToStart}}]
+          {{/if}}
         </td>
       </tr>
       <tr>
         <td>Last Task Finish Time</td>
         <td>
           {{txt model.lastTaskFinishTime type="date"}}
+          {{#if lastTasksToFinish}}
+            [{{em-table-linked-cell content=lastTasksToFinish}}]
+          {{/if}}
         </td>
       </tr>
     </tbody>
@@ -94,19 +100,40 @@
     <tbody>
       <tr>
         <td>Total Tasks</td>
-        <td>{{txt model.totalTasks type="number"}}</td>
+          <td>
+            <a href="{{pathname}}/tasks">{{txt model.totalTasks type="number"}} Tasks</a>
+          </td>
       </tr>
       <tr>
         <td>Successful Tasks</td>
-        <td>{{txt model.successfulTasks type="number"}}</td>
+        {{#if model.successfulTasks}}
+          <td>
+            <a href="{{pathname}}/tasks?searchText=SUCCEEDED">{{txt model.successfulTasks type="number"}} Succeeded</a>
+          </td>
+        {{else}}
+          <td>{{txt model.successfulTasks type="number"}}</td>
+        {{/if}}
       </tr>
       <tr>
         <td>Failed Tasks</td>
-        <td>{{txt model.failedTasks type="number"}}</td>
+        {{#if model.failedTasks}}
+          <td>
+            <a href="{{pathname}}/tasks?searchText=FAILED">{{txt model.failedTasks type="number"}} Failed</a>
+          </td>
+        {{else}}
+          <td>{{txt model.failedTasks type="number"}}</td>
+        {{/if}}
       </tr>
       <tr>
         <td>Killed Tasks</td>
-        <td>{{txt model.killedTasks type="number"}}</td>
+        {{#if model.killedTasks}}
+          <td>
+            <a href="{{pathname}}/tasks?searchText=KILLED">{{txt model.killedTasks type="number"}} Killed</a>
+          </td>
+        {{else}}
+          <td>{{txt model.killedTasks type="number"}}</td>
+        {{/if}}
+
       </tr>
       <tr>
         <td>Average Duration</td>
@@ -118,16 +145,34 @@
         <td>Minimum Duration</td>
         <td>
           {{txt model.minDuration type="duration"}}
+          {{#if shortestDurationTasks}}
+            [{{em-table-linked-cell content=shortestDurationTasks}}]
+          {{/if}}
         </td>
       </tr>
       <tr>
         <td>Maximum Duration</td>
         <td>
           {{txt model.maxDuration type="duration"}}
+          {{#if longestDurationTasks}}
+            [{{em-table-linked-cell content=longestDurationTasks}}]
+          {{/if}}
         </td>
       </tr>
     </tbody>
   </table>
+
+  {{#if model.diagnostics}}
+    <div class="panel panel-danger">
+      <div class="panel-heading">
+        Diagnostics
+      </div>
+      <div class="diagnostics">
+        {{{model.diagnostics}}}
+      </div>
+    </div>
+  {{/if}}
+
 {{else}}
   {{partial "loading"}}
 {{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/08e55ceb/tez-ui2/src/main/webapp/tests/unit/controllers/app/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/app/index-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/app/index-test.js
index 9bd6604..676b1d4 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/app/index-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/app/index-test.js
@@ -32,4 +32,5 @@ test('Basic creation test', function(assert) {
   });
 
   assert.ok(controller);
+  assert.ok(controller.trackingURL);
 });


[20/45] tez git commit: TEZ-3039. Tez UI 2: Create all sub-pages for DAG (sree)

Posted by sr...@apache.org.
TEZ-3039. Tez UI 2: Create all sub-pages for DAG (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/a1c3622a
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/a1c3622a
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/a1c3622a

Branch: refs/heads/TEZ-2980
Commit: a1c3622abdcb70151314bb272bcb0ece12b337b0
Parents: a0ba39c
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Mon Jan 18 21:25:54 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:32:15 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |  1 +
 tez-ui2/src/main/webapp/app/adapters/attempt.js | 22 ++++++
 tez-ui2/src/main/webapp/app/adapters/task.js    | 22 ++++++
 .../src/main/webapp/app/adapters/timeline.js    | 77 +++++++++++++++++++-
 tez-ui2/src/main/webapp/app/adapters/vertex.js  | 22 ++++++
 .../main/webapp/app/controllers/dag/attempts.js | 61 +++++++++++++++-
 .../main/webapp/app/controllers/dag/tasks.js    | 49 ++++++++++++-
 .../main/webapp/app/controllers/dag/vertices.js | 61 +++++++++++++++-
 tez-ui2/src/main/webapp/app/controllers/dags.js |  2 +-
 .../main/webapp/app/controllers/table-page.js   | 15 +++-
 tez-ui2/src/main/webapp/app/models/attempt.js   | 71 ++++++++++++++++++
 tez-ui2/src/main/webapp/app/models/dag.js       |  2 +
 tez-ui2/src/main/webapp/app/models/task.js      | 62 ++++++++++++++++
 tez-ui2/src/main/webapp/app/models/vertex.js    | 61 ++++++++++++++++
 .../src/main/webapp/app/routes/dag/attempts.js  |  8 +-
 tez-ui2/src/main/webapp/app/routes/dag/tasks.js |  8 +-
 .../src/main/webapp/app/routes/dag/vertices.js  |  8 +-
 .../src/main/webapp/app/serializers/attempt.js  | 30 ++++++++
 tez-ui2/src/main/webapp/app/serializers/dag.js  | 21 +++++-
 tez-ui2/src/main/webapp/app/serializers/task.js | 26 +++++++
 .../src/main/webapp/app/serializers/timeline.js | 13 ++++
 .../src/main/webapp/app/serializers/vertex.js   | 44 +++++++++++
 .../main/webapp/app/templates/dag/attempts.hbs  | 16 +++-
 .../src/main/webapp/app/templates/dag/tasks.hbs | 16 +++-
 .../main/webapp/app/templates/dag/vertices.hbs  | 16 +++-
 .../src/main/webapp/config/default-app-conf.js  |  3 +-
 .../webapp/tests/unit/adapters/attempt-test.js  | 30 ++++++++
 .../webapp/tests/unit/adapters/task-test.js     | 29 ++++++++
 .../webapp/tests/unit/adapters/timeline-test.js | 53 ++++++++++++++
 .../webapp/tests/unit/adapters/vertex-test.js   | 30 ++++++++
 .../tests/unit/controllers/dag/attempts-test.js |  1 +
 .../tests/unit/controllers/dag/tasks-test.js    |  1 +
 .../tests/unit/controllers/dag/vertices-test.js |  1 +
 .../webapp/tests/unit/models/attempt-test.js    | 63 ++++++++++++++++
 .../main/webapp/tests/unit/models/task-test.js  | 55 ++++++++++++++
 .../webapp/tests/unit/models/vertex-test.js     | 48 ++++++++++++
 .../tests/unit/routes/dag/attempts-test.js      |  1 +
 .../webapp/tests/unit/routes/dag/tasks-test.js  |  1 +
 .../tests/unit/routes/dag/vertices-test.js      |  1 +
 .../tests/unit/serializers/attempt-test.js      | 31 ++++++++
 .../webapp/tests/unit/serializers/dag-test.js   | 22 ++++++
 .../webapp/tests/unit/serializers/task-test.js  | 31 ++++++++
 .../tests/unit/serializers/timeline-test.js     |  1 +
 .../tests/unit/serializers/vertex-test.js       | 49 +++++++++++++
 44 files changed, 1163 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index 925dc7f..372369a 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -14,3 +14,4 @@ ALL CHANGES:
   TEZ-3027. Tez UI 2: Add header and footer elements
   TEZ-2986. Tez UI 2: Implement All DAGs page
   TEZ-3038. Tez UI 2: Create DAG details page
+  TEZ-3039. Tez UI 2: Create all sub-pages for DAG

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/app/adapters/attempt.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/attempt.js b/tez-ui2/src/main/webapp/app/adapters/attempt.js
new file mode 100644
index 0000000..b47e05f
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/adapters/attempt.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 TimelineAdapter from './timeline';
+
+export default TimelineAdapter.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/app/adapters/task.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/task.js b/tez-ui2/src/main/webapp/app/adapters/task.js
new file mode 100644
index 0000000..b47e05f
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/adapters/task.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 TimelineAdapter from './timeline';
+
+export default TimelineAdapter.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/app/adapters/timeline.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/timeline.js b/tez-ui2/src/main/webapp/app/adapters/timeline.js
index 454cbc9..6e06c7b 100644
--- a/tez-ui2/src/main/webapp/app/adapters/timeline.js
+++ b/tez-ui2/src/main/webapp/app/adapters/timeline.js
@@ -1,3 +1,5 @@
+/*global more*/
+
 /**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -18,8 +20,81 @@
 
 import AbstractAdapter from './abstract';
 
+var MoreObject = more.Object;
+
 export default AbstractAdapter.extend({
   serverName: "timeline",
 
-  // Any timeline specific adapter changes must be added here
+  filters: {
+    dagID: 'TEZ_DAG_ID',
+    vertexID: 'TEZ_VERTEX_ID',
+    taskID: 'TEZ_TASK_ID',
+    attemptID: 'TEZ_TASK_ATTEMPT_ID',
+    hiveQueryID: 'HIVE_QUERY_ID',
+    appID: 'applicationId'
+  },
+
+  stringifyFilters: function (filters) {
+    var filterStrs = [];
+
+    MoreObject.forEach(filters, function (key, value) {
+      filterStrs.push(`${key}:${value}`);
+    });
+
+    return filterStrs.join(",");
+  },
+
+  normalizeQuery: function(query) {
+    var primaryFilter = null, // Primary must have just one single filter
+        secondaryFilters = {},
+        normalQuery = {},
+        filterStr;
+
+    MoreObject.forEach(query, function (key, value) {
+      var filter = this.get(`filters.${key}`);
+
+      if(filter) {
+        if(!primaryFilter) {
+          primaryFilter = {};
+          primaryFilter[filter] = value;
+        }
+        else {
+          secondaryFilters[filter] = value;
+        }
+      }
+      else {
+        normalQuery[key] = value;
+      }
+    }, this);
+
+    // primaryFilter
+    if(primaryFilter) {
+      filterStr = this.stringifyFilters(primaryFilter);
+    }
+    if(filterStr) {
+      normalQuery.primaryFilter = filterStr;
+    }
+
+    // secondaryFilters
+    filterStr = this.stringifyFilters(secondaryFilters);
+    if(filterStr) {
+      normalQuery.secondaryFilter = filterStr;
+    }
+
+    // Limit
+    normalQuery.limit = normalQuery.limit || this.get("env.app.rowLoadLimit");
+
+    return normalQuery;
+  },
+
+  query: function (store, type, query/*, recordArray*/) {
+    var queryParams = query.params,
+        url = this.buildURL(type.modelName, null, null, 'query', queryParams, query.urlParams);
+
+    if(query) {
+      queryParams = this.normalizeQuery(queryParams);
+    }
+
+    return this._loaderAjax(url, queryParams, query.nameSpace);
+  }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/app/adapters/vertex.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/vertex.js b/tez-ui2/src/main/webapp/app/adapters/vertex.js
new file mode 100644
index 0000000..b47e05f
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/adapters/vertex.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 TimelineAdapter from './timeline';
+
+export default TimelineAdapter.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js b/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
index d5efc50..1ffc00c 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
@@ -16,11 +16,66 @@
  * limitations under the License.
  */
 
-import PageController from '../page';
+import TablePageController from '../table-page';
+import ColumnDefinition from 'em-table/utils/column-definition';
 
-export default PageController.extend({
+export default TablePageController.extend({
   breadcrumbs: [{
     text: "All Attempts",
     routeName: "dag.attempts",
-  }]
+  }],
+
+  columns: ColumnDefinition.make([{
+    id: 'index',
+    headerTitle: 'Attempt No',
+    contentPath: 'index'
+  },{
+    id: 'taskIndex',
+    headerTitle: 'Task Index',
+    contentPath: 'taskIndex'
+  },{
+    id: 'vertexName',
+    headerTitle: 'Vertex Index',
+    contentPath: 'vertexName'
+  },{
+    id: 'status',
+    headerTitle: 'Status',
+    contentPath: 'status',
+    cellComponentName: 'em-table-status-cell'
+  },{
+    id: 'progress',
+    headerTitle: 'Progress',
+    contentPath: 'progress',
+    cellComponentName: 'em-table-progress-cell',
+    observePath: true
+  },{
+    id: 'startTime',
+    headerTitle: 'Start Time',
+    contentPath: 'startTime',
+    cellDefinition: {
+      type: 'date'
+    }
+  },{
+    id: 'endTime',
+    headerTitle: 'End Time',
+    contentPath: 'endTime',
+    cellDefinition: {
+      type: 'date'
+    }
+  },{
+    id: 'duration',
+    headerTitle: 'Duration',
+    contentPath: 'duration',
+    cellDefinition: {
+      type: 'duration'
+    }
+  },{
+    id: 'containerID',
+    headerTitle: 'Container',
+    contentPath: 'containerID'
+  },{
+    id: 'nodeID',
+    headerTitle: 'Node',
+    contentPath: 'nodeID'
+  }])
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js b/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
index e83df5d..7c91deb 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
@@ -16,11 +16,54 @@
  * limitations under the License.
  */
 
-import PageController from '../page';
+import TablePageController from '../table-page';
+import ColumnDefinition from 'em-table/utils/column-definition';
 
-export default PageController.extend({
+export default TablePageController.extend({
   breadcrumbs: [{
     text: "All Tasks",
     routeName: "dag.tasks",
-  }]
+  }],
+
+  columns: ColumnDefinition.make([{
+    id: 'index',
+    headerTitle: 'Task Index',
+    contentPath: 'index'
+  },{
+    id: 'vertexName',
+    headerTitle: 'Vertex Name',
+    contentPath: 'vertexName'
+  },{
+    id: 'status',
+    headerTitle: 'Status',
+    contentPath: 'status',
+    cellComponentName: 'em-table-status-cell'
+  },{
+    id: 'progress',
+    headerTitle: 'Progress',
+    contentPath: 'progress',
+    cellComponentName: 'em-table-progress-cell',
+    observePath: true
+  },{
+    id: 'startTime',
+    headerTitle: 'Start Time',
+    contentPath: 'startTime',
+    cellDefinition: {
+      type: 'date'
+    }
+  },{
+    id: 'endTime',
+    headerTitle: 'End Time',
+    contentPath: 'endTime',
+    cellDefinition: {
+      type: 'date'
+    }
+  },{
+    id: 'duration',
+    headerTitle: 'Duration',
+    contentPath: 'duration',
+    cellDefinition: {
+      type: 'duration'
+    }
+  }])
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js b/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
index e001652..7bdc229 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
@@ -16,11 +16,66 @@
  * limitations under the License.
  */
 
-import PageController from '../page';
+import TablePageController from '../table-page';
+import ColumnDefinition from 'em-table/utils/column-definition';
 
-export default PageController.extend({
+export default TablePageController.extend({
   breadcrumbs: [{
     text: "All Vertices",
     routeName: "dag.vertices",
-  }]
+  }],
+
+  columns: ColumnDefinition.make([{
+    id: 'name',
+    headerTitle: 'Vertex Name',
+    contentPath: 'name',
+  },{
+    id: 'entityID',
+    headerTitle: 'Vertex Id',
+    contentPath: 'entityID'
+  },{
+    id: 'status',
+    headerTitle: 'Status',
+    contentPath: 'status',
+    cellComponentName: 'em-table-status-cell'
+  },{
+    id: 'progress',
+    headerTitle: 'Progress',
+    contentPath: 'progress',
+    cellComponentName: 'em-table-progress-cell',
+    observePath: true
+  },{
+    id: 'startTime',
+    headerTitle: 'Start Time',
+    contentPath: 'startTime',
+    cellDefinition: {
+      type: 'date'
+    }
+  },{
+    id: 'endTime',
+    headerTitle: 'End Time',
+    contentPath: 'endTime',
+    cellDefinition: {
+      type: 'date'
+    }
+  },{
+    id: 'duration',
+    headerTitle: 'Duration',
+    contentPath: 'duration',
+    cellDefinition: {
+      type: 'duration'
+    }
+  },{
+    id: 'firstTaskStartTime',
+    headerTitle: 'First Task Start Time',
+    contentPath: 'firstTaskStartTime',
+    cellDefinition: {
+     type: 'date'
+    }
+  },{
+    id: 'processorClassName',
+    headerTitle: 'Processor Class',
+    contentPath: 'processorClassName',
+  }])
+
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/app/controllers/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dags.js b/tez-ui2/src/main/webapp/app/controllers/dags.js
index 354f4f8..8d7e73e 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dags.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dags.js
@@ -24,7 +24,7 @@ export default TablePageController.extend({
   breadcrumbs: [],
 
   columns: ColumnDefinition.make([{
-    id: 'dagName',
+    id: 'name',
     headerTitle: 'Dag Name',
     contentPath: 'name',
     cellComponentName: 'em-table-linked-cell',

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/app/controllers/table-page.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/table-page.js b/tez-ui2/src/main/webapp/app/controllers/table-page.js
index 14219d9..1f2fe57 100644
--- a/tez-ui2/src/main/webapp/app/controllers/table-page.js
+++ b/tez-ui2/src/main/webapp/app/controllers/table-page.js
@@ -16,7 +16,10 @@
  * limitations under the License.
  */
 
+import Ember from 'ember';
+
 import PageController from './page';
+import TableDefinition from 'em-table/utils/table-definition';
 
 export default PageController.extend({
   queryParams: ["rowCount", "searchText", "sortColumnId", "sortOrder", "pageNo"],
@@ -26,6 +29,16 @@ export default PageController.extend({
   sortOrder: "",
   pageNo: 1,
 
+  definition: Ember.computed(function () {
+    return TableDefinition.create({
+      rowCount: this.get("rowCount"),
+      searchText: this.get("searchText"),
+      sortColumnId: this.get("sortColumnId"),
+      sortOrder: this.get("sortOrder"),
+      pageNo: this.get("pageNo")
+    });
+  }),
+
   actions: {
     searchChanged: function (searchText) {
       this.set("searchText", searchText);
@@ -41,7 +54,7 @@ export default PageController.extend({
       this.set("rowCount", rowCount);
     },
     pageChanged: function (pageNum) {
-      this.set("pageNum", pageNum);
+      this.set("pageNo", pageNum);
     },
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/app/models/attempt.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/attempt.js b/tez-ui2/src/main/webapp/app/models/attempt.js
new file mode 100644
index 0000000..eb99169
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/models/attempt.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 Ember from 'ember';
+import DS from 'ember-data';
+
+import TimelineModel from './timeline';
+/*
+  Inherited properties
+
+  entityID - String
+  appID - Computed from entityID
+
+  status - String
+  progress - Computed from status
+
+  startTime - Number
+  endTime - Number
+  duration - Computed from start & end times
+
+  counterGroups - Array
+  counterHash - Computed from counterGroups
+*/
+
+export default TimelineModel.extend({
+  needs: {
+    dag: {
+      type: "dag",
+      idKey: "dagID",
+      silent: true
+    }
+  },
+
+  index: Ember.computed("entityID", function () {
+    var idParts = this.get("entityID").split("_");
+    return idParts[Math.max(idParts.length - 1, 1)];
+  }),
+
+  taskID: DS.attr('string'),
+  taskIndex: Ember.computed("taskID", function () {
+    var idParts = this.get("taskID").split("_");
+    return idParts.slice(Math.max(idParts.length - 2, 1)).join("_");
+  }),
+
+  vertexID: DS.attr('string'),
+  vertexName: Ember.computed("vertexID", "dag", function () {
+    var vertexID = this.get("vertexID");
+    return this.get(`dag.vertexIdNameMap.${vertexID}`);
+  }),
+
+  dagID: DS.attr('string'),
+  dag: DS.attr('object'), // Auto-loaded by need
+
+  containerID: DS.attr('string'),
+  nodeID: DS.attr('string'),
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/app/models/dag.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/dag.js b/tez-ui2/src/main/webapp/app/models/dag.js
index 4e9ff7c..2efb65f 100644
--- a/tez-ui2/src/main/webapp/app/models/dag.js
+++ b/tez-ui2/src/main/webapp/app/models/dag.js
@@ -48,4 +48,6 @@ export default TimelineModel.extend({
   queue: Ember.computed("app", function () {
     return this.get("app.queue");
   }),
+
+  vertexIdNameMap: DS.attr("object"),
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/app/models/task.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/task.js b/tez-ui2/src/main/webapp/app/models/task.js
new file mode 100644
index 0000000..2ded910
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/models/task.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 DS from 'ember-data';
+
+import TimelineModel from './timeline';
+/*
+  Inherited properties
+
+  entityID - String
+  appID - Computed from entityID
+
+  status - String
+  progress - Computed from status
+
+  startTime - Number
+  endTime - Number
+  duration - Computed from start & end times
+
+  counterGroups - Array
+  counterHash - Computed from counterGroups
+*/
+
+export default TimelineModel.extend({
+  needs: {
+    dag: {
+      type: "dag",
+      idKey: "dagID",
+      silent: true
+    }
+  },
+
+  index: Ember.computed("entityID", function () {
+    var idParts = this.get("entityID").split("_");
+    return idParts.slice(Math.max(idParts.length - 2, 1)).join("_");
+  }),
+
+  vertexID: DS.attr('string'),
+  vertexName: Ember.computed("vertexID", "dag", function () {
+    var vertexID = this.get("vertexID");
+    return this.get(`dag.vertexIdNameMap.${vertexID}`);
+  }),
+
+  dagID: DS.attr('string'),
+  dag: DS.attr('object'), // Auto-loaded by need
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/app/models/vertex.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/vertex.js b/tez-ui2/src/main/webapp/app/models/vertex.js
new file mode 100644
index 0000000..dcdb0f2
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/models/vertex.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 Ember from 'ember';
+import DS from 'ember-data';
+
+import TimelineModel from './timeline';
+/*
+  Inherited properties
+
+  entityID - String
+  appID - Computed from entityID
+
+  status - String
+  progress - Computed from status
+
+  startTime - Number
+  endTime - Number
+  duration - Computed from start & end times
+
+  counterGroups - Array
+  counterHash - Computed from counterGroups
+*/
+
+export default TimelineModel.extend({
+  name: DS.attr('string'),
+
+  firstTaskStartTime: DS.attr('number'),
+
+  numTasks: DS.attr('number'),
+  failedTasks: DS.attr('number'),
+  sucessfulTasks: DS.attr('number'),
+  killedTasks: DS.attr('number'),
+
+  runningTasks: Ember.computed("status", function () {
+    return this.get("status") === 'SUCCEEDED' ? 0 : null;
+  }),
+  pendingTasks: Ember.computed("status", function () {
+    return this.get("status") === 'SUCCEEDED' ? 0 : null;
+  }),
+
+  failedTaskAttempts: DS.attr('number'),
+  killedTaskAttempts: DS.attr('number'),
+
+  processorClassName: DS.attr('string'),
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/app/routes/dag/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag/attempts.js b/tez-ui2/src/main/webapp/app/routes/dag/attempts.js
index 5de1cab..3a05867 100644
--- a/tez-ui2/src/main/webapp/app/routes/dag/attempts.js
+++ b/tez-ui2/src/main/webapp/app/routes/dag/attempts.js
@@ -20,10 +20,16 @@ import Ember from 'ember';
 import AbstractRoute from '../abstract';
 
 export default AbstractRoute.extend({
-  title: "DAG Details",
+  title: "All Attempts",
 
   setupController: function (controller, model) {
     this._super(controller, model);
     Ember.run.later(this, "startCrumbBubble");
   },
+
+  load: function (/*value, query*/) {
+    return this.get("loader").query('attempt', {
+      dagID: this.modelFor("dag").id
+    });
+  }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/app/routes/dag/tasks.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag/tasks.js b/tez-ui2/src/main/webapp/app/routes/dag/tasks.js
index 5de1cab..3408a3e 100644
--- a/tez-ui2/src/main/webapp/app/routes/dag/tasks.js
+++ b/tez-ui2/src/main/webapp/app/routes/dag/tasks.js
@@ -20,10 +20,16 @@ import Ember from 'ember';
 import AbstractRoute from '../abstract';
 
 export default AbstractRoute.extend({
-  title: "DAG Details",
+  title: "All Tasks",
 
   setupController: function (controller, model) {
     this._super(controller, model);
     Ember.run.later(this, "startCrumbBubble");
   },
+
+  load: function (/*value, query*/) {
+    return this.get("loader").query('task', {
+      dagID: this.modelFor("dag").id
+    });
+  }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/app/routes/dag/vertices.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag/vertices.js b/tez-ui2/src/main/webapp/app/routes/dag/vertices.js
index 5de1cab..e8c0770 100644
--- a/tez-ui2/src/main/webapp/app/routes/dag/vertices.js
+++ b/tez-ui2/src/main/webapp/app/routes/dag/vertices.js
@@ -20,10 +20,16 @@ import Ember from 'ember';
 import AbstractRoute from '../abstract';
 
 export default AbstractRoute.extend({
-  title: "DAG Details",
+  title: "All Vertices",
 
   setupController: function (controller, model) {
     this._super(controller, model);
     Ember.run.later(this, "startCrumbBubble");
   },
+
+  load: function (/*value, query*/) {
+    return this.get("loader").query('vertex', {
+      dagID: this.modelFor("dag").id
+    });
+  }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/app/serializers/attempt.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/attempt.js b/tez-ui2/src/main/webapp/app/serializers/attempt.js
new file mode 100644
index 0000000..d7e2a7d
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/serializers/attempt.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 TimelineSerializer from './timeline';
+
+export default TimelineSerializer.extend({
+  maps: {
+    taskID: 'primaryfilters.TEZ_TASK_ID.0',
+    vertexID: 'primaryfilters.TEZ_VERTEX_ID.0',
+    dagID: 'primaryfilters.TEZ_DAG_ID.0',
+
+    containerID: 'otherinfo.containerId',
+    nodeID: 'otherinfo.nodeId',
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/app/serializers/dag.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/dag.js b/tez-ui2/src/main/webapp/app/serializers/dag.js
index 35c53ba..00113e4 100644
--- a/tez-ui2/src/main/webapp/app/serializers/dag.js
+++ b/tez-ui2/src/main/webapp/app/serializers/dag.js
@@ -1,3 +1,4 @@
+/*global more*/
 /**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -20,6 +21,8 @@ import Ember from 'ember';
 
 import TimelineSerializer from './timeline';
 
+var MoreObject = more.Object;
+
 function getStatus(source) {
   var status = Ember.get(source, 'otherinfo.status') || Ember.get(source, 'primaryfilters.status.0'),
       event = source.events;
@@ -86,9 +89,21 @@ function getContainerLogs(source) {
   return containerLogs;
 }
 
+function getIdNameMap(source) {
+  var nameIdMap = Ember.get(source, 'otherinfo.vertexNameIdMapping'),
+      idNameMap = {};
+
+  if(nameIdMap) {
+    MoreObject.forEach(nameIdMap, function (name, id) {
+      idNameMap[id] = name;
+    });
+  }
+
+  return idNameMap;
+}
+
 export default TimelineSerializer.extend({
   maps: {
-    entityID: 'entity',
     name: 'primaryfilters.dagName.0',
 
     user: 'primaryfilters.user.0',
@@ -101,11 +116,11 @@ export default TimelineSerializer.extend({
     endTime: getEndTime,
     // duration
 
-    appID: 'otherinfo.applicationId',
+    // appID
     domain: 'domain',
     // queue
     containerLogs: getContainerLogs,
 
-    counterGroups: 'otherinfo.counters.counterGroups'
+    vertexIdNameMap: getIdNameMap
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/app/serializers/task.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/task.js b/tez-ui2/src/main/webapp/app/serializers/task.js
new file mode 100644
index 0000000..7918e89
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/serializers/task.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 TimelineSerializer from './timeline';
+
+export default TimelineSerializer.extend({
+  maps: {
+    vertexID: 'primaryfilters.TEZ_VERTEX_ID.0',
+    dagID: 'primaryfilters.TEZ_DAG_ID.0',
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/app/serializers/timeline.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/timeline.js b/tez-ui2/src/main/webapp/app/serializers/timeline.js
index 27f1894..7e20317 100644
--- a/tez-ui2/src/main/webapp/app/serializers/timeline.js
+++ b/tez-ui2/src/main/webapp/app/serializers/timeline.js
@@ -21,7 +21,20 @@ import LoaderSerializer from './loader';
 export default LoaderSerializer.extend({
   primaryKey: 'entity',
 
+  mergedProperties: ["maps"],
+
   extractArrayPayload: function (payload) {
     return payload.entities;
+  },
+
+  maps: {
+    entityID: 'entity',
+
+    atsStatus: 'otherinfo.status',
+
+    startTime: 'otherinfo.startTime',
+    endTime: 'otherinfo.endTime',
+
+    counterGroups: 'otherinfo.counters.counterGroups'
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/app/serializers/vertex.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/vertex.js b/tez-ui2/src/main/webapp/app/serializers/vertex.js
new file mode 100644
index 0000000..88ee5d3
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/serializers/vertex.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 TimelineSerializer from './timeline';
+
+function getProcessorClass(source) {
+  var name = Ember.get(source, 'otherinfo.processorClassName') || "";
+  return name.substr(name.lastIndexOf('.') + 1);
+}
+
+export default TimelineSerializer.extend({
+  maps: {
+    name: 'otherinfo.vertexName',
+
+    firstTaskStartTime: 'otherinfo.stats.firstTaskStartTime',
+
+    numTasks: 'otherinfo.numTasks',
+    failedTasks: 'otherinfo.numFailedTasks',
+    sucessfulTasks: 'otherinfo.numSucceededTasks',
+    killedTasks: 'otherinfo.numKilledTasks',
+
+    failedTaskAttempts: 'otherinfo.numFailedTaskAttempts',
+    killedTaskAttempts: 'otherinfo.numKilledTaskAttempts',
+
+    processorClassName: getProcessorClass,
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/app/templates/dag/attempts.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/attempts.hbs b/tez-ui2/src/main/webapp/app/templates/dag/attempts.hbs
index 63840f5..932db09 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag/attempts.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag/attempts.hbs
@@ -16,4 +16,18 @@
  * limitations under the License.
 }}
 
-Attempts
\ No newline at end of file
+{{#if loaded}}
+  {{em-table
+    columns=columns
+    rows=model
+
+    definition=definition
+
+    searchAction="searchChanged"
+    sortAction="sortChanged"
+    rowAction="rowsChanged"
+    pageAction="pageChanged"
+  }}
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/app/templates/dag/tasks.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/tasks.hbs b/tez-ui2/src/main/webapp/app/templates/dag/tasks.hbs
index daee5b5..932db09 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag/tasks.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag/tasks.hbs
@@ -16,4 +16,18 @@
  * limitations under the License.
 }}
 
-Tasks
\ No newline at end of file
+{{#if loaded}}
+  {{em-table
+    columns=columns
+    rows=model
+
+    definition=definition
+
+    searchAction="searchChanged"
+    sortAction="sortChanged"
+    rowAction="rowsChanged"
+    pageAction="pageChanged"
+  }}
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/app/templates/dag/vertices.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/vertices.hbs b/tez-ui2/src/main/webapp/app/templates/dag/vertices.hbs
index 7f0bd85..932db09 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag/vertices.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag/vertices.hbs
@@ -16,4 +16,18 @@
  * limitations under the License.
 }}
 
-Vertices
\ No newline at end of file
+{{#if loaded}}
+  {{em-table
+    columns=columns
+    rows=model
+
+    definition=definition
+
+    searchAction="searchChanged"
+    sortAction="sortChanged"
+    rowAction="rowsChanged"
+    pageAction="pageChanged"
+  }}
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/config/default-app-conf.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/config/default-app-conf.js b/tez-ui2/src/main/webapp/config/default-app-conf.js
index e3d9076..feea181 100644
--- a/tez-ui2/src/main/webapp/config/default-app-conf.js
+++ b/tez-ui2/src/main/webapp/config/default-app-conf.js
@@ -19,6 +19,7 @@
 module.exports = { // Tez App configurations
   buildVersion: "",
   isStandalone: true, // Must be set false while running in wrapped mode
+  rowLoadLimit: 9007199254740991,
   hosts: {
     timeline: 'localhost:8188',
     rm: 'localhost:8088',
@@ -39,7 +40,7 @@ module.exports = { // Tez App configurations
       dag: 'TEZ_DAG_ID',
       vertex: 'TEZ_VERTEX_ID',
       task: 'TEZ_TASK_ID',
-      taskAttempt: 'TEZ_TASK_ATTEMPT_ID',
+      attempt: 'TEZ_TASK_ATTEMPT_ID',
 
       hiveQuery: 'HIVE_QUERY_ID',
 

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/tests/unit/adapters/attempt-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/attempt-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/attempt-test.js
new file mode 100644
index 0000000..584c46e
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/adapters/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('adapter:attempt', 'Unit | Adapter | attempt', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let adapter = this.subject();
+
+  assert.ok(adapter);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/tests/unit/adapters/task-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/task-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/task-test.js
new file mode 100644
index 0000000..ca39e56
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/adapters/task-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('adapter:task', 'Unit | Adapter | task', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let adapter = this.subject();
+  assert.ok(adapter);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/tests/unit/adapters/timeline-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/timeline-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/timeline-test.js
index 9b1a8de..7b0e978 100644
--- a/tez-ui2/src/main/webapp/tests/unit/adapters/timeline-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/adapters/timeline-test.js
@@ -27,5 +27,58 @@ test('Basic creation test', function(assert) {
   let adapter = this.subject();
 
   assert.ok(adapter);
+  assert.ok(adapter.filters);
+  assert.ok(adapter.stringifyFilters);
+  assert.ok(adapter.normalizeQuery);
+  assert.ok(adapter.query);
+
   assert.equal(adapter.serverName, "timeline");
 });
+
+test('stringifyFilters test', function(assert) {
+  let adapter = this.subject();
+
+  assert.equal(adapter.stringifyFilters({a: 1, b: 2}), "a:1,b:2");
+  assert.throws(function () {
+    adapter.stringifyFilters();
+  });
+});
+
+test('normalizeQuery test', function(assert) {
+  let adapter = this.subject(),
+      normalQuery;
+
+  adapter.set("filters", {
+    a: "A_ID",
+    b: "B_ID",
+  });
+
+  normalQuery = adapter.normalizeQuery({a: 1, b: 2, c: 3, d: 4});
+
+  assert.deepEqual(normalQuery.primaryFilter, "A_ID:1");
+  assert.deepEqual(normalQuery.secondaryFilter, "B_ID:2");
+  assert.deepEqual(normalQuery.c, 3);
+  assert.deepEqual(normalQuery.d, 4);
+});
+
+test('query test', function(assert) {
+  let adapter = this.subject(),
+      normalQuery = {},
+      testStore = {},
+      testType = "ts",
+      testQuery = {};
+
+  assert.expect(1 + 1);
+
+  adapter.normalizeQuery = function (params) {
+    assert.equal(params, testQuery);
+    return normalQuery;
+  };
+  adapter._loaderAjax = function (url, queryParams) {
+    assert.equal(queryParams, normalQuery);
+  };
+
+  adapter.query(testStore, testType, {
+    params: testQuery
+  });
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/tests/unit/adapters/vertex-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/vertex-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/vertex-test.js
new file mode 100644
index 0000000..191f781
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/adapters/vertex-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:vertex', 'Unit | Adapter | vertex', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let adapter = this.subject();
+
+  assert.ok(adapter);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js
index 1908e69..11bb0fa 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js
@@ -32,4 +32,5 @@ test('Basic creation test', function(assert) {
 
   assert.ok(controller);
   assert.ok(controller.breadcrumbs);
+  assert.ok(controller.columns);
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js
index 9d22331..073e3d3 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js
@@ -32,4 +32,5 @@ test('Basic creation test', function(assert) {
 
   assert.ok(controller);
   assert.ok(controller.breadcrumbs);
+  assert.ok(controller.columns);
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
index ca6d3d9..fc75935 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
@@ -32,4 +32,5 @@ test('Basic creation test', function(assert) {
 
   assert.ok(controller);
   assert.ok(controller.breadcrumbs);
+  assert.ok(controller.columns);
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/tests/unit/models/attempt-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/attempt-test.js b/tez-ui2/src/main/webapp/tests/unit/models/attempt-test.js
new file mode 100644
index 0000000..7d0a78e
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/models/attempt-test.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 { moduleForModel, test } from 'ember-qunit';
+
+moduleForModel('attempt', 'Unit | Model | attempt', {
+  // 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.index);
+  assert.ok(model.taskIndex);
+  assert.ok(model.vertexName);
+});
+
+test('index test', function(assert) {
+  let model = this.subject({
+    entityID: "1_2_3"
+  });
+
+  assert.equal(model.get("index"), "3");
+});
+
+test('taskIndex test', function(assert) {
+  let model = this.subject({
+        taskID: "1_2_3",
+      });
+
+  assert.equal(model.get("taskIndex"), "2_3");
+});
+
+test('vertexName test', function(assert) {
+  let testVertexName = "Test Vertex",
+      model = this.subject({
+        vertexID: "1_2",
+        dag: {
+          vertexIdNameMap: {
+            "1_2": testVertexName
+          }
+        }
+      });
+
+  assert.equal(model.get("vertexName"), testVertexName);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/tests/unit/models/task-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/task-test.js b/tez-ui2/src/main/webapp/tests/unit/models/task-test.js
new file mode 100644
index 0000000..3d59df6
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/models/task-test.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 { moduleForModel, test } from 'ember-qunit';
+
+moduleForModel('task', 'Unit | Model | task', {
+  // 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.needs);
+  assert.ok(model.index);
+  assert.ok(model.vertexName);
+});
+
+test('index test', function(assert) {
+  let model = this.subject({
+        entityID: "1_2_3",
+      });
+
+  assert.equal(model.get("index"), "2_3");
+});
+
+test('vertexName test', function(assert) {
+  let testVertexName = "Test Vertex",
+      model = this.subject({
+        vertexID: "1_2",
+        dag: {
+          vertexIdNameMap: {
+            "1_2": testVertexName
+          }
+        }
+      });
+
+  assert.equal(model.get("vertexName"), testVertexName);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/tests/unit/models/vertex-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/vertex-test.js b/tez-ui2/src/main/webapp/tests/unit/models/vertex-test.js
new file mode 100644
index 0000000..bea4317
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/models/vertex-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('vertex', 'Unit | Model | vertex', {
+  // 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.runningTasks);
+  assert.ok(model.pendingTasks);
+});
+
+test('runningTasks test', function(assert) {
+  let model = this.subject();
+
+  assert.equal(model.get("runningTasks"), null);
+  model.set("status", "SUCCEEDED");
+  assert.equal(model.get("runningTasks"), 0);
+});
+
+test('pendingTasks test', function(assert) {
+  let model = this.subject();
+
+  assert.equal(model.get("pendingTasks"), null);
+  model.set("status", "SUCCEEDED");
+  assert.equal(model.get("pendingTasks"), 0);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/tests/unit/routes/dag/attempts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/dag/attempts-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/dag/attempts-test.js
index f997891..36a67b4 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/dag/attempts-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/dag/attempts-test.js
@@ -29,6 +29,7 @@ test('Basic creation test', function(assert) {
   assert.ok(route);
   assert.ok(route.title);
   assert.ok(route.setupController);
+  assert.ok(route.load);
 });
 
 test('setupController test', function(assert) {

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/tests/unit/routes/dag/tasks-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/dag/tasks-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/dag/tasks-test.js
index 3e283ca..fa30f2e 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/dag/tasks-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/dag/tasks-test.js
@@ -29,6 +29,7 @@ test('Basic creation test', function(assert) {
   assert.ok(route);
   assert.ok(route.title);
   assert.ok(route.setupController);
+  assert.ok(route.load);
 });
 
 test('setupController test', function(assert) {

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/tests/unit/routes/dag/vertices-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/dag/vertices-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/dag/vertices-test.js
index e55e184..fb27c80 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/dag/vertices-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/dag/vertices-test.js
@@ -29,6 +29,7 @@ test('Basic creation test', function(assert) {
   assert.ok(route);
   assert.ok(route.title);
   assert.ok(route.setupController);
+  assert.ok(route.load);
 });
 
 test('setupController test', function(assert) {

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/tests/unit/serializers/attempt-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/serializers/attempt-test.js b/tez-ui2/src/main/webapp/tests/unit/serializers/attempt-test.js
new file mode 100644
index 0000000..452b8af
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/serializers/attempt-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('serializer:attempt', 'Unit | Serializer | attempt', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:attempt']
+});
+
+// Replace this with your real tests.
+test('Basic creation test', function(assert) {
+  let serializer = this.subject();
+
+  assert.ok(serializer);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/tests/unit/serializers/dag-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/serializers/dag-test.js b/tez-ui2/src/main/webapp/tests/unit/serializers/dag-test.js
index 7dd635c..eb39508 100644
--- a/tez-ui2/src/main/webapp/tests/unit/serializers/dag-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/serializers/dag-test.js
@@ -31,6 +31,7 @@ test('Basic creation test', function(assert) {
   assert.ok(serializer.maps.startTime);
   assert.ok(serializer.maps.endTime);
   assert.ok(serializer.maps.containerLogs);
+  assert.ok(serializer.maps.vertexIdNameMap);
 });
 
 test('atsStatus test', function(assert) {
@@ -107,3 +108,24 @@ test('containerLogs test', function(assert) {
     otherinfo: {inProgressLogsURL_1: "foo", inProgressLogsURL_2: "bar"},
   }), [{text: "1", href: "http://foo"}, {text: "2", href: "http://bar"}], "2 logs");
 });
+
+test('vertexIdNameMap test', function(assert) {
+  let serializer = this.subject(),
+      mapper = serializer.maps.vertexIdNameMap;
+
+  let nameIdMap = {
+    otherinfo: {
+      vertexNameIdMapping: {
+        name1: "ID1",
+        name2: "ID2",
+        name3: "ID3",
+      }
+    }
+  };
+
+  assert.deepEqual(mapper(nameIdMap), {
+    ID1: "name1",
+    ID2: "name2",
+    ID3: "name3",
+  });
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/tests/unit/serializers/task-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/serializers/task-test.js b/tez-ui2/src/main/webapp/tests/unit/serializers/task-test.js
new file mode 100644
index 0000000..fc79ae9
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/serializers/task-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('serializer:task', 'Unit | Serializer | task', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:task']
+});
+
+test('Basic creation test', function(assert) {
+  let serializer = this.subject();
+
+  assert.ok(serializer);
+  assert.ok(serializer.maps);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/tests/unit/serializers/timeline-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/serializers/timeline-test.js b/tez-ui2/src/main/webapp/tests/unit/serializers/timeline-test.js
index 53f0b06..3c267ad 100644
--- a/tez-ui2/src/main/webapp/tests/unit/serializers/timeline-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/serializers/timeline-test.js
@@ -28,6 +28,7 @@ test('Basic creation test', function(assert) {
 
   assert.ok(serializer);
   assert.ok(serializer.extractArrayPayload);
+  assert.ok(serializer.maps);
 });
 
 test('extractArrayPayload test', function(assert) {

http://git-wip-us.apache.org/repos/asf/tez/blob/a1c3622a/tez-ui2/src/main/webapp/tests/unit/serializers/vertex-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/serializers/vertex-test.js b/tez-ui2/src/main/webapp/tests/unit/serializers/vertex-test.js
new file mode 100644
index 0000000..7dfb5da
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/serializers/vertex-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:vertex', 'Unit | Serializer | vertex', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:vertex']
+});
+
+test('Basic creation test', function(assert) {
+  let serializer = this.subject();
+
+  assert.ok(serializer);
+  assert.ok(serializer.maps);
+  assert.ok(serializer.maps.processorClassName);
+});
+
+test('processorClassName test', function(assert) {
+  let serializer = this.subject(),
+      processorClassName = serializer.maps.processorClassName;
+
+  assert.equal(processorClassName({}), "");
+  assert.equal(processorClassName({
+    otherinfo: {
+      processorClassName: "foo"
+    }
+  }), "foo");
+  assert.equal(processorClassName({
+    otherinfo: {
+      processorClassName: "a.b.foo"
+    }
+  }), "foo");
+});


[39/45] tez git commit: TEZ-3127. Tez UI 2: Release audit is failing (sree)

Posted by sr...@apache.org.
TEZ-3127. Tez UI 2: Release audit is failing (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/37513ba7
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/37513ba7
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/37513ba7

Branch: refs/heads/TEZ-2980
Commit: 37513ba7c9ce516d0e72266de8af5c9071beea27
Parents: 6b8e328
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Fri Feb 19 00:36:04 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:32:53 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                              |  1 +
 pom.xml                                           |  1 +
 tez-ui2/pom.xml                                   |  8 ++++++--
 .../main/webapp/app/templates/dag/graphical.hbs   | 18 ++++++++++++++++++
 tez-ui2/src/main/webapp/config/configs.env        | 18 ++++++++++++++++++
 tez-ui2/src/main/webapp/public/crossdomain.xml    | 15 ---------------
 tez-ui2/src/main/webapp/public/robots.txt         |  3 ---
 7 files changed, 44 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/37513ba7/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index 949dcb6..d09ebc3 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -38,3 +38,4 @@ ALL CHANGES:
   TEZ-3088. Tez UI 2: Licenses of all the packages used by Tez Ui must be documented
   TEZ-2916. Tez UI 2: Show counts of running tasks on the DAG visualization page
   TEZ-3125. Tez UI 2: All auto-refresh pages refresh multiple times shortly after application complete
+  TEZ-3127. Tez UI 2: Release audit is failing

http://git-wip-us.apache.org/repos/asf/tez/blob/37513ba7/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 26abc24..058ee79 100644
--- a/pom.xml
+++ b/pom.xml
@@ -800,6 +800,7 @@
           <configuration>
             <excludes>
               <exclude>CHANGES.txt</exclude>
+              <exclude>TEZ-2980-CHANGES.txt</exclude>
               <exclude>**/LICENSE*</exclude>
               <!-- IDE files -->
               <exclude>.idea/**</exclude>

http://git-wip-us.apache.org/repos/asf/tez/blob/37513ba7/tez-ui2/pom.xml
----------------------------------------------------------------------
diff --git a/tez-ui2/pom.xml b/tez-ui2/pom.xml
index 8dbea41..695cacb 100644
--- a/tez-ui2/pom.xml
+++ b/tez-ui2/pom.xml
@@ -46,19 +46,23 @@
             <exclude>src/main/webapp/node/**/*</exclude>
             <exclude>src/main/webapp/node_modules/**/*</exclude>
             <exclude>src/main/webapp/bower_components/**/*</exclude>
-            <exclude>src/main/webapp/.tmp/</exclude>
+            <exclude>src/main/webapp/.tmp/**/*</exclude>
             <exclude>src/main/webapp/dist/**/*</exclude>
+            <exclude>src/main/webapp/tmp/**/*</exclude>
             <exclude>src/main/webapp/.bowerrc</exclude>
             <exclude>src/main/webapp/.editorconfig</exclude>
             <exclude>src/main/webapp/.ember-cli</exclude>
             <exclude>src/main/webapp/.gitignore</exclude>
             <exclude>src/main/webapp/.jshintrc</exclude>
+            <exclude>src/main/webapp/tests/.jshintrc</exclude>
+            <exclude>src/main/webapp/blueprints/.jshintrc</exclude>
             <exclude>src/main/webapp/.travis.yml</exclude>
             <exclude>src/main/webapp/.watchmanconfig</exclude>
             <exclude>src/main/webapp/bower.json</exclude>
             <exclude>src/main/webapp/ember-cli-build.js</exclude>
             <exclude>src/main/webapp/package.json</exclude>
-            <exclude>src/main/webapp/testem.js</exclude>
+            <exclude>src/main/webapp/testem.json</exclude>
+            <exclude>src/main/webapp/public/assets/images/*</exclude>
           </excludes>
         </configuration>
       </plugin>

http://git-wip-us.apache.org/repos/asf/tez/blob/37513ba7/tez-ui2/src/main/webapp/app/templates/dag/graphical.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/graphical.hbs b/tez-ui2/src/main/webapp/app/templates/dag/graphical.hbs
index fcb7e86..1b4e110 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag/graphical.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag/graphical.hbs
@@ -1,3 +1,21 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 loaded}}
   <br/>
   <div id="graphical-view-component-container">

http://git-wip-us.apache.org/repos/asf/tez/blob/37513ba7/tez-ui2/src/main/webapp/config/configs.env
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/config/configs.env b/tez-ui2/src/main/webapp/config/configs.env
index a0d2198..56c5e22 100644
--- a/tez-ui2/src/main/webapp/config/configs.env
+++ b/tez-ui2/src/main/webapp/config/configs.env
@@ -1,3 +1,21 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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: {
     /*

http://git-wip-us.apache.org/repos/asf/tez/blob/37513ba7/tez-ui2/src/main/webapp/public/crossdomain.xml
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/public/crossdomain.xml b/tez-ui2/src/main/webapp/public/crossdomain.xml
deleted file mode 100644
index 0c16a7a..0000000
--- a/tez-ui2/src/main/webapp/public/crossdomain.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
-<cross-domain-policy>
-  <!-- Read this: www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html -->
-
-  <!-- Most restrictive policy: -->
-  <site-control permitted-cross-domain-policies="none"/>
-
-  <!-- Least restrictive policy: -->
-  <!--
-  <site-control permitted-cross-domain-policies="all"/>
-  <allow-access-from domain="*" to-ports="*" secure="false"/>
-  <allow-http-request-headers-from domain="*" headers="*" secure="false"/>
-  -->
-</cross-domain-policy>

http://git-wip-us.apache.org/repos/asf/tez/blob/37513ba7/tez-ui2/src/main/webapp/public/robots.txt
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/public/robots.txt b/tez-ui2/src/main/webapp/public/robots.txt
deleted file mode 100644
index f591645..0000000
--- a/tez-ui2/src/main/webapp/public/robots.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-# http://www.robotstxt.org
-User-agent: *
-Disallow:


[31/45] tez git commit: TEZ-3069. Tez UI 2: Make error bar fully functional (sree)

Posted by sr...@apache.org.
TEZ-3069. Tez UI 2: Make error bar fully functional (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/6d4bb2c6
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/6d4bb2c6
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/6d4bb2c6

Branch: refs/heads/TEZ-2980
Commit: 6d4bb2c6366e01971ce07460664e88fa8344eb30
Parents: 963e77a
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Sat Jan 30 19:55:25 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:32:52 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |   1 +
 .../src/main/webapp/app/adapters/abstract.js    |  15 +++
 tez-ui2/src/main/webapp/app/adapters/am.js      |   1 +
 tez-ui2/src/main/webapp/app/adapters/rm.js      |   1 +
 .../src/main/webapp/app/adapters/timeline.js    |   1 +
 .../src/main/webapp/app/components/error-bar.js | 109 +++++++++++++++++++
 .../main/webapp/app/controllers/application.js  |   2 +
 tez-ui2/src/main/webapp/app/entities/entity.js  |   2 +
 tez-ui2/src/main/webapp/app/routes/abstract.js  |  12 +-
 .../src/main/webapp/app/routes/am-pollster.js   |   6 +-
 tez-ui2/src/main/webapp/app/routes/app.js       |   3 +-
 .../src/main/webapp/app/routes/application.js   |   2 +-
 tez-ui2/src/main/webapp/app/routes/attempt.js   |   3 +-
 tez-ui2/src/main/webapp/app/routes/dag.js       |   3 +-
 .../main/webapp/app/routes/dag/index/index.js   |   5 +
 tez-ui2/src/main/webapp/app/routes/pollster.js  |  18 +--
 tez-ui2/src/main/webapp/app/routes/task.js      |   3 +-
 tez-ui2/src/main/webapp/app/routes/vertex.js    |   3 +-
 tez-ui2/src/main/webapp/app/styles/app.less     |   8 +-
 .../src/main/webapp/app/styles/error-bar.less   | 102 +++++++++++++++++
 .../main/webapp/app/templates/application.hbs   |   3 +-
 .../app/templates/components/error-bar.hbs      |  31 ++++++
 .../integration/components/error-bar-test.js    |  43 ++++++++
 .../webapp/tests/unit/entities/entity-test.js   |   3 +
 .../webapp/tests/unit/routes/abstract-test.js   |   6 +-
 25 files changed, 362 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/6d4bb2c6/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index fc99577..0457cb0 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -28,3 +28,4 @@ ALL CHANGES:
   TEZ-3070. Tez UI 2: Jenkins build is failing
   TEZ-3060. Tez UI 2: Activate auto-refresh
   TEZ-3061. Tez UI 2: Display in-progress vertex table in DAG details
+  TEZ-3069. Tez UI 2: Make error bar fully functional

http://git-wip-us.apache.org/repos/asf/tez/blob/6d4bb2c6/tez-ui2/src/main/webapp/app/adapters/abstract.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/abstract.js b/tez-ui2/src/main/webapp/app/adapters/abstract.js
index 6cb701b..121d4ee 100644
--- a/tez-ui2/src/main/webapp/app/adapters/abstract.js
+++ b/tez-ui2/src/main/webapp/app/adapters/abstract.js
@@ -52,4 +52,19 @@ export default LoaderAdapter.extend({
     Ember.assert(`Path not found for type:${type} to server:${serverName}`, path);
     return path;
   },
+
+  normalizeErrorResponse: function(status, headers, payload) {
+    var response;
+
+    if(payload && payload.exception && !payload.errors) {
+      payload = `${payload.exception}\n${payload.message}\n${payload.javaClassName}`;
+      response = this._super(status, headers, payload);
+    }
+    else {
+      response = this._super(status, headers, payload);
+      Ember.set(response, '0.title', this.get("outOfReachMessage"));
+    }
+
+    return response;
+  }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/6d4bb2c6/tez-ui2/src/main/webapp/app/adapters/am.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/am.js b/tez-ui2/src/main/webapp/app/adapters/am.js
index 85f3d27..c4cb75d 100644
--- a/tez-ui2/src/main/webapp/app/adapters/am.js
+++ b/tez-ui2/src/main/webapp/app/adapters/am.js
@@ -20,6 +20,7 @@ import AbstractAdapter from './abstract';
 
 export default AbstractAdapter.extend({
   serverName: "am",
+  outOfReachMessage: "Application Master (AM) is out of reach. Either it's down, or CORS is not enabled for YARN ResourceManager.",
 
   queryRecord: function(store, type, query) {
     return this.query(store, type, query);

http://git-wip-us.apache.org/repos/asf/tez/blob/6d4bb2c6/tez-ui2/src/main/webapp/app/adapters/rm.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/rm.js b/tez-ui2/src/main/webapp/app/adapters/rm.js
index b87c77d..252affb 100644
--- a/tez-ui2/src/main/webapp/app/adapters/rm.js
+++ b/tez-ui2/src/main/webapp/app/adapters/rm.js
@@ -20,6 +20,7 @@ import AbstractAdapter from './abstract';
 
 export default AbstractAdapter.extend({
   serverName: "rm",
+  outOfReachMessage: "Resource Manager (RM) is out of reach. Either it's down, or CORS is not enabled.",
 
   // Any rm specific adapter changes must be added here
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/6d4bb2c6/tez-ui2/src/main/webapp/app/adapters/timeline.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/timeline.js b/tez-ui2/src/main/webapp/app/adapters/timeline.js
index 93e83cb..82faed8 100644
--- a/tez-ui2/src/main/webapp/app/adapters/timeline.js
+++ b/tez-ui2/src/main/webapp/app/adapters/timeline.js
@@ -24,6 +24,7 @@ var MoreObject = more.Object;
 
 export default AbstractAdapter.extend({
   serverName: "timeline",
+  outOfReachMessage: "Timeline server (ATS) is out of reach. Either it's down, or CORS is not enabled.",
 
   filters: {
     dagID: 'TEZ_DAG_ID',

http://git-wip-us.apache.org/repos/asf/tez/blob/6d4bb2c6/tez-ui2/src/main/webapp/app/components/error-bar.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/components/error-bar.js b/tez-ui2/src/main/webapp/app/components/error-bar.js
new file mode 100644
index 0000000..1086010
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/components/error-bar.js
@@ -0,0 +1,109 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 DISPLAY_TIME = 30 * 1000;
+
+export default Ember.Component.extend({
+
+  error: null,
+
+  visible: false,
+  detailsAvailable: false,
+
+  classNames: ['error-bar'],
+  classNameBindings: ['visible', 'detailsAvailable'],
+
+  code: null,
+  message: null,
+  details: null,
+  stack: null,
+
+  showDetails: false,
+
+  displayTimerId: 0,
+
+  _errorObserver: Ember.observer("error", function () {
+    var error = this.get("error"),
+
+        code = Ember.get(error, "errors.0.status"),
+        title = Ember.get(error, "errors.0.title"),
+        message = error.message || "Error",
+        details = Ember.get(error, "errors.0.detail") || "",
+        stack = error.stack,
+        lineEndIndex = Math.min(message.indexOf('\n'), message.indexOf('<br'));
+
+    if(code === "0") {
+      code = "";
+    }
+
+    if(title) {
+      message += ". " + title;
+    }
+
+    if(lineEndIndex > 0) {
+      if(details) {
+        details = "\n" + details;
+      }
+      details = message.substr(lineEndIndex) + details;
+      message = message.substr(0, lineEndIndex);
+    }
+
+    if(details) {
+      details += "\n";
+    }
+
+    if(error) {
+      this.setProperties({
+        code: code,
+        message: message,
+        details: details,
+        stack: stack,
+
+        detailsAvailable: !!(details || stack),
+        visible: true
+      });
+
+      this.clearTimer();
+      this.set("displayTimerId", setTimeout(this.close.bind(this), DISPLAY_TIME));
+    }
+    else {
+      this.close();
+    }
+  }),
+
+  clearTimer: function () {
+    clearTimeout(this.get("displayTimerId"));
+  },
+  close: function () {
+    this.set("visible", false);
+    this.clearTimer();
+  },
+
+  actions: {
+    toggleDetailsDisplay: function () {
+      this.toggleProperty("showDetails");
+      this.clearTimer();
+    },
+    close: function () {
+      this.close();
+    }
+  }
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/6d4bb2c6/tez-ui2/src/main/webapp/app/controllers/application.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/application.js b/tez-ui2/src/main/webapp/app/controllers/application.js
index 24db40a..4911a16 100644
--- a/tez-ui2/src/main/webapp/app/controllers/application.js
+++ b/tez-ui2/src/main/webapp/app/controllers/application.js
@@ -25,6 +25,8 @@ const BREADCRUMB_PREFIX = [{
 
 export default Ember.Controller.extend({
   breadcrumbs: null,
+  appError: null,
+
   prefixedBreadcrumbs: Ember.computed("breadcrumbs", function () {
     var prefix = BREADCRUMB_PREFIX,
     breadcrumbs = this.get('breadcrumbs');

http://git-wip-us.apache.org/repos/asf/tez/blob/6d4bb2c6/tez-ui2/src/main/webapp/app/entities/entity.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/entities/entity.js b/tez-ui2/src/main/webapp/app/entities/entity.js
index 8a10dee..6f98097 100644
--- a/tez-ui2/src/main/webapp/app/entities/entity.js
+++ b/tez-ui2/src/main/webapp/app/entities/entity.js
@@ -98,11 +98,13 @@ var Entity = Ember.Object.extend(NameMixin, {
     );
 
     needLoader.then(function (model) {
+      parentModel.refreshLoadTime();
       parentModel.set(needOptions.name, model);
     });
 
     if(needOptions.silent) {
       needLoader = needLoader.catch(function () {
+        parentModel.refreshLoadTime();
         parentModel.set(needOptions.name, null);
       });
     }

http://git-wip-us.apache.org/repos/asf/tez/blob/6d4bb2c6/tez-ui2/src/main/webapp/app/routes/abstract.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/abstract.js b/tez-ui2/src/main/webapp/app/routes/abstract.js
index 923ac96..39b8314 100644
--- a/tez-ui2/src/main/webapp/app/routes/abstract.js
+++ b/tez-ui2/src/main/webapp/app/routes/abstract.js
@@ -98,7 +98,8 @@ export default Ember.Route.extend(NameMixin, {
       then(this.checkAndCall.bind(this, promiseId, "beforeLoad", query, options)).
       then(this.checkAndCall.bind(this, promiseId, "load", query, options)).
       then(this.checkAndCall.bind(this, promiseId, "afterLoad", query, options)).
-      then(this.checkAndCall.bind(this, promiseId, "setValue", query, options));
+      then(this.checkAndCall.bind(this, promiseId, "setValue", query, options)).
+      catch(this.onLoadFailure.bind(this));
   },
 
   setLoading: function (/*query, options*/) {
@@ -124,6 +125,15 @@ export default Ember.Route.extend(NameMixin, {
 
     return value;
   },
+  onLoadFailure: function (error) {
+    if(error instanceof UnlinkedPromise) {
+      Ember.Logger.warn("Slow down, you are refreshing too fast!");
+    }
+    else {
+      this.send("error", error);
+      throw(error);
+    }
+  },
 
   getLoadTime: function (value) {
     if(value instanceof DS.RecordArray) {

http://git-wip-us.apache.org/repos/asf/tez/blob/6d4bb2c6/tez-ui2/src/main/webapp/app/routes/am-pollster.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/am-pollster.js b/tez-ui2/src/main/webapp/app/routes/am-pollster.js
index 5907a91..6752ffd 100644
--- a/tez-ui2/src/main/webapp/app/routes/am-pollster.js
+++ b/tez-ui2/src/main/webapp/app/routes/am-pollster.js
@@ -17,6 +17,8 @@
  * limitations under the License.
  */
 
+import Ember from 'ember';
+
 import PollsterRoute from './pollster';
 
 var MoreObject = more.Object;
@@ -45,13 +47,11 @@ export default PollsterRoute.extend({
         that.reload();
       }
       else {
-        error.message = "Application Master (AM) is out of reach. Either it's down, or CORS is not enabled for YARN ResourceManager.";
         that.send("error", error);
       }
     }, function (error) {
-      error.message = "Resource Manager (RM) is out of reach. Either it's down, or CORS is not enabled.";
       that.send("error", error);
-      that.reload();
+      Ember.run.later(that, "reload", this.get("polling.interval") * 3);
     });
   },
 

http://git-wip-us.apache.org/repos/asf/tez/blob/6d4bb2c6/tez-ui2/src/main/webapp/app/routes/app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/app.js b/tez-ui2/src/main/webapp/app/routes/app.js
index a60025e..395a9be 100644
--- a/tez-ui2/src/main/webapp/app/routes/app.js
+++ b/tez-ui2/src/main/webapp/app/routes/app.js
@@ -26,7 +26,8 @@ export default AbstractRoute.extend({
   },
 
   model: function (params) {
-    return this.get("loader").queryRecord('app', "tez_" + this.queryFromParams(params).id);
+    return this.get("loader").queryRecord('app', "tez_" + this.queryFromParams(params).id).
+      catch(this.onLoadFailure.bind(this));
   },
 
   actions: {

http://git-wip-us.apache.org/repos/asf/tez/blob/6d4bb2c6/tez-ui2/src/main/webapp/app/routes/application.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/application.js b/tez-ui2/src/main/webapp/app/routes/application.js
index 121eda2..41ea3fb 100644
--- a/tez-ui2/src/main/webapp/app/routes/application.js
+++ b/tez-ui2/src/main/webapp/app/routes/application.js
@@ -38,7 +38,7 @@ export default Ember.Route.extend({
     },
 
     error: function (error) {
-      // Display error bar
+      this.set("controller.appError", error);
       Ember.Logger.error(error);
     },
 

http://git-wip-us.apache.org/repos/asf/tez/blob/6d4bb2c6/tez-ui2/src/main/webapp/app/routes/attempt.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/attempt.js b/tez-ui2/src/main/webapp/app/routes/attempt.js
index 4a1ac20..3d0224f 100644
--- a/tez-ui2/src/main/webapp/app/routes/attempt.js
+++ b/tez-ui2/src/main/webapp/app/routes/attempt.js
@@ -26,7 +26,8 @@ export default AbstractRoute.extend({
   },
 
   model: function (params) {
-    return this.get("loader").queryRecord('attempt', this.queryFromParams(params).id);
+    return this.get("loader").queryRecord('attempt', this.queryFromParams(params).id).
+      catch(this.onLoadFailure.bind(this));
   },
 
   actions: {

http://git-wip-us.apache.org/repos/asf/tez/blob/6d4bb2c6/tez-ui2/src/main/webapp/app/routes/dag.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag.js b/tez-ui2/src/main/webapp/app/routes/dag.js
index 51e6ed9..13f1bc0 100644
--- a/tez-ui2/src/main/webapp/app/routes/dag.js
+++ b/tez-ui2/src/main/webapp/app/routes/dag.js
@@ -26,7 +26,8 @@ export default AbstractRoute.extend({
   },
 
   model: function (params) {
-    return this.get("loader").queryRecord('dag', this.queryFromParams(params).id);
+    return this.get("loader").queryRecord('dag', this.queryFromParams(params).id).
+      catch(this.onLoadFailure.bind(this));
   },
 
   actions: {

http://git-wip-us.apache.org/repos/asf/tez/blob/6d4bb2c6/tez-ui2/src/main/webapp/app/routes/dag/index/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag/index/index.js b/tez-ui2/src/main/webapp/app/routes/dag/index/index.js
index 15d485f..72d8686 100644
--- a/tez-ui2/src/main/webapp/app/routes/dag/index/index.js
+++ b/tez-ui2/src/main/webapp/app/routes/dag/index/index.js
@@ -44,8 +44,13 @@ export default MultiAmPollsterRoute.extend({
     }
   }),
 
+  updateLoadTime: function (value) {
+    return value;
+  },
+
   actions: {
     reload: function () {
+      this._super();
       return true;
     },
     willTransition: function () {

http://git-wip-us.apache.org/repos/asf/tez/blob/6d4bb2c6/tez-ui2/src/main/webapp/app/routes/pollster.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/pollster.js b/tez-ui2/src/main/webapp/app/routes/pollster.js
index 5a7af16..7d62c39 100644
--- a/tez-ui2/src/main/webapp/app/routes/pollster.js
+++ b/tez-ui2/src/main/webapp/app/routes/pollster.js
@@ -25,19 +25,18 @@ export default AbstractRoute.extend({
   polledRecords: null,
 
   // Must be implemented by inheriting classes
-  onRecordPoll: Ember.K,
-  onPollSuccess: Ember.K,
-  onPollFailure: Ember.K,
+  onRecordPoll: function (val) {return val;},
+  onPollSuccess: function (val) {return val;},
+  onPollFailure: function (err) {throw(err);},
 
   pollData: function () {
     var polledRecords = this.get("polledRecords");
 
     if(!this.get("isLoading") && polledRecords) {
       polledRecords = polledRecords.map(this.onRecordPoll.bind(this));
-      return Ember.RSVP.all(polledRecords).then(
-        this.onPollSuccess.bind(this),
-        this.onPollFailure.bind(this)
-      );
+      return Ember.RSVP.all(polledRecords).
+      then(this.updateLoadTime.bind(this)).
+      then(this.onPollSuccess.bind(this), this.onPollFailure.bind(this));
     }
     return Ember.RSVP.reject();
   },
@@ -46,6 +45,11 @@ export default AbstractRoute.extend({
     return this.get("polledRecords") && this.get("loadedValue");
   }),
 
+  updateLoadTime: function (value) {
+    this.send("setLoadTime", this.getLoadTime(value));
+    return value;
+  },
+
   _canPollInit: Ember.on("init", function () {
     // This sets a flag that ensures that the _canPollObserver is called whenever
     // canPoll changes. By default observers on un-used computed properties

http://git-wip-us.apache.org/repos/asf/tez/blob/6d4bb2c6/tez-ui2/src/main/webapp/app/routes/task.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/task.js b/tez-ui2/src/main/webapp/app/routes/task.js
index 42d9715..54d29f1 100644
--- a/tez-ui2/src/main/webapp/app/routes/task.js
+++ b/tez-ui2/src/main/webapp/app/routes/task.js
@@ -26,7 +26,8 @@ export default AbstractRoute.extend({
   },
 
   model: function (params) {
-    return this.get("loader").queryRecord('task', this.queryFromParams(params).id);
+    return this.get("loader").queryRecord('task', this.queryFromParams(params).id).
+      catch(this.onLoadFailure.bind(this));
   },
 
   actions: {

http://git-wip-us.apache.org/repos/asf/tez/blob/6d4bb2c6/tez-ui2/src/main/webapp/app/routes/vertex.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/vertex.js b/tez-ui2/src/main/webapp/app/routes/vertex.js
index 5e8ed33..6e99fd1 100644
--- a/tez-ui2/src/main/webapp/app/routes/vertex.js
+++ b/tez-ui2/src/main/webapp/app/routes/vertex.js
@@ -26,7 +26,8 @@ export default AbstractRoute.extend({
   },
 
   model: function (params) {
-    return this.get("loader").queryRecord('vertex', this.queryFromParams(params).id);
+    return this.get("loader").queryRecord('vertex', this.queryFromParams(params).id).
+      catch(this.onLoadFailure.bind(this));
   },
 
   actions: {

http://git-wip-us.apache.org/repos/asf/tez/blob/6d4bb2c6/tez-ui2/src/main/webapp/app/styles/app.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/app.less b/tez-ui2/src/main/webapp/app/styles/app.less
index 758d1ab..cdeccd1 100644
--- a/tez-ui2/src/main/webapp/app/styles/app.less
+++ b/tez-ui2/src/main/webapp/app/styles/app.less
@@ -16,15 +16,19 @@
  * limitations under the License.
  */
 
+// Prerequisites
 @import "colors";
 @import "shared";
 
 @import "tooltip";
 
+// Components
 @import "tab-n-refresh";
 @import "dags-page-search";
+@import "table-controls";
+@import "column-selector";
+@import "error-bar";
 
+// Pages
 @import "page-layout";
 @import "details-page";
-@import "table-controls";
-@import "column-selector";

http://git-wip-us.apache.org/repos/asf/tez/blob/6d4bb2c6/tez-ui2/src/main/webapp/app/styles/error-bar.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/error-bar.less b/tez-ui2/src/main/webapp/app/styles/error-bar.less
new file mode 100644
index 0000000..dec2100
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/styles/error-bar.less
@@ -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.
+ */
+
+.error-bar {
+  position: fixed;
+  z-index: 1000;
+
+  padding: 9px 30px;
+  min-height: 50px;
+  width: 100%;
+
+  bottom: -50px;
+  opacity: 0;
+  height: 50px;
+
+  &.visible {
+    bottom: -10px;
+    opacity: 1;
+    height: auto;
+  }
+
+  transition: all .2s cubic-bezier(0.175, 0.885, 0.320, 1.275);
+  transition-property: bottom, opacity, height;
+  -webkit-transition: all .2s cubic-bezier(0.175, 0.885, 0.320, 1.275);
+  -webkit-transition-property: bottom, opacity, height;
+
+  border-top: 1px @border-lite solid;
+  background-color: #F5F5DC;
+  color: @text-red;
+
+  .message, .details {
+    overflow: scroll;
+    max-height: 100px;
+
+    text-align: left;
+  }
+
+  .details {
+    display: none;
+    visibility: hidden;
+
+    margin-bottom: 10px;
+
+    border-top: 1px @border-lite solid;
+
+    .force-scrollbar;
+    white-space: pre-line;
+
+    &.visible {
+      display: block;
+    }
+  }
+
+  .close-button, .show-details {
+    position: absolute;
+    top: 12px;
+
+    color: @text-color;
+    opacity: .7;
+
+    &:hover {
+      cursor: pointer;
+      opacity: 1;
+    }
+  }
+
+  .close-button {
+    right: 30px;
+  }
+
+  .show-details {
+    right: 45px;
+    visibility: hidden;
+  }
+
+  &.details-available {
+    .message {
+      cursor: pointer;
+    }
+    .details {
+      visibility: visible;
+    }
+    .show-details {
+      visibility: visible;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/6d4bb2c6/tez-ui2/src/main/webapp/app/templates/application.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/application.hbs b/tez-ui2/src/main/webapp/app/templates/application.hbs
index 16a0329..7bdc2b7 100644
--- a/tez-ui2/src/main/webapp/app/templates/application.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/application.hbs
@@ -23,7 +23,6 @@
       <div class="lr-margin content">
         {{#link-to 'application' class="logo"}}
           <img src="assets/images/logo.png" width="70px"/>
-          <span>{{unbound App.env.version}}</span>
         {{/link-to}}
 
         <div class="breadcrumb-container">
@@ -64,3 +63,5 @@
 </div>
 
 {{outlet "modal"}}
+
+{{error-bar error=appError}}

http://git-wip-us.apache.org/repos/asf/tez/blob/6d4bb2c6/tez-ui2/src/main/webapp/app/templates/components/error-bar.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/components/error-bar.hbs b/tez-ui2/src/main/webapp/app/templates/components/error-bar.hbs
new file mode 100644
index 0000000..a21bba0
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/components/error-bar.hbs
@@ -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.
+}}
+
+<div class="message" {{action "toggleDetailsDisplay"}}>
+  <i class="fa fa-exclamation-circle"></i>
+  {{#if code}}
+    <b>{{code}}</b> :
+  {{/if}}
+  {{message}}
+  <i class="show-details fa {{if showDetails 'fa-minus-circle' 'fa-plus-circle'}}"></i>
+</div>
+<div class="details {{if showDetails "visible"}}">{{{details}}}{{#if stack}}<b>Stack:</b>
+    {{stack}}
+  {{/if}}
+</div>
+<i class="close-button fa fa-arrow-circle-down" {{action "close"}}></i>

http://git-wip-us.apache.org/repos/asf/tez/blob/6d4bb2c6/tez-ui2/src/main/webapp/tests/integration/components/error-bar-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/integration/components/error-bar-test.js b/tez-ui2/src/main/webapp/tests/integration/components/error-bar-test.js
new file mode 100644
index 0000000..10c6c7d
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/integration/components/error-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('error-bar', 'Integration | Component | error bar', {
+  integration: true
+});
+
+test('Basic creation test', function(assert) {
+
+  // Set any properties with this.set('myProperty', 'value');
+  // Handle any actions with this.on('myAction', function(val) { ... });" + EOL + EOL +
+
+  this.render(hbs`{{error-bar}}`);
+
+  assert.equal(this.$().text().trim(), '');
+
+  // Template block usage:" + EOL +
+  this.render(hbs`
+    {{#error-bar}}
+      template block text
+    {{/error-bar}}
+  `);
+
+  assert.equal(this.$().text().trim(), '');
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/6d4bb2c6/tez-ui2/src/main/webapp/tests/unit/entities/entity-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/entities/entity-test.js b/tez-ui2/src/main/webapp/tests/unit/entities/entity-test.js
index fb0bd8a..9e2550d 100644
--- a/tez-ui2/src/main/webapp/tests/unit/entities/entity-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/entities/entity-test.js
@@ -78,6 +78,7 @@ test('loadAllNeeds basic test', function(assert) {
   let adapter = this.subject(),
       loader,
       testModel = Ember.Object.create({
+        refreshLoadTime: Ember.K,
         needs: {
           app: "appID",
           foo: "fooID"
@@ -115,6 +116,7 @@ test('loadAllNeeds silent=false test', function(assert) {
   let adapter = this.subject(),
       loader,
       testModel = Ember.Object.create({
+        refreshLoadTime: Ember.K,
         needs: {
           app: {
             idKey: "appID",
@@ -142,6 +144,7 @@ test('loadAllNeeds silent=true test', function(assert) {
   let adapter = this.subject(),
       loader,
       testModel = Ember.Object.create({
+        refreshLoadTime: Ember.K,
         needs: {
           app: {
             idKey: "appID",

http://git-wip-us.apache.org/repos/asf/tez/blob/6d4bb2c6/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js
index 202e889..9ed3452 100644
--- a/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js
@@ -18,8 +18,6 @@
 
 import Ember from 'ember';
 
-import UnlinkedPromise from '../../../errors/unlinked-promise';
-
 import { moduleFor, test } from 'ember-qunit';
 
 moduleFor('route:abstract', 'Unit | Route | abstract', {
@@ -174,8 +172,8 @@ test('loadData test - ID change check with exception throw', function(assert) {
 
   route.loadData().then(function () {
     assert.notOk("Shouldn't be called");
-  }).catch(function (e) {
-    assert.ok(e instanceof UnlinkedPromise, "Exception thrown");
+  }).catch(function () {
+    assert.ok(true, "Exception thrown");
   });
 });
 


[30/45] tez git commit: TEZ-3060. Tez UI 2: Activate auto-refresh (sree)

Posted by sr...@apache.org.
TEZ-3060. Tez UI 2: Activate auto-refresh (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/eb50a0e1
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/eb50a0e1
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/eb50a0e1

Branch: refs/heads/TEZ-2980
Commit: eb50a0e1d87803e8fabf61f9c68c9dc9151ed82c
Parents: 1c88ee4
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Thu Jan 28 23:41:36 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:32:52 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |   1 +
 tez-ui2/src/main/webapp/app/adapters/am.js      |   4 +-
 tez-ui2/src/main/webapp/app/adapters/app-rm.js  |  22 +++
 .../src/main/webapp/app/adapters/attempt-am.js  |  22 +++
 tez-ui2/src/main/webapp/app/adapters/dag-am.js  |  22 +++
 tez-ui2/src/main/webapp/app/adapters/loader.js  |   2 +-
 tez-ui2/src/main/webapp/app/adapters/task-am.js |  22 +++
 .../src/main/webapp/app/adapters/vertex-am.js   |  22 +++
 .../main/webapp/app/components/tab-n-refresh.js |   7 +-
 .../src/main/webapp/app/controllers/abstract.js |   7 +-
 tez-ui2/src/main/webapp/app/controllers/app.js  |   4 +-
 .../main/webapp/app/controllers/app/configs.js  |   4 +-
 .../src/main/webapp/app/controllers/app/dags.js |   7 +-
 .../src/main/webapp/app/controllers/attempt.js  |   4 +-
 .../webapp/app/controllers/attempt/counters.js  |   4 +-
 .../webapp/app/controllers/counters-page.js     |  63 ---------
 .../webapp/app/controllers/counters-table.js    |  74 ++++++++++
 tez-ui2/src/main/webapp/app/controllers/dag.js  |   4 +-
 .../main/webapp/app/controllers/dag/attempts.js |   7 +-
 .../main/webapp/app/controllers/dag/counters.js |   4 +-
 .../main/webapp/app/controllers/dag/tasks.js    |   7 +-
 .../main/webapp/app/controllers/dag/vertices.js |   7 +-
 tez-ui2/src/main/webapp/app/controllers/dags.js |   7 +-
 .../main/webapp/app/controllers/multi-table.js  |  37 +++++
 tez-ui2/src/main/webapp/app/controllers/page.js |   9 +-
 .../src/main/webapp/app/controllers/parent.js   |  30 ++++
 .../main/webapp/app/controllers/table-page.js   | 135 ------------------
 .../src/main/webapp/app/controllers/table.js    | 138 +++++++++++++++++++
 tez-ui2/src/main/webapp/app/controllers/task.js |   6 +-
 .../webapp/app/controllers/task/attempts.js     |   7 +-
 .../webapp/app/controllers/task/counters.js     |   4 +-
 .../src/main/webapp/app/controllers/vertex.js   |   6 +-
 .../webapp/app/controllers/vertex/attempts.js   |   7 +-
 .../webapp/app/controllers/vertex/counters.js   |   4 +-
 .../main/webapp/app/controllers/vertex/tasks.js |   7 +-
 tez-ui2/src/main/webapp/app/entities/am.js      |  58 ++++++++
 .../src/main/webapp/app/entities/attempt-am.js  |  23 ++++
 tez-ui2/src/main/webapp/app/entities/entity.js  | 138 ++++++++++++++-----
 tez-ui2/src/main/webapp/app/entities/task-am.js |  23 ++++
 .../src/main/webapp/app/entities/vertex-am.js   |  23 ++++
 .../main/webapp/app/initializers/entities.js    |   1 +
 .../webapp/app/mixins/auto-counter-column.js    |  14 +-
 tez-ui2/src/main/webapp/app/models/abstract.js  |  21 +++
 tez-ui2/src/main/webapp/app/models/ahs-app.js   |   2 -
 .../src/main/webapp/app/models/am-timeline.js   |  46 +++++++
 tez-ui2/src/main/webapp/app/models/am.js        |  31 +++++
 tez-ui2/src/main/webapp/app/models/app-rm.js    |  22 +++
 tez-ui2/src/main/webapp/app/models/app.js       |  16 ---
 .../src/main/webapp/app/models/attempt-am.js    |  22 +++
 tez-ui2/src/main/webapp/app/models/attempt.js   |  53 +++----
 tez-ui2/src/main/webapp/app/models/dag-am.js    |  22 +++
 tez-ui2/src/main/webapp/app/models/dag.js       |  39 +++---
 tez-ui2/src/main/webapp/app/models/rm.js        |  26 ++++
 tez-ui2/src/main/webapp/app/models/task-am.js   |  22 +++
 tez-ui2/src/main/webapp/app/models/task.js      |  48 +++----
 tez-ui2/src/main/webapp/app/models/timeline.js  |  11 +-
 tez-ui2/src/main/webapp/app/models/vertex-am.js |  22 +++
 tez-ui2/src/main/webapp/app/models/vertex.js    |  37 ++---
 tez-ui2/src/main/webapp/app/router.js           |   2 +
 tez-ui2/src/main/webapp/app/routes/abstract.js  |   7 +-
 .../src/main/webapp/app/routes/am-pollster.js   |  88 ++++++++++++
 .../src/main/webapp/app/routes/app/configs.js   |   6 +-
 tez-ui2/src/main/webapp/app/routes/app/dags.js  |   4 +-
 tez-ui2/src/main/webapp/app/routes/app/index.js |   8 +-
 .../src/main/webapp/app/routes/application.js   |   5 +
 tez-ui2/src/main/webapp/app/routes/attempt.js   |   2 +-
 .../main/webapp/app/routes/attempt/counters.js  |   4 +-
 .../src/main/webapp/app/routes/attempt/index.js |   4 +-
 .../src/main/webapp/app/routes/dag/attempts.js  |   4 +-
 .../src/main/webapp/app/routes/dag/counters.js  |   4 +-
 tez-ui2/src/main/webapp/app/routes/dag/index.js |   4 +-
 tez-ui2/src/main/webapp/app/routes/dag/tasks.js |   4 +-
 .../src/main/webapp/app/routes/dag/vertices.js  |   4 +-
 tez-ui2/src/main/webapp/app/routes/dags.js      |   6 +-
 .../main/webapp/app/routes/multi-am-pollster.js |  35 +++++
 tez-ui2/src/main/webapp/app/routes/pollster.js  |  65 +++++++++
 .../webapp/app/routes/single-am-pollster.js     |  34 +++++
 tez-ui2/src/main/webapp/app/routes/task.js      |   2 +-
 .../src/main/webapp/app/routes/task/attempts.js |   4 +-
 .../src/main/webapp/app/routes/task/counters.js |   4 +-
 .../src/main/webapp/app/routes/task/index.js    |   4 +-
 .../main/webapp/app/routes/vertex/attempts.js   |   4 +-
 .../main/webapp/app/routes/vertex/counters.js   |   4 +-
 .../src/main/webapp/app/routes/vertex/index.js  |   4 +-
 .../src/main/webapp/app/routes/vertex/tasks.js  |   4 +-
 tez-ui2/src/main/webapp/app/serializers/am.js   |  41 ++++++
 .../src/main/webapp/app/serializers/app-rm.js   |  33 +++++
 .../main/webapp/app/serializers/attempt-am.js   |  23 ++++
 .../src/main/webapp/app/serializers/dag-am.js   |  28 ++++
 .../src/main/webapp/app/serializers/loader.js   |   1 +
 tez-ui2/src/main/webapp/app/serializers/rm.js   |  28 ++++
 .../src/main/webapp/app/serializers/task-am.js  |  23 ++++
 .../src/main/webapp/app/serializers/timeline.js |   4 +-
 .../main/webapp/app/serializers/vertex-am.js    |  23 ++++
 tez-ui2/src/main/webapp/app/services/hosts.js   |   4 +
 tez-ui2/src/main/webapp/app/services/loader.js  |  79 +++++------
 .../src/main/webapp/app/services/pollster.js    |  83 +++++++++++
 tez-ui2/src/main/webapp/app/templates/app.hbs   |   2 +-
 .../src/main/webapp/app/templates/app/dags.hbs  |   4 +-
 .../src/main/webapp/app/templates/attempt.hbs   |   2 +-
 .../webapp/app/templates/attempt/counters.hbs   |   2 +-
 .../main/webapp/app/templates/attempt/index.hbs |   8 +-
 .../app/templates/components/tab-n-refresh.hbs  |   6 +-
 tez-ui2/src/main/webapp/app/templates/dag.hbs   |   2 +-
 .../main/webapp/app/templates/dag/attempts.hbs  |   4 +-
 .../main/webapp/app/templates/dag/counters.hbs  |   2 +-
 .../src/main/webapp/app/templates/dag/index.hbs |   4 +
 .../src/main/webapp/app/templates/dag/tasks.hbs |   4 +-
 .../main/webapp/app/templates/dag/vertices.hbs  |   4 +-
 tez-ui2/src/main/webapp/app/templates/dags.hbs  |   4 +-
 tez-ui2/src/main/webapp/app/templates/task.hbs  |   2 +-
 .../main/webapp/app/templates/task/attempts.hbs |   4 +-
 .../main/webapp/app/templates/task/counters.hbs |   2 +-
 .../main/webapp/app/templates/task/index.hbs    |   8 +-
 .../src/main/webapp/app/templates/vertex.hbs    |   2 +-
 .../webapp/app/templates/vertex/attempts.hbs    |   4 +-
 .../webapp/app/templates/vertex/counters.hbs    |   2 +-
 .../main/webapp/app/templates/vertex/index.hbs  |   4 +
 .../main/webapp/app/templates/vertex/tasks.hbs  |   4 +-
 .../app/utils/counter-column-definition.js      |   2 +-
 .../src/main/webapp/config/default-app-conf.js  |  13 +-
 tez-ui2/src/main/webapp/package.json            |   2 +-
 .../main/webapp/tests/unit/adapters/am-test.js  |  19 +++
 .../webapp/tests/unit/adapters/app-rm-test.js   |  29 ++++
 .../tests/unit/adapters/attempt-am-test.js      |  29 ++++
 .../webapp/tests/unit/adapters/dag-am-test.js   |  29 ++++
 .../webapp/tests/unit/adapters/task-am-test.js  |  29 ++++
 .../tests/unit/adapters/vertex-am-test.js       |  29 ++++
 .../tests/unit/controllers/abstract-test.js     |   1 +
 .../tests/unit/controllers/app/dags-test.js     |   3 +-
 .../unit/controllers/counters-page-test.js      |  97 -------------
 .../unit/controllers/counters-table-test.js     |  91 ++++++++++++
 .../tests/unit/controllers/dag/attempts-test.js |   5 +-
 .../tests/unit/controllers/dag/tasks-test.js    |   5 +-
 .../tests/unit/controllers/dag/vertices-test.js |   5 +-
 .../tests/unit/controllers/multi-table-test.js  |  40 ++++++
 .../tests/unit/controllers/parent-test.js       |  36 +++++
 .../tests/unit/controllers/table-page-test.js   |  64 ---------
 .../webapp/tests/unit/controllers/table-test.js |  64 +++++++++
 .../unit/controllers/task/attempts-test.js      |   5 +-
 .../unit/controllers/vertex/attempts-test.js    |   5 +-
 .../tests/unit/controllers/vertex/tasks-test.js |   5 +-
 .../main/webapp/tests/unit/entities/am-test.js  |  33 +++++
 .../tests/unit/entities/attempt-am-test.js      |  31 +++++
 .../webapp/tests/unit/entities/entity-test.js   |  95 +++----------
 .../webapp/tests/unit/entities/task-am-test.js  |  31 +++++
 .../tests/unit/entities/vertex-am-test.js       |  31 +++++
 .../unit/mixins/auto-counter-column-test.js     |  32 +++--
 .../webapp/tests/unit/models/abstract-test.js   |   5 +
 .../webapp/tests/unit/models/ahs-app-test.js    |   2 +
 .../main/webapp/tests/unit/models/am-test.js    |  31 +++++
 .../tests/unit/models/am-timeline-test.js       |  34 +++++
 .../webapp/tests/unit/models/app-rm-test.js     |  30 ++++
 .../webapp/tests/unit/models/attempt-am-test.js |  30 ++++
 .../webapp/tests/unit/models/attempt-test.js    |  17 ++-
 .../webapp/tests/unit/models/dag-am-test.js     |  30 ++++
 .../main/webapp/tests/unit/models/dag-test.js   |   1 +
 .../main/webapp/tests/unit/models/rm-test.js    |  30 ++++
 .../webapp/tests/unit/models/task-am-test.js    |  30 ++++
 .../main/webapp/tests/unit/models/task-test.js  |  12 +-
 .../webapp/tests/unit/models/timeline-test.js   |  16 +--
 .../webapp/tests/unit/models/vertex-am-test.js  |  30 ++++
 .../webapp/tests/unit/models/vertex-test.js     |  22 ++-
 .../tests/unit/routes/am-pollster-test.js       |  34 +++++
 .../tests/unit/routes/multi-am-pollster-test.js |  32 +++++
 .../webapp/tests/unit/routes/pollster-test.js   |  39 ++++++
 .../unit/routes/single-am-pollster-test.js      |  32 +++++
 .../tests/unit/routes/vertex/tasks-test.js      |   7 +-
 .../webapp/tests/unit/serializers/am-test.js    |  30 ++++
 .../tests/unit/serializers/app-rm-test.js       |  30 ++++
 .../tests/unit/serializers/attempt-am-test.js   |  31 +++++
 .../tests/unit/serializers/dag-am-test.js       |  30 ++++
 .../webapp/tests/unit/serializers/rm-test.js    |  30 ++++
 .../tests/unit/serializers/task-am-test.js      |  31 +++++
 .../tests/unit/serializers/vertex-am-test.js    |  31 +++++
 .../webapp/tests/unit/services/loader-test.js   |  74 ++++------
 .../webapp/tests/unit/services/pollster-test.js |  29 ++++
 .../utils/counter-column-definition-test.js     |   4 +-
 178 files changed, 3009 insertions(+), 842 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index f5660a5..60eb715 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -26,3 +26,4 @@ ALL CHANGES:
   TEZ-3064. Tez UI 2: Add All DAGs filters
   TEZ-3059. Tez UI 2: Make refresh functional
   TEZ-3070. Tez UI 2: Jenkins build is failing
+  TEZ-3060. Tez UI 2: Activate auto-refresh

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/adapters/am.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/am.js b/tez-ui2/src/main/webapp/app/adapters/am.js
index f80cdd5..85f3d27 100644
--- a/tez-ui2/src/main/webapp/app/adapters/am.js
+++ b/tez-ui2/src/main/webapp/app/adapters/am.js
@@ -21,5 +21,7 @@ import AbstractAdapter from './abstract';
 export default AbstractAdapter.extend({
   serverName: "am",
 
-  // Any am specific adapter changes must be added here
+  queryRecord: function(store, type, query) {
+    return this.query(store, type, query);
+  },
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/adapters/app-rm.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/app-rm.js b/tez-ui2/src/main/webapp/app/adapters/app-rm.js
new file mode 100644
index 0000000..b61e391
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/adapters/app-rm.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 RMAdapter from './rm';
+
+export default RMAdapter.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/adapters/attempt-am.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/attempt-am.js b/tez-ui2/src/main/webapp/app/adapters/attempt-am.js
new file mode 100644
index 0000000..39cd2a4
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/adapters/attempt-am.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 AMAdapter from './am';
+
+export default AMAdapter.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/adapters/dag-am.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/dag-am.js b/tez-ui2/src/main/webapp/app/adapters/dag-am.js
new file mode 100644
index 0000000..39cd2a4
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/adapters/dag-am.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 AMAdapter from './am';
+
+export default AMAdapter.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/adapters/loader.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/loader.js b/tez-ui2/src/main/webapp/app/adapters/loader.js
index d4b502c..f63bd07 100644
--- a/tez-ui2/src/main/webapp/app/adapters/loader.js
+++ b/tez-ui2/src/main/webapp/app/adapters/loader.js
@@ -25,7 +25,7 @@ export default DS.RESTAdapter.extend({
   _isLoader: true,
 
   buildURL: function(modelName, id, snapshot, requestType, query, params) {
-    var url = this._super(modelName, id, snapshot, null, query);
+    var url = this._super(modelName, id, snapshot, requestType, query);
     return params ? MoreString.fmt(url, params) : url;
   },
 

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/adapters/task-am.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/task-am.js b/tez-ui2/src/main/webapp/app/adapters/task-am.js
new file mode 100644
index 0000000..39cd2a4
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/adapters/task-am.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 AMAdapter from './am';
+
+export default AMAdapter.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/adapters/vertex-am.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/vertex-am.js b/tez-ui2/src/main/webapp/app/adapters/vertex-am.js
new file mode 100644
index 0000000..39cd2a4
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/adapters/vertex-am.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 AMAdapter from './am';
+
+export default AMAdapter.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/components/tab-n-refresh.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/components/tab-n-refresh.js b/tez-ui2/src/main/webapp/app/components/tab-n-refresh.js
index 75bac20..6ac6454 100644
--- a/tez-ui2/src/main/webapp/app/components/tab-n-refresh.js
+++ b/tez-ui2/src/main/webapp/app/components/tab-n-refresh.js
@@ -24,13 +24,18 @@ export default Ember.Component.extend({
     this.setApplication();
   },
 
-  autoRefreshEnabled: true,
+  autoRefreshEnabled: false,
+  autoRefreshVisible: true,
 
   setApplication: function () {
     var application = this.get("targetObject.container").lookup('controller:application');
     this.set("application", application);
   },
 
+  autoRefreshObserver: Ember.observer("autoRefreshEnabled", function () {
+    this.get('targetObject').send('autoRefreshChanged', this.get("autoRefreshEnabled"));
+  }),
+
   normalizedTabs: Ember.computed("tabs", "application.currentPath", function () {
     var tabs = this.get("tabs") || [],
         activeRouteName = this.get("application.currentPath");

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/controllers/abstract.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/abstract.js b/tez-ui2/src/main/webapp/app/controllers/abstract.js
index 816e7d1..863a63f 100644
--- a/tez-ui2/src/main/webapp/app/controllers/abstract.js
+++ b/tez-ui2/src/main/webapp/app/controllers/abstract.js
@@ -24,14 +24,19 @@ export default Ember.Controller.extend(NameMixin, {
   // Must be set by inheriting classes
   breadcrumbs: null,
 
-  // Must be set from route
+  // Must be set from abstract route
   loadTime: null,
+  isLoading: false,
 
   init: function () {
     this._super();
     Ember.run.later(this, "setBreadcrumbs");
   },
 
+  loaded: Ember.computed("model", "isLoading", function () {
+    return this.get("model") && !this.get("isLoading");
+  }),
+
   crumbObserver: Ember.observer("breadcrumbs", function () {
     Ember.run.later(this, "setBreadcrumbs");
   }),

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/controllers/app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/app.js b/tez-ui2/src/main/webapp/app/controllers/app.js
index 8333220..f379e80 100644
--- a/tez-ui2/src/main/webapp/app/controllers/app.js
+++ b/tez-ui2/src/main/webapp/app/controllers/app.js
@@ -18,9 +18,9 @@
 
 import Ember from 'ember';
 
-import AbstractController from './abstract';
+import ParentController from './parent';
 
-export default AbstractController.extend({
+export default ParentController.extend({
   breadcrumbs: Ember.computed("model.appID", "model.app.name", function () {
     var name = this.get("model.app.name") || this.get("model.appID");
 

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/controllers/app/configs.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/app/configs.js b/tez-ui2/src/main/webapp/app/controllers/app/configs.js
index 517d43b..838abc1 100644
--- a/tez-ui2/src/main/webapp/app/controllers/app/configs.js
+++ b/tez-ui2/src/main/webapp/app/controllers/app/configs.js
@@ -19,12 +19,12 @@
 
 import Ember from 'ember';
 
-import TablePageController from '../table-page';
+import TableController from '../table';
 import ColumnDefinition from 'em-table/utils/column-definition';
 
 var MoreObject = more.Object;
 
-export default TablePageController.extend({
+export default TableController.extend({
   searchText: "tez",
 
   breadcrumbs: [{

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/controllers/app/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/app/dags.js b/tez-ui2/src/main/webapp/app/controllers/app/dags.js
index 547c4ee..b3e855a 100644
--- a/tez-ui2/src/main/webapp/app/controllers/app/dags.js
+++ b/tez-ui2/src/main/webapp/app/controllers/app/dags.js
@@ -16,10 +16,10 @@
  * limitations under the License.
  */
 
-import TablePageController from '../table-page';
+import MultiTableController from '../multi-table';
 import ColumnDefinition from 'em-table/utils/column-definition';
 
-export default TablePageController.extend({
+export default MultiTableController.extend({
   breadcrumbs: [{
     text: "DAGs",
     routeName: "app.dags",
@@ -49,7 +49,8 @@ export default TablePageController.extend({
     id: 'status',
     headerTitle: 'Status',
     contentPath: 'status',
-    cellComponentName: 'em-table-status-cell'
+    cellComponentName: 'em-table-status-cell',
+    observePath: true
   },{
     id: 'progress',
     headerTitle: 'Progress',

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/controllers/attempt.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/attempt.js b/tez-ui2/src/main/webapp/app/controllers/attempt.js
index 64c8a67..b10fc7f 100644
--- a/tez-ui2/src/main/webapp/app/controllers/attempt.js
+++ b/tez-ui2/src/main/webapp/app/controllers/attempt.js
@@ -18,9 +18,9 @@
 
 import Ember from 'ember';
 
-import AbstractController from './abstract';
+import ParentController from './parent';
 
-export default AbstractController.extend({
+export default ParentController.extend({
   breadcrumbs: Ember.computed("model.dag", function () {
     var dagName = this.get("model.dag.name"),
         vertexName = this.get("model.vertexName"),

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/controllers/attempt/counters.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/attempt/counters.js b/tez-ui2/src/main/webapp/app/controllers/attempt/counters.js
index 9442838..1a93c80 100644
--- a/tez-ui2/src/main/webapp/app/controllers/attempt/counters.js
+++ b/tez-ui2/src/main/webapp/app/controllers/attempt/counters.js
@@ -16,9 +16,9 @@
  * limitations under the License.
  */
 
-import CountersPageController from '../counters-page';
+import CountersTableController from '../counters-table';
 
-export default CountersPageController.extend({
+export default CountersTableController.extend({
   breadcrumbs: [{
     text: "Attempt Counters",
     routeName: "attempt.counters",

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/controllers/counters-page.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/counters-page.js b/tez-ui2/src/main/webapp/app/controllers/counters-page.js
deleted file mode 100644
index ef22ef1..0000000
--- a/tez-ui2/src/main/webapp/app/controllers/counters-page.js
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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 TablePageController from './table-page';
-import ColumnDefinition from 'em-table/utils/column-definition';
-
-export default TablePageController.extend({
-  columns: ColumnDefinition.make([{
-    id: 'groupName',
-    headerTitle: 'Group Name',
-    contentPath: 'groupName',
-  }, {
-    id: 'counterName',
-    headerTitle: 'Counter Name',
-    contentPath: 'counterName',
-  }, {
-    id: 'counterValue',
-    headerTitle: 'Counter Value',
-    contentPath: 'counterValue',
-  }]),
-
-  counters: Ember.computed("model.counterGroups", function () {
-    var counterGroups = this.get("model.counterGroups"),
-        counterRows = [];
-
-    if(counterGroups) {
-      counterGroups.forEach(function (group) {
-        var counterGroupName = group.counterGroupName,
-            counters = group.counters;
-
-        if(counters) {
-          counterGroupName = counterGroupName.substr(counterGroupName.lastIndexOf('.') + 1);
-          counters.forEach(function (counter) {
-            counterRows.push(Ember.Object.create({
-              groupName: counterGroupName,
-              counterName: counter.counterName,
-              counterValue: counter.counterValue
-            }));
-          });
-        }
-      });
-    }
-
-    return Ember.A(counterRows);
-  })
-});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/controllers/counters-table.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/counters-table.js b/tez-ui2/src/main/webapp/app/controllers/counters-table.js
new file mode 100644
index 0000000..42361b4
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/counters-table.js
@@ -0,0 +1,74 @@
+/*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 TableController from './table';
+import ColumnDefinition from 'em-table/utils/column-definition';
+
+var MoreObject = more.Object;
+
+export default TableController.extend({
+  counters: Ember.A(),
+  countersCount: 0, // Because Ember.Array doesn't handle length well
+
+  columns: ColumnDefinition.make([{
+    id: 'groupName',
+    headerTitle: 'Group Name',
+    contentPath: 'groupName',
+  }, {
+    id: 'counterName',
+    headerTitle: 'Counter Name',
+    contentPath: 'counterName',
+  }, {
+    id: 'counterValue',
+    headerTitle: 'Counter Value',
+    contentPath: 'counterValue',
+    observePath: true
+  }]),
+
+  _countersObserver: Ember.observer("model.counterGroupsHash", function () {
+    var counterGroupsHash = this.get("model.counterGroupsHash"),
+        counters = this.get("counters"),
+        counterIndex = 0;
+
+    if(counterGroupsHash) {
+      MoreObject.forEach(counterGroupsHash, function (groupName, countersHash) {
+        if(countersHash) {
+          MoreObject.forEach(countersHash, function (counterName, counterValue) {
+            let counterRow = counters.get(counterIndex);
+            if(!counterRow) {
+              counterRow = Ember.Object.create();
+              counters.push(counterRow);
+            }
+
+            counterRow.setProperties({
+              groupName: groupName,
+              counterName: counterName,
+              counterValue: counterValue
+            });
+            counterIndex++;
+          });
+        }
+      });
+    }
+
+    this.set("countersCount", counterIndex);
+  })
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/controllers/dag.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag.js b/tez-ui2/src/main/webapp/app/controllers/dag.js
index 14f9df6..f2b04d1 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag.js
@@ -18,9 +18,9 @@
 
 import Ember from 'ember';
 
-import AbstractController from './abstract';
+import ParentController from './parent';
 
-export default AbstractController.extend({
+export default ParentController.extend({
   breadcrumbs: Ember.computed("model", function () {
     var name = this.get("model.name");
 

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js b/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
index d9cb9e9..94bca3e 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
@@ -16,10 +16,10 @@
  * limitations under the License.
  */
 
-import TablePageController from '../table-page';
+import MultiTableController from '../multi-table';
 import ColumnDefinition from 'em-table/utils/column-definition';
 
-export default TablePageController.extend({
+export default MultiTableController.extend({
   breadcrumbs: [{
     text: "All Task Attempts",
     routeName: "dag.attempts",
@@ -65,7 +65,8 @@ export default TablePageController.extend({
     id: 'status',
     headerTitle: 'Status',
     contentPath: 'status',
-    cellComponentName: 'em-table-status-cell'
+    cellComponentName: 'em-table-status-cell',
+    observePath: true
   },{
     id: 'progress',
     headerTitle: 'Progress',

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/controllers/dag/counters.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/counters.js b/tez-ui2/src/main/webapp/app/controllers/dag/counters.js
index c4fbea6..c54fd7e 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag/counters.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/counters.js
@@ -16,9 +16,9 @@
  * limitations under the License.
  */
 
-import CountersPageController from '../counters-page';
+import CountersTableController from '../counters-table';
 
-export default CountersPageController.extend({
+export default CountersTableController.extend({
   breadcrumbs: [{
     text: "DAG Counters",
     routeName: "dag.counters",

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js b/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
index 1a5c776..58e0163 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
@@ -16,10 +16,10 @@
  * limitations under the License.
  */
 
-import TablePageController from '../table-page';
+import MultiTableController from '../multi-table';
 import ColumnDefinition from 'em-table/utils/column-definition';
 
-export default TablePageController.extend({
+export default MultiTableController.extend({
   breadcrumbs: [{
     text: "All Tasks",
     routeName: "dag.tasks",
@@ -53,7 +53,8 @@ export default TablePageController.extend({
     id: 'status',
     headerTitle: 'Status',
     contentPath: 'status',
-    cellComponentName: 'em-table-status-cell'
+    cellComponentName: 'em-table-status-cell',
+    observePath: true
   },{
     id: 'progress',
     headerTitle: 'Progress',

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js b/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
index b20a558..1b9f136 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
@@ -16,10 +16,10 @@
  * limitations under the License.
  */
 
-import TablePageController from '../table-page';
+import MultiTableController from '../multi-table';
 import ColumnDefinition from 'em-table/utils/column-definition';
 
-export default TablePageController.extend({
+export default MultiTableController.extend({
   breadcrumbs: [{
     text: "All Vertices",
     routeName: "dag.vertices",
@@ -45,7 +45,8 @@ export default TablePageController.extend({
     id: 'status',
     headerTitle: 'Status',
     contentPath: 'status',
-    cellComponentName: 'em-table-status-cell'
+    cellComponentName: 'em-table-status-cell',
+    observePath: true
   },{
     id: 'progress',
     headerTitle: 'Progress',

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/controllers/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dags.js b/tez-ui2/src/main/webapp/app/controllers/dags.js
index d35d8f7..021a1e0 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dags.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dags.js
@@ -18,11 +18,11 @@
 
 import Ember from 'ember';
 
-import TablePageController from './table-page';
+import TableController from './table';
 import ColumnDefinition from 'em-table/utils/column-definition';
 import TableDefinition from 'em-table/utils/table-definition';
 
-export default TablePageController.extend({
+export default TableController.extend({
 
   queryParams: ["dagName", "dagID", "submitter", "status", "appID", "contextID", "pageNo"],
   dagName: "",
@@ -75,7 +75,8 @@ export default TablePageController.extend({
     id: 'status',
     headerTitle: 'Status',
     contentPath: 'status',
-    cellComponentName: 'em-table-status-cell'
+    cellComponentName: 'em-table-status-cell',
+    observePath: true
   },{
     id: 'progress',
     headerTitle: 'Progress',

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/controllers/multi-table.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/multi-table.js b/tez-ui2/src/main/webapp/app/controllers/multi-table.js
new file mode 100644
index 0000000..3a11830
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/multi-table.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 TableController from './table';
+import CounterColumnDefinition from '../utils/counter-column-definition';
+
+export default TableController.extend({
+
+  _visibleColumnsObserver: Ember.on("init", Ember.observer("visibleColumns", function () {
+    Ember.run.later(this, "sendCountersChanged");
+  })),
+
+  sendCountersChanged: function () {
+    var visibleCounters = this.get("visibleColumns").filter(function (definition) {
+      return definition instanceof CounterColumnDefinition;
+    });
+    this.send("countersToPollChanged", visibleCounters);
+  }
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/controllers/page.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/page.js b/tez-ui2/src/main/webapp/app/controllers/page.js
index 84882a8..14ad6b5 100644
--- a/tez-ui2/src/main/webapp/app/controllers/page.js
+++ b/tez-ui2/src/main/webapp/app/controllers/page.js
@@ -16,15 +16,8 @@
  * limitations under the License.
  */
 
-import Ember from 'ember';
-
 import AbstractController from './abstract';
 
 export default AbstractController.extend({
-  // Must be set from route
-  isLoading: false,
-
-  loaded: Ember.computed("model", "isLoading", function () {
-    return this.get("model") && !this.get("isLoading");
-  }),
+  // Any page specific
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/controllers/parent.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/parent.js b/tez-ui2/src/main/webapp/app/controllers/parent.js
new file mode 100644
index 0000000..089ed77
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/parent.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 AbstractController from './abstract';
+
+export default AbstractController.extend({
+  polling: Ember.inject.service("pollster"),
+  actions: {
+    autoRefreshChanged: function (state) {
+      this.get("polling").set("active", state);
+    }
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/controllers/table-page.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/table-page.js b/tez-ui2/src/main/webapp/app/controllers/table-page.js
deleted file mode 100644
index 12f4715..0000000
--- a/tez-ui2/src/main/webapp/app/controllers/table-page.js
+++ /dev/null
@@ -1,135 +0,0 @@
-/*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 PageController from './page';
-import TableDefinition from 'em-table/utils/table-definition';
-import isIOCounter from '../utils/misc';
-
-import CounterColumnDefinition from '../utils/counter-column-definition';
-
-var MoreObject = more.Object;
-
-export default PageController.extend({
-  queryParams: ["rowCount", "searchText", "sortColumnId", "sortOrder", "pageNo"],
-  rowCount: 10,
-  searchText: "",
-  sortColumnId: "",
-  sortOrder: "",
-  pageNo: 1,
-
-  columns: [],
-
-  headerComponentNames: ['em-table-search-ui', 'table-controls', 'em-table-pagination-ui'],
-
-  visibleColumnIDs: {},
-  columnSelectorTitle: 'Column Selector',
-  columnSelectorMessage: "",
-
-  definition: Ember.computed(function () {
-    return TableDefinition.create({
-      rowCount: this.get("rowCount"),
-      searchText: this.get("searchText"),
-      sortColumnId: this.get("sortColumnId"),
-      sortOrder: this.get("sortOrder"),
-      pageNo: this.get("pageNo")
-    });
-  }),
-
-  storageID: Ember.computed("name", function () {
-    return this.get("name") + ":visibleColumnIDs";
-  }),
-
-  initVisibleColumns: Ember.on("init", Ember.observer("columns", function () { //To reset on entity change
-    var visibleColumnIDs = this.get("localStorage").get(this.get("storageID")) || {};
-
-    this.get('columns').forEach(function (config) {
-      if(visibleColumnIDs[config.id] !== false) {
-        visibleColumnIDs[config.id] = true;
-      }
-    });
-
-    this.set('visibleColumnIDs', visibleColumnIDs);
-  })),
-
-  allColumns: Ember.computed("columns", function () {
-    var columns = this.get("columns"),
-        counters = this.getCounterColumns();
-
-    return columns.concat(CounterColumnDefinition.make(counters));
-  }),
-
-  visibleColumns: Ember.computed('visibleColumnIDs', 'allColumns', function() {
-    var visibleColumnIDs = this.visibleColumnIDs;
-    return this.get('allColumns').filter(function (column) {
-      return visibleColumnIDs[column.get("id")];
-    });
-  }),
-
-  getCounterColumns: function () {
-    return this.get('env.app.tables.defaultColumns.counters');
-  },
-
-  actions: {
-    searchChanged: function (searchText) {
-      this.set("searchText", searchText);
-    },
-    sortChanged: function (sortColumnId, sortOrder) {
-      this.setProperties({
-        sortColumnId,
-        sortOrder
-      });
-    },
-    rowsChanged: function (rowCount) {
-      // Change to rows action in em-table
-      this.set("rowCount", rowCount);
-    },
-    pageChanged: function (pageNum) {
-      this.set("pageNo", pageNum);
-    },
-
-    // Column selection actions
-    openColumnSelector: function () {
-      this.send("openModal", "column-selector", {
-        title: this.get('columnSelectorTitle'),
-        targetObject: this,
-        content: {
-          message: this.get('columnSelectorMessage'),
-          columns: this.get('allColumns'),
-          visibleColumnIDs: this.get('visibleColumnIDs')
-        }
-      });
-    },
-    columnsSelected: function (visibleColumnIDs) {
-      var columnIDs = {};
-
-      MoreObject.forEach(visibleColumnIDs, function (key, value) {
-        if(!isIOCounter(key)) {
-          columnIDs[key] = value;
-        }
-      });
-
-      if(!MoreObject.equals(columnIDs, this.get("visibleColumnIDs"))) {
-        this.get("localStorage").set(this.get("storageID"), columnIDs);
-        this.set('visibleColumnIDs', columnIDs);
-      }
-    }
-  }
-});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/controllers/table.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/table.js b/tez-ui2/src/main/webapp/app/controllers/table.js
new file mode 100644
index 0000000..0891e8d
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/table.js
@@ -0,0 +1,138 @@
+/*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 AbstractController from './abstract';
+import TableDefinition from 'em-table/utils/table-definition';
+import isIOCounter from '../utils/misc';
+
+import CounterColumnDefinition from '../utils/counter-column-definition';
+
+var MoreObject = more.Object;
+
+export default AbstractController.extend({
+  queryParams: ["rowCount", "searchText", "sortColumnId", "sortOrder", "pageNo"],
+  rowCount: 10,
+  searchText: "",
+  sortColumnId: "",
+  sortOrder: "",
+  pageNo: 1,
+
+  columns: [],
+
+  headerComponentNames: ['em-table-search-ui', 'table-controls', 'em-table-pagination-ui'],
+
+  visibleColumnIDs: {},
+  columnSelectorTitle: 'Column Selector',
+  columnSelectorMessage: "",
+
+  definition: Ember.computed(function () {
+    return TableDefinition.create({
+      rowCount: this.get("rowCount"),
+      searchText: this.get("searchText"),
+      sortColumnId: this.get("sortColumnId"),
+      sortOrder: this.get("sortOrder"),
+      pageNo: this.get("pageNo")
+    });
+  }),
+
+  storageID: Ember.computed("name", function () {
+    return this.get("name") + ":visibleColumnIDs";
+  }),
+
+  initVisibleColumns: Ember.on("init", Ember.observer("columns", function () { //To reset on entity change
+    var visibleColumnIDs = this.get("localStorage").get(this.get("storageID")) || {};
+
+    this.get('columns').forEach(function (config) {
+      if(visibleColumnIDs[config.id] !== false) {
+        visibleColumnIDs[config.id] = true;
+      }
+    });
+
+    this.set('visibleColumnIDs', visibleColumnIDs);
+  })),
+
+  allColumns: Ember.computed("columns", function () {
+    var columns = this.get("columns"),
+        counters = this.getCounterColumns();
+
+    return columns.concat(CounterColumnDefinition.make(counters));
+  }),
+
+  visibleColumns: Ember.computed('visibleColumnIDs', 'allColumns', function() {
+    var visibleColumnIDs = this.visibleColumnIDs;
+    return this.get('allColumns').filter(function (column) {
+      return visibleColumnIDs[column.get("id")];
+    });
+  }),
+
+  getCounterColumns: function () {
+    return this.get('env.app.tables.defaultColumns.counters');
+  },
+
+  actions: {
+    searchChanged: function (searchText) {
+      this.set("searchText", searchText);
+    },
+    sortChanged: function (sortColumnId, sortOrder) {
+      this.setProperties({
+        sortColumnId,
+        sortOrder
+      });
+    },
+    rowCountChanged: function (rowCount) {
+      this.set("rowCount", rowCount);
+    },
+    pageChanged: function (pageNum) {
+      this.set("pageNo", pageNum);
+    },
+
+    rowsChanged: function (rows) {
+      this.send("setPollingRecords", rows);
+    },
+
+    // Column selection actions
+    openColumnSelector: function () {
+      this.send("openModal", "column-selector", {
+        title: this.get('columnSelectorTitle'),
+        targetObject: this,
+        content: {
+          message: this.get('columnSelectorMessage'),
+          columns: this.get('allColumns'),
+          visibleColumnIDs: this.get('visibleColumnIDs')
+        }
+      });
+    },
+    columnsSelected: function (visibleColumnIDs) {
+      var columnIDs = {};
+
+      MoreObject.forEach(visibleColumnIDs, function (key, value) {
+        if(!isIOCounter(key)) {
+          columnIDs[key] = value;
+        }
+      });
+
+      if(!MoreObject.equals(columnIDs, this.get("visibleColumnIDs"))) {
+        this.get("localStorage").set(this.get("storageID"), columnIDs);
+        this.set('visibleColumnIDs', columnIDs);
+      }
+    }
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/controllers/task.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/task.js b/tez-ui2/src/main/webapp/app/controllers/task.js
index 2092162..ffd4ffe 100644
--- a/tez-ui2/src/main/webapp/app/controllers/task.js
+++ b/tez-ui2/src/main/webapp/app/controllers/task.js
@@ -18,12 +18,12 @@
 
 import Ember from 'ember';
 
-import AbstractController from './abstract';
+import ParentController from './parent';
 
-export default AbstractController.extend({
+export default ParentController.extend({
   breadcrumbs: Ember.computed("model.dag", function () {
     var dagName = this.get("model.dag.name"),
-        vertexName = this.get("model.vertexName"),
+        vertexName = this.get("model.vertexName") || this.get("model.vertexIndex"),
         taskIndex = this.get("model.index");
 
     return [{

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/controllers/task/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/task/attempts.js b/tez-ui2/src/main/webapp/app/controllers/task/attempts.js
index d7bec55..472d04f 100644
--- a/tez-ui2/src/main/webapp/app/controllers/task/attempts.js
+++ b/tez-ui2/src/main/webapp/app/controllers/task/attempts.js
@@ -16,12 +16,12 @@
  * limitations under the License.
  */
 
-import TablePageController from '../table-page';
+import MultiTableController from '../multi-table';
 import ColumnDefinition from 'em-table/utils/column-definition';
 
 import AutoCounterColumn from '../../mixins/auto-counter-column';
 
-export default TablePageController.extend(AutoCounterColumn, {
+export default MultiTableController.extend(AutoCounterColumn, {
   breadcrumbs: [{
     text: "Task Attempts",
     routeName: "task.attempts",
@@ -43,7 +43,8 @@ export default TablePageController.extend(AutoCounterColumn, {
     id: 'status',
     headerTitle: 'Status',
     contentPath: 'status',
-    cellComponentName: 'em-table-status-cell'
+    cellComponentName: 'em-table-status-cell',
+    observePath: true
   },{
     id: 'progress',
     headerTitle: 'Progress',

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/controllers/task/counters.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/task/counters.js b/tez-ui2/src/main/webapp/app/controllers/task/counters.js
index b9c00e3..4aa071c 100644
--- a/tez-ui2/src/main/webapp/app/controllers/task/counters.js
+++ b/tez-ui2/src/main/webapp/app/controllers/task/counters.js
@@ -16,9 +16,9 @@
  * limitations under the License.
  */
 
-import CountersPageController from '../counters-page';
+import CountersTableController from '../counters-table';
 
-export default CountersPageController.extend({
+export default CountersTableController.extend({
   breadcrumbs: [{
     text: "Task Counters",
     routeName: "task.counters",

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/controllers/vertex.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/vertex.js b/tez-ui2/src/main/webapp/app/controllers/vertex.js
index 5543924..78f5db9 100644
--- a/tez-ui2/src/main/webapp/app/controllers/vertex.js
+++ b/tez-ui2/src/main/webapp/app/controllers/vertex.js
@@ -18,12 +18,12 @@
 
 import Ember from 'ember';
 
-import AbstractController from './abstract';
+import ParentController from './parent';
 
-export default AbstractController.extend({
+export default ParentController.extend({
   breadcrumbs: Ember.computed("model.dag", function () {
     var dagName = this.get("model.dag.name"),
-        vertexName = this.get("model.name");
+        vertexName = this.get("model.name") || this.get("model.index");
 
     return [{
       text: `DAG [ ${dagName} ]`,

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js b/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js
index b0fb983..34a067f 100644
--- a/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js
+++ b/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js
@@ -16,12 +16,12 @@
  * limitations under the License.
  */
 
-import TablePageController from '../table-page';
+import MultiTableController from '../multi-table';
 import ColumnDefinition from 'em-table/utils/column-definition';
 
 import AutoCounterColumn from '../../mixins/auto-counter-column';
 
-export default TablePageController.extend(AutoCounterColumn, {
+export default MultiTableController.extend(AutoCounterColumn, {
   breadcrumbs: [{
     text: "Task Attempts",
     routeName: "vertex.attempts",
@@ -55,7 +55,8 @@ export default TablePageController.extend(AutoCounterColumn, {
     id: 'status',
     headerTitle: 'Status',
     contentPath: 'status',
-    cellComponentName: 'em-table-status-cell'
+    cellComponentName: 'em-table-status-cell',
+    observePath: true
   },{
     id: 'progress',
     headerTitle: 'Progress',

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/controllers/vertex/counters.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/vertex/counters.js b/tez-ui2/src/main/webapp/app/controllers/vertex/counters.js
index 245ae1b..1213728 100644
--- a/tez-ui2/src/main/webapp/app/controllers/vertex/counters.js
+++ b/tez-ui2/src/main/webapp/app/controllers/vertex/counters.js
@@ -16,9 +16,9 @@
  * limitations under the License.
  */
 
-import CountersPageController from '../counters-page';
+import CountersTableController from '../counters-table';
 
-export default CountersPageController.extend({
+export default CountersTableController.extend({
   breadcrumbs: [{
     text: "Vertex Counters",
     routeName: "vertex.counters",

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.js b/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.js
index 350d246..ea02d61 100644
--- a/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.js
+++ b/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.js
@@ -16,12 +16,12 @@
  * limitations under the License.
  */
 
-import TablePageController from '../table-page';
+import MultiTableController from '../multi-table';
 import ColumnDefinition from 'em-table/utils/column-definition';
 
 import AutoCounterColumn from '../../mixins/auto-counter-column';
 
-export default TablePageController.extend(AutoCounterColumn, {
+export default MultiTableController.extend(AutoCounterColumn, {
   breadcrumbs: [{
     text: "Tasks",
     routeName: "vertex.tasks",
@@ -43,7 +43,8 @@ export default TablePageController.extend(AutoCounterColumn, {
     id: 'status',
     headerTitle: 'Status',
     contentPath: 'status',
-    cellComponentName: 'em-table-status-cell'
+    cellComponentName: 'em-table-status-cell',
+    observePath: true
   },{
     id: 'progress',
     headerTitle: 'Progress',

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/entities/am.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/entities/am.js b/tez-ui2/src/main/webapp/app/entities/am.js
new file mode 100644
index 0000000..56d061d
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/entities/am.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 Entity from './entity';
+
+export default Entity.extend({
+
+  idsToJoin: null,
+  deferred: null,
+
+  resetJoiner: Ember.on("init", function () {
+    this.set("idsToJoin", []);
+    this.set("deferred", Ember.RSVP.defer());
+  }),
+
+  queryRecord: function (loader, id, options, query, urlParams) {
+    this.get("idsToJoin").push(query[this.get("queryPropertyToJoin")]);
+
+    // Yup, only the last query would be taken by design
+    Ember.run.once(this, "queryJoinedRecords", loader, options, query, urlParams);
+
+    return this.get("deferred.promise").then(function (recordHash) {
+      return recordHash[id];
+    });
+  },
+
+  queryJoinedRecords: function (loader, options, query, urlParams) {
+    var deferred = this.get("deferred");
+
+    query[this.get("queryPropertyToJoin")] = this.get("idsToJoin").join(",");
+    this.query(loader, query, options, urlParams).then(function (records) {
+      deferred.resolve(records.reduce(function (recordHash, record) {
+        recordHash[record.get("entityID")] = record;
+        return recordHash;
+      }, {}));
+    }, function (error) {
+      deferred.reject(error);
+    }).finally(this.resetJoiner.bind(this));
+  }
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/entities/attempt-am.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/entities/attempt-am.js b/tez-ui2/src/main/webapp/app/entities/attempt-am.js
new file mode 100644
index 0000000..077c494
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/entities/attempt-am.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.
+ */
+
+import AMEntity from './am';
+
+export default AMEntity.extend({
+  queryPropertyToJoin: "attemptID",
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/entities/entity.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/entities/entity.js b/tez-ui2/src/main/webapp/app/entities/entity.js
index 9cad7b7..8a10dee 100644
--- a/tez-ui2/src/main/webapp/app/entities/entity.js
+++ b/tez-ui2/src/main/webapp/app/entities/entity.js
@@ -18,61 +18,133 @@
  */
 
 import Ember from 'ember';
+import NameMixin from '../mixins/name';
 
 var MoreObject = more.Object;
 
-export default Ember.Object.extend({
-
-  loadRelations: function (loader, model, options, urlParams) {
-    var needsPromise = this.loadNeeds(loader, model, options, urlParams);
+var Entity = Ember.Object.extend(NameMixin, {
+
+  queryRecord: function (loader, id, options, query, urlParams) {
+    var that = this;
+    return this.get('store').queryRecord(this.get("name"), {
+      id: id,
+      nameSpace: loader.get('nameSpace'),
+      params: query,
+      urlParams: urlParams
+    }).then(function (record) {
+      return that._loadAllNeeds(loader, record, options, urlParams);
+    });
+  },
 
-    if(needsPromise) {
-      return needsPromise.then(function () {
-        return model;
+  query: function (loader, query, options, urlParams) {
+    var that = this;
+    return this.get('store').query(this.get("name"), {
+      nameSpace: loader.get('nameSpace'),
+      params: query,
+      urlParams: urlParams
+    }).then(function (records) {
+      return Ember.RSVP.all(records.map(function (record) {
+        return that._loadAllNeeds(loader, record, options, urlParams);
+      })).then(function () {
+       return records;
       });
-    }
-
-    return model;
+    });
   },
 
-  normalizeNeed: function(name, options) {
+  normalizeNeed: function(name, needOptions, parentModel, queryParams, urlParams) {
     var need = {
       name: name,
       type: name,
-      idKey: options,
-      lazy: false,
-      silent: false
-    };
+      idKey: needOptions,
+
+      loadType: "", // Possible values lazy, demand
+      silent: false,
+
+      //urlParams
+      //queryParams
+    },
+    overrides = {};
+
+    if(typeof needOptions === 'object') {
+      Ember.assert(`idKey not defined for need '${name}'!`, needOptions.idKey);
+
+      if(MoreObject.isFunction(needOptions.urlParams)) {
+        overrides.urlParams = needOptions.urlParams.call(needOptions, parentModel);
+      }
+      if(MoreObject.isFunction(needOptions.queryParams)) {
+        overrides.queryParams = needOptions.queryParams.call(needOptions, parentModel);
+      }
+
+      overrides = Ember.Object.create({}, needOptions, overrides);
+    }
+
+    if(queryParams) {
+      overrides.queryParams = Ember.$.extend({}, overrides.queryParams, queryParams);
+    }
+    if(urlParams) {
+      overrides.urlParams = Ember.$.extend({}, overrides.urlParams, urlParams);
+    }
+
+    return Ember.Object.create(need, overrides);
+  },
+
+  _loadNeed: function (loader, parentModel, needOptions, options) {
+    var needLoader = loader.queryRecord(
+      needOptions.type,
+      parentModel.get(needOptions.idKey),
+      options,
+      needOptions.queryParams,
+      needOptions.urlParams
+    );
+
+    needLoader.then(function (model) {
+      parentModel.set(needOptions.name, model);
+    });
+
+    if(needOptions.silent) {
+      needLoader = needLoader.catch(function () {
+        parentModel.set(needOptions.name, null);
+      });
+    }
+
+    return needLoader;
+  },
+
+  loadNeed: function (loader, parentModel, needName, options, queryParams, urlParams) {
+    var needOptions = parentModel.get(`needs.${needName}`);
+    Ember.assert(`Need '${needName}' not defined in model!`, needOptions);
+
+    needOptions = this.normalizeNeed(needName, needOptions, parentModel, queryParams, urlParams);
+    return this._loadNeed(loader, parentModel, needOptions, options);
+  },
 
-    if(typeof options === 'object') {
-      return Ember.Object.create(need, options);
+  _loadAllNeeds: function (loader, model, options/*, urlParams*/) {
+    var needsPromise = this.loadAllNeeds(loader, model, options);
+
+    if(needsPromise) {
+      return needsPromise.then(function () {
+        return model;
+      });
     }
 
-    return Ember.Object.create(need);
+    return model;
   },
 
-  loadNeeds: function (loader, parentModel, options, urlParams) {
+  loadAllNeeds: function (loader, parentModel, options, queryParams, urlParams) {
     var needLoaders = [],
         that = this,
         needs = parentModel.get("needs");
 
     if(needs) {
       MoreObject.forEach(needs, function (name, needOptions) {
-        var need = that.normalizeNeed(name, needOptions),
-            needLoader = loader.queryRecord(need.type, parentModel.get(need.idKey), null, options, urlParams);
-
-        needLoader.then(function (model) {
-          parentModel.set(need.name, model);
-        });
+        needOptions = that.normalizeNeed(name, needOptions, parentModel, queryParams, urlParams);
 
-        if(need.silent) {
-          needLoader = needLoader.catch(function () {
-            parentModel.set(need.name, null);
-          });
-        }
+        if(needOptions.loadType !== "demand") {
+          let needLoader = that._loadNeed(loader, parentModel, needOptions, options);
 
-        if(!need.lazy) {
-          needLoaders.push(needLoader);
+          if(needOptions.loadType !== "lazy") {
+            needLoaders.push(needLoader);
+          }
         }
       });
     }
@@ -83,3 +155,5 @@ export default Ember.Object.extend({
   },
 
 });
+
+export default Entity;

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/entities/task-am.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/entities/task-am.js b/tez-ui2/src/main/webapp/app/entities/task-am.js
new file mode 100644
index 0000000..0e41239
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/entities/task-am.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.
+ */
+
+import AMEntity from './am';
+
+export default AMEntity.extend({
+  queryPropertyToJoin: "taskID",
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/entities/vertex-am.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/entities/vertex-am.js b/tez-ui2/src/main/webapp/app/entities/vertex-am.js
new file mode 100644
index 0000000..15a26da
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/entities/vertex-am.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.
+ */
+
+import AMEntity from './am';
+
+export default AMEntity.extend({
+  queryPropertyToJoin: "vertexID",
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/initializers/entities.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/initializers/entities.js b/tez-ui2/src/main/webapp/app/initializers/entities.js
index 86d796c..b5afd31 100644
--- a/tez-ui2/src/main/webapp/app/initializers/entities.js
+++ b/tez-ui2/src/main/webapp/app/initializers/entities.js
@@ -20,6 +20,7 @@ import registerWithContainer from "ember-cli-auto-register/register";
 
 export function initialize(application) {
   registerWithContainer("entity", application);
+  application.inject('entitie', 'store', 'service:store');
 }
 
 export default {

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/mixins/auto-counter-column.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/mixins/auto-counter-column.js b/tez-ui2/src/main/webapp/app/mixins/auto-counter-column.js
index 7820e4a..0504d4b 100644
--- a/tez-ui2/src/main/webapp/app/mixins/auto-counter-column.js
+++ b/tez-ui2/src/main/webapp/app/mixins/auto-counter-column.js
@@ -39,16 +39,16 @@ export default Ember.Mixin.create({
 
     if(records) {
       records.forEach(function (record) {
-        let counterGroups = Ember.get(record, 'counterGroups');
+        let counterGroupsHash = Ember.get(record, 'counterGroupsHash');
 
-        if(counterGroups) {
-          counterGroups.forEach(function (group) {
+        if(counterGroupsHash) {
+          MoreObject.forEach(counterGroupsHash, function (groupName, countersHash) {
             var groupHash =
-                counterHash[group.counterGroupName] =
-                counterHash[group.counterGroupName] || {};
+                counterHash[groupName] =
+                counterHash[groupName] || {};
 
-            group.counters.forEach(function (counter) {
-              groupHash[counter.counterName] = counter.counterName;
+            MoreObject.forEach(countersHash, function (counterName) {
+              groupHash[counterName] = counterName;
             });
           });
         }

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/models/abstract.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/abstract.js b/tez-ui2/src/main/webapp/app/models/abstract.js
index cf6ea8a..24bcbd3 100644
--- a/tez-ui2/src/main/webapp/app/models/abstract.js
+++ b/tez-ui2/src/main/webapp/app/models/abstract.js
@@ -16,6 +16,7 @@
  * limitations under the License.
  */
 
+import Ember from 'ember';
 import DS from 'ember-data';
 
 export default DS.Model.extend({
@@ -36,4 +37,24 @@ export default DS.Model.extend({
   didLoad: function () {
     this.refreshLoadTime();
   },
+
+  entityID: DS.attr("string"),
+
+  index: Ember.computed("entityID", function () {
+    var id = this.get("entityID") || "";
+    return id.substr(id.lastIndexOf('_') + 1);
+  }),
+
+  status: DS.attr("string"),
+  isComplete: Ember.computed("status", function () {
+    switch(this.get("status")) {
+      case "SUCCEEDED":
+      case "FINISHED":
+      case "FAILED":
+      case "KILLED":
+        return true;
+    }
+    return false;
+  }),
+
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/models/ahs-app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/ahs-app.js b/tez-ui2/src/main/webapp/app/models/ahs-app.js
index ce087eb31..c18bed9 100644
--- a/tez-ui2/src/main/webapp/app/models/ahs-app.js
+++ b/tez-ui2/src/main/webapp/app/models/ahs-app.js
@@ -22,8 +22,6 @@ import DS from 'ember-data';
 import AbstractModel from './abstract';
 
 export default AbstractModel.extend({
-  entityID: DS.attr('string'),
-
   attemptID: DS.attr('string'),
 
   name: DS.attr('string'),

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/models/am-timeline.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/am-timeline.js b/tez-ui2/src/main/webapp/app/models/am-timeline.js
new file mode 100644
index 0000000..bfd03b3
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/models/am-timeline.js
@@ -0,0 +1,46 @@
+/*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 DS from 'ember-data';
+
+import TimelineModel from './timeline';
+
+var MoreObject = more.Object;
+
+// For all AM related entities that can be updated from AM
+export default TimelineModel.extend({
+
+  am: DS.attr("object"), // Represents data from am
+
+  status: Ember.computed("am.status", "atsStatus", "app.status", "app.finalStatus", function () {
+    return this.get("am.status") || this._super();
+  }),
+
+  progress: Ember.computed("am.progress", "status", function () {
+    var progress = this.get("am.progress");
+    return MoreObject.isNumber(progress) ? progress : this._super();
+  }),
+
+  counterGroupsHash: Ember.computed("am.counterGroupsHash", "_counterGroups", function () {
+    var amCounters = this.get("am.counterGroupsHash"),
+        atsCounters = this._super();
+    return amCounters ? Ember.$.extend({}, atsCounters, amCounters) : atsCounters;
+  })
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/models/am.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/am.js b/tez-ui2/src/main/webapp/app/models/am.js
new file mode 100644
index 0000000..46ec75e
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/models/am.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';
+
+import AbstractModel from './abstract';
+
+export default AbstractModel.extend({
+
+  entityID: DS.attr("string"),
+
+  status: DS.attr("string"),
+  progress: DS.attr("number"),
+
+  counterGroupsHash: DS.attr("object")
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/models/app-rm.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/app-rm.js b/tez-ui2/src/main/webapp/app/models/app-rm.js
new file mode 100644
index 0000000..34bf6b3
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/models/app-rm.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 RMModel from './rm';
+
+export default RMModel.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/models/app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/app.js b/tez-ui2/src/main/webapp/app/models/app.js
index 82ffffc..6dcedd1 100644
--- a/tez-ui2/src/main/webapp/app/models/app.js
+++ b/tez-ui2/src/main/webapp/app/models/app.js
@@ -20,22 +20,6 @@ import Ember from 'ember';
 import DS from 'ember-data';
 
 import TimelineModel from './timeline';
-/*
-  Inherited properties
-
-  entityID - String
-  appID - Computed from entityID
-
-  status - String
-  progress - Computed from status
-
-  startTime - Number
-  endTime - Number
-  duration - Computed from start & end times
-
-  counterGroups - Array
-  counterHash - Computed from counterGroups
-*/
 
 export default TimelineModel.extend({
   appID: Ember.computed("entityID", function () {

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/models/attempt-am.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/attempt-am.js b/tez-ui2/src/main/webapp/app/models/attempt-am.js
new file mode 100644
index 0000000..55722b6
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/models/attempt-am.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 AMModel from './am';
+
+export default AMModel.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/models/attempt.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/attempt.js b/tez-ui2/src/main/webapp/app/models/attempt.js
index eb99169..5f865a0 100644
--- a/tez-ui2/src/main/webapp/app/models/attempt.js
+++ b/tez-ui2/src/main/webapp/app/models/attempt.js
@@ -19,45 +19,48 @@
 import Ember from 'ember';
 import DS from 'ember-data';
 
-import TimelineModel from './timeline';
-/*
-  Inherited properties
+import AMTimelineModel from './am-timeline';
 
-  entityID - String
-  appID - Computed from entityID
-
-  status - String
-  progress - Computed from status
-
-  startTime - Number
-  endTime - Number
-  duration - Computed from start & end times
-
-  counterGroups - Array
-  counterHash - Computed from counterGroups
-*/
-
-export default TimelineModel.extend({
+export default AMTimelineModel.extend({
   needs: {
     dag: {
       type: "dag",
       idKey: "dagID",
       silent: true
+    },
+    am: {
+      type: "attemptAm",
+      idKey: "entityID",
+      loadType: "demand",
+      queryParams: function (model) {
+        var vertexIndex = parseInt(model.get("vertexIndex")),
+            taskIndex = parseInt(model.get("taskIndex")),
+            attemptIndex = parseInt(model.get("index"));
+        return {
+          attemptID: `${vertexIndex}_${taskIndex}_${attemptIndex}`,
+          dagID: parseInt(model.get("dag.index")),
+          counters: "*"
+        };
+      },
+      urlParams: function (model) {
+        return {
+          app_id: model.get("appID")
+        };
+      }
     }
   },
 
-  index: Ember.computed("entityID", function () {
-    var idParts = this.get("entityID").split("_");
-    return idParts[Math.max(idParts.length - 1, 1)];
-  }),
-
   taskID: DS.attr('string'),
   taskIndex: Ember.computed("taskID", function () {
-    var idParts = this.get("taskID").split("_");
-    return idParts.slice(Math.max(idParts.length - 2, 1)).join("_");
+    var id = this.get("taskID") || "";
+    return id.substr(id.lastIndexOf('_') + 1);
   }),
 
   vertexID: DS.attr('string'),
+  vertexIndex: Ember.computed("vertexID", function () {
+    var id = this.get("vertexID") || "";
+    return id.substr(id.lastIndexOf('_') + 1);
+  }),
   vertexName: Ember.computed("vertexID", "dag", function () {
     var vertexID = this.get("vertexID");
     return this.get(`dag.vertexIdNameMap.${vertexID}`);

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/models/dag-am.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/dag-am.js b/tez-ui2/src/main/webapp/app/models/dag-am.js
new file mode 100644
index 0000000..55722b6
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/models/dag-am.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 AMModel from './am';
+
+export default AMModel.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/models/dag.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/dag.js b/tez-ui2/src/main/webapp/app/models/dag.js
index e0a4b55..bb4c5df 100644
--- a/tez-ui2/src/main/webapp/app/models/dag.js
+++ b/tez-ui2/src/main/webapp/app/models/dag.js
@@ -19,25 +19,28 @@
 import Ember from 'ember';
 import DS from 'ember-data';
 
-import TimelineModel from './timeline';
-/*
-  Inherited properties
+import AMTimelineModel from './am-timeline';
+
+export default AMTimelineModel.extend({
+  needs: {
+    am: {
+      type: "dagAm",
+      idKey: "entityID",
+      loadType: "demand",
+      queryParams: function (model) {
+        return {
+          dagID: parseInt(model.get("index")),
+          counters: "*"
+        };
+      },
+      urlParams: function (model) {
+        return {
+          app_id: model.get("appID")
+        };
+      }
+    }
+  },
 
-  entityID - String
-  appID - Computed from entityID
-
-  status - String
-  progress - Computed from status
-
-  startTime - Number
-  endTime - Number
-  duration - Computed from start & end times
-
-  counterGroups - Array
-  counterHash - Computed from counterGroups
-*/
-
-export default TimelineModel.extend({
   name: DS.attr("string"),
 
   submitter: DS.attr("string"),

http://git-wip-us.apache.org/repos/asf/tez/blob/eb50a0e1/tez-ui2/src/main/webapp/app/models/rm.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/rm.js b/tez-ui2/src/main/webapp/app/models/rm.js
new file mode 100644
index 0000000..d35ba23
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/models/rm.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';
+
+import AbstractModel from './abstract';
+
+export default AbstractModel.extend({
+  entityID: DS.attr("string"),
+  status: DS.attr("string"),
+});


[04/45] tez git commit: TEZ-2982. Tez UI: Create tez-ui2 directory and get a basic dummy page working in ember 2.2 (sree)

Posted by sr...@apache.org.
TEZ-2982. Tez UI: Create tez-ui2 directory and get a basic dummy page working in ember 2.2 (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/d072f3d6
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/d072f3d6
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/d072f3d6

Branch: refs/heads/TEZ-2980
Commit: d072f3d6d90cb0900c9d273077344af97b76c6b2
Parents: 701e9aa
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Tue Dec 22 23:25:06 2015 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:31:58 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |   2 +
 pom.xml                                         |   1 +
 tez-ui2/README.md                               |  37 ++
 tez-ui2/findbugs-exclude.xml                    |  16 +
 tez-ui2/pom.xml                                 | 153 ++++++++
 tez-ui2/src/main/resources/META-INF/LICENSE.txt | 386 +++++++++++++++++++
 tez-ui2/src/main/resources/META-INF/NOTICE.txt  |  10 +
 tez-ui2/src/main/webapp/.bowerrc                |   4 +
 tez-ui2/src/main/webapp/.editorconfig           |  34 ++
 tez-ui2/src/main/webapp/.ember-cli              |   9 +
 tez-ui2/src/main/webapp/.gitignore              |  18 +
 tez-ui2/src/main/webapp/.jshintrc               |  32 ++
 tez-ui2/src/main/webapp/.travis.yml             |  23 ++
 tez-ui2/src/main/webapp/.watchmanconfig         |   3 +
 tez-ui2/src/main/webapp/README.md               |  41 ++
 tez-ui2/src/main/webapp/WEB-INF/web.xml         |  25 ++
 tez-ui2/src/main/webapp/app/app.js              |  18 +
 tez-ui2/src/main/webapp/app/index.html          |  25 ++
 tez-ui2/src/main/webapp/app/router.js           |  11 +
 tez-ui2/src/main/webapp/app/styles/app.less     |   1 +
 .../main/webapp/app/templates/application.hbs   |   3 +
 tez-ui2/src/main/webapp/bower.json              |  15 +
 tez-ui2/src/main/webapp/config/environment.js   |  47 +++
 tez-ui2/src/main/webapp/ember-cli-build.js      |  24 ++
 tez-ui2/src/main/webapp/package.json            |  45 +++
 tez-ui2/src/main/webapp/public/crossdomain.xml  |  15 +
 tez-ui2/src/main/webapp/public/robots.txt       |   3 +
 tez-ui2/src/main/webapp/testem.json             |  12 +
 tez-ui2/src/main/webapp/tests/.jshintrc         |  52 +++
 .../main/webapp/tests/helpers/destroy-app.js    |   5 +
 .../tests/helpers/module-for-acceptance.js      |  23 ++
 .../src/main/webapp/tests/helpers/resolver.js   |  11 +
 .../src/main/webapp/tests/helpers/start-app.js  |  18 +
 tez-ui2/src/main/webapp/tests/index.html        |  34 ++
 tez-ui2/src/main/webapp/tests/test-helper.js    |   6 +
 35 files changed, 1162 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
new file mode 100644
index 0000000..7130897
--- /dev/null
+++ b/TEZ-2980-CHANGES.txt
@@ -0,0 +1,2 @@
+ALL CHANGES:
+  TEZ-2982. Tez UI: Create tez-ui2 directory and get a basic dummy page working in ember 2.2

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 78e28f5..26abc24 100644
--- a/pom.xml
+++ b/pom.xml
@@ -702,6 +702,7 @@
     <module>tez-dag</module>
     <module>tez-ext-service-tests</module>
     <module>tez-ui</module>
+    <module>tez-ui2</module>
     <module>tez-plugins</module>
     <module>tez-tools</module>
     <module>hadoop-shim-impls</module>

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/README.md
----------------------------------------------------------------------
diff --git a/tez-ui2/README.md b/tez-ui2/README.md
new file mode 100644
index 0000000..a10f460
--- /dev/null
+++ b/tez-ui2/README.md
@@ -0,0 +1,37 @@
+# Tez-ui
+
+The Tez UI is an ember based web application that provides visualization of Tez applications
+running on the Apache Hadoop YARN framework.
+
+For more information on Tez and the Tez UI - the [tez homepage](http://tez.apache.org/ "Apache Tez Homepage").
+
+## Prerequisites
+
+You will need the following things properly installed on your computer.
+
+* [Git](http://git-scm.com/)
+* [Node.js](http://nodejs.org/) (with NPM)
+* [Bower](http://bower.io/)
+* [Ember CLI](http://www.ember-cli.com/)
+* [PhantomJS](http://phantomjs.org/)
+
+## Installation
+
+* `git clone <repository-url>` this repository
+* In tez/tez-ui2/src/main/webapp
+* `npm install`
+
+## Running / Development
+
+* `ember server`
+* Visit your app at [http://localhost:4200](http://localhost:4200).
+
+### Running Tests
+
+* `ember test`
+* `ember test --server`
+
+### Building
+
+* `ember build` (development)
+* `ember build --environment production` (production)

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/findbugs-exclude.xml
----------------------------------------------------------------------
diff --git a/tez-ui2/findbugs-exclude.xml b/tez-ui2/findbugs-exclude.xml
new file mode 100644
index 0000000..5b11308
--- /dev/null
+++ b/tez-ui2/findbugs-exclude.xml
@@ -0,0 +1,16 @@
+<!--
+  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
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License. See accompanying LICENSE file.
+-->
+<FindBugsFilter>
+
+</FindBugsFilter>

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/pom.xml
----------------------------------------------------------------------
diff --git a/tez-ui2/pom.xml b/tez-ui2/pom.xml
new file mode 100644
index 0000000..2b7503c
--- /dev/null
+++ b/tez-ui2/pom.xml
@@ -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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.tez</groupId>
+    <artifactId>tez</artifactId>
+    <version>0.8.2-SNAPSHOT</version>
+  </parent>
+  <artifactId>tez-ui2</artifactId>
+  <packaging>war</packaging>
+
+  <properties>
+    <webappDir>src/main/webapp</webappDir>
+    <node.executable>${basedir}/src/main/webapp/node/node</node.executable>
+    <nodeVersion>v0.12.2</nodeVersion>
+    <npmVersion>2.10.0</npmVersion>
+    <skipTests>false</skipTests>
+  </properties>
+
+  <build>
+    <plugins>
+
+      <!-- Apache RAT -->
+      <plugin>
+        <groupId>org.apache.rat</groupId>
+        <artifactId>apache-rat-plugin</artifactId>
+        <configuration>
+          <excludes>
+            <exclude>src/main/webapp/node/**/*</exclude>
+            <exclude>src/main/webapp/node_modules/**/*</exclude>
+            <exclude>src/main/webapp/bower_components/**/*</exclude>
+            <exclude>src/main/webapp/.tmp/</exclude>
+            <exclude>src/main/webapp/dist/**/*</exclude>
+            <exclude>src/main/webapp/.bowerrc</exclude>
+            <exclude>src/main/webapp/.editorconfig</exclude>
+            <exclude>src/main/webapp/.ember-cli</exclude>
+            <exclude>src/main/webapp/.gitignore</exclude>
+            <exclude>src/main/webapp/.jshintrc</exclude>
+            <exclude>src/main/webapp/.travis.yml</exclude>
+            <exclude>src/main/webapp/.watchmanconfig</exclude>
+            <exclude>src/main/webapp/bower.json</exclude>
+            <exclude>src/main/webapp/ember-cli-build.js</exclude>
+            <exclude>src/main/webapp/package.json</exclude>
+            <exclude>src/main/webapp/testem.js</exclude>
+          </excludes>
+        </configuration>
+      </plugin>
+
+      <!-- NPM Install -->
+      <plugin>
+        <groupId>com.github.eirslett</groupId>
+        <artifactId>frontend-maven-plugin</artifactId>
+        <configuration>
+          <workingDirectory>${webappDir}</workingDirectory>
+        </configuration>
+        <executions>
+          <execution>
+            <phase>generate-sources</phase>
+            <id>install node and npm</id>
+            <goals>
+              <goal>install-node-and-npm</goal>
+            </goals>
+            <configuration>
+              <nodeVersion>${nodeVersion}</nodeVersion>
+              <npmVersion>${npmVersion}</npmVersion>
+            </configuration>
+          </execution>
+          <execution>
+            <phase>generate-sources</phase>
+            <id>npm install</id>
+            <goals>
+              <goal>npm</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+
+      <!-- Bower install & grunt build-->
+      <plugin>
+        <artifactId>exec-maven-plugin</artifactId>
+        <groupId>org.codehaus.mojo</groupId>
+        <executions>
+          <execution>
+            <id>ember build</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>exec</goal>
+            </goals>
+            <configuration>
+              <workingDirectory>${webappDir}</workingDirectory>
+              <executable>${node.executable}</executable>
+              <arguments>
+                <argument>node_modules/ember-cli/bin/ember</argument>
+                <argument>build</argument>
+                <argument>-prod</argument>
+              </arguments>
+            </configuration>
+          </execution>
+          <execution>
+            <id>ember test</id>
+            <phase>generate-resources</phase>
+            <goals>
+              <goal>exec</goal>
+            </goals>
+            <configuration>
+              <skip>${skipTests}</skip>
+              <workingDirectory>${webappDir}</workingDirectory>
+              <executable>${node.executable}</executable>
+              <arguments>
+                <argument>node_modules/ember-cli/bin/ember</argument>
+                <argument>test</argument>
+              </arguments>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+
+      <!-- Package into war -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-war-plugin</artifactId>
+        <configuration>
+          <webXml>${basedir}/src/main/webapp/WEB-INF/web.xml</webXml>
+          <warSourceDirectory>${webappDir}/dist</warSourceDirectory>
+          <webResources>
+            <resource>
+              <filtering>false</filtering>
+              <directory>${basedir}/src/main/resources/</directory>
+            </resource>
+          </webResources>
+        </configuration>
+      </plugin>
+
+    </plugins>
+  </build>
+</project>

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/src/main/resources/META-INF/LICENSE.txt
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/resources/META-INF/LICENSE.txt b/tez-ui2/src/main/resources/META-INF/LICENSE.txt
new file mode 100644
index 0000000..4f0c9d4
--- /dev/null
+++ b/tez-ui2/src/main/resources/META-INF/LICENSE.txt
@@ -0,0 +1,386 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   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
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+=======================================================================
+Apache Tez Subcomponents:
+
+The Apache Tez project contains subcomponents with separate copyright
+notices and license terms. Your use of the source code for the these
+subcomponents is subject to the terms and conditions of the following
+licenses.
+
+-----------------------------------------------------------------------
+ The MIT License
+-----------------------------------------------------------------------
+
+The Apache TEZ tez-ui bundles the following files under the MIT License:
+
+ - antiscroll v1.0.0 (https://github.com/LearnBoost/antiscroll) - Copyright (c) 2011 Guillermo Rauch <gu...@learnboost.com>
+ - bootstrap v3.3.1 (http://getbootstrap.com) - Copyright (c) 2011-2014 Twitter, Inc
+ - ember v1.7.0 (http://emberjs.com/) - Copyright (c) 2014 Yehuda Katz, Tom Dale and Ember.js contributors
+ - ember-data v1.0.0-beta.11 (https://github.com/emberjs/data) - Copyright (C) 2011-2014 Tilde, Inc. and contributors, Portions Copyright (C) 2011 LivingSocial Inc.
+ - ember-json-mapper v1.0.0 (https://github.com/onechiporenko/ember-json-mapper) - Copyright (c) 2014 onechiporenko
+ - font-awesome css/less files v4.2.0 (http://fontawesome.io/) - Created by Dave Gandy
+ - handlebars v1.3.0 (http://handlebarsjs.com/) - Copyright (C) 2011-2014 by Yehuda Katz
+ - jquery v1.10.2 (http://jquery.org) - Copyright 2005, 2014 jQuery Foundation and other contributors
+ - jquery-mousewheel v3.1.12 (https://github.com/jquery/jquery-mousewheel) - Copyright 2006, 2014 jQuery Foundation and other contributors, https://jquery.org/
+ - jquery-ui v1.11 (http://jqueryui.com/) - Copyright 2014 jQuery Foundation and other contributors
+ - moment v2.10.6 (http://momentjs.com/) - Copyright (c) 2011-2015 Tim Wood, Iskren Chernev, Moment.js contributors
+ - moment-timezone v0.4.0 (http://momentjs.com/timezone/) - Copyright (c) 2014 Tim Wood
+ - FileSaver.js master branch #24b303f49213b905ec9062b708f7cd43d56a5dde (https://github.com/eligrey/FileSaver.js) authors : Eli Grey.
+ - CodeMirror 5.2.0 (https://codemirror.net/) authors: Copyright (C) 2015 by Marijn Haverbeke <ma...@gmail.com> and others
+
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated 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.
+
+-----------------------------------------------------------------------
+ BSD-style Licenses
+-----------------------------------------------------------------------
+
+The Apache Tez tez-ui bundles the following files under BSD licenses:
+
+(3-clause BSD license)
+ - D3 v3.4.11 (http://d3js.org/) - Copyright (c) 2010-2014, Michael Bostock
+ - ember-table v0.2.2 (https://github.com/Addepar/ember-table) - Copyright © 2012 Addepar, Inc. All Rights Reserved.
+ - zip.js master branch #bfd76c66293305faaf9fcbb65b5ff7fe2dbe621a (https://github.com/gildas-lormeau/zip.js)
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this list
+   of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice, this
+   list of conditions and the following disclaimer in the documentation and/or
+   other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its contributors may
+   be used to endorse or promote products derived from this software without
+   specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+-----------------------------------------------------------------------
+ The Open Font License
+-----------------------------------------------------------------------
+
+The Apache Tez tez-ui bundles the following fonts under the
+SIL Open Font License v1.1 (OFT) - http://scripts.sil.org/OFL
+
+ - font-awesome fonts v4.2.0 (http://fontawesome.io/) - Created by Dave Gandy
+
+SIL OPEN FONT LICENSE
+
+Version 1.1 - 26 February 2007
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting — in part or in whole — any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
+

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/src/main/resources/META-INF/NOTICE.txt
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/resources/META-INF/NOTICE.txt b/tez-ui2/src/main/resources/META-INF/NOTICE.txt
new file mode 100644
index 0000000..9a6feaf
--- /dev/null
+++ b/tez-ui2/src/main/resources/META-INF/NOTICE.txt
@@ -0,0 +1,10 @@
+Apache Tez
+Copyright (c) 2015 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+This tez-ui bundle includes fonts protected under the Open Font License.
+These fonts can only be distributed as part of a piece of software, but
+not individually. See the license for details.  http://scripts.sil.org/OFL.
+More information on included fonts can be found in the LICENSE file.

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/src/main/webapp/.bowerrc
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/.bowerrc b/tez-ui2/src/main/webapp/.bowerrc
new file mode 100644
index 0000000..959e169
--- /dev/null
+++ b/tez-ui2/src/main/webapp/.bowerrc
@@ -0,0 +1,4 @@
+{
+  "directory": "bower_components",
+  "analytics": false
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/src/main/webapp/.editorconfig
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/.editorconfig b/tez-ui2/src/main/webapp/.editorconfig
new file mode 100644
index 0000000..47c5438
--- /dev/null
+++ b/tez-ui2/src/main/webapp/.editorconfig
@@ -0,0 +1,34 @@
+# EditorConfig helps developers define and maintain consistent
+# coding styles between different editors and IDEs
+# editorconfig.org
+
+root = true
+
+
+[*]
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+indent_style = space
+indent_size = 2
+
+[*.js]
+indent_style = space
+indent_size = 2
+
+[*.hbs]
+insert_final_newline = false
+indent_style = space
+indent_size = 2
+
+[*.css]
+indent_style = space
+indent_size = 2
+
+[*.html]
+indent_style = space
+indent_size = 2
+
+[*.{diff,md}]
+trim_trailing_whitespace = false

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/src/main/webapp/.ember-cli
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/.ember-cli b/tez-ui2/src/main/webapp/.ember-cli
new file mode 100644
index 0000000..ee64cfe
--- /dev/null
+++ b/tez-ui2/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
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/src/main/webapp/.gitignore
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/.gitignore b/tez-ui2/src/main/webapp/.gitignore
new file mode 100644
index 0000000..8470f82
--- /dev/null
+++ b/tez-ui2/src/main/webapp/.gitignore
@@ -0,0 +1,18 @@
+# See http://help.github.com/ignore-files/ for more about ignoring files.
+
+# compiled output
+/dist
+/tmp
+
+# dependencies
+/node
+/node_modules
+/bower_components
+
+# misc
+/.sass-cache
+/connect.lock
+/coverage/*
+/libpeerconnection.log
+npm-debug.log
+testem.log

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/src/main/webapp/.jshintrc
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/.jshintrc b/tez-ui2/src/main/webapp/.jshintrc
new file mode 100644
index 0000000..08096ef
--- /dev/null
+++ b/tez-ui2/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
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/src/main/webapp/.travis.yml
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/.travis.yml b/tez-ui2/src/main/webapp/.travis.yml
new file mode 100644
index 0000000..66dd107
--- /dev/null
+++ b/tez-ui2/src/main/webapp/.travis.yml
@@ -0,0 +1,23 @@
+---
+language: node_js
+node_js:
+  - "0.12"
+
+sudo: false
+
+cache:
+  directories:
+    - node_modules
+
+before_install:
+  - export PATH=/usr/local/phantomjs-2.0.0/bin:$PATH
+  - "npm config set spin false"
+  - "npm install -g npm@^2"
+
+install:
+  - npm install -g bower
+  - npm install
+  - bower install
+
+script:
+  - npm test

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/src/main/webapp/.watchmanconfig
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/.watchmanconfig b/tez-ui2/src/main/webapp/.watchmanconfig
new file mode 100644
index 0000000..e7834e3
--- /dev/null
+++ b/tez-ui2/src/main/webapp/.watchmanconfig
@@ -0,0 +1,3 @@
+{
+  "ignore_dirs": ["tmp", "dist"]
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/src/main/webapp/README.md
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/README.md b/tez-ui2/src/main/webapp/README.md
new file mode 100644
index 0000000..291e05f
--- /dev/null
+++ b/tez-ui2/src/main/webapp/README.md
@@ -0,0 +1,41 @@
+# Tez-ui
+
+The Tez UI is an ember based web application that provides visualization of Tez applications
+running on the Apache Hadoop YARN framework.
+
+For more information on Tez and the Tez UI - the [tez homepage](http://tez.apache.org/ "Apache Tez Homepage").
+
+## Prerequisites
+
+You will need the following things properly installed on your computer.
+
+* [Git](http://git-scm.com/)
+* [Node.js](http://nodejs.org/) (with NPM)
+* [Bower](http://bower.io/)
+* [Ember CLI](http://www.ember-cli.com/)
+* [PhantomJS](http://phantomjs.org/)
+
+## Installation
+
+* `git clone <repository-url>` this repository
+* change into the new directory
+* `npm install`
+
+## Running / Development
+
+* `ember server`
+* Visit your app at [http://localhost:4200](http://localhost:4200).
+
+### Code Generators
+
+Make use of the many generators for code, try `ember help generate` for more details
+
+### Running Tests
+
+* `ember test`
+* `ember test --server`
+
+### Building
+
+* `ember build` (development)
+* `ember build --environment production` (production)

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/WEB-INF/web.xml b/tez-ui2/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..62bfe31
--- /dev/null
+++ b/tez-ui2/src/main/webapp/WEB-INF/web.xml
@@ -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.
+-->
+
+<!DOCTYPE web-app PUBLIC
+ "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+ "http://java.sun.com/dtd/web-app_2_3.dtd" >
+
+<web-app>
+  <display-name>TEZ UI</display-name>
+</web-app>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/src/main/webapp/app/app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/app.js b/tez-ui2/src/main/webapp/app/app.js
new file mode 100644
index 0000000..8b234d6
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/app.js
@@ -0,0 +1,18 @@
+import Ember from 'ember';
+import Resolver from 'ember/resolver';
+import loadInitializers from 'ember/load-initializers';
+import config from './config/environment';
+
+let App;
+
+Ember.MODEL_FACTORY_INJECTIONS = true;
+
+App = Ember.Application.extend({
+  modulePrefix: config.modulePrefix,
+  podModulePrefix: config.podModulePrefix,
+  Resolver
+});
+
+loadInitializers(App, config.modulePrefix);
+
+export default App;

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/src/main/webapp/app/index.html
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/index.html b/tez-ui2/src/main/webapp/app/index.html
new file mode 100644
index 0000000..23a7578
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/index.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <title>Tez UI</title>
+    <meta name="description" content="">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+
+    {{content-for 'head'}}
+
+    <link rel="stylesheet" href="assets/vendor.css">
+    <link rel="stylesheet" href="assets/tez-ui.css">
+
+    {{content-for 'head-footer'}}
+  </head>
+  <body>
+    {{content-for 'body'}}
+
+    <script src="assets/vendor.js"></script>
+    <script src="assets/tez-ui.js"></script>
+
+    {{content-for 'body-footer'}}
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/src/main/webapp/app/router.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/router.js b/tez-ui2/src/main/webapp/app/router.js
new file mode 100644
index 0000000..3bba78e
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/router.js
@@ -0,0 +1,11 @@
+import Ember from 'ember';
+import config from './config/environment';
+
+const Router = Ember.Router.extend({
+  location: config.locationType
+});
+
+Router.map(function() {
+});
+
+export default Router;

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/src/main/webapp/app/styles/app.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/app.less b/tez-ui2/src/main/webapp/app/styles/app.less
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/styles/app.less
@@ -0,0 +1 @@
+

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/src/main/webapp/app/templates/application.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/application.hbs b/tez-ui2/src/main/webapp/app/templates/application.hbs
new file mode 100644
index 0000000..f8bc38e
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/application.hbs
@@ -0,0 +1,3 @@
+<h2 id="title">Welcome to Ember</h2>
+
+{{outlet}}

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/src/main/webapp/bower.json
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/bower.json b/tez-ui2/src/main/webapp/bower.json
new file mode 100644
index 0000000..fb312cb
--- /dev/null
+++ b/tez-ui2/src/main/webapp/bower.json
@@ -0,0 +1,15 @@
+{
+  "name": "tez-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": "^1.11.3",
+    "loader.js": "3.3.0",
+    "qunit": "~1.19.0"
+  }
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/src/main/webapp/config/environment.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/config/environment.js b/tez-ui2/src/main/webapp/config/environment.js
new file mode 100644
index 0000000..9243b2b
--- /dev/null
+++ b/tez-ui2/src/main/webapp/config/environment.js
@@ -0,0 +1,47 @@
+/* jshint node: true */
+
+module.exports = function(environment) {
+  var ENV = {
+    modulePrefix: 'tez-ui',
+    environment: environment,
+    baseURL: '/',
+    locationType: 'auto',
+    EmberENV: {
+      FEATURES: {
+        // Here you can enable experimental features on an ember canary build
+        // e.g. 'with-controller': true
+      }
+    },
+
+    APP: {
+      // Here you can pass flags/options to your application instance
+      // when it is created
+    }
+  };
+
+  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;
+};

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/src/main/webapp/ember-cli-build.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/ember-cli-build.js b/tez-ui2/src/main/webapp/ember-cli-build.js
new file mode 100644
index 0000000..2537ce2
--- /dev/null
+++ b/tez-ui2/src/main/webapp/ember-cli-build.js
@@ -0,0 +1,24 @@
+/*jshint node:true*/
+/* global require, module */
+var EmberApp = require('ember-cli/lib/broccoli/ember-app');
+
+module.exports = function(defaults) {
+  var app = new EmberApp(defaults, {
+    // Add options here
+  });
+
+  // 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.
+
+  return app.toTree();
+};

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/src/main/webapp/package.json
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/package.json b/tez-ui2/src/main/webapp/package.json
new file mode 100644
index 0000000..7e474e3
--- /dev/null
+++ b/tez-ui2/src/main/webapp/package.json
@@ -0,0 +1,45 @@
+{
+  "name": "tez-ui",
+  "version": "0.2.0",
+  "description": "Apache Tez UI",
+  "private": true,
+  "directories": {
+    "doc": "doc",
+    "test": "tests"
+  },
+  "scripts": {
+    "build": "ember build",
+    "start": "ember server",
+    "test": "ember test",
+    "postinstall": "bower install"
+  },
+  "repository" : {
+    "type" : "git",
+    "url" : "https://git-wip-us.apache.org/repos/asf/tez.git"
+  },
+  "engines": {
+    "node": ">= 0.10.0"
+  },
+  "devDependencies": {
+    "broccoli-asset-rev": "^2.2.0",
+    "ember-cli": "1.13.13",
+    "ember-cli-app-version": "^1.0.0",
+    "ember-cli-babel": "^5.1.5",
+    "ember-cli-content-security-policy": "0.4.0",
+    "ember-cli-dependency-checker": "^1.1.0",
+    "ember-cli-htmlbars-inline-precompile": "^0.3.1",
+    "ember-cli-inject-live-reload": "^1.3.1",
+    "ember-cli-qunit": "^1.0.4",
+    "ember-cli-release": "0.2.8",
+    "ember-cli-sri": "^1.2.0",
+    "ember-cli-uglify": "^1.2.0",
+    "ember-data": "2.1.0",
+    "ember-disable-proxy-controllers": "^1.0.1",
+    "ember-export-application-global": "^1.0.4",
+    "ember-resolver": "^2.0.3"
+  },
+  "dependencies": {
+    "ember-cli-htmlbars": "^1.0.1",
+    "ember-cli-less": "^1.4.0"
+  }
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/src/main/webapp/public/crossdomain.xml
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/public/crossdomain.xml b/tez-ui2/src/main/webapp/public/crossdomain.xml
new file mode 100644
index 0000000..0c16a7a
--- /dev/null
+++ b/tez-ui2/src/main/webapp/public/crossdomain.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
+<cross-domain-policy>
+  <!-- Read this: www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html -->
+
+  <!-- Most restrictive policy: -->
+  <site-control permitted-cross-domain-policies="none"/>
+
+  <!-- Least restrictive policy: -->
+  <!--
+  <site-control permitted-cross-domain-policies="all"/>
+  <allow-access-from domain="*" to-ports="*" secure="false"/>
+  <allow-http-request-headers-from domain="*" headers="*" secure="false"/>
+  -->
+</cross-domain-policy>

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/src/main/webapp/public/robots.txt
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/public/robots.txt b/tez-ui2/src/main/webapp/public/robots.txt
new file mode 100644
index 0000000..f591645
--- /dev/null
+++ b/tez-ui2/src/main/webapp/public/robots.txt
@@ -0,0 +1,3 @@
+# http://www.robotstxt.org
+User-agent: *
+Disallow:

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/src/main/webapp/testem.json
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/testem.json b/tez-ui2/src/main/webapp/testem.json
new file mode 100644
index 0000000..0f35392
--- /dev/null
+++ b/tez-ui2/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"
+  ]
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/src/main/webapp/tests/.jshintrc
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/.jshintrc b/tez-ui2/src/main/webapp/tests/.jshintrc
new file mode 100644
index 0000000..6ec0b7c
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/.jshintrc
@@ -0,0 +1,52 @@
+{
+  "predef": [
+    "document",
+    "window",
+    "location",
+    "setTimeout",
+    "$",
+    "-Promise",
+    "define",
+    "console",
+    "visit",
+    "exists",
+    "fillIn",
+    "click",
+    "keyEvent",
+    "triggerEvent",
+    "find",
+    "findWithAssert",
+    "wait",
+    "DS",
+    "andThen",
+    "currentURL",
+    "currentPath",
+    "currentRouteName"
+  ],
+  "node": false,
+  "browser": false,
+  "boss": true,
+  "curly": true,
+  "debug": false,
+  "devel": false,
+  "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
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/src/main/webapp/tests/helpers/destroy-app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/helpers/destroy-app.js b/tez-ui2/src/main/webapp/tests/helpers/destroy-app.js
new file mode 100644
index 0000000..c3d4d1a
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/helpers/destroy-app.js
@@ -0,0 +1,5 @@
+import Ember from 'ember';
+
+export default function destroyApp(application) {
+  Ember.run(application, 'destroy');
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/src/main/webapp/tests/helpers/module-for-acceptance.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/helpers/module-for-acceptance.js b/tez-ui2/src/main/webapp/tests/helpers/module-for-acceptance.js
new file mode 100644
index 0000000..ed23003
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/helpers/module-for-acceptance.js
@@ -0,0 +1,23 @@
+import { module } from 'qunit';
+import startApp from '../helpers/start-app';
+import destroyApp from '../helpers/destroy-app';
+
+export default function(name, options = {}) {
+  module(name, {
+    beforeEach() {
+      this.application = startApp();
+
+      if (options.beforeEach) {
+        options.beforeEach.apply(this, arguments);
+      }
+    },
+
+    afterEach() {
+      destroyApp(this.application);
+
+      if (options.afterEach) {
+        options.afterEach.apply(this, arguments);
+      }
+    }
+  });
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/src/main/webapp/tests/helpers/resolver.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/helpers/resolver.js b/tez-ui2/src/main/webapp/tests/helpers/resolver.js
new file mode 100644
index 0000000..ebfb4e4
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/helpers/resolver.js
@@ -0,0 +1,11 @@
+import Resolver from 'ember/resolver';
+import config from '../../config/environment';
+
+const resolver = Resolver.create();
+
+resolver.namespace = {
+  modulePrefix: config.modulePrefix,
+  podModulePrefix: config.podModulePrefix
+};
+
+export default resolver;

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/src/main/webapp/tests/helpers/start-app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/helpers/start-app.js b/tez-ui2/src/main/webapp/tests/helpers/start-app.js
new file mode 100644
index 0000000..e098f1d
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/helpers/start-app.js
@@ -0,0 +1,18 @@
+import Ember from 'ember';
+import Application from '../../app';
+import config from '../../config/environment';
+
+export default function startApp(attrs) {
+  let application;
+
+  let attributes = Ember.merge({}, config.APP);
+  attributes = Ember.merge(attributes, attrs); // use defaults, but you can override;
+
+  Ember.run(() => {
+    application = Application.create(attributes);
+    application.setupForTesting();
+    application.injectTestHelpers();
+  });
+
+  return application;
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/src/main/webapp/tests/index.html
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/index.html b/tez-ui2/src/main/webapp/tests/index.html
new file mode 100644
index 0000000..b5205de
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/index.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <title>TezUi Tests</title>
+    <meta name="description" content="">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+
+    {{content-for 'head'}}
+    {{content-for 'test-head'}}
+
+    <link rel="stylesheet" href="assets/vendor.css">
+    <link rel="stylesheet" href="assets/tez-ui.css">
+    <link rel="stylesheet" href="assets/test-support.css">
+
+    {{content-for 'head-footer'}}
+    {{content-for 'test-head-footer'}}
+  </head>
+  <body>
+    {{content-for 'body'}}
+    {{content-for 'test-body'}}
+
+    <script src="assets/vendor.js"></script>
+    <script src="assets/test-support.js"></script>
+    <script src="assets/tez-ui.js"></script>
+    <script src="testem.js" integrity=""></script>
+    <script src="assets/tests.js"></script>
+    <script src="assets/test-loader.js"></script>
+
+    {{content-for 'body-footer'}}
+    {{content-for 'test-body-footer'}}
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/tez/blob/d072f3d6/tez-ui2/src/main/webapp/tests/test-helper.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/test-helper.js b/tez-ui2/src/main/webapp/tests/test-helper.js
new file mode 100644
index 0000000..e6cfb70
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/test-helper.js
@@ -0,0 +1,6 @@
+import resolver from './helpers/resolver';
+import {
+  setResolver
+} from 'ember-qunit';
+
+setResolver(resolver);


[12/45] tez git commit: TEZ-3045. Tez UI 2: Create application details page with DAGs tab (sree)

Posted by sr...@apache.org.
TEZ-3045. Tez UI 2: Create application details page with DAGs tab (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/e893e946
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/e893e946
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/e893e946

Branch: refs/heads/TEZ-2980
Commit: e893e94645612cb4d8708e4bcaed1375b3e05a6b
Parents: 70c6b5f
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Tue Jan 19 03:12:39 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:32:15 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |   1 +
 tez-ui2/src/main/webapp/app/adapters/app.js     |  22 ++++
 tez-ui2/src/main/webapp/app/controllers/app.js  |  41 ++++++
 .../src/main/webapp/app/controllers/app/dags.js |  98 +++++++++++++++
 .../main/webapp/app/controllers/app/index.js    |  22 ++++
 tez-ui2/src/main/webapp/app/controllers/dags.js |  10 +-
 tez-ui2/src/main/webapp/app/models/ahs-app.js   |  14 ++-
 tez-ui2/src/main/webapp/app/models/app.js       |  52 ++++++++
 tez-ui2/src/main/webapp/app/router.js           |   4 +-
 tez-ui2/src/main/webapp/app/routes/app.js       |  13 +-
 tez-ui2/src/main/webapp/app/routes/app/dags.js  |  35 ++++++
 tez-ui2/src/main/webapp/app/routes/app/index.js |  33 +++++
 .../src/main/webapp/app/serializers/ahs-app.js  |   6 +-
 tez-ui2/src/main/webapp/app/serializers/app.js  |  30 +++++
 .../main/webapp/app/styles/details-page.less    |   4 +
 tez-ui2/src/main/webapp/app/templates/app.hbs   |   3 +-
 .../src/main/webapp/app/templates/app/dags.hbs  |  33 +++++
 .../src/main/webapp/app/templates/app/index.hbs | 126 +++++++++++++++++++
 .../src/main/webapp/app/templates/dag/index.hbs |   4 +-
 .../src/main/webapp/config/default-app-conf.js  |   2 +-
 .../main/webapp/tests/unit/adapters/app-test.js |  30 +++++
 .../webapp/tests/unit/controllers/app-test.js   |  36 ++++++
 .../tests/unit/controllers/app/dags-test.js     |  36 ++++++
 .../tests/unit/controllers/app/index-test.js    |  34 +++++
 .../main/webapp/tests/unit/models/app-test.js   |  40 ++++++
 .../webapp/tests/unit/routes/app/dags-test.js   |  45 +++++++
 .../webapp/tests/unit/routes/app/index-test.js  |  45 +++++++
 .../webapp/tests/unit/serializers/app-test.js   |  31 +++++
 28 files changed, 833 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/e893e946/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index 354816e..366396f 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -17,3 +17,4 @@ ALL CHANGES:
   TEZ-3039. Tez UI 2: Create all sub-pages for DAG
   TEZ-3040. Tez UI 2: Create Vertex details page & sub tables
   TEZ-3041. Tez UI 2: Create Task & Attempt details page with sub tables
+  TEZ-3045. Tez UI 2: Create application details page with DAGs tab

http://git-wip-us.apache.org/repos/asf/tez/blob/e893e946/tez-ui2/src/main/webapp/app/adapters/app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/app.js b/tez-ui2/src/main/webapp/app/adapters/app.js
new file mode 100644
index 0000000..b47e05f
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/adapters/app.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 TimelineAdapter from './timeline';
+
+export default TimelineAdapter.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/e893e946/tez-ui2/src/main/webapp/app/controllers/app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/app.js b/tez-ui2/src/main/webapp/app/controllers/app.js
new file mode 100644
index 0000000..95159c5
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/app.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 AbstractController from './abstract';
+
+export default AbstractController.extend({
+  breadcrumbs: Ember.computed("model.appID", "model.app.name", function () {
+    var name = this.get("model.app.name") || this.get("model.appID");
+
+    return [{
+      text: `Application [ ${name} ]`,
+      routeName: "app.index",
+      model: this.get("model.entityID")
+    }];
+  }),
+
+  tabs: [{
+    text: "Application Details",
+    routeName: "app.index"
+  }, {
+    text: "DAGs",
+    routeName: "app.dags"
+  }]
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/e893e946/tez-ui2/src/main/webapp/app/controllers/app/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/app/dags.js b/tez-ui2/src/main/webapp/app/controllers/app/dags.js
new file mode 100644
index 0000000..bcb4db8
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/app/dags.js
@@ -0,0 +1,98 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import TablePageController from '../table-page';
+import ColumnDefinition from 'em-table/utils/column-definition';
+
+export default TablePageController.extend({
+  breadcrumbs: [{
+    text: "DAGs",
+    routeName: "app.dags",
+  }],
+
+  columns: ColumnDefinition.make([{
+    id: 'name',
+    headerTitle: 'Dag Name',
+    contentPath: 'name',
+    cellComponentName: 'em-table-linked-cell',
+    getCellContent: function (row) {
+      return {
+        routeName: "dag",
+        model: row.get("entityID"),
+        text: row.get("name")
+      };
+    }
+  },{
+    id: 'entityID',
+    headerTitle: 'Id',
+    contentPath: 'entityID'
+  },{
+    id: 'user',
+    headerTitle: 'Submitter',
+    contentPath: 'user'
+  },{
+    id: 'status',
+    headerTitle: 'Status',
+    contentPath: 'status',
+    cellComponentName: 'em-table-status-cell'
+  },{
+    id: 'progress',
+    headerTitle: 'Progress',
+    contentPath: 'progress',
+    cellComponentName: 'em-table-progress-cell',
+    observePath: true
+  },{
+    id: 'startTime',
+    headerTitle: 'Start Time',
+    contentPath: 'startTime',
+    cellDefinition: {
+      type: 'date'
+    }
+  },{
+    id: 'endTime',
+    headerTitle: 'End Time',
+    contentPath: 'endTime',
+    cellDefinition: {
+      type: 'date'
+    }
+  },{
+    id: 'duration',
+    headerTitle: 'Duration',
+    contentPath: 'duration',
+    cellDefinition: {
+      type: 'duration'
+    }
+  },{
+    id: 'queue',
+    headerTitle: 'Queue',
+    contentPath: 'queue'
+  },{
+    id: 'contextID',
+    headerTitle: 'Context ID',
+    contentPath: 'contextID'
+  },{
+    id: 'logs',
+    headerTitle: 'Logs',
+    contentPath: 'containerLogs',
+    cellComponentName: "em-table-linked-cell",
+    cellDefinition: {
+      target: "_blank"
+    }
+  }]),
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/e893e946/tez-ui2/src/main/webapp/app/controllers/app/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/app/index.js b/tez-ui2/src/main/webapp/app/controllers/app/index.js
new file mode 100644
index 0000000..9745328
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/app/index.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 PageController from '../page';
+
+export default PageController.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/e893e946/tez-ui2/src/main/webapp/app/controllers/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dags.js b/tez-ui2/src/main/webapp/app/controllers/dags.js
index 8d7e73e..fced7d8 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dags.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dags.js
@@ -78,7 +78,15 @@ export default TablePageController.extend({
   },{
     id: 'appID',
     headerTitle: 'Application Id',
-    contentPath: 'appID'
+    contentPath: 'appID',
+    cellComponentName: 'em-table-linked-cell',
+    getCellContent: function (row) {
+      return {
+        routeName: "app",
+        model: row.get("appID"),
+        text: row.get("appID")
+      };
+    }
   },{
     id: 'queue',
     headerTitle: 'Queue',

http://git-wip-us.apache.org/repos/asf/tez/blob/e893e946/tez-ui2/src/main/webapp/app/models/ahs-app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/ahs-app.js b/tez-ui2/src/main/webapp/app/models/ahs-app.js
index 8f4a153..ce087eb31 100644
--- a/tez-ui2/src/main/webapp/app/models/ahs-app.js
+++ b/tez-ui2/src/main/webapp/app/models/ahs-app.js
@@ -16,10 +16,14 @@
  * limitations under the License.
  */
 
+import Ember from 'ember';
+
 import DS from 'ember-data';
 import AbstractModel from './abstract';
 
 export default AbstractModel.extend({
+  entityID: DS.attr('string'),
+
   attemptID: DS.attr('string'),
 
   name: DS.attr('string'),
@@ -30,10 +34,12 @@ export default AbstractModel.extend({
   status: DS.attr('string'),
   finalStatus: DS.attr('string'),
 
-  startedTime: DS.attr('number'),
-  elapsedTime: DS.attr('number'),
-  finishedTime: DS.attr('number'),
-  submittedTime: DS.attr('number'),
+  startTime: DS.attr('number'),
+  endTime: DS.attr('number'),
+  duration: Ember.computed("startTime", "endTime", function () {
+    var duration = this.get("endTime") - this.get("startTime");
+    return duration > 0 ? duration : null;
+  }),
 
   diagnostics: DS.attr('string'),
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/e893e946/tez-ui2/src/main/webapp/app/models/app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/app.js b/tez-ui2/src/main/webapp/app/models/app.js
new file mode 100644
index 0000000..42fa1c5
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/models/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 DS from 'ember-data';
+
+import TimelineModel from './timeline';
+/*
+  Inherited properties
+
+  entityID - String
+  appID - Computed from entityID
+
+  status - String
+  progress - Computed from status
+
+  startTime - Number
+  endTime - Number
+  duration - Computed from start & end times
+
+  counterGroups - Array
+  counterHash - Computed from counterGroups
+*/
+
+export default TimelineModel.extend({
+  appID: Ember.computed("entityID", function () {
+    return this.get("entityID").substr(4);
+  }),
+
+  domain: DS.attr("string"),
+
+  user: DS.attr("string"),
+
+  buildTime: DS.attr("string"),
+  tezRevision: DS.attr("string"),
+  tezVersion: DS.attr("string"),
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/e893e946/tez-ui2/src/main/webapp/app/router.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/router.js b/tez-ui2/src/main/webapp/app/router.js
index e907cc7..d619e42 100644
--- a/tez-ui2/src/main/webapp/app/router.js
+++ b/tez-ui2/src/main/webapp/app/router.js
@@ -38,7 +38,9 @@ Router.map(function() {
     this.route('attempts');
   });
   this.route('attempt', {path: '/attempt/:attempt_id'}, function () {});
-  this.route('app', {path: '/app/:app_id'}, function () {});
+  this.route('app', {path: '/app/:app_id'}, function () {
+    this.route('dags');
+  });
 });
 
 export default Router;

http://git-wip-us.apache.org/repos/asf/tez/blob/e893e946/tez-ui2/src/main/webapp/app/routes/app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/app.js b/tez-ui2/src/main/webapp/app/routes/app.js
index 8719170..2bbf14a 100644
--- a/tez-ui2/src/main/webapp/app/routes/app.js
+++ b/tez-ui2/src/main/webapp/app/routes/app.js
@@ -16,7 +16,16 @@
  * limitations under the License.
  */
 
-import Ember from 'ember';
+import AbstractRoute from './abstract';
 
-export default Ember.Route.extend({
+export default AbstractRoute.extend({
+  title: "Application",
+
+  loaderQueryParams: {
+    id: "app_id"
+  },
+
+  model: function (params) {
+    return this.get("loader").queryRecord('app', "tez_" + this.queryFromParams(params).id);
+  }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/e893e946/tez-ui2/src/main/webapp/app/routes/app/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/app/dags.js b/tez-ui2/src/main/webapp/app/routes/app/dags.js
new file mode 100644
index 0000000..8c695b3
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/app/dags.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({
+  title: "DAGs",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (/*value, query*/) {
+    return this.get("loader").query('dag', {
+      appID: (this.modelFor("app").id || "").substr(4)
+    });
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/e893e946/tez-ui2/src/main/webapp/app/routes/app/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/app/index.js b/tez-ui2/src/main/webapp/app/routes/app/index.js
new file mode 100644
index 0000000..b6768fa
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/app/index.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';
+import AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  title: "Application Details",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (/*value, query*/) {
+    return this.get("loader").queryRecord('app', this.modelFor("app").id);
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/e893e946/tez-ui2/src/main/webapp/app/serializers/ahs-app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/ahs-app.js b/tez-ui2/src/main/webapp/app/serializers/ahs-app.js
index 10825b2..0c35d54 100644
--- a/tez-ui2/src/main/webapp/app/serializers/ahs-app.js
+++ b/tez-ui2/src/main/webapp/app/serializers/ahs-app.js
@@ -41,10 +41,8 @@ export default LoaderSerializer.extend({
     status: 'appState',
     finalStatus: 'finalAppStatus',
 
-    startedTime: 'startedTime',
-    elapsedTime: 'elapsedTime',
-    finishedTime: 'finishedTime',
-    submittedTime: 'submittedTime',
+    startTime: 'startedTime',
+    endTime: 'finishedTime',
 
     diagnostics: 'otherinfo.diagnostics',
   }

http://git-wip-us.apache.org/repos/asf/tez/blob/e893e946/tez-ui2/src/main/webapp/app/serializers/app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/app.js b/tez-ui2/src/main/webapp/app/serializers/app.js
new file mode 100644
index 0000000..86d8fa0
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/serializers/app.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 TimelineSerializer from './timeline';
+
+export default TimelineSerializer.extend({
+  maps: {
+    domain: 'domain',
+    user: 'otherinfo.user',
+
+    buildTime: 'otherinfo.tezVersion.buildTime',
+    tezRevision: 'otherinfo.tezVersion.revision',
+    tezVersion: 'otherinfo.tezVersion.version',
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/e893e946/tez-ui2/src/main/webapp/app/styles/details-page.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/details-page.less b/tez-ui2/src/main/webapp/app/styles/details-page.less
index 8c85d1f..4f65018 100644
--- a/tez-ui2/src/main/webapp/app/styles/details-page.less
+++ b/tez-ui2/src/main/webapp/app/styles/details-page.less
@@ -17,6 +17,10 @@
  */
 
 .detail-list {
+  display: inline-block;
+
+  margin: 0 10px 10px 0;
+
   table-layout: fixed;
   white-space: nowrap;
 

http://git-wip-us.apache.org/repos/asf/tez/blob/e893e946/tez-ui2/src/main/webapp/app/templates/app.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/app.hbs b/tez-ui2/src/main/webapp/app/templates/app.hbs
index c1a05b4..308b905 100644
--- a/tez-ui2/src/main/webapp/app/templates/app.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/app.hbs
@@ -16,4 +16,5 @@
  * limitations under the License.
 }}
 
-{{outlet}}
+{{tab-n-refresh tabs=tabs}}
+{{outlet}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/e893e946/tez-ui2/src/main/webapp/app/templates/app/dags.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/app/dags.hbs b/tez-ui2/src/main/webapp/app/templates/app/dags.hbs
new file mode 100644
index 0000000..cdb28aa
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/app/dags.hbs
@@ -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.
+}}
+
+{{#if loaded}}
+  {{em-table
+  columns=columns
+  rows=model
+
+  definition=definition
+
+  searchAction="searchChanged"
+  sortAction="sortChanged"
+  rowAction="rowsChanged"
+  pageAction="pageChanged"
+  }}
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/e893e946/tez-ui2/src/main/webapp/app/templates/app/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/app/index.hbs b/tez-ui2/src/main/webapp/app/templates/app/index.hbs
new file mode 100644
index 0000000..916051b
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/app/index.hbs
@@ -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.
+}}
+
+{{#if loaded}}
+  {{#if model.app}}
+    <table class='detail-list'>
+      <thead>
+      <tr>
+        <th colspan=2>YARN App Details</th>
+      </tr>
+      </thead>
+      <tbody>
+      <tr>
+        <td>Status</td>
+        <td>{{em-table-status-cell content=model.app.status}}</td>
+      </tr>
+      <tr>
+        <td>Final Status</td>
+        <td>{{em-table-status-cell content=model.app.finalStatus}}</td>
+      </tr>
+      <tr>
+        <td>Start Time</td>
+        <td>{{txt model.app.startTime type="date"}}</td>
+      </tr>
+      <tr>
+        <td>End Time</td>
+        <td>{{txt model.app.endTime type="date"}}</td>
+      </tr>
+      <tr>
+        <td>Duration</td>
+        <td>{{txt model.app.duration type="duration"}}</td>
+      </tr>
+      </tbody>
+    </table>
+    <table class='detail-list'>
+      <thead>
+      <tr>
+        <th colspan=2>YARN App Description</th>
+      </tr>
+      </thead>
+      <tbody>
+      <tr>
+        <td>Application ID</td>
+        <td>{{model.app.entityID}}</td>
+      </tr>
+      <tr>
+        <td>Application Name</td>
+        <td>{{model.app.name}}</td>
+      </tr>
+      <tr>
+        <td>Queue</td>
+        <td>{{model.app.queue}}</td>
+      </tr>
+      <tr>
+        <td>Application Type</td>
+        <td>{{model.app.type}}</td>
+      </tr>
+      <tr>
+        <td>User</td>
+        <td>{{model.app.user}}</td>
+      </tr>
+      </tbody>
+    </table>
+    <br/>
+  {{/if}}
+  <table class='detail-list'>
+    <thead>
+      <tr>
+        <th colspan=2>Tez Details</th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>Application ID</td>
+        <td>{{model.appID}}</td>
+      </tr>
+      <tr>
+        <td>Domain</td>
+        <td>{{model.domain}}</td>
+      </tr>
+      <tr>
+        <td>User</td>
+        <td>{{model.user}}</td>
+      </tr>
+    </tbody>
+  </table>
+
+  <table class='detail-list'>
+    <thead>
+      <tr>
+        <th colspan=2>Version Details</th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>Build Version</td>
+        <td>{{model.tezVersion}}</td>
+      </tr>
+      <tr>
+        <td>Build Revision</td>
+        <td>{{model.tezRevision}}</td>
+      </tr>
+      <tr>
+        <td>Build Time</td>
+        <td>{{model.buildTime}}</td>
+      </tr>
+    </tbody>
+  </table>
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/e893e946/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/index.hbs b/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
index 1bd3c21..fdb0a91 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
@@ -47,9 +47,7 @@
       </tr>
       <tr>
         <td>Status</td>
-        <td>
-          {{em-table-status-cell content=model.status}}
-        </td>
+        <td>{{em-table-status-cell content=model.status}}</td>
       </tr>
       <tr>
         <td>Start Time</td>

http://git-wip-us.apache.org/repos/asf/tez/blob/e893e946/tez-ui2/src/main/webapp/config/default-app-conf.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/config/default-app-conf.js b/tez-ui2/src/main/webapp/config/default-app-conf.js
index feea181..400290a 100644
--- a/tez-ui2/src/main/webapp/config/default-app-conf.js
+++ b/tez-ui2/src/main/webapp/config/default-app-conf.js
@@ -44,7 +44,7 @@ module.exports = { // Tez App configurations
 
       hiveQuery: 'HIVE_QUERY_ID',
 
-      tezApp: 'TEZ_APPLICATION'
+      app: 'TEZ_APPLICATION'
     }
   },
   hrefs: {

http://git-wip-us.apache.org/repos/asf/tez/blob/e893e946/tez-ui2/src/main/webapp/tests/unit/adapters/app-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/app-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/app-test.js
new file mode 100644
index 0000000..dd2db50
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/adapters/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:app', 'Unit | Adapter | dag', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let adapter = this.subject();
+
+  assert.ok(adapter);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/e893e946/tez-ui2/src/main/webapp/tests/unit/controllers/app-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/app-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/app-test.js
new file mode 100644
index 0000000..304321e
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/app-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:dag', 'Unit | Controller | dag', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+  assert.ok(controller.tabs);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/e893e946/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js
new file mode 100644
index 0000000..10ba8a3
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:app/dags', 'Unit | Controller | vertex/attempts', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+  assert.ok(controller.columns);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/e893e946/tez-ui2/src/main/webapp/tests/unit/controllers/app/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/app/index-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/app/index-test.js
new file mode 100644
index 0000000..c2004ba
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/app/index-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:app/index', 'Unit | Controller | vertex/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/e893e946/tez-ui2/src/main/webapp/tests/unit/models/app-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/app-test.js b/tez-ui2/src/main/webapp/tests/unit/models/app-test.js
new file mode 100644
index 0000000..e0fb7f0
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/models/app-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 { moduleForModel, test } from 'ember-qunit';
+
+moduleForModel('app', 'Unit | Model | task', {
+  // 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.needs);
+  assert.ok(model.appID);
+});
+
+test('appID test', function(assert) {
+  let model = this.subject({
+        entityID: "tez_1_2_3",
+      });
+
+  assert.equal(model.get("appID"), "1_2_3");
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/e893e946/tez-ui2/src/main/webapp/tests/unit/routes/app/dags-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/app/dags-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/app/dags-test.js
new file mode 100644
index 0000000..05c1436
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/app/dags-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:app/dags', 'Unit | Route | vertex/attempts', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+  assert.ok(route.load);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/e893e946/tez-ui2/src/main/webapp/tests/unit/routes/app/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/app/index-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/app/index-test.js
new file mode 100644
index 0000000..83697f4
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/app/index-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:app/index', 'Unit | Route | vertex/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+  assert.ok(route.load);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/e893e946/tez-ui2/src/main/webapp/tests/unit/serializers/app-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/serializers/app-test.js b/tez-ui2/src/main/webapp/tests/unit/serializers/app-test.js
new file mode 100644
index 0000000..fc79ae9
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/serializers/app-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('serializer:task', 'Unit | Serializer | task', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:task']
+});
+
+test('Basic creation test', function(assert) {
+  let serializer = this.subject();
+
+  assert.ok(serializer);
+  assert.ok(serializer.maps);
+});


[23/45] tez git commit: TEZ-3042. Tez UI 2: Create Counters pages (sree)

Posted by sr...@apache.org.
TEZ-3042. Tez UI 2: Create Counters pages (sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/a3a4637a
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/a3a4637a
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/a3a4637a

Branch: refs/heads/TEZ-2980
Commit: a3a4637a73ab7a7ad189bb4870e8e152bd723ba3
Parents: a42b6f6
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Tue Jan 19 14:38:20 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Thu Feb 25 03:32:16 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |  1 +
 .../src/main/webapp/app/controllers/attempt.js  |  3 +
 .../webapp/app/controllers/attempt/counters.js  | 26 ++++++
 .../webapp/app/controllers/counters-page.js     | 63 +++++++++++++
 tez-ui2/src/main/webapp/app/controllers/dag.js  |  3 +
 .../main/webapp/app/controllers/dag/counters.js | 26 ++++++
 tez-ui2/src/main/webapp/app/controllers/task.js |  3 +
 .../webapp/app/controllers/task/counters.js     | 26 ++++++
 .../src/main/webapp/app/controllers/vertex.js   |  3 +
 .../webapp/app/controllers/vertex/counters.js   | 26 ++++++
 tez-ui2/src/main/webapp/app/router.js           |  7 +-
 .../main/webapp/app/routes/attempt/counters.js  | 33 +++++++
 .../src/main/webapp/app/routes/dag/counters.js  | 34 +++++++
 .../src/main/webapp/app/routes/task/counters.js | 33 +++++++
 .../main/webapp/app/routes/vertex/counters.js   | 33 +++++++
 .../webapp/app/templates/attempt/counters.hbs   | 34 +++++++
 .../main/webapp/app/templates/dag/counters.hbs  | 34 +++++++
 .../main/webapp/app/templates/task/counters.hbs | 34 +++++++
 .../webapp/app/templates/vertex/counters.hbs    | 34 +++++++
 .../unit/controllers/attempt/counters-test.js   | 35 ++++++++
 .../unit/controllers/counters-page-test.js      | 95 ++++++++++++++++++++
 .../tests/unit/controllers/dag/counters-test.js | 35 ++++++++
 .../unit/controllers/task/counters-test.js      | 35 ++++++++
 .../unit/controllers/vertex/counters-test.js    | 35 ++++++++
 .../tests/unit/routes/attempt/counters-test.js  | 45 ++++++++++
 .../tests/unit/routes/dag/counters-test.js      | 46 ++++++++++
 .../tests/unit/routes/task/counters-test.js     | 45 ++++++++++
 .../tests/unit/routes/vertex/counters-test.js   | 45 ++++++++++
 28 files changed, 871 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/a3a4637a/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index 65fdcb5..a79198e 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -19,3 +19,4 @@ ALL CHANGES:
   TEZ-3041. Tez UI 2: Create Task & Attempt details page with sub tables
   TEZ-3045. Tez UI 2: Create application details page with DAGs tab
   TEZ-3048. Tez UI 2: Make PhantomJS a local dependency for build tests
+  TEZ-3042. Tez UI 2: Create Counters pages

http://git-wip-us.apache.org/repos/asf/tez/blob/a3a4637a/tez-ui2/src/main/webapp/app/controllers/attempt.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/attempt.js b/tez-ui2/src/main/webapp/app/controllers/attempt.js
index f17e317..64c8a67 100644
--- a/tez-ui2/src/main/webapp/app/controllers/attempt.js
+++ b/tez-ui2/src/main/webapp/app/controllers/attempt.js
@@ -49,5 +49,8 @@ export default AbstractController.extend({
   tabs: [{
     text: "Attempt Details",
     routeName: "attempt.index"
+  },{
+    text: "Attempt Counters",
+    routeName: "attempt.counters"
   }]
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/a3a4637a/tez-ui2/src/main/webapp/app/controllers/attempt/counters.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/attempt/counters.js b/tez-ui2/src/main/webapp/app/controllers/attempt/counters.js
new file mode 100644
index 0000000..9442838
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/attempt/counters.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 CountersPageController from '../counters-page';
+
+export default CountersPageController.extend({
+  breadcrumbs: [{
+    text: "Attempt Counters",
+    routeName: "attempt.counters",
+  }],
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a3a4637a/tez-ui2/src/main/webapp/app/controllers/counters-page.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/counters-page.js b/tez-ui2/src/main/webapp/app/controllers/counters-page.js
new file mode 100644
index 0000000..ef22ef1
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/counters-page.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 TablePageController from './table-page';
+import ColumnDefinition from 'em-table/utils/column-definition';
+
+export default TablePageController.extend({
+  columns: ColumnDefinition.make([{
+    id: 'groupName',
+    headerTitle: 'Group Name',
+    contentPath: 'groupName',
+  }, {
+    id: 'counterName',
+    headerTitle: 'Counter Name',
+    contentPath: 'counterName',
+  }, {
+    id: 'counterValue',
+    headerTitle: 'Counter Value',
+    contentPath: 'counterValue',
+  }]),
+
+  counters: Ember.computed("model.counterGroups", function () {
+    var counterGroups = this.get("model.counterGroups"),
+        counterRows = [];
+
+    if(counterGroups) {
+      counterGroups.forEach(function (group) {
+        var counterGroupName = group.counterGroupName,
+            counters = group.counters;
+
+        if(counters) {
+          counterGroupName = counterGroupName.substr(counterGroupName.lastIndexOf('.') + 1);
+          counters.forEach(function (counter) {
+            counterRows.push(Ember.Object.create({
+              groupName: counterGroupName,
+              counterName: counter.counterName,
+              counterValue: counter.counterValue
+            }));
+          });
+        }
+      });
+    }
+
+    return Ember.A(counterRows);
+  })
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a3a4637a/tez-ui2/src/main/webapp/app/controllers/dag.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag.js b/tez-ui2/src/main/webapp/app/controllers/dag.js
index 732a0df..14f9df6 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag.js
@@ -35,6 +35,9 @@ export default AbstractController.extend({
     text: "DAG Details",
     routeName: "dag.index"
   }, {
+    text: "DAG Counters",
+    routeName: "dag.counters"
+  }, {
     text: "All Vertices",
     routeName: "dag.vertices"
   }, {

http://git-wip-us.apache.org/repos/asf/tez/blob/a3a4637a/tez-ui2/src/main/webapp/app/controllers/dag/counters.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/counters.js b/tez-ui2/src/main/webapp/app/controllers/dag/counters.js
new file mode 100644
index 0000000..c4fbea6
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/counters.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 CountersPageController from '../counters-page';
+
+export default CountersPageController.extend({
+  breadcrumbs: [{
+    text: "DAG Counters",
+    routeName: "dag.counters",
+  }],
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a3a4637a/tez-ui2/src/main/webapp/app/controllers/task.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/task.js b/tez-ui2/src/main/webapp/app/controllers/task.js
index 5b2510c..2092162 100644
--- a/tez-ui2/src/main/webapp/app/controllers/task.js
+++ b/tez-ui2/src/main/webapp/app/controllers/task.js
@@ -45,6 +45,9 @@ export default AbstractController.extend({
     text: "Task Details",
     routeName: "task.index"
   }, {
+    text: "Task Counters",
+    routeName: "task.counters"
+  }, {
     text: "Task Attempts",
     routeName: "task.attempts"
   }]

http://git-wip-us.apache.org/repos/asf/tez/blob/a3a4637a/tez-ui2/src/main/webapp/app/controllers/task/counters.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/task/counters.js b/tez-ui2/src/main/webapp/app/controllers/task/counters.js
new file mode 100644
index 0000000..b9c00e3
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/task/counters.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 CountersPageController from '../counters-page';
+
+export default CountersPageController.extend({
+  breadcrumbs: [{
+    text: "Task Counters",
+    routeName: "task.counters",
+  }],
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a3a4637a/tez-ui2/src/main/webapp/app/controllers/vertex.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/vertex.js b/tez-ui2/src/main/webapp/app/controllers/vertex.js
index 946eaa5..5543924 100644
--- a/tez-ui2/src/main/webapp/app/controllers/vertex.js
+++ b/tez-ui2/src/main/webapp/app/controllers/vertex.js
@@ -40,6 +40,9 @@ export default AbstractController.extend({
     text: "Vertex Details",
     routeName: "vertex.index"
   }, {
+    text: "Vertex Counters",
+    routeName: "vertex.counters"
+  }, {
     text: "Tasks",
     routeName: "vertex.tasks"
   }, {

http://git-wip-us.apache.org/repos/asf/tez/blob/a3a4637a/tez-ui2/src/main/webapp/app/controllers/vertex/counters.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/vertex/counters.js b/tez-ui2/src/main/webapp/app/controllers/vertex/counters.js
new file mode 100644
index 0000000..245ae1b
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/vertex/counters.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 CountersPageController from '../counters-page';
+
+export default CountersPageController.extend({
+  breadcrumbs: [{
+    text: "Vertex Counters",
+    routeName: "vertex.counters",
+  }],
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a3a4637a/tez-ui2/src/main/webapp/app/router.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/router.js b/tez-ui2/src/main/webapp/app/router.js
index d619e42..0193672 100644
--- a/tez-ui2/src/main/webapp/app/router.js
+++ b/tez-ui2/src/main/webapp/app/router.js
@@ -29,15 +29,20 @@ Router.map(function() {
     this.route('vertices');
     this.route('tasks');
     this.route('attempts');
+    this.route('counters');
   });
   this.route('vertex', {path: '/vertex/:vertex_id'}, function() {
     this.route('tasks');
     this.route('attempts');
+    this.route('counters');
   });
   this.route('task', {path: '/task/:task_id'}, function() {
     this.route('attempts');
+    this.route('counters');
+  });
+  this.route('attempt', {path: '/attempt/:attempt_id'}, function () {
+    this.route('counters');
   });
-  this.route('attempt', {path: '/attempt/:attempt_id'}, function () {});
   this.route('app', {path: '/app/:app_id'}, function () {
     this.route('dags');
   });

http://git-wip-us.apache.org/repos/asf/tez/blob/a3a4637a/tez-ui2/src/main/webapp/app/routes/attempt/counters.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/attempt/counters.js b/tez-ui2/src/main/webapp/app/routes/attempt/counters.js
new file mode 100644
index 0000000..f88737d
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/attempt/counters.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';
+import AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  title: "DAG Details",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (/*value, query*/) {
+    return this.get("loader").queryRecord('attempt', this.modelFor("attempt").id);
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a3a4637a/tez-ui2/src/main/webapp/app/routes/dag/counters.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag/counters.js b/tez-ui2/src/main/webapp/app/routes/dag/counters.js
new file mode 100644
index 0000000..90929d0
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/dag/counters.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({
+  title: "DAG Details",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (/*value, query*/) {
+    return this.get("loader").queryRecord('dag', this.modelFor("dag").id);
+  },
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a3a4637a/tez-ui2/src/main/webapp/app/routes/task/counters.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/task/counters.js b/tez-ui2/src/main/webapp/app/routes/task/counters.js
new file mode 100644
index 0000000..fd76df9
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/task/counters.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';
+import AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  title: "DAG Details",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (/*value, query*/) {
+    return this.get("loader").queryRecord('task', this.modelFor("task").id);
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a3a4637a/tez-ui2/src/main/webapp/app/routes/vertex/counters.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/vertex/counters.js b/tez-ui2/src/main/webapp/app/routes/vertex/counters.js
new file mode 100644
index 0000000..d05e5f6
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/vertex/counters.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';
+import AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  title: "DAG Details",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (/*value, query*/) {
+    return this.get("loader").queryRecord('vertex', this.modelFor("vertex").id);
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a3a4637a/tez-ui2/src/main/webapp/app/templates/attempt/counters.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/attempt/counters.hbs b/tez-ui2/src/main/webapp/app/templates/attempt/counters.hbs
new file mode 100644
index 0000000..e590b36
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/attempt/counters.hbs
@@ -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.
+}}
+
+{{#if loaded}}
+  {{em-table
+  columns=columns
+  rows=counters
+
+  rowCount=counters.length
+  definition=definition
+
+  enablePagination=false
+
+  searchAction="searchChanged"
+  sortAction="sortChanged"
+  }}
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/a3a4637a/tez-ui2/src/main/webapp/app/templates/dag/counters.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/counters.hbs b/tez-ui2/src/main/webapp/app/templates/dag/counters.hbs
new file mode 100644
index 0000000..e590b36
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/dag/counters.hbs
@@ -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.
+}}
+
+{{#if loaded}}
+  {{em-table
+  columns=columns
+  rows=counters
+
+  rowCount=counters.length
+  definition=definition
+
+  enablePagination=false
+
+  searchAction="searchChanged"
+  sortAction="sortChanged"
+  }}
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/a3a4637a/tez-ui2/src/main/webapp/app/templates/task/counters.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/task/counters.hbs b/tez-ui2/src/main/webapp/app/templates/task/counters.hbs
new file mode 100644
index 0000000..e590b36
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/task/counters.hbs
@@ -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.
+}}
+
+{{#if loaded}}
+  {{em-table
+  columns=columns
+  rows=counters
+
+  rowCount=counters.length
+  definition=definition
+
+  enablePagination=false
+
+  searchAction="searchChanged"
+  sortAction="sortChanged"
+  }}
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/a3a4637a/tez-ui2/src/main/webapp/app/templates/vertex/counters.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/vertex/counters.hbs b/tez-ui2/src/main/webapp/app/templates/vertex/counters.hbs
new file mode 100644
index 0000000..e590b36
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/vertex/counters.hbs
@@ -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.
+}}
+
+{{#if loaded}}
+  {{em-table
+  columns=columns
+  rows=counters
+
+  rowCount=counters.length
+  definition=definition
+
+  enablePagination=false
+
+  searchAction="searchChanged"
+  sortAction="sortChanged"
+  }}
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/a3a4637a/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/counters-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/counters-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/counters-test.js
new file mode 100644
index 0000000..0231fa6
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/counters-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:attempt/counters', 'Unit | Controller | vertex/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a3a4637a/tez-ui2/src/main/webapp/tests/unit/controllers/counters-page-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/counters-page-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/counters-page-test.js
new file mode 100644
index 0000000..44a888e
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/counters-page-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 Ember from 'ember';
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:counters-page', 'Unit | Controller | counters page', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.columns);
+  assert.ok(controller.counters);
+});
+
+test('counters test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K,
+    model: {
+      counterGroups: [{
+        counterGroupName: "a.b.foo",
+        counters: [{
+          counterName: "Foo Name 1",
+          counterValue: "Value 1"
+        },{
+          counterName: "Foo Name 2",
+          counterValue: "Value 2"
+        },{
+          counterName: "Foo Name 3",
+          counterValue: "Value 3"
+        },]
+      },{
+        counterGroupName: "a.b.bar",
+        counters: [{
+          counterName: "Bar Name 1",
+          counterValue: "Value 1"
+        },{
+          counterName: "Bar Name 2",
+          counterValue: "Value 2"
+        },{
+          counterName: "Bar Name 3",
+          counterValue: "Value 3"
+        },]
+      }]
+    }
+  });
+
+  assert.equal(controller.get("counters.0.groupName"), "foo");
+  assert.equal(controller.get("counters.0.counterName"), "Foo Name 1");
+  assert.equal(controller.get("counters.0.counterValue"), "Value 1");
+
+  assert.equal(controller.get("counters.1.groupName"), "foo");
+  assert.equal(controller.get("counters.1.counterName"), "Foo Name 2");
+  assert.equal(controller.get("counters.1.counterValue"), "Value 2");
+
+  assert.equal(controller.get("counters.2.groupName"), "foo");
+  assert.equal(controller.get("counters.2.counterName"), "Foo Name 3");
+  assert.equal(controller.get("counters.2.counterValue"), "Value 3");
+
+
+  assert.equal(controller.get("counters.3.groupName"), "bar");
+  assert.equal(controller.get("counters.3.counterName"), "Bar Name 1");
+  assert.equal(controller.get("counters.3.counterValue"), "Value 1");
+
+  assert.equal(controller.get("counters.4.groupName"), "bar");
+  assert.equal(controller.get("counters.4.counterName"), "Bar Name 2");
+  assert.equal(controller.get("counters.4.counterValue"), "Value 2");
+
+  assert.equal(controller.get("counters.5.groupName"), "bar");
+  assert.equal(controller.get("counters.5.counterName"), "Bar Name 3");
+  assert.equal(controller.get("counters.5.counterValue"), "Value 3");
+});
+

http://git-wip-us.apache.org/repos/asf/tez/blob/a3a4637a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/counters-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/counters-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/counters-test.js
new file mode 100644
index 0000000..982bea0
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/counters-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:dag/counters', 'Unit | Controller | vertex/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a3a4637a/tez-ui2/src/main/webapp/tests/unit/controllers/task/counters-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/task/counters-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/task/counters-test.js
new file mode 100644
index 0000000..e4f2532
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/task/counters-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:task/counters', 'Unit | Controller | vertex/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a3a4637a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/counters-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/counters-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/counters-test.js
new file mode 100644
index 0000000..83d946c
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/counters-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:vertex/counters', 'Unit | Controller | vertex/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a3a4637a/tez-ui2/src/main/webapp/tests/unit/routes/attempt/counters-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/attempt/counters-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/attempt/counters-test.js
new file mode 100644
index 0000000..5a65685
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/attempt/counters-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:attempt/counters', 'Unit | Route | vertex/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+  assert.ok(route.load);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a3a4637a/tez-ui2/src/main/webapp/tests/unit/routes/dag/counters-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/dag/counters-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/dag/counters-test.js
new file mode 100644
index 0000000..24940b2
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/dag/counters-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:dag/counters', 'Unit | Route | dag/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+  assert.ok(route.load);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});
+

http://git-wip-us.apache.org/repos/asf/tez/blob/a3a4637a/tez-ui2/src/main/webapp/tests/unit/routes/task/counters-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/task/counters-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/task/counters-test.js
new file mode 100644
index 0000000..472a635
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/task/counters-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:task/counters', 'Unit | Route | vertex/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+  assert.ok(route.load);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a3a4637a/tez-ui2/src/main/webapp/tests/unit/routes/vertex/counters-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/vertex/counters-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/vertex/counters-test.js
new file mode 100644
index 0000000..ec33b8a
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/vertex/counters-test.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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:vertex/counters', 'Unit | Route | vertex/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+  assert.ok(route.load);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});