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/01/15 13:00:20 UTC

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

Repository: tez
Updated Branches:
  refs/heads/TEZ-2980 05296def0 -> 7146475eb


http://git-wip-us.apache.org/repos/asf/tez/blob/7146475e/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/7146475e/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);
+});


[2/2] 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/7146475e
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/7146475e
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/7146475e

Branch: refs/heads/TEZ-2980
Commit: 7146475eb6b1155991603ec18cd33668f41efb7d
Parents: 05296de
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Fri Jan 15 17:29:30 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Fri Jan 15 17:29:30 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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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/7146475e/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);
+});