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/20 18:05:27 UTC

[01/50] [abbrv] tez git commit: TEZ-3006. Remove unused import in TestHistoryParser (rbalamohan)

Repository: tez
Updated Branches:
  refs/heads/TEZ-2980 d36f9066b -> 8d80272ca


TEZ-3006. Remove unused import in TestHistoryParser (rbalamohan)


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

Branch: refs/heads/TEZ-2980
Commit: eee485a69c1899824bd9ed14b6d77719ff07d375
Parents: 2c7abeb
Author: Rajesh Balamohan <rb...@apache.org>
Authored: Wed Dec 16 20:07:25 2015 +0530
Committer: Rajesh Balamohan <rb...@apache.org>
Committed: Wed Dec 16 20:07:25 2015 +0530

----------------------------------------------------------------------
 CHANGES.txt                                                        | 2 ++
 .../src/test/java/org/apache/tez/history/TestHistoryParser.java    | 1 -
 2 files changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/eee485a6/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 8588923..2a2addc 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -10,6 +10,7 @@ INCOMPATIBLE CHANGES
   TEZ-604. Revert temporary changes made in TEZ-603 to kill the provided tez session, if running a MapReduce job.
 
 ALL CHANGES:
+  TEZ-3006. Remove unused import in TestHistoryParser.
   TEZ-2910. Set caller context for tracing ( integrate with HDFS-9184 ).
   TEZ-2976. Recovery fails when InputDescriptor is changed during input initialization.
   TEZ-2997. Tez UI: Support searches by CallerContext ID for DAGs
@@ -295,6 +296,7 @@ INCOMPATIBLE CHANGES
   TEZ-2949. Allow duplicate dag names within session for Tez.
 
 ALL CHANGES
+  TEZ-3006. Remove unused import in TestHistoryParser.
   TEZ-2979. FlakyTest: org.apache.tez.history.TestHistoryParser.
   TEZ-2684. ShuffleVertexManager.parsePartitionStats throws IllegalStateException: Stats should be initialized.
   TEZ-2496. Consider scheduling tasks in ShuffleVertexManager based on the partition sizes from the source.

http://git-wip-us.apache.org/repos/asf/tez/blob/eee485a6/tez-plugins/tez-history-parser/src/test/java/org/apache/tez/history/TestHistoryParser.java
----------------------------------------------------------------------
diff --git a/tez-plugins/tez-history-parser/src/test/java/org/apache/tez/history/TestHistoryParser.java b/tez-plugins/tez-history-parser/src/test/java/org/apache/tez/history/TestHistoryParser.java
index 2b23294..b373f6e 100644
--- a/tez-plugins/tez-history-parser/src/test/java/org/apache/tez/history/TestHistoryParser.java
+++ b/tez-plugins/tez-history-parser/src/test/java/org/apache/tez/history/TestHistoryParser.java
@@ -19,7 +19,6 @@
 package org.apache.tez.history;
 
 import com.google.common.collect.Sets;
-import com.sun.tools.internal.ws.processor.ProcessorException;
 import org.apache.commons.cli.ParseException;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang.RandomStringUtils;


[43/50] [abbrv] tez git commit: TEZ-3042. Tez UI 2: Create Counters pages (sree)

Posted by sr...@apache.org.
TEZ-3042. Tez UI 2: Create Counters pages (sree)


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

Branch: refs/heads/TEZ-2980
Commit: 98cb99d1e53c91e0b7fdefdfaa6e8920ea13de32
Parents: fca31c5
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Tue Jan 19 14:38:20 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Wed Jan 20 22:30:07 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |  1 +
 .../src/main/webapp/app/controllers/attempt.js  |  3 +
 .../webapp/app/controllers/attempt/counters.js  | 26 ++++++
 .../webapp/app/controllers/counters-page.js     | 63 +++++++++++++
 tez-ui2/src/main/webapp/app/controllers/dag.js  |  3 +
 .../main/webapp/app/controllers/dag/counters.js | 26 ++++++
 tez-ui2/src/main/webapp/app/controllers/task.js |  3 +
 .../webapp/app/controllers/task/counters.js     | 26 ++++++
 .../src/main/webapp/app/controllers/vertex.js   |  3 +
 .../webapp/app/controllers/vertex/counters.js   | 26 ++++++
 tez-ui2/src/main/webapp/app/router.js           |  7 +-
 .../main/webapp/app/routes/attempt/counters.js  | 33 +++++++
 .../src/main/webapp/app/routes/dag/counters.js  | 34 +++++++
 .../src/main/webapp/app/routes/task/counters.js | 33 +++++++
 .../main/webapp/app/routes/vertex/counters.js   | 33 +++++++
 .../webapp/app/templates/attempt/counters.hbs   | 34 +++++++
 .../main/webapp/app/templates/dag/counters.hbs  | 34 +++++++
 .../main/webapp/app/templates/task/counters.hbs | 34 +++++++
 .../webapp/app/templates/vertex/counters.hbs    | 34 +++++++
 .../unit/controllers/attempt/counters-test.js   | 35 ++++++++
 .../unit/controllers/counters-page-test.js      | 95 ++++++++++++++++++++
 .../tests/unit/controllers/dag/counters-test.js | 35 ++++++++
 .../unit/controllers/task/counters-test.js      | 35 ++++++++
 .../unit/controllers/vertex/counters-test.js    | 35 ++++++++
 .../tests/unit/routes/attempt/counters-test.js  | 45 ++++++++++
 .../tests/unit/routes/dag/counters-test.js      | 46 ++++++++++
 .../tests/unit/routes/task/counters-test.js     | 45 ++++++++++
 .../tests/unit/routes/vertex/counters-test.js   | 45 ++++++++++
 28 files changed, 871 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


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

http://git-wip-us.apache.org/repos/asf/tez/blob/98cb99d1/tez-ui2/src/main/webapp/app/controllers/attempt.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/attempt.js b/tez-ui2/src/main/webapp/app/controllers/attempt.js
index f17e317..64c8a67 100644
--- a/tez-ui2/src/main/webapp/app/controllers/attempt.js
+++ b/tez-ui2/src/main/webapp/app/controllers/attempt.js
@@ -49,5 +49,8 @@ export default AbstractController.extend({
   tabs: [{
     text: "Attempt Details",
     routeName: "attempt.index"
+  },{
+    text: "Attempt Counters",
+    routeName: "attempt.counters"
   }]
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/98cb99d1/tez-ui2/src/main/webapp/app/controllers/attempt/counters.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/attempt/counters.js b/tez-ui2/src/main/webapp/app/controllers/attempt/counters.js
new file mode 100644
index 0000000..9442838
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/attempt/counters.js
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import CountersPageController from '../counters-page';
+
+export default CountersPageController.extend({
+  breadcrumbs: [{
+    text: "Attempt Counters",
+    routeName: "attempt.counters",
+  }],
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/98cb99d1/tez-ui2/src/main/webapp/app/controllers/counters-page.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/counters-page.js b/tez-ui2/src/main/webapp/app/controllers/counters-page.js
new file mode 100644
index 0000000..ef22ef1
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/counters-page.js
@@ -0,0 +1,63 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import TablePageController from './table-page';
+import ColumnDefinition from 'em-table/utils/column-definition';
+
+export default TablePageController.extend({
+  columns: ColumnDefinition.make([{
+    id: 'groupName',
+    headerTitle: 'Group Name',
+    contentPath: 'groupName',
+  }, {
+    id: 'counterName',
+    headerTitle: 'Counter Name',
+    contentPath: 'counterName',
+  }, {
+    id: 'counterValue',
+    headerTitle: 'Counter Value',
+    contentPath: 'counterValue',
+  }]),
+
+  counters: Ember.computed("model.counterGroups", function () {
+    var counterGroups = this.get("model.counterGroups"),
+        counterRows = [];
+
+    if(counterGroups) {
+      counterGroups.forEach(function (group) {
+        var counterGroupName = group.counterGroupName,
+            counters = group.counters;
+
+        if(counters) {
+          counterGroupName = counterGroupName.substr(counterGroupName.lastIndexOf('.') + 1);
+          counters.forEach(function (counter) {
+            counterRows.push(Ember.Object.create({
+              groupName: counterGroupName,
+              counterName: counter.counterName,
+              counterValue: counter.counterValue
+            }));
+          });
+        }
+      });
+    }
+
+    return Ember.A(counterRows);
+  })
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/98cb99d1/tez-ui2/src/main/webapp/app/controllers/dag.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag.js b/tez-ui2/src/main/webapp/app/controllers/dag.js
index 732a0df..14f9df6 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag.js
@@ -35,6 +35,9 @@ export default AbstractController.extend({
     text: "DAG Details",
     routeName: "dag.index"
   }, {
+    text: "DAG Counters",
+    routeName: "dag.counters"
+  }, {
     text: "All Vertices",
     routeName: "dag.vertices"
   }, {

http://git-wip-us.apache.org/repos/asf/tez/blob/98cb99d1/tez-ui2/src/main/webapp/app/controllers/dag/counters.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/counters.js b/tez-ui2/src/main/webapp/app/controllers/dag/counters.js
new file mode 100644
index 0000000..c4fbea6
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/counters.js
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import CountersPageController from '../counters-page';
+
+export default CountersPageController.extend({
+  breadcrumbs: [{
+    text: "DAG Counters",
+    routeName: "dag.counters",
+  }],
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/98cb99d1/tez-ui2/src/main/webapp/app/controllers/task.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/task.js b/tez-ui2/src/main/webapp/app/controllers/task.js
index 5b2510c..2092162 100644
--- a/tez-ui2/src/main/webapp/app/controllers/task.js
+++ b/tez-ui2/src/main/webapp/app/controllers/task.js
@@ -45,6 +45,9 @@ export default AbstractController.extend({
     text: "Task Details",
     routeName: "task.index"
   }, {
+    text: "Task Counters",
+    routeName: "task.counters"
+  }, {
     text: "Task Attempts",
     routeName: "task.attempts"
   }]

http://git-wip-us.apache.org/repos/asf/tez/blob/98cb99d1/tez-ui2/src/main/webapp/app/controllers/task/counters.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/task/counters.js b/tez-ui2/src/main/webapp/app/controllers/task/counters.js
new file mode 100644
index 0000000..b9c00e3
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/task/counters.js
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import CountersPageController from '../counters-page';
+
+export default CountersPageController.extend({
+  breadcrumbs: [{
+    text: "Task Counters",
+    routeName: "task.counters",
+  }],
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/98cb99d1/tez-ui2/src/main/webapp/app/controllers/vertex.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/vertex.js b/tez-ui2/src/main/webapp/app/controllers/vertex.js
index 946eaa5..5543924 100644
--- a/tez-ui2/src/main/webapp/app/controllers/vertex.js
+++ b/tez-ui2/src/main/webapp/app/controllers/vertex.js
@@ -40,6 +40,9 @@ export default AbstractController.extend({
     text: "Vertex Details",
     routeName: "vertex.index"
   }, {
+    text: "Vertex Counters",
+    routeName: "vertex.counters"
+  }, {
     text: "Tasks",
     routeName: "vertex.tasks"
   }, {

http://git-wip-us.apache.org/repos/asf/tez/blob/98cb99d1/tez-ui2/src/main/webapp/app/controllers/vertex/counters.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/vertex/counters.js b/tez-ui2/src/main/webapp/app/controllers/vertex/counters.js
new file mode 100644
index 0000000..245ae1b
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/vertex/counters.js
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import CountersPageController from '../counters-page';
+
+export default CountersPageController.extend({
+  breadcrumbs: [{
+    text: "Vertex Counters",
+    routeName: "vertex.counters",
+  }],
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/98cb99d1/tez-ui2/src/main/webapp/app/router.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/router.js b/tez-ui2/src/main/webapp/app/router.js
index d619e42..0193672 100644
--- a/tez-ui2/src/main/webapp/app/router.js
+++ b/tez-ui2/src/main/webapp/app/router.js
@@ -29,15 +29,20 @@ Router.map(function() {
     this.route('vertices');
     this.route('tasks');
     this.route('attempts');
+    this.route('counters');
   });
   this.route('vertex', {path: '/vertex/:vertex_id'}, function() {
     this.route('tasks');
     this.route('attempts');
+    this.route('counters');
   });
   this.route('task', {path: '/task/:task_id'}, function() {
     this.route('attempts');
+    this.route('counters');
+  });
+  this.route('attempt', {path: '/attempt/:attempt_id'}, function () {
+    this.route('counters');
   });
-  this.route('attempt', {path: '/attempt/:attempt_id'}, function () {});
   this.route('app', {path: '/app/:app_id'}, function () {
     this.route('dags');
   });

http://git-wip-us.apache.org/repos/asf/tez/blob/98cb99d1/tez-ui2/src/main/webapp/app/routes/attempt/counters.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/attempt/counters.js b/tez-ui2/src/main/webapp/app/routes/attempt/counters.js
new file mode 100644
index 0000000..f88737d
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/attempt/counters.js
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  title: "DAG Details",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (/*value, query*/) {
+    return this.get("loader").queryRecord('attempt', this.modelFor("attempt").id);
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/98cb99d1/tez-ui2/src/main/webapp/app/routes/dag/counters.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag/counters.js b/tez-ui2/src/main/webapp/app/routes/dag/counters.js
new file mode 100644
index 0000000..90929d0
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/dag/counters.js
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  title: "DAG Details",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (/*value, query*/) {
+    return this.get("loader").queryRecord('dag', this.modelFor("dag").id);
+  },
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/98cb99d1/tez-ui2/src/main/webapp/app/routes/task/counters.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/task/counters.js b/tez-ui2/src/main/webapp/app/routes/task/counters.js
new file mode 100644
index 0000000..fd76df9
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/task/counters.js
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  title: "DAG Details",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (/*value, query*/) {
+    return this.get("loader").queryRecord('task', this.modelFor("task").id);
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/98cb99d1/tez-ui2/src/main/webapp/app/routes/vertex/counters.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/vertex/counters.js b/tez-ui2/src/main/webapp/app/routes/vertex/counters.js
new file mode 100644
index 0000000..d05e5f6
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/vertex/counters.js
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  title: "DAG Details",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (/*value, query*/) {
+    return this.get("loader").queryRecord('vertex', this.modelFor("vertex").id);
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/98cb99d1/tez-ui2/src/main/webapp/app/templates/attempt/counters.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/attempt/counters.hbs b/tez-ui2/src/main/webapp/app/templates/attempt/counters.hbs
new file mode 100644
index 0000000..e590b36
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/attempt/counters.hbs
@@ -0,0 +1,34 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+}}
+
+{{#if loaded}}
+  {{em-table
+  columns=columns
+  rows=counters
+
+  rowCount=counters.length
+  definition=definition
+
+  enablePagination=false
+
+  searchAction="searchChanged"
+  sortAction="sortChanged"
+  }}
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/98cb99d1/tez-ui2/src/main/webapp/app/templates/dag/counters.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/counters.hbs b/tez-ui2/src/main/webapp/app/templates/dag/counters.hbs
new file mode 100644
index 0000000..e590b36
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/dag/counters.hbs
@@ -0,0 +1,34 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+}}
+
+{{#if loaded}}
+  {{em-table
+  columns=columns
+  rows=counters
+
+  rowCount=counters.length
+  definition=definition
+
+  enablePagination=false
+
+  searchAction="searchChanged"
+  sortAction="sortChanged"
+  }}
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/98cb99d1/tez-ui2/src/main/webapp/app/templates/task/counters.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/task/counters.hbs b/tez-ui2/src/main/webapp/app/templates/task/counters.hbs
new file mode 100644
index 0000000..e590b36
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/task/counters.hbs
@@ -0,0 +1,34 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+}}
+
+{{#if loaded}}
+  {{em-table
+  columns=columns
+  rows=counters
+
+  rowCount=counters.length
+  definition=definition
+
+  enablePagination=false
+
+  searchAction="searchChanged"
+  sortAction="sortChanged"
+  }}
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/98cb99d1/tez-ui2/src/main/webapp/app/templates/vertex/counters.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/vertex/counters.hbs b/tez-ui2/src/main/webapp/app/templates/vertex/counters.hbs
new file mode 100644
index 0000000..e590b36
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/vertex/counters.hbs
@@ -0,0 +1,34 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+}}
+
+{{#if loaded}}
+  {{em-table
+  columns=columns
+  rows=counters
+
+  rowCount=counters.length
+  definition=definition
+
+  enablePagination=false
+
+  searchAction="searchChanged"
+  sortAction="sortChanged"
+  }}
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/98cb99d1/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/counters-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/counters-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/counters-test.js
new file mode 100644
index 0000000..0231fa6
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/counters-test.js
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:attempt/counters', 'Unit | Controller | vertex/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+});

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

http://git-wip-us.apache.org/repos/asf/tez/blob/98cb99d1/tez-ui2/src/main/webapp/tests/unit/controllers/dag/counters-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/counters-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/counters-test.js
new file mode 100644
index 0000000..982bea0
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/counters-test.js
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:dag/counters', 'Unit | Controller | vertex/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/98cb99d1/tez-ui2/src/main/webapp/tests/unit/controllers/task/counters-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/task/counters-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/task/counters-test.js
new file mode 100644
index 0000000..e4f2532
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/task/counters-test.js
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:task/counters', 'Unit | Controller | vertex/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/98cb99d1/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/counters-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/counters-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/counters-test.js
new file mode 100644
index 0000000..83d946c
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/counters-test.js
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:vertex/counters', 'Unit | Controller | vertex/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/98cb99d1/tez-ui2/src/main/webapp/tests/unit/routes/attempt/counters-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/attempt/counters-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/attempt/counters-test.js
new file mode 100644
index 0000000..5a65685
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/attempt/counters-test.js
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:attempt/counters', 'Unit | Route | vertex/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+  assert.ok(route.load);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/98cb99d1/tez-ui2/src/main/webapp/tests/unit/routes/dag/counters-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/dag/counters-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/dag/counters-test.js
new file mode 100644
index 0000000..24940b2
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/dag/counters-test.js
@@ -0,0 +1,46 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:dag/counters', 'Unit | Route | dag/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+  assert.ok(route.load);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});
+

http://git-wip-us.apache.org/repos/asf/tez/blob/98cb99d1/tez-ui2/src/main/webapp/tests/unit/routes/task/counters-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/task/counters-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/task/counters-test.js
new file mode 100644
index 0000000..472a635
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/task/counters-test.js
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:task/counters', 'Unit | Route | vertex/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+  assert.ok(route.load);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/98cb99d1/tez-ui2/src/main/webapp/tests/unit/routes/vertex/counters-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/vertex/counters-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/vertex/counters-test.js
new file mode 100644
index 0000000..ec33b8a
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/vertex/counters-test.js
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:vertex/counters', 'Unit | Route | vertex/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+  assert.ok(route.load);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});


[21/50] [abbrv] tez git commit: TEZ-2937. Can Processor.close() be called after closing inputs and outputs? (jeagles)

Posted by sr...@apache.org.
TEZ-2937. Can Processor.close() be called after closing inputs and outputs? (jeagles)


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

Branch: refs/heads/TEZ-2980
Commit: b0ba133ffcf1339b2c505878e9622084d4290bde
Parents: d0348b0
Author: Jonathan Eagles <je...@yahoo-inc.com>
Authored: Fri Jan 15 10:58:37 2016 -0600
Committer: Jonathan Eagles <je...@yahoo-inc.com>
Committed: Fri Jan 15 10:58:37 2016 -0600

----------------------------------------------------------------------
 CHANGES.txt                                     |  2 +
 .../runtime/LogicalIOProcessorRuntimeTask.java  | 53 ++++++++++----------
 2 files changed, 29 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/b0ba133f/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index d6a53aa..5226ea6 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -6,6 +6,7 @@ Release 0.8.3: Unreleased
 INCOMPATIBLE CHANGES
 
 ALL CHANGES:
+  TEZ-2937. Can Processor.close() be called after closing inputs and outputs?
   TEZ-3037. History URL should be set regardless of which history logging service is enabled.
   TEZ-3032. DAG start time getting logged using system time instead of recorded time in startTime field.
 
@@ -314,6 +315,7 @@ INCOMPATIBLE CHANGES
   TEZ-2949. Allow duplicate dag names within session for Tez.
 
 ALL CHANGES
+  TEZ-2937. Can Processor.close() be called after closing inputs and outputs?
   TEZ-3037. History URL should be set regardless of which history logging service is enabled.
   TEZ-3032. DAG start time getting logged using system time instead of recorded time in startTime field.
   TEZ-2129. Task and Attempt views should contain links to the logs

http://git-wip-us.apache.org/repos/asf/tez/blob/b0ba133f/tez-runtime-internals/src/main/java/org/apache/tez/runtime/LogicalIOProcessorRuntimeTask.java
----------------------------------------------------------------------
diff --git a/tez-runtime-internals/src/main/java/org/apache/tez/runtime/LogicalIOProcessorRuntimeTask.java b/tez-runtime-internals/src/main/java/org/apache/tez/runtime/LogicalIOProcessorRuntimeTask.java
index df09fdb..7f546e6 100644
--- a/tez-runtime-internals/src/main/java/org/apache/tez/runtime/LogicalIOProcessorRuntimeTask.java
+++ b/tez-runtime-internals/src/main/java/org/apache/tez/runtime/LogicalIOProcessorRuntimeTask.java
@@ -357,10 +357,6 @@ public class LogicalIOProcessorRuntimeTask extends RuntimeTask {
           "Can only run while in RUNNING state. Current: " + this.state);
       this.state.set(State.CLOSED);
 
-      // Close the Processor.
-      processorClosed = true;
-      processor.close();
-
       // Close the Inputs.
       for (InputSpec inputSpec : inputSpecs) {
         String srcVertexName = inputSpec.getSourceVertexName();
@@ -380,6 +376,11 @@ public class LogicalIOProcessorRuntimeTask extends RuntimeTask {
             EventProducerConsumerType.OUTPUT, taskSpec.getVertexName(),
             destVertexName, taskSpec.getTaskAttemptID());
       }
+
+      // Close the Processor.
+      processorClosed = true;
+      processor.close();
+
     } finally {
       setTaskDone();
       if (eventRouterThread != null) {
@@ -843,28 +844,6 @@ public class LogicalIOProcessorRuntimeTask extends RuntimeTask {
       LOG.debug("Num of outputs to be closed={}", initializedOutputs.size());
     }
 
-    // Close processor
-    if (!processorClosed && processor != null) {
-      try {
-        processorClosed = true;
-        processor.close();
-        LOG.info("Closed processor for vertex={}, index={}, interruptedStatus={}",
-            processor
-                .getContext().getTaskVertexName(),
-            processor.getContext().getTaskVertexIndex(),
-            Thread.currentThread().isInterrupted());
-        maybeResetInterruptStatus();
-      } catch (InterruptedException ie) {
-        //reset the status
-        LOG.info("Resetting interrupt for processor");
-        Thread.currentThread().interrupt();
-      } catch (Throwable e) {
-        LOG.warn(
-            "Ignoring Exception when closing processor(cleanup). Exception class={}, message={}" +
-                e.getClass().getName(), e.getMessage());
-      }
-    }
-
     // Close the remaining inited Inputs.
     Iterator<Map.Entry<String, LogicalInput>> inputIterator = initializedInputs.entrySet().iterator();
     while (inputIterator.hasNext()) {
@@ -917,6 +896,28 @@ public class LogicalIOProcessorRuntimeTask extends RuntimeTask {
       printThreads();
     }
 
+    // Close processor
+    if (!processorClosed && processor != null) {
+      try {
+        processorClosed = true;
+        processor.close();
+        LOG.info("Closed processor for vertex={}, index={}, interruptedStatus={}",
+            processor
+            .getContext().getTaskVertexName(),
+            processor.getContext().getTaskVertexIndex(),
+            Thread.currentThread().isInterrupted());
+        maybeResetInterruptStatus();
+      } catch (InterruptedException ie) {
+        //reset the status
+        LOG.info("Resetting interrupt for processor");
+        Thread.currentThread().interrupt();
+      } catch (Throwable e) {
+        LOG.warn(
+            "Ignoring Exception when closing processor(cleanup). Exception class={}, message={}" +
+            e.getClass().getName(), e.getMessage());
+      }
+    }
+
     try {
       closeContexts();
       // Cleanup references which may be held by misbehaved tasks.


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

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


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

Branch: refs/heads/TEZ-2980
Commit: 3888786059326fa6c2e544f8936097ac341c8702
Parents: a4f6831
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Sat Jan 9 13:18:01 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Wed Jan 20 22:30:07 2016 +0530

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


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

http://git-wip-us.apache.org/repos/asf/tez/blob/38887860/tez-ui2/src/main/webapp/app/controllers/application.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/application.js b/tez-ui2/src/main/webapp/app/controllers/application.js
new file mode 100644
index 0000000..24db40a
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/application.js
@@ -0,0 +1,38 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+const BREADCRUMB_PREFIX = [{
+  text: "All DAGs",
+  routeName: 'application'
+}];
+
+export default Ember.Controller.extend({
+  breadcrumbs: null,
+  prefixedBreadcrumbs: Ember.computed("breadcrumbs", function () {
+    var prefix = BREADCRUMB_PREFIX,
+    breadcrumbs = this.get('breadcrumbs');
+
+    if(Array.isArray(breadcrumbs)) {
+      prefix = prefix.concat(breadcrumbs);
+    }
+
+    return prefix;
+  })
+});

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

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

http://git-wip-us.apache.org/repos/asf/tez/blob/38887860/tez-ui2/src/main/webapp/app/routes/application.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/application.js b/tez-ui2/src/main/webapp/app/routes/application.js
new file mode 100644
index 0000000..1540107
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/application.js
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Route.extend({
+
+  pageReset: function () {
+    Ember.$(document).tooltip("close");
+  },
+
+  actions: {
+    didTransition: function(/* transition */) {
+      this.pageReset();
+    },
+    pageChanged: function (breadcrumbs) {
+      this.set("controller.breadcrumbs", breadcrumbs);
+    }
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/38887860/tez-ui2/src/main/webapp/app/services/env.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/services/env.js b/tez-ui2/src/main/webapp/app/services/env.js
index bd7dde7..78193ee 100644
--- a/tez-ui2/src/main/webapp/app/services/env.js
+++ b/tez-ui2/src/main/webapp/app/services/env.js
@@ -42,9 +42,16 @@ export default Ember.Service.extend({
       MoreObject.merge(collatedENV.APP, ENV);
     }
 
+    this.setComputedENVs(collatedENV);
+
     this.set("ENV", collatedENV);
   },
 
+  setComputedENVs: function (env) {
+    var navigator = window.navigator;
+    env.isIE = navigator.userAgent.indexOf('MSIE') !== -1 || navigator.appVersion.indexOf('Trident/') > 0;
+  },
+
   app: Ember.computed("ENV.APP", function () {
     return this.get("ENV.APP");
   })

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

http://git-wip-us.apache.org/repos/asf/tez/blob/38887860/tez-ui2/src/main/webapp/app/styles/colors.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/colors.less b/tez-ui2/src/main/webapp/app/styles/colors.less
new file mode 100644
index 0000000..af470ff
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/styles/colors.less
@@ -0,0 +1,44 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Colors
+@logo-orange: #D27A22;
+
+@bg-lite: #f5f5f5;
+@bg-liter: #f5f5f5;
+@bg-red-light: #FFE6E6;
+
+@bg-grey: #f0f0f0;
+
+@border-lite: #e5e5e5;
+@border-color: #dcdcdc;
+
+@white: #fff;
+
+@text-color: rgb(70, 70, 70);
+@text-red: red;
+@text-light: #BBBBBB;
+@text-green: green;
+
+@top-nav-bg-color-from: #d5d5d5;
+@top-nav-bg-color-to: #f0f0f0;
+
+@success-color: limegreen;
+@error-color: crimson;
+@warning-color: orange;
+@unknown-color: crimson;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/38887860/tez-ui2/src/main/webapp/app/styles/page-layout.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/page-layout.less b/tez-ui2/src/main/webapp/app/styles/page-layout.less
new file mode 100644
index 0000000..ef00b40
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/styles/page-layout.less
@@ -0,0 +1,150 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@import "colors";
+@import "../../bower_components/snippet-ss/less/no";
+
+body, html, body > .ember-view {
+  height: 100%;
+  overflow: visible;
+  color: @text-color;
+
+  .san-helvetica;
+}
+body, html {
+  min-width: 1024px;
+}
+
+// Styles used in both standalone and wrapped modes
+.standalone, .wrapped {
+
+  .lr-margin {
+    margin: 0px 30px;
+  }
+
+  .header, .footer {
+    .content {
+      position: relative;
+
+      .breadcrumb-container {
+        position: absolute;
+        left: 70px;
+        right: 20px;
+        top: 9px;
+
+        .breadcrumb {
+          .no-border;
+
+          background-color: transparent;
+          margin-bottom: 0px;
+        }
+      }
+
+      .ui-info {
+        position: absolute;
+        right: 0px;
+        top: 0px;
+
+        span {
+          .left-delim;
+        }
+        span:first-child {
+          .no-border;
+        }
+      }
+    }
+  }
+
+  .header {
+    background-color: @bg-lite;
+
+    height: 40px;
+    border-bottom: 1px @border-color solid;
+    margin-bottom: 10px;
+
+    a.logo {
+      img {
+        margin-top: 2px;
+        height: 34px;
+        width: 70px;
+      }
+      &:hover {
+        text-decoration: none;
+      }
+    }
+
+    .ui-info {
+      background-color: @bg-lite;
+      margin-top: 10px;
+
+      .fa::before {
+        font-size: 20px;
+      }
+    }
+  }
+
+  .footer {
+    background-color: @white;
+    color: @text-color;
+
+    padding: 10px 0px;
+    margin: 0px;
+
+    border-top: 1px @border-color solid;
+
+    font-size: .8em;
+
+    .ui-info {
+      background-color: @white;
+    }
+  }
+}
+
+// TEZ UI in stand alone mode
+.standalone {
+  height: 100%;
+
+  a, .pagination > li > a, .btn-default, .clickable {
+    color: @logo-orange;
+  }
+
+  .footer, .footer-frame {
+    height: 40px;
+  }
+
+  .footer-pusher {
+    min-height: 100%;
+    height: auto !important;
+    height: 100%;
+    margin: 0 auto -40px; // Must be same as footer & footer-frame
+  }
+}
+
+// TEZ UI wrapped in a host like Ambari
+.wrapped {
+  .header {
+    border: 1px @border-lite solid;
+    border-radius: 5px;
+  }
+  .footer {
+    display: none;
+  }
+}
+
+
+

http://git-wip-us.apache.org/repos/asf/tez/blob/38887860/tez-ui2/src/main/webapp/app/styles/shared.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/shared.less b/tez-ui2/src/main/webapp/app/styles/shared.less
new file mode 100644
index 0000000..7fd4db9
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/styles/shared.less
@@ -0,0 +1,32 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@import "colors";
+
+b {
+  font-weight: bold;
+}
+.horizontal-half {
+  width: 50%;
+}
+
+.left-delim {
+  border-left: 1px solid @border-color;
+  margin-left: 5px;
+  padding-left: 5px;
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/38887860/tez-ui2/src/main/webapp/app/styles/tooltip.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/tooltip.less b/tez-ui2/src/main/webapp/app/styles/tooltip.less
new file mode 100644
index 0000000..8a21537
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/styles/tooltip.less
@@ -0,0 +1,24 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+.generic-tooltip {
+  padding: 3px 5px !important;
+  background: rgba(0,0,0,.8) !important;
+  color: white !important;
+  border: none !important;
+}

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

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

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

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

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

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

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

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

http://git-wip-us.apache.org/repos/asf/tez/blob/38887860/tez-ui2/src/main/webapp/tests/unit/controllers/application-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/application-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/application-test.js
new file mode 100644
index 0000000..6fe69df
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/application-test.js
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:application', 'Unit | Controller | application', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject();
+
+  assert.ok(controller.prefixedBreadcrumbs);
+});
+
+test('prefixedBreadcrumbs test', function(assert) {
+  let controller = this.subject(),
+      prefixedBreadcrumbs,
+      testText = "foo";
+
+  controller.breadcrumbs = [{
+    text: testText
+  }];
+  prefixedBreadcrumbs = controller.get("prefixedBreadcrumbs");
+
+  assert.equal(prefixedBreadcrumbs.length, 2);
+  assert.equal(prefixedBreadcrumbs[0].text, "All DAGs");
+  assert.equal(prefixedBreadcrumbs[1].text, testText);
+});

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

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


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

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


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

Branch: refs/heads/TEZ-2980
Commit: f1d1084279ff92ee664f59f603d51e09372403eb
Parents: fd75e33
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Wed Dec 30 20:51:21 2015 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Wed Jan 20 22:26:20 2016 +0530

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


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

http://git-wip-us.apache.org/repos/asf/tez/blob/f1d10842/tez-ui2/src/main/webapp/app/entities/entity.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/entities/entity.js b/tez-ui2/src/main/webapp/app/entities/entity.js
new file mode 100644
index 0000000..3d858c8
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/entities/entity.js
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+export default Ember.ObjectProxy.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/f1d10842/tez-ui2/src/main/webapp/app/initializers/entities.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/initializers/entities.js b/tez-ui2/src/main/webapp/app/initializers/entities.js
new file mode 100644
index 0000000..86d796c
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/initializers/entities.js
@@ -0,0 +1,28 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import registerWithContainer from "ember-cli-auto-register/register";
+
+export function initialize(application) {
+  registerWithContainer("entity", application);
+}
+
+export default {
+  name: 'entities',
+  initialize
+};

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

http://git-wip-us.apache.org/repos/asf/tez/blob/f1d10842/tez-ui2/src/main/webapp/blueprints/entity-test/files/tests/unit/entities/__name__-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/blueprints/entity-test/files/tests/unit/entities/__name__-test.js b/tez-ui2/src/main/webapp/blueprints/entity-test/files/tests/unit/entities/__name__-test.js
new file mode 100644
index 0000000..179c5e5
--- /dev/null
+++ b/tez-ui2/src/main/webapp/blueprints/entity-test/files/tests/unit/entities/__name__-test.js
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('entitie:<%= dasherizedModuleName %>', '<%= friendlyTestDescription %>', {
+  // Specify the other units that are required for this test.
+  // needs: ['entitie:foo']
+});
+
+// Replace this with your real tests.
+test('it exists', function(assert) {
+  let adapter = this.subject();
+  assert.ok(adapter);
+});

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

http://git-wip-us.apache.org/repos/asf/tez/blob/f1d10842/tez-ui2/src/main/webapp/blueprints/entity/files/app/entities/__name__.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/blueprints/entity/files/app/entities/__name__.js b/tez-ui2/src/main/webapp/blueprints/entity/files/app/entities/__name__.js
new file mode 100644
index 0000000..334868e
--- /dev/null
+++ b/tez-ui2/src/main/webapp/blueprints/entity/files/app/entities/__name__.js
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Entity from './entity';
+
+export default Entity.extend({
+});

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

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

http://git-wip-us.apache.org/repos/asf/tez/blob/f1d10842/tez-ui2/src/main/webapp/tests/unit/initializers/entities-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/initializers/entities-test.js b/tez-ui2/src/main/webapp/tests/unit/initializers/entities-test.js
new file mode 100644
index 0000000..ea54a11
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/initializers/entities-test.js
@@ -0,0 +1,40 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import EntitiesInitializer from '../../../initializers/entities';
+import { module, test } from 'qunit';
+
+let application;
+
+module('Unit | Initializer | entities', {
+  beforeEach() {
+    Ember.run(function() {
+      application = Ember.Application.create();
+      application.deferReadiness();
+    });
+  }
+});
+
+// Replace this with your real tests.
+test('it works', function(assert) {
+  EntitiesInitializer.initialize(application);
+
+  // you would normally confirm the results of the initializer here
+  assert.ok(true);
+});


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

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


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

Branch: refs/heads/TEZ-2980
Commit: 17ab6f557dcb8d9923d98953211cec6d03d51fd5
Parents: 976337a
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Tue Dec 29 14:58:28 2015 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Wed Jan 20 22:26:20 2016 +0530

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


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

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

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

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


[19/50] [abbrv] tez git commit: TEZ-3037. History URL should be set regardless of which history logging service is enabled. (hitesh)

Posted by sr...@apache.org.
TEZ-3037. History URL should be set regardless of which history logging service is enabled. (hitesh)


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

Branch: refs/heads/TEZ-2980
Commit: b47af5729360ce6d171baf624f3e97f946d0b733
Parents: 885ad73
Author: Hitesh Shah <hi...@apache.org>
Authored: Thu Jan 14 14:10:10 2016 -0800
Committer: Hitesh Shah <hi...@apache.org>
Committed: Thu Jan 14 14:10:10 2016 -0800

----------------------------------------------------------------------
 CHANGES.txt                                              |  2 ++
 .../org/apache/tez/dag/app/rm/TaskSchedulerManager.java  |  5 +----
 .../apache/tez/dag/app/rm/TestTaskSchedulerManager.java  | 11 +++--------
 3 files changed, 6 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/b47af572/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index a9dc823..d6a53aa 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -6,6 +6,7 @@ Release 0.8.3: Unreleased
 INCOMPATIBLE CHANGES
 
 ALL CHANGES:
+  TEZ-3037. History URL should be set regardless of which history logging service is enabled.
   TEZ-3032. DAG start time getting logged using system time instead of recorded time in startTime field.
 
 Release 0.8.2: 2016-01-19
@@ -313,6 +314,7 @@ INCOMPATIBLE CHANGES
   TEZ-2949. Allow duplicate dag names within session for Tez.
 
 ALL CHANGES
+  TEZ-3037. History URL should be set regardless of which history logging service is enabled.
   TEZ-3032. DAG start time getting logged using system time instead of recorded time in startTime field.
   TEZ-2129. Task and Attempt views should contain links to the logs
   TEZ-3025. InputInitializer creation should use the dag ugi.

http://git-wip-us.apache.org/repos/asf/tez/blob/b47af572/tez-dag/src/main/java/org/apache/tez/dag/app/rm/TaskSchedulerManager.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/rm/TaskSchedulerManager.java b/tez-dag/src/main/java/org/apache/tez/dag/app/rm/TaskSchedulerManager.java
index e4612b6..fa9fb81 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/rm/TaskSchedulerManager.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/rm/TaskSchedulerManager.java
@@ -943,14 +943,11 @@ public class TaskSchedulerManager extends AbstractService implements
     Configuration config = this.appContext.getAMConf();
     String historyUrl = "";
 
-    String loggingClass =  config.get(TezConfiguration.TEZ_HISTORY_LOGGING_SERVICE_CLASS, "");
     String historyUrlTemplate = config.get(TezConfiguration.TEZ_AM_TEZ_UI_HISTORY_URL_TEMPLATE,
             TezConfiguration.TEZ_AM_TEZ_UI_HISTORY_URL_TEMPLATE_DEFAULT);
     String historyUrlBase = config.get(TezConfiguration.TEZ_HISTORY_URL_BASE, "");
 
-
-    if (loggingClass.equals("org.apache.tez.dag.history.logging.ats.ATSHistoryLoggingService") &&
-        !historyUrlTemplate.isEmpty() &&
+    if (!historyUrlTemplate.isEmpty() &&
         !historyUrlBase.isEmpty()) {
       // replace the placeholders, while tolerating extra or missing "/" in input. replace all
       // instances of consecutive "/" with single (except for the http(s):// case

http://git-wip-us.apache.org/repos/asf/tez/blob/b47af572/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestTaskSchedulerManager.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestTaskSchedulerManager.java b/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestTaskSchedulerManager.java
index c62ff21..4d828e2 100644
--- a/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestTaskSchedulerManager.java
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestTaskSchedulerManager.java
@@ -381,17 +381,12 @@ public class TestTaskSchedulerManager {
   @Test (timeout = 5000)
   public void testHistoryUrlConf() throws Exception {
     Configuration conf = schedulerHandler.appContext.getAMConf();
-
-    // ensure history url is empty when timeline server is not the logging class
-    conf.set(TezConfiguration.TEZ_HISTORY_URL_BASE, "http://ui-host:9999");
-    assertTrue("".equals(schedulerHandler.getHistoryUrl()));
-
-    // ensure expansion of url happens
-    conf.set(TezConfiguration.TEZ_HISTORY_LOGGING_SERVICE_CLASS,
-        "org.apache.tez.dag.history.logging.ats.ATSHistoryLoggingService");
     final ApplicationId mockApplicationId = mock(ApplicationId.class);
     doReturn("TEST_APP_ID").when(mockApplicationId).toString();
     doReturn(mockApplicationId).when(mockAppContext).getApplicationID();
+
+    // ensure history url is empty when timeline server is not the logging class
+    conf.set(TezConfiguration.TEZ_HISTORY_URL_BASE, "http://ui-host:9999");
     assertTrue("http://ui-host:9999/#/tez-app/TEST_APP_ID"
         .equals(schedulerHandler.getHistoryUrl()));
 


[20/50] [abbrv] tez git commit: TEZ-3032. Addendum patch. DAG start time getting logged using system time instead of recorded time in startTime field. (hitesh)

Posted by sr...@apache.org.
TEZ-3032. Addendum patch. DAG start time getting logged using system time instead of recorded time in startTime field. (hitesh)


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

Branch: refs/heads/TEZ-2980
Commit: d0348b03b84bc83e0fc503e424f7ae57fa86cc90
Parents: b47af57
Author: Hitesh Shah <hi...@apache.org>
Authored: Thu Jan 14 14:59:59 2016 -0800
Committer: Hitesh Shah <hi...@apache.org>
Committed: Thu Jan 14 14:59:59 2016 -0800

----------------------------------------------------------------------
 .../src/main/java/org/apache/tez/dag/app/dag/impl/DAGImpl.java    | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/d0348b03/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/DAGImpl.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/DAGImpl.java b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/DAGImpl.java
index 139fd51..dd6f834 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/DAGImpl.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/DAGImpl.java
@@ -1245,9 +1245,8 @@ public class DAGImpl implements org.apache.tez.dag.app.dag.DAG,
     if (recoveryData == null
         || recoveryData.getDAGFinishedEvent() == null) {
       Map<String, Integer> taskStats = constructTaskStats(getDAGProgress());
-
       DAGFinishedEvent finishEvt = new DAGFinishedEvent(dagId, startTime,
-          clock.getTime(), state,
+          finishTime, state,
           StringUtils.join(getDiagnostics(), LINE_SEPARATOR),
           counters, this.userName, this.dagName, taskStats,
           this.appContext.getApplicationAttemptId(), this.jobPlan);


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

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


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

Branch: refs/heads/TEZ-2980
Commit: 869d712dd2694ba0ff5d4d8ad45305f3a0936b02
Parents: 98cb99d
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Tue Jan 19 16:07:26 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Wed Jan 20 22:30:07 2016 +0530

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


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

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

http://git-wip-us.apache.org/repos/asf/tez/blob/869d712d/tez-ui2/src/main/webapp/app/controllers/app/configs.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/app/configs.js b/tez-ui2/src/main/webapp/app/controllers/app/configs.js
new file mode 100644
index 0000000..517d43b
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/app/configs.js
@@ -0,0 +1,60 @@
+/*global more*/
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import TablePageController from '../table-page';
+import ColumnDefinition from 'em-table/utils/column-definition';
+
+var MoreObject = more.Object;
+
+export default TablePageController.extend({
+  searchText: "tez",
+
+  breadcrumbs: [{
+    text: "Configurations",
+    routeName: "app.configs",
+  }],
+
+  columns: ColumnDefinition.make([{
+    id: 'configName',
+    headerTitle: 'Configuration Name',
+    contentPath: 'configName',
+  }, {
+    id: 'configValue',
+    headerTitle: 'Configuration Value',
+    contentPath: 'configValue',
+  }]),
+
+  configs: Ember.computed("model.configs", function () {
+    var configs = this.get("model.configs"),
+        configRows = [];
+
+    if(configs) {
+      MoreObject.forEach(configs, function (key, value) {
+        configRows.push(Ember.Object.create({
+          configName: key,
+          configValue: value
+        }));
+      });
+    }
+
+    return Ember.A(configRows);
+  })
+});

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

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

http://git-wip-us.apache.org/repos/asf/tez/blob/869d712d/tez-ui2/src/main/webapp/app/routes/app/configs.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/app/configs.js b/tez-ui2/src/main/webapp/app/routes/app/configs.js
new file mode 100644
index 0000000..b6768fa
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/app/configs.js
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  title: "Application Details",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (/*value, query*/) {
+    return this.get("loader").queryRecord('app', this.modelFor("app").id);
+  },
+});

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

http://git-wip-us.apache.org/repos/asf/tez/blob/869d712d/tez-ui2/src/main/webapp/app/templates/app/configs.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/app/configs.hbs b/tez-ui2/src/main/webapp/app/templates/app/configs.hbs
new file mode 100644
index 0000000..8617c81
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/app/configs.hbs
@@ -0,0 +1,34 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+}}
+
+{{#if loaded}}
+  {{em-table
+  columns=columns
+  rows=configs
+
+  rowCount=configs.length
+  definition=definition
+
+  enablePagination=false
+
+  searchAction="searchChanged"
+  sortAction="sortChanged"
+  }}
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

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

http://git-wip-us.apache.org/repos/asf/tez/blob/869d712d/tez-ui2/src/main/webapp/tests/unit/controllers/app/configs-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/app/configs-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/app/configs-test.js
new file mode 100644
index 0000000..c04e5c2
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/app/configs-test.js
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:app/configs', 'Unit | Controller | app/configs', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+  assert.ok(controller.columns);
+  assert.ok(controller.configs);
+
+  assert.ok(controller.get("searchText"), "tez");
+});

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

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

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

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

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

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

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

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

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

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

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

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

http://git-wip-us.apache.org/repos/asf/tez/blob/869d712d/tez-ui2/src/main/webapp/tests/unit/routes/app/configs-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/app/configs-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/app/configs-test.js
new file mode 100644
index 0000000..9ca6a7a
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/app/configs-test.js
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:app/configs', 'Unit | Route | app/configs', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+  assert.ok(route.load);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});

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

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

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

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

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

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

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

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

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

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

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

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


[08/50] [abbrv] tez git commit: TEZ-3017. HistoryACLManager does not have a close method for cleanup (bikas)

Posted by sr...@apache.org.
TEZ-3017. HistoryACLManager does not have a close method for cleanup (bikas)


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

Branch: refs/heads/TEZ-2980
Commit: 9816a49bba0c89651f9b5bb66ac20f4eb0364ef2
Parents: 5334d62
Author: Bikas Saha <bi...@apache.org>
Authored: Tue Dec 29 01:54:00 2015 -0800
Committer: Bikas Saha <bi...@apache.org>
Committed: Tue Dec 29 01:54:00 2015 -0800

----------------------------------------------------------------------
 CHANGES.txt                                              |  2 ++
 .../src/main/java/org/apache/tez/client/TezClient.java   |  4 ++++
 .../tez/common/security/HistoryACLPolicyManager.java     |  5 ++++-
 .../test/java/org/apache/tez/client/TestTezClient.java   |  6 +++++-
 .../dag/history/ats/acls/ATSHistoryACLPolicyManager.java | 11 ++++++++---
 .../tez/dag/history/ats/acls/TestATSHistoryWithACLs.java |  9 ++++++---
 .../history/logging/ats/ATSHistoryLoggingService.java    |  3 +++
 7 files changed, 32 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/9816a49b/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 546c3fd..ce35fd1 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -11,6 +11,7 @@ INCOMPATIBLE CHANGES
   TEZ-2972. Avoid task rescheduling when a node turns unhealthy
 
 ALL CHANGES:
+  TEZ-3017. HistoryACLManager does not have a close method for cleanup
   TEZ-2914. Ability to limit vertex concurrency
   TEZ-3011. Link Vertex Name in Dag Tasks/Task Attempts to Vertex
   TEZ-3006. Remove unused import in TestHistoryParser.
@@ -300,6 +301,7 @@ INCOMPATIBLE CHANGES
   TEZ-2949. Allow duplicate dag names within session for Tez.
 
 ALL CHANGES
+  TEZ-3017. HistoryACLManager does not have a close method for cleanup
   TEZ-2914. Ability to limit vertex concurrency
   TEZ-2918. Make progress notifications in IOs
   TEZ-2952. NPE in TestOnFileUnorderedKVOutput

http://git-wip-us.apache.org/repos/asf/tez/blob/9816a49b/tez-api/src/main/java/org/apache/tez/client/TezClient.java
----------------------------------------------------------------------
diff --git a/tez-api/src/main/java/org/apache/tez/client/TezClient.java b/tez-api/src/main/java/org/apache/tez/client/TezClient.java
index ff131e0..fc98d1a 100644
--- a/tez-api/src/main/java/org/apache/tez/client/TezClient.java
+++ b/tez-api/src/main/java/org/apache/tez/client/TezClient.java
@@ -558,6 +558,10 @@ public class TezClient {
    */
   public synchronized void stop() throws TezException, IOException {
     try {
+      if (historyACLPolicyManager != null) {
+        historyACLPolicyManager.close();
+      }
+
       if (sessionStarted) {
         LOG.info("Shutting down Tez Session"
             + ", sessionName=" + clientName

http://git-wip-us.apache.org/repos/asf/tez/blob/9816a49b/tez-api/src/main/java/org/apache/tez/common/security/HistoryACLPolicyManager.java
----------------------------------------------------------------------
diff --git a/tez-api/src/main/java/org/apache/tez/common/security/HistoryACLPolicyManager.java b/tez-api/src/main/java/org/apache/tez/common/security/HistoryACLPolicyManager.java
index dea89cc..fc0f57c 100644
--- a/tez-api/src/main/java/org/apache/tez/common/security/HistoryACLPolicyManager.java
+++ b/tez-api/src/main/java/org/apache/tez/common/security/HistoryACLPolicyManager.java
@@ -69,5 +69,8 @@ public interface HistoryACLPolicyManager extends Configurable {
 
   public void updateTimelineEntityDomain(Object timelineEntity, String domainId);
 
-
+  /**
+   * Call this to stop and clean up
+   */
+  public void close();
 }

http://git-wip-us.apache.org/repos/asf/tez/blob/9816a49b/tez-api/src/test/java/org/apache/tez/client/TestTezClient.java
----------------------------------------------------------------------
diff --git a/tez-api/src/test/java/org/apache/tez/client/TestTezClient.java b/tez-api/src/test/java/org/apache/tez/client/TestTezClient.java
index 9adb9bd..c2531c6 100644
--- a/tez-api/src/test/java/org/apache/tez/client/TestTezClient.java
+++ b/tez-api/src/test/java/org/apache/tez/client/TestTezClient.java
@@ -56,6 +56,7 @@ import org.apache.hadoop.yarn.exceptions.YarnException;
 import org.apache.tez.common.counters.LimitExceededException;
 import org.apache.tez.common.counters.Limits;
 import org.apache.tez.common.counters.TezCounters;
+import org.apache.tez.common.security.HistoryACLPolicyManager;
 import org.apache.tez.dag.api.DAG;
 import org.apache.tez.dag.api.PreWarmVertex;
 import org.apache.tez.dag.api.ProcessorDescriptor;
@@ -162,10 +163,12 @@ public class TestTezClient {
         LocalResourceType.FILE, LocalResourceVisibility.PUBLIC, 1, 1));
     
     TezClientForTest client = configureAndCreateTezClient(lrs, isSession, null);
-    
+    HistoryACLPolicyManager mockAcl = mock(HistoryACLPolicyManager.class);
+
     ArgumentCaptor<ApplicationSubmissionContext> captor = ArgumentCaptor.forClass(ApplicationSubmissionContext.class);
     when(client.mockYarnClient.getApplicationReport(client.mockAppId).getYarnApplicationState())
     .thenReturn(YarnApplicationState.RUNNING);
+    client.setUpHistoryAclManager(mockAcl);
     client.start();
     verify(client.mockYarnClient, times(1)).init((Configuration)any());
     verify(client.mockYarnClient, times(1)).start();
@@ -263,6 +266,7 @@ public class TestTezClient {
           (ShutdownSessionRequestProto) any());
     }
     verify(client.mockYarnClient, times(1)).stop();
+    verify(mockAcl, times(1)).close();
   }
   
   @Test (timeout=5000)

http://git-wip-us.apache.org/repos/asf/tez/blob/9816a49b/tez-plugins/tez-yarn-timeline-history-with-acls/src/main/java/org/apache/tez/dag/history/ats/acls/ATSHistoryACLPolicyManager.java
----------------------------------------------------------------------
diff --git a/tez-plugins/tez-yarn-timeline-history-with-acls/src/main/java/org/apache/tez/dag/history/ats/acls/ATSHistoryACLPolicyManager.java b/tez-plugins/tez-yarn-timeline-history-with-acls/src/main/java/org/apache/tez/dag/history/ats/acls/ATSHistoryACLPolicyManager.java
index 3fa3db6..91ffe7b 100644
--- a/tez-plugins/tez-yarn-timeline-history-with-acls/src/main/java/org/apache/tez/dag/history/ats/acls/ATSHistoryACLPolicyManager.java
+++ b/tez-plugins/tez-yarn-timeline-history-with-acls/src/main/java/org/apache/tez/dag/history/ats/acls/ATSHistoryACLPolicyManager.java
@@ -24,6 +24,7 @@ import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.hadoop.service.Service;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.apache.hadoop.conf.Configuration;
@@ -32,7 +33,6 @@ import org.apache.hadoop.yarn.api.records.ApplicationId;
 import org.apache.hadoop.yarn.api.records.timeline.TimelineDomain;
 import org.apache.hadoop.yarn.api.records.timeline.TimelineEntity;
 import org.apache.hadoop.yarn.client.api.TimelineClient;
-import org.apache.hadoop.yarn.exceptions.YarnException;
 import org.apache.tez.common.security.ACLConfigurationParser;
 import org.apache.tez.common.security.ACLManager;
 import org.apache.tez.common.security.ACLType;
@@ -43,8 +43,6 @@ import org.apache.hadoop.yarn.conf.YarnConfiguration;
 import org.apache.tez.dag.api.TezConfiguration;
 import org.apache.tez.dag.api.TezUncheckedException;
 
-import com.google.common.annotations.VisibleForTesting;
-
 public class ATSHistoryACLPolicyManager implements HistoryACLPolicyManager {
 
   private final static Logger LOG = LoggerFactory.getLogger(ATSHistoryACLPolicyManager.class);
@@ -250,4 +248,11 @@ public class ATSHistoryACLPolicyManager implements HistoryACLPolicyManager {
     entity.setDomainId(domainId);
   }
 
+  @Override
+  public void close() {
+    if (timelineClient != null && timelineClient.isInState(Service.STATE.STARTED)) {
+      timelineClient.stop();
+    }
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/tez/blob/9816a49b/tez-plugins/tez-yarn-timeline-history-with-acls/src/test/java/org/apache/tez/dag/history/ats/acls/TestATSHistoryWithACLs.java
----------------------------------------------------------------------
diff --git a/tez-plugins/tez-yarn-timeline-history-with-acls/src/test/java/org/apache/tez/dag/history/ats/acls/TestATSHistoryWithACLs.java b/tez-plugins/tez-yarn-timeline-history-with-acls/src/test/java/org/apache/tez/dag/history/ats/acls/TestATSHistoryWithACLs.java
index eaf24d3..512913d 100644
--- a/tez-plugins/tez-yarn-timeline-history-with-acls/src/test/java/org/apache/tez/dag/history/ats/acls/TestATSHistoryWithACLs.java
+++ b/tez-plugins/tez-yarn-timeline-history-with-acls/src/test/java/org/apache/tez/dag/history/ats/acls/TestATSHistoryWithACLs.java
@@ -22,6 +22,7 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.*;
 
 import java.io.IOException;
 import java.util.Collection;
@@ -74,9 +75,6 @@ import com.sun.jersey.api.client.WebResource;
 
 import org.mockito.Matchers;
 
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.doThrow;
-
 public class TestATSHistoryWithACLs {
 
   private static final Logger LOG = LoggerFactory.getLogger(TestATSHistoryWithACLs.class);
@@ -385,7 +383,9 @@ public class TestATSHistoryWithACLs {
     }
     dagLogging = dag2.getDagConf().get(TezConfiguration.TEZ_DAG_HISTORY_LOGGING_ENABLED);
     Assert.assertNull(dagLogging);
+    myAclPolicyManager.timelineClient = spy(myAclPolicyManager.timelineClient);
     tezSession.stop();
+    verify(myAclPolicyManager.timelineClient, times(1)).stop();
   }
   
 /**
@@ -465,7 +465,10 @@ public class TestATSHistoryWithACLs {
     }
     dagLogging = dag2.getDagConf().get(TezConfiguration.TEZ_DAG_HISTORY_LOGGING_ENABLED);
     Assert.assertNull(dagLogging);
+    myAclPolicyManager.timelineClient = spy(myAclPolicyManager.timelineClient);
     tezClient.stop();
+    verify(myAclPolicyManager.timelineClient, times(1)).stop();
+
   }
   /**
    * Test Disable Logging for all dags in a session 

http://git-wip-us.apache.org/repos/asf/tez/blob/9816a49b/tez-plugins/tez-yarn-timeline-history/src/main/java/org/apache/tez/dag/history/logging/ats/ATSHistoryLoggingService.java
----------------------------------------------------------------------
diff --git a/tez-plugins/tez-yarn-timeline-history/src/main/java/org/apache/tez/dag/history/logging/ats/ATSHistoryLoggingService.java b/tez-plugins/tez-yarn-timeline-history/src/main/java/org/apache/tez/dag/history/logging/ats/ATSHistoryLoggingService.java
index 6ea21e2..a66da24 100644
--- a/tez-plugins/tez-yarn-timeline-history/src/main/java/org/apache/tez/dag/history/logging/ats/ATSHistoryLoggingService.java
+++ b/tez-plugins/tez-yarn-timeline-history/src/main/java/org/apache/tez/dag/history/logging/ats/ATSHistoryLoggingService.java
@@ -243,6 +243,9 @@ public class ATSHistoryLoggingService extends HistoryLoggingService {
           + ", eventQueueBacklog=" + eventQueue.size());
     }
     timelineClient.stop();
+    if (historyACLPolicyManager != null) {
+      historyACLPolicyManager.close();
+    }
   }
 
   private void getEventBatch(List<DAGHistoryEvent> events) throws InterruptedException {


[26/50] [abbrv] tez git commit: TEZ-2982. Tez UI: Create tez-ui2 directory and get a basic dummy page working in ember 2.2 (sree)

Posted by sr...@apache.org.
TEZ-2982. Tez UI: Create tez-ui2 directory and get a basic dummy page working in ember 2.2 (sree)


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

Branch: refs/heads/TEZ-2980
Commit: 976337a5697ce8bbd503b18af6415d6f0d109d5d
Parents: cc06400
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Tue Dec 22 23:25:06 2015 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Wed Jan 20 22:26:20 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |   2 +
 pom.xml                                         |   1 +
 tez-ui2/README.md                               |  37 ++
 tez-ui2/findbugs-exclude.xml                    |  16 +
 tez-ui2/pom.xml                                 | 153 ++++++++
 tez-ui2/src/main/resources/META-INF/LICENSE.txt | 386 +++++++++++++++++++
 tez-ui2/src/main/resources/META-INF/NOTICE.txt  |  10 +
 tez-ui2/src/main/webapp/.bowerrc                |   4 +
 tez-ui2/src/main/webapp/.editorconfig           |  34 ++
 tez-ui2/src/main/webapp/.ember-cli              |   9 +
 tez-ui2/src/main/webapp/.gitignore              |  18 +
 tez-ui2/src/main/webapp/.jshintrc               |  32 ++
 tez-ui2/src/main/webapp/.travis.yml             |  23 ++
 tez-ui2/src/main/webapp/.watchmanconfig         |   3 +
 tez-ui2/src/main/webapp/README.md               |  41 ++
 tez-ui2/src/main/webapp/WEB-INF/web.xml         |  25 ++
 tez-ui2/src/main/webapp/app/app.js              |  18 +
 tez-ui2/src/main/webapp/app/index.html          |  25 ++
 tez-ui2/src/main/webapp/app/router.js           |  11 +
 tez-ui2/src/main/webapp/app/styles/app.less     |   1 +
 .../main/webapp/app/templates/application.hbs   |   3 +
 tez-ui2/src/main/webapp/bower.json              |  15 +
 tez-ui2/src/main/webapp/config/environment.js   |  47 +++
 tez-ui2/src/main/webapp/ember-cli-build.js      |  24 ++
 tez-ui2/src/main/webapp/package.json            |  45 +++
 tez-ui2/src/main/webapp/public/crossdomain.xml  |  15 +
 tez-ui2/src/main/webapp/public/robots.txt       |   3 +
 tez-ui2/src/main/webapp/testem.json             |  12 +
 tez-ui2/src/main/webapp/tests/.jshintrc         |  52 +++
 .../main/webapp/tests/helpers/destroy-app.js    |   5 +
 .../tests/helpers/module-for-acceptance.js      |  23 ++
 .../src/main/webapp/tests/helpers/resolver.js   |  11 +
 .../src/main/webapp/tests/helpers/start-app.js  |  18 +
 tez-ui2/src/main/webapp/tests/index.html        |  34 ++
 tez-ui2/src/main/webapp/tests/test-helper.js    |   6 +
 35 files changed, 1162 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
new file mode 100644
index 0000000..7130897
--- /dev/null
+++ b/TEZ-2980-CHANGES.txt
@@ -0,0 +1,2 @@
+ALL CHANGES:
+  TEZ-2982. Tez UI: Create tez-ui2 directory and get a basic dummy page working in ember 2.2

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 78e28f5..26abc24 100644
--- a/pom.xml
+++ b/pom.xml
@@ -702,6 +702,7 @@
     <module>tez-dag</module>
     <module>tez-ext-service-tests</module>
     <module>tez-ui</module>
+    <module>tez-ui2</module>
     <module>tez-plugins</module>
     <module>tez-tools</module>
     <module>hadoop-shim-impls</module>

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/README.md
----------------------------------------------------------------------
diff --git a/tez-ui2/README.md b/tez-ui2/README.md
new file mode 100644
index 0000000..a10f460
--- /dev/null
+++ b/tez-ui2/README.md
@@ -0,0 +1,37 @@
+# Tez-ui
+
+The Tez UI is an ember based web application that provides visualization of Tez applications
+running on the Apache Hadoop YARN framework.
+
+For more information on Tez and the Tez UI - the [tez homepage](http://tez.apache.org/ "Apache Tez Homepage").
+
+## Prerequisites
+
+You will need the following things properly installed on your computer.
+
+* [Git](http://git-scm.com/)
+* [Node.js](http://nodejs.org/) (with NPM)
+* [Bower](http://bower.io/)
+* [Ember CLI](http://www.ember-cli.com/)
+* [PhantomJS](http://phantomjs.org/)
+
+## Installation
+
+* `git clone <repository-url>` this repository
+* In tez/tez-ui2/src/main/webapp
+* `npm install`
+
+## Running / Development
+
+* `ember server`
+* Visit your app at [http://localhost:4200](http://localhost:4200).
+
+### Running Tests
+
+* `ember test`
+* `ember test --server`
+
+### Building
+
+* `ember build` (development)
+* `ember build --environment production` (production)

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/findbugs-exclude.xml
----------------------------------------------------------------------
diff --git a/tez-ui2/findbugs-exclude.xml b/tez-ui2/findbugs-exclude.xml
new file mode 100644
index 0000000..5b11308
--- /dev/null
+++ b/tez-ui2/findbugs-exclude.xml
@@ -0,0 +1,16 @@
+<!--
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License. See accompanying LICENSE file.
+-->
+<FindBugsFilter>
+
+</FindBugsFilter>

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/pom.xml
----------------------------------------------------------------------
diff --git a/tez-ui2/pom.xml b/tez-ui2/pom.xml
new file mode 100644
index 0000000..2b7503c
--- /dev/null
+++ b/tez-ui2/pom.xml
@@ -0,0 +1,153 @@
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.tez</groupId>
+    <artifactId>tez</artifactId>
+    <version>0.8.2-SNAPSHOT</version>
+  </parent>
+  <artifactId>tez-ui2</artifactId>
+  <packaging>war</packaging>
+
+  <properties>
+    <webappDir>src/main/webapp</webappDir>
+    <node.executable>${basedir}/src/main/webapp/node/node</node.executable>
+    <nodeVersion>v0.12.2</nodeVersion>
+    <npmVersion>2.10.0</npmVersion>
+    <skipTests>false</skipTests>
+  </properties>
+
+  <build>
+    <plugins>
+
+      <!-- Apache RAT -->
+      <plugin>
+        <groupId>org.apache.rat</groupId>
+        <artifactId>apache-rat-plugin</artifactId>
+        <configuration>
+          <excludes>
+            <exclude>src/main/webapp/node/**/*</exclude>
+            <exclude>src/main/webapp/node_modules/**/*</exclude>
+            <exclude>src/main/webapp/bower_components/**/*</exclude>
+            <exclude>src/main/webapp/.tmp/</exclude>
+            <exclude>src/main/webapp/dist/**/*</exclude>
+            <exclude>src/main/webapp/.bowerrc</exclude>
+            <exclude>src/main/webapp/.editorconfig</exclude>
+            <exclude>src/main/webapp/.ember-cli</exclude>
+            <exclude>src/main/webapp/.gitignore</exclude>
+            <exclude>src/main/webapp/.jshintrc</exclude>
+            <exclude>src/main/webapp/.travis.yml</exclude>
+            <exclude>src/main/webapp/.watchmanconfig</exclude>
+            <exclude>src/main/webapp/bower.json</exclude>
+            <exclude>src/main/webapp/ember-cli-build.js</exclude>
+            <exclude>src/main/webapp/package.json</exclude>
+            <exclude>src/main/webapp/testem.js</exclude>
+          </excludes>
+        </configuration>
+      </plugin>
+
+      <!-- NPM Install -->
+      <plugin>
+        <groupId>com.github.eirslett</groupId>
+        <artifactId>frontend-maven-plugin</artifactId>
+        <configuration>
+          <workingDirectory>${webappDir}</workingDirectory>
+        </configuration>
+        <executions>
+          <execution>
+            <phase>generate-sources</phase>
+            <id>install node and npm</id>
+            <goals>
+              <goal>install-node-and-npm</goal>
+            </goals>
+            <configuration>
+              <nodeVersion>${nodeVersion}</nodeVersion>
+              <npmVersion>${npmVersion}</npmVersion>
+            </configuration>
+          </execution>
+          <execution>
+            <phase>generate-sources</phase>
+            <id>npm install</id>
+            <goals>
+              <goal>npm</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+
+      <!-- Bower install & grunt build-->
+      <plugin>
+        <artifactId>exec-maven-plugin</artifactId>
+        <groupId>org.codehaus.mojo</groupId>
+        <executions>
+          <execution>
+            <id>ember build</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>exec</goal>
+            </goals>
+            <configuration>
+              <workingDirectory>${webappDir}</workingDirectory>
+              <executable>${node.executable}</executable>
+              <arguments>
+                <argument>node_modules/ember-cli/bin/ember</argument>
+                <argument>build</argument>
+                <argument>-prod</argument>
+              </arguments>
+            </configuration>
+          </execution>
+          <execution>
+            <id>ember test</id>
+            <phase>generate-resources</phase>
+            <goals>
+              <goal>exec</goal>
+            </goals>
+            <configuration>
+              <skip>${skipTests}</skip>
+              <workingDirectory>${webappDir}</workingDirectory>
+              <executable>${node.executable}</executable>
+              <arguments>
+                <argument>node_modules/ember-cli/bin/ember</argument>
+                <argument>test</argument>
+              </arguments>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+
+      <!-- Package into war -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-war-plugin</artifactId>
+        <configuration>
+          <webXml>${basedir}/src/main/webapp/WEB-INF/web.xml</webXml>
+          <warSourceDirectory>${webappDir}/dist</warSourceDirectory>
+          <webResources>
+            <resource>
+              <filtering>false</filtering>
+              <directory>${basedir}/src/main/resources/</directory>
+            </resource>
+          </webResources>
+        </configuration>
+      </plugin>
+
+    </plugins>
+  </build>
+</project>

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/src/main/resources/META-INF/LICENSE.txt
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/resources/META-INF/LICENSE.txt b/tez-ui2/src/main/resources/META-INF/LICENSE.txt
new file mode 100644
index 0000000..4f0c9d4
--- /dev/null
+++ b/tez-ui2/src/main/resources/META-INF/LICENSE.txt
@@ -0,0 +1,386 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+=======================================================================
+Apache Tez Subcomponents:
+
+The Apache Tez project contains subcomponents with separate copyright
+notices and license terms. Your use of the source code for the these
+subcomponents is subject to the terms and conditions of the following
+licenses.
+
+-----------------------------------------------------------------------
+ The MIT License
+-----------------------------------------------------------------------
+
+The Apache TEZ tez-ui bundles the following files under the MIT License:
+
+ - antiscroll v1.0.0 (https://github.com/LearnBoost/antiscroll) - Copyright (c) 2011 Guillermo Rauch <gu...@learnboost.com>
+ - bootstrap v3.3.1 (http://getbootstrap.com) - Copyright (c) 2011-2014 Twitter, Inc
+ - ember v1.7.0 (http://emberjs.com/) - Copyright (c) 2014 Yehuda Katz, Tom Dale and Ember.js contributors
+ - ember-data v1.0.0-beta.11 (https://github.com/emberjs/data) - Copyright (C) 2011-2014 Tilde, Inc. and contributors, Portions Copyright (C) 2011 LivingSocial Inc.
+ - ember-json-mapper v1.0.0 (https://github.com/onechiporenko/ember-json-mapper) - Copyright (c) 2014 onechiporenko
+ - font-awesome css/less files v4.2.0 (http://fontawesome.io/) - Created by Dave Gandy
+ - handlebars v1.3.0 (http://handlebarsjs.com/) - Copyright (C) 2011-2014 by Yehuda Katz
+ - jquery v1.10.2 (http://jquery.org) - Copyright 2005, 2014 jQuery Foundation and other contributors
+ - jquery-mousewheel v3.1.12 (https://github.com/jquery/jquery-mousewheel) - Copyright 2006, 2014 jQuery Foundation and other contributors, https://jquery.org/
+ - jquery-ui v1.11 (http://jqueryui.com/) - Copyright 2014 jQuery Foundation and other contributors
+ - moment v2.10.6 (http://momentjs.com/) - Copyright (c) 2011-2015 Tim Wood, Iskren Chernev, Moment.js contributors
+ - moment-timezone v0.4.0 (http://momentjs.com/timezone/) - Copyright (c) 2014 Tim Wood
+ - FileSaver.js master branch #24b303f49213b905ec9062b708f7cd43d56a5dde (https://github.com/eligrey/FileSaver.js) authors : Eli Grey.
+ - CodeMirror 5.2.0 (https://codemirror.net/) authors: Copyright (C) 2015 by Marijn Haverbeke <ma...@gmail.com> and others
+
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+-----------------------------------------------------------------------
+ BSD-style Licenses
+-----------------------------------------------------------------------
+
+The Apache Tez tez-ui bundles the following files under BSD licenses:
+
+(3-clause BSD license)
+ - D3 v3.4.11 (http://d3js.org/) - Copyright (c) 2010-2014, Michael Bostock
+ - ember-table v0.2.2 (https://github.com/Addepar/ember-table) - Copyright © 2012 Addepar, Inc. All Rights Reserved.
+ - zip.js master branch #bfd76c66293305faaf9fcbb65b5ff7fe2dbe621a (https://github.com/gildas-lormeau/zip.js)
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this list
+   of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice, this
+   list of conditions and the following disclaimer in the documentation and/or
+   other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its contributors may
+   be used to endorse or promote products derived from this software without
+   specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+-----------------------------------------------------------------------
+ The Open Font License
+-----------------------------------------------------------------------
+
+The Apache Tez tez-ui bundles the following fonts under the
+SIL Open Font License v1.1 (OFT) - http://scripts.sil.org/OFL
+
+ - font-awesome fonts v4.2.0 (http://fontawesome.io/) - Created by Dave Gandy
+
+SIL OPEN FONT LICENSE
+
+Version 1.1 - 26 February 2007
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting — in part or in whole — any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
+

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/src/main/resources/META-INF/NOTICE.txt
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/resources/META-INF/NOTICE.txt b/tez-ui2/src/main/resources/META-INF/NOTICE.txt
new file mode 100644
index 0000000..9a6feaf
--- /dev/null
+++ b/tez-ui2/src/main/resources/META-INF/NOTICE.txt
@@ -0,0 +1,10 @@
+Apache Tez
+Copyright (c) 2015 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+This tez-ui bundle includes fonts protected under the Open Font License.
+These fonts can only be distributed as part of a piece of software, but
+not individually. See the license for details.  http://scripts.sil.org/OFL.
+More information on included fonts can be found in the LICENSE file.

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/src/main/webapp/.bowerrc
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/.bowerrc b/tez-ui2/src/main/webapp/.bowerrc
new file mode 100644
index 0000000..959e169
--- /dev/null
+++ b/tez-ui2/src/main/webapp/.bowerrc
@@ -0,0 +1,4 @@
+{
+  "directory": "bower_components",
+  "analytics": false
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/src/main/webapp/.editorconfig
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/.editorconfig b/tez-ui2/src/main/webapp/.editorconfig
new file mode 100644
index 0000000..47c5438
--- /dev/null
+++ b/tez-ui2/src/main/webapp/.editorconfig
@@ -0,0 +1,34 @@
+# EditorConfig helps developers define and maintain consistent
+# coding styles between different editors and IDEs
+# editorconfig.org
+
+root = true
+
+
+[*]
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+indent_style = space
+indent_size = 2
+
+[*.js]
+indent_style = space
+indent_size = 2
+
+[*.hbs]
+insert_final_newline = false
+indent_style = space
+indent_size = 2
+
+[*.css]
+indent_style = space
+indent_size = 2
+
+[*.html]
+indent_style = space
+indent_size = 2
+
+[*.{diff,md}]
+trim_trailing_whitespace = false

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/src/main/webapp/.ember-cli
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/.ember-cli b/tez-ui2/src/main/webapp/.ember-cli
new file mode 100644
index 0000000..ee64cfe
--- /dev/null
+++ b/tez-ui2/src/main/webapp/.ember-cli
@@ -0,0 +1,9 @@
+{
+  /**
+    Ember CLI sends analytics information by default. The data is completely
+    anonymous, but there are times when you might want to disable this behavior.
+
+    Setting `disableAnalytics` to true will prevent any data from being sent.
+  */
+  "disableAnalytics": false
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/src/main/webapp/.gitignore
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/.gitignore b/tez-ui2/src/main/webapp/.gitignore
new file mode 100644
index 0000000..8470f82
--- /dev/null
+++ b/tez-ui2/src/main/webapp/.gitignore
@@ -0,0 +1,18 @@
+# See http://help.github.com/ignore-files/ for more about ignoring files.
+
+# compiled output
+/dist
+/tmp
+
+# dependencies
+/node
+/node_modules
+/bower_components
+
+# misc
+/.sass-cache
+/connect.lock
+/coverage/*
+/libpeerconnection.log
+npm-debug.log
+testem.log

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/src/main/webapp/.jshintrc
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/.jshintrc b/tez-ui2/src/main/webapp/.jshintrc
new file mode 100644
index 0000000..08096ef
--- /dev/null
+++ b/tez-ui2/src/main/webapp/.jshintrc
@@ -0,0 +1,32 @@
+{
+  "predef": [
+    "document",
+    "window",
+    "-Promise"
+  ],
+  "browser": true,
+  "boss": true,
+  "curly": true,
+  "debug": false,
+  "devel": true,
+  "eqeqeq": true,
+  "evil": true,
+  "forin": false,
+  "immed": false,
+  "laxbreak": false,
+  "newcap": true,
+  "noarg": true,
+  "noempty": false,
+  "nonew": false,
+  "nomen": false,
+  "onevar": false,
+  "plusplus": false,
+  "regexp": false,
+  "undef": true,
+  "sub": true,
+  "strict": false,
+  "white": false,
+  "eqnull": true,
+  "esnext": true,
+  "unused": true
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/src/main/webapp/.travis.yml
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/.travis.yml b/tez-ui2/src/main/webapp/.travis.yml
new file mode 100644
index 0000000..66dd107
--- /dev/null
+++ b/tez-ui2/src/main/webapp/.travis.yml
@@ -0,0 +1,23 @@
+---
+language: node_js
+node_js:
+  - "0.12"
+
+sudo: false
+
+cache:
+  directories:
+    - node_modules
+
+before_install:
+  - export PATH=/usr/local/phantomjs-2.0.0/bin:$PATH
+  - "npm config set spin false"
+  - "npm install -g npm@^2"
+
+install:
+  - npm install -g bower
+  - npm install
+  - bower install
+
+script:
+  - npm test

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/src/main/webapp/.watchmanconfig
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/.watchmanconfig b/tez-ui2/src/main/webapp/.watchmanconfig
new file mode 100644
index 0000000..e7834e3
--- /dev/null
+++ b/tez-ui2/src/main/webapp/.watchmanconfig
@@ -0,0 +1,3 @@
+{
+  "ignore_dirs": ["tmp", "dist"]
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/src/main/webapp/README.md
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/README.md b/tez-ui2/src/main/webapp/README.md
new file mode 100644
index 0000000..291e05f
--- /dev/null
+++ b/tez-ui2/src/main/webapp/README.md
@@ -0,0 +1,41 @@
+# Tez-ui
+
+The Tez UI is an ember based web application that provides visualization of Tez applications
+running on the Apache Hadoop YARN framework.
+
+For more information on Tez and the Tez UI - the [tez homepage](http://tez.apache.org/ "Apache Tez Homepage").
+
+## Prerequisites
+
+You will need the following things properly installed on your computer.
+
+* [Git](http://git-scm.com/)
+* [Node.js](http://nodejs.org/) (with NPM)
+* [Bower](http://bower.io/)
+* [Ember CLI](http://www.ember-cli.com/)
+* [PhantomJS](http://phantomjs.org/)
+
+## Installation
+
+* `git clone <repository-url>` this repository
+* change into the new directory
+* `npm install`
+
+## Running / Development
+
+* `ember server`
+* Visit your app at [http://localhost:4200](http://localhost:4200).
+
+### Code Generators
+
+Make use of the many generators for code, try `ember help generate` for more details
+
+### Running Tests
+
+* `ember test`
+* `ember test --server`
+
+### Building
+
+* `ember build` (development)
+* `ember build --environment production` (production)

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/WEB-INF/web.xml b/tez-ui2/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..62bfe31
--- /dev/null
+++ b/tez-ui2/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,25 @@
+<!--
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+-->
+
+<!DOCTYPE web-app PUBLIC
+ "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+ "http://java.sun.com/dtd/web-app_2_3.dtd" >
+
+<web-app>
+  <display-name>TEZ UI</display-name>
+</web-app>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/src/main/webapp/app/app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/app.js b/tez-ui2/src/main/webapp/app/app.js
new file mode 100644
index 0000000..8b234d6
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/app.js
@@ -0,0 +1,18 @@
+import Ember from 'ember';
+import Resolver from 'ember/resolver';
+import loadInitializers from 'ember/load-initializers';
+import config from './config/environment';
+
+let App;
+
+Ember.MODEL_FACTORY_INJECTIONS = true;
+
+App = Ember.Application.extend({
+  modulePrefix: config.modulePrefix,
+  podModulePrefix: config.podModulePrefix,
+  Resolver
+});
+
+loadInitializers(App, config.modulePrefix);
+
+export default App;

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/src/main/webapp/app/index.html
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/index.html b/tez-ui2/src/main/webapp/app/index.html
new file mode 100644
index 0000000..23a7578
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/index.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <title>Tez UI</title>
+    <meta name="description" content="">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+
+    {{content-for 'head'}}
+
+    <link rel="stylesheet" href="assets/vendor.css">
+    <link rel="stylesheet" href="assets/tez-ui.css">
+
+    {{content-for 'head-footer'}}
+  </head>
+  <body>
+    {{content-for 'body'}}
+
+    <script src="assets/vendor.js"></script>
+    <script src="assets/tez-ui.js"></script>
+
+    {{content-for 'body-footer'}}
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/src/main/webapp/app/router.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/router.js b/tez-ui2/src/main/webapp/app/router.js
new file mode 100644
index 0000000..3bba78e
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/router.js
@@ -0,0 +1,11 @@
+import Ember from 'ember';
+import config from './config/environment';
+
+const Router = Ember.Router.extend({
+  location: config.locationType
+});
+
+Router.map(function() {
+});
+
+export default Router;

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/src/main/webapp/app/styles/app.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/app.less b/tez-ui2/src/main/webapp/app/styles/app.less
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/styles/app.less
@@ -0,0 +1 @@
+

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/src/main/webapp/app/templates/application.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/application.hbs b/tez-ui2/src/main/webapp/app/templates/application.hbs
new file mode 100644
index 0000000..f8bc38e
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/application.hbs
@@ -0,0 +1,3 @@
+<h2 id="title">Welcome to Ember</h2>
+
+{{outlet}}

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/src/main/webapp/bower.json
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/bower.json b/tez-ui2/src/main/webapp/bower.json
new file mode 100644
index 0000000..fb312cb
--- /dev/null
+++ b/tez-ui2/src/main/webapp/bower.json
@@ -0,0 +1,15 @@
+{
+  "name": "tez-ui",
+  "dependencies": {
+    "ember": "2.2.0",
+    "ember-cli-shims": "0.0.6",
+    "ember-cli-test-loader": "0.2.1",
+    "ember-data": "2.1.0",
+    "ember-load-initializers": "0.1.7",
+    "ember-qunit": "0.4.16",
+    "ember-qunit-notifications": "0.1.0",
+    "jquery": "^1.11.3",
+    "loader.js": "3.3.0",
+    "qunit": "~1.19.0"
+  }
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/src/main/webapp/config/environment.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/config/environment.js b/tez-ui2/src/main/webapp/config/environment.js
new file mode 100644
index 0000000..9243b2b
--- /dev/null
+++ b/tez-ui2/src/main/webapp/config/environment.js
@@ -0,0 +1,47 @@
+/* jshint node: true */
+
+module.exports = function(environment) {
+  var ENV = {
+    modulePrefix: 'tez-ui',
+    environment: environment,
+    baseURL: '/',
+    locationType: 'auto',
+    EmberENV: {
+      FEATURES: {
+        // Here you can enable experimental features on an ember canary build
+        // e.g. 'with-controller': true
+      }
+    },
+
+    APP: {
+      // Here you can pass flags/options to your application instance
+      // when it is created
+    }
+  };
+
+  if (environment === 'development') {
+    // ENV.APP.LOG_RESOLVER = true;
+    // ENV.APP.LOG_ACTIVE_GENERATION = true;
+    // ENV.APP.LOG_TRANSITIONS = true;
+    // ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
+    // ENV.APP.LOG_VIEW_LOOKUPS = true;
+  }
+
+  if (environment === 'test') {
+    // Testem prefers this...
+    ENV.baseURL = '/';
+    ENV.locationType = 'none';
+
+    // keep test console output quieter
+    ENV.APP.LOG_ACTIVE_GENERATION = false;
+    ENV.APP.LOG_VIEW_LOOKUPS = false;
+
+    ENV.APP.rootElement = '#ember-testing';
+  }
+
+  if (environment === 'production') {
+
+  }
+
+  return ENV;
+};

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/src/main/webapp/ember-cli-build.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/ember-cli-build.js b/tez-ui2/src/main/webapp/ember-cli-build.js
new file mode 100644
index 0000000..2537ce2
--- /dev/null
+++ b/tez-ui2/src/main/webapp/ember-cli-build.js
@@ -0,0 +1,24 @@
+/*jshint node:true*/
+/* global require, module */
+var EmberApp = require('ember-cli/lib/broccoli/ember-app');
+
+module.exports = function(defaults) {
+  var app = new EmberApp(defaults, {
+    // Add options here
+  });
+
+  // Use `app.import` to add additional libraries to the generated
+  // output files.
+  //
+  // If you need to use different assets in different
+  // environments, specify an object as the first parameter. That
+  // object's keys should be the environment name and the values
+  // should be the asset to use in that environment.
+  //
+  // If the library that you are including contains AMD or ES6
+  // modules that you would like to import into your application
+  // please specify an object with the list of modules as keys
+  // along with the exports of each module as its value.
+
+  return app.toTree();
+};

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/src/main/webapp/package.json
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/package.json b/tez-ui2/src/main/webapp/package.json
new file mode 100644
index 0000000..7e474e3
--- /dev/null
+++ b/tez-ui2/src/main/webapp/package.json
@@ -0,0 +1,45 @@
+{
+  "name": "tez-ui",
+  "version": "0.2.0",
+  "description": "Apache Tez UI",
+  "private": true,
+  "directories": {
+    "doc": "doc",
+    "test": "tests"
+  },
+  "scripts": {
+    "build": "ember build",
+    "start": "ember server",
+    "test": "ember test",
+    "postinstall": "bower install"
+  },
+  "repository" : {
+    "type" : "git",
+    "url" : "https://git-wip-us.apache.org/repos/asf/tez.git"
+  },
+  "engines": {
+    "node": ">= 0.10.0"
+  },
+  "devDependencies": {
+    "broccoli-asset-rev": "^2.2.0",
+    "ember-cli": "1.13.13",
+    "ember-cli-app-version": "^1.0.0",
+    "ember-cli-babel": "^5.1.5",
+    "ember-cli-content-security-policy": "0.4.0",
+    "ember-cli-dependency-checker": "^1.1.0",
+    "ember-cli-htmlbars-inline-precompile": "^0.3.1",
+    "ember-cli-inject-live-reload": "^1.3.1",
+    "ember-cli-qunit": "^1.0.4",
+    "ember-cli-release": "0.2.8",
+    "ember-cli-sri": "^1.2.0",
+    "ember-cli-uglify": "^1.2.0",
+    "ember-data": "2.1.0",
+    "ember-disable-proxy-controllers": "^1.0.1",
+    "ember-export-application-global": "^1.0.4",
+    "ember-resolver": "^2.0.3"
+  },
+  "dependencies": {
+    "ember-cli-htmlbars": "^1.0.1",
+    "ember-cli-less": "^1.4.0"
+  }
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/src/main/webapp/public/crossdomain.xml
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/public/crossdomain.xml b/tez-ui2/src/main/webapp/public/crossdomain.xml
new file mode 100644
index 0000000..0c16a7a
--- /dev/null
+++ b/tez-ui2/src/main/webapp/public/crossdomain.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
+<cross-domain-policy>
+  <!-- Read this: www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html -->
+
+  <!-- Most restrictive policy: -->
+  <site-control permitted-cross-domain-policies="none"/>
+
+  <!-- Least restrictive policy: -->
+  <!--
+  <site-control permitted-cross-domain-policies="all"/>
+  <allow-access-from domain="*" to-ports="*" secure="false"/>
+  <allow-http-request-headers-from domain="*" headers="*" secure="false"/>
+  -->
+</cross-domain-policy>

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/src/main/webapp/public/robots.txt
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/public/robots.txt b/tez-ui2/src/main/webapp/public/robots.txt
new file mode 100644
index 0000000..f591645
--- /dev/null
+++ b/tez-ui2/src/main/webapp/public/robots.txt
@@ -0,0 +1,3 @@
+# http://www.robotstxt.org
+User-agent: *
+Disallow:

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/src/main/webapp/testem.json
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/testem.json b/tez-ui2/src/main/webapp/testem.json
new file mode 100644
index 0000000..0f35392
--- /dev/null
+++ b/tez-ui2/src/main/webapp/testem.json
@@ -0,0 +1,12 @@
+{
+  "framework": "qunit",
+  "test_page": "tests/index.html?hidepassed",
+  "disable_watching": true,
+  "launch_in_ci": [
+    "PhantomJS"
+  ],
+  "launch_in_dev": [
+    "PhantomJS",
+    "Chrome"
+  ]
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/src/main/webapp/tests/.jshintrc
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/.jshintrc b/tez-ui2/src/main/webapp/tests/.jshintrc
new file mode 100644
index 0000000..6ec0b7c
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/.jshintrc
@@ -0,0 +1,52 @@
+{
+  "predef": [
+    "document",
+    "window",
+    "location",
+    "setTimeout",
+    "$",
+    "-Promise",
+    "define",
+    "console",
+    "visit",
+    "exists",
+    "fillIn",
+    "click",
+    "keyEvent",
+    "triggerEvent",
+    "find",
+    "findWithAssert",
+    "wait",
+    "DS",
+    "andThen",
+    "currentURL",
+    "currentPath",
+    "currentRouteName"
+  ],
+  "node": false,
+  "browser": false,
+  "boss": true,
+  "curly": true,
+  "debug": false,
+  "devel": false,
+  "eqeqeq": true,
+  "evil": true,
+  "forin": false,
+  "immed": false,
+  "laxbreak": false,
+  "newcap": true,
+  "noarg": true,
+  "noempty": false,
+  "nonew": false,
+  "nomen": false,
+  "onevar": false,
+  "plusplus": false,
+  "regexp": false,
+  "undef": true,
+  "sub": true,
+  "strict": false,
+  "white": false,
+  "eqnull": true,
+  "esnext": true,
+  "unused": true
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/src/main/webapp/tests/helpers/destroy-app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/helpers/destroy-app.js b/tez-ui2/src/main/webapp/tests/helpers/destroy-app.js
new file mode 100644
index 0000000..c3d4d1a
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/helpers/destroy-app.js
@@ -0,0 +1,5 @@
+import Ember from 'ember';
+
+export default function destroyApp(application) {
+  Ember.run(application, 'destroy');
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/src/main/webapp/tests/helpers/module-for-acceptance.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/helpers/module-for-acceptance.js b/tez-ui2/src/main/webapp/tests/helpers/module-for-acceptance.js
new file mode 100644
index 0000000..ed23003
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/helpers/module-for-acceptance.js
@@ -0,0 +1,23 @@
+import { module } from 'qunit';
+import startApp from '../helpers/start-app';
+import destroyApp from '../helpers/destroy-app';
+
+export default function(name, options = {}) {
+  module(name, {
+    beforeEach() {
+      this.application = startApp();
+
+      if (options.beforeEach) {
+        options.beforeEach.apply(this, arguments);
+      }
+    },
+
+    afterEach() {
+      destroyApp(this.application);
+
+      if (options.afterEach) {
+        options.afterEach.apply(this, arguments);
+      }
+    }
+  });
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/src/main/webapp/tests/helpers/resolver.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/helpers/resolver.js b/tez-ui2/src/main/webapp/tests/helpers/resolver.js
new file mode 100644
index 0000000..ebfb4e4
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/helpers/resolver.js
@@ -0,0 +1,11 @@
+import Resolver from 'ember/resolver';
+import config from '../../config/environment';
+
+const resolver = Resolver.create();
+
+resolver.namespace = {
+  modulePrefix: config.modulePrefix,
+  podModulePrefix: config.podModulePrefix
+};
+
+export default resolver;

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/src/main/webapp/tests/helpers/start-app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/helpers/start-app.js b/tez-ui2/src/main/webapp/tests/helpers/start-app.js
new file mode 100644
index 0000000..e098f1d
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/helpers/start-app.js
@@ -0,0 +1,18 @@
+import Ember from 'ember';
+import Application from '../../app';
+import config from '../../config/environment';
+
+export default function startApp(attrs) {
+  let application;
+
+  let attributes = Ember.merge({}, config.APP);
+  attributes = Ember.merge(attributes, attrs); // use defaults, but you can override;
+
+  Ember.run(() => {
+    application = Application.create(attributes);
+    application.setupForTesting();
+    application.injectTestHelpers();
+  });
+
+  return application;
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/src/main/webapp/tests/index.html
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/index.html b/tez-ui2/src/main/webapp/tests/index.html
new file mode 100644
index 0000000..b5205de
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/index.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <title>TezUi Tests</title>
+    <meta name="description" content="">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+
+    {{content-for 'head'}}
+    {{content-for 'test-head'}}
+
+    <link rel="stylesheet" href="assets/vendor.css">
+    <link rel="stylesheet" href="assets/tez-ui.css">
+    <link rel="stylesheet" href="assets/test-support.css">
+
+    {{content-for 'head-footer'}}
+    {{content-for 'test-head-footer'}}
+  </head>
+  <body>
+    {{content-for 'body'}}
+    {{content-for 'test-body'}}
+
+    <script src="assets/vendor.js"></script>
+    <script src="assets/test-support.js"></script>
+    <script src="assets/tez-ui.js"></script>
+    <script src="testem.js" integrity=""></script>
+    <script src="assets/tests.js"></script>
+    <script src="assets/test-loader.js"></script>
+
+    {{content-for 'body-footer'}}
+    {{content-for 'test-body-footer'}}
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/tez/blob/976337a5/tez-ui2/src/main/webapp/tests/test-helper.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/test-helper.js b/tez-ui2/src/main/webapp/tests/test-helper.js
new file mode 100644
index 0000000..e6cfb70
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/test-helper.js
@@ -0,0 +1,6 @@
+import resolver from './helpers/resolver';
+import {
+  setResolver
+} from 'ember-qunit';
+
+setResolver(resolver);


[16/50] [abbrv] tez git commit: TEZ-3033 changes for 0.8.2 release part1. Update version to 0.8.3-SNAPSHOT. Add a section in CHANGES.txt. (sseth)

Posted by sr...@apache.org.
TEZ-3033 changes for 0.8.2 release part1. Update version to
0.8.3-SNAPSHOT. Add a section in CHANGES.txt. (sseth)


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

Branch: refs/heads/TEZ-2980
Commit: b656157600cc0f205e3044a726686420da39b16b
Parents: fad1642
Author: Siddharth Seth <ss...@apache.org>
Authored: Tue Jan 12 18:09:38 2016 -0800
Committer: Siddharth Seth <ss...@apache.org>
Committed: Tue Jan 12 18:09:38 2016 -0800

----------------------------------------------------------------------
 CHANGES.txt                                             | 8 +++++++-
 docs/pom.xml                                            | 2 +-
 hadoop-shim-impls/hadoop-shim-2.4/pom.xml               | 2 +-
 hadoop-shim-impls/hadoop-shim-2.6/pom.xml               | 2 +-
 hadoop-shim-impls/hadoop-shim-2.8/pom.xml               | 2 +-
 hadoop-shim-impls/pom.xml                               | 2 +-
 hadoop-shim/pom.xml                                     | 2 +-
 pom.xml                                                 | 2 +-
 tez-api/pom.xml                                         | 2 +-
 tez-common/pom.xml                                      | 2 +-
 tez-dag/pom.xml                                         | 2 +-
 tez-dist/pom.xml                                        | 2 +-
 tez-examples/pom.xml                                    | 2 +-
 tez-ext-service-tests/pom.xml                           | 2 +-
 tez-mapreduce/pom.xml                                   | 2 +-
 tez-plugins/pom.xml                                     | 2 +-
 tez-plugins/tez-history-parser/pom.xml                  | 2 +-
 tez-plugins/tez-yarn-timeline-history-with-acls/pom.xml | 2 +-
 tez-plugins/tez-yarn-timeline-history/pom.xml           | 2 +-
 tez-runtime-internals/pom.xml                           | 2 +-
 tez-runtime-library/pom.xml                             | 2 +-
 tez-tests/pom.xml                                       | 2 +-
 tez-tools/analyzers/job-analyzer/pom.xml                | 2 +-
 tez-tools/analyzers/pom.xml                             | 2 +-
 tez-tools/pom.xml                                       | 2 +-
 tez-tools/tez-javadoc-tools/pom.xml                     | 2 +-
 tez-tools/tez-tfile-parser/pom.xml                      | 2 +-
 tez-ui/pom.xml                                          | 2 +-
 28 files changed, 34 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/b6561576/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 0645591..ec3e84b 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,7 +1,13 @@
 Apache Tez Change Log
 =====================
 
-Release 0.8.2: Unreleased
+Release 0.8.3: Unreleased
+
+INCOMPATIBLE CHANGES
+
+ALL CHANGES:
+
+Release 0.8.2: 2016-01-19
 
 INCOMPATIBLE CHANGES
   TEZ-3024. Move TaskCommunicator to correct package.

http://git-wip-us.apache.org/repos/asf/tez/blob/b6561576/docs/pom.xml
----------------------------------------------------------------------
diff --git a/docs/pom.xml b/docs/pom.xml
index 84fab46..3fa9a16 100644
--- a/docs/pom.xml
+++ b/docs/pom.xml
@@ -27,7 +27,7 @@
     <parent>
       <groupId>org.apache.tez</groupId>
       <artifactId>tez</artifactId>
-      <version>0.8.2-SNAPSHOT</version>
+      <version>0.8.3-SNAPSHOT</version>
     </parent>
     <artifactId>tez-docs</artifactId>
     <packaging>pom</packaging>

http://git-wip-us.apache.org/repos/asf/tez/blob/b6561576/hadoop-shim-impls/hadoop-shim-2.4/pom.xml
----------------------------------------------------------------------
diff --git a/hadoop-shim-impls/hadoop-shim-2.4/pom.xml b/hadoop-shim-impls/hadoop-shim-2.4/pom.xml
index 3ffe4e2..133bc0e 100644
--- a/hadoop-shim-impls/hadoop-shim-2.4/pom.xml
+++ b/hadoop-shim-impls/hadoop-shim-2.4/pom.xml
@@ -19,7 +19,7 @@
   <parent>
     <artifactId>hadoop-shim-impls</artifactId>
     <groupId>org.apache.tez</groupId>
-    <version>0.8.2-SNAPSHOT</version>
+    <version>0.8.3-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <artifactId>hadoop-shim-2.4</artifactId>

http://git-wip-us.apache.org/repos/asf/tez/blob/b6561576/hadoop-shim-impls/hadoop-shim-2.6/pom.xml
----------------------------------------------------------------------
diff --git a/hadoop-shim-impls/hadoop-shim-2.6/pom.xml b/hadoop-shim-impls/hadoop-shim-2.6/pom.xml
index 8346c37..06563e6 100644
--- a/hadoop-shim-impls/hadoop-shim-2.6/pom.xml
+++ b/hadoop-shim-impls/hadoop-shim-2.6/pom.xml
@@ -19,7 +19,7 @@
   <parent>
     <artifactId>hadoop-shim-impls</artifactId>
     <groupId>org.apache.tez</groupId>
-    <version>0.8.2-SNAPSHOT</version>
+    <version>0.8.3-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <artifactId>hadoop-shim-2.6</artifactId>

http://git-wip-us.apache.org/repos/asf/tez/blob/b6561576/hadoop-shim-impls/hadoop-shim-2.8/pom.xml
----------------------------------------------------------------------
diff --git a/hadoop-shim-impls/hadoop-shim-2.8/pom.xml b/hadoop-shim-impls/hadoop-shim-2.8/pom.xml
index 41928fe..3d209de 100644
--- a/hadoop-shim-impls/hadoop-shim-2.8/pom.xml
+++ b/hadoop-shim-impls/hadoop-shim-2.8/pom.xml
@@ -19,7 +19,7 @@
   <parent>
     <artifactId>hadoop-shim-impls</artifactId>
     <groupId>org.apache.tez</groupId>
-    <version>0.8.2-SNAPSHOT</version>
+    <version>0.8.3-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <artifactId>hadoop-shim-2.8</artifactId>

http://git-wip-us.apache.org/repos/asf/tez/blob/b6561576/hadoop-shim-impls/pom.xml
----------------------------------------------------------------------
diff --git a/hadoop-shim-impls/pom.xml b/hadoop-shim-impls/pom.xml
index 6c8f7d2..3e40c94 100644
--- a/hadoop-shim-impls/pom.xml
+++ b/hadoop-shim-impls/pom.xml
@@ -20,7 +20,7 @@
   <parent>
     <artifactId>tez</artifactId>
     <groupId>org.apache.tez</groupId>
-    <version>0.8.2-SNAPSHOT</version>
+    <version>0.8.3-SNAPSHOT</version>
   </parent>
   <artifactId>hadoop-shim-impls</artifactId>
   <packaging>pom</packaging>

http://git-wip-us.apache.org/repos/asf/tez/blob/b6561576/hadoop-shim/pom.xml
----------------------------------------------------------------------
diff --git a/hadoop-shim/pom.xml b/hadoop-shim/pom.xml
index 1f70e6f..c18d449 100644
--- a/hadoop-shim/pom.xml
+++ b/hadoop-shim/pom.xml
@@ -20,7 +20,7 @@
   <parent>
      <artifactId>tez</artifactId>
      <groupId>org.apache.tez</groupId>
-     <version>0.8.2-SNAPSHOT</version>
+     <version>0.8.3-SNAPSHOT</version>
   </parent>
   <artifactId>hadoop-shim</artifactId>
 

http://git-wip-us.apache.org/repos/asf/tez/blob/b6561576/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 1835fa5..78e28f5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,7 +19,7 @@
   <groupId>org.apache.tez</groupId>
   <artifactId>tez</artifactId>
   <packaging>pom</packaging>
-  <version>0.8.2-SNAPSHOT</version>
+  <version>0.8.3-SNAPSHOT</version>
   <name>tez</name>
 
   <licenses>

http://git-wip-us.apache.org/repos/asf/tez/blob/b6561576/tez-api/pom.xml
----------------------------------------------------------------------
diff --git a/tez-api/pom.xml b/tez-api/pom.xml
index 9b4f0c8..7a72ed5 100644
--- a/tez-api/pom.xml
+++ b/tez-api/pom.xml
@@ -20,7 +20,7 @@
   <parent>
     <groupId>org.apache.tez</groupId>
     <artifactId>tez</artifactId>
-    <version>0.8.2-SNAPSHOT</version>
+    <version>0.8.3-SNAPSHOT</version>
   </parent>
   <artifactId>tez-api</artifactId>
 

http://git-wip-us.apache.org/repos/asf/tez/blob/b6561576/tez-common/pom.xml
----------------------------------------------------------------------
diff --git a/tez-common/pom.xml b/tez-common/pom.xml
index e133c9c..f710d84 100644
--- a/tez-common/pom.xml
+++ b/tez-common/pom.xml
@@ -20,7 +20,7 @@
   <parent>
     <groupId>org.apache.tez</groupId>
     <artifactId>tez</artifactId>
-    <version>0.8.2-SNAPSHOT</version>
+    <version>0.8.3-SNAPSHOT</version>
   </parent>
   <artifactId>tez-common</artifactId>
 

http://git-wip-us.apache.org/repos/asf/tez/blob/b6561576/tez-dag/pom.xml
----------------------------------------------------------------------
diff --git a/tez-dag/pom.xml b/tez-dag/pom.xml
index 7ca92db..427e7b6 100644
--- a/tez-dag/pom.xml
+++ b/tez-dag/pom.xml
@@ -19,7 +19,7 @@
   <parent>
     <groupId>org.apache.tez</groupId>
     <artifactId>tez</artifactId>
-    <version>0.8.2-SNAPSHOT</version>
+    <version>0.8.3-SNAPSHOT</version>
   </parent>
   <properties>
     <tez.component>tez-dag</tez.component>

http://git-wip-us.apache.org/repos/asf/tez/blob/b6561576/tez-dist/pom.xml
----------------------------------------------------------------------
diff --git a/tez-dist/pom.xml b/tez-dist/pom.xml
index 9a9a790..9ff4416 100644
--- a/tez-dist/pom.xml
+++ b/tez-dist/pom.xml
@@ -21,7 +21,7 @@
   <parent>
     <groupId>org.apache.tez</groupId>
     <artifactId>tez</artifactId>
-    <version>0.8.2-SNAPSHOT</version>
+    <version>0.8.3-SNAPSHOT</version>
   </parent>
   <artifactId>tez-dist</artifactId>
 

http://git-wip-us.apache.org/repos/asf/tez/blob/b6561576/tez-examples/pom.xml
----------------------------------------------------------------------
diff --git a/tez-examples/pom.xml b/tez-examples/pom.xml
index b182ec6..01f915c 100644
--- a/tez-examples/pom.xml
+++ b/tez-examples/pom.xml
@@ -20,7 +20,7 @@
   <parent>
     <groupId>org.apache.tez</groupId>
     <artifactId>tez</artifactId>
-    <version>0.8.2-SNAPSHOT</version>
+    <version>0.8.3-SNAPSHOT</version>
   </parent>
 
   <artifactId>tez-examples</artifactId>

http://git-wip-us.apache.org/repos/asf/tez/blob/b6561576/tez-ext-service-tests/pom.xml
----------------------------------------------------------------------
diff --git a/tez-ext-service-tests/pom.xml b/tez-ext-service-tests/pom.xml
index a548a78..2ac1ba3 100644
--- a/tez-ext-service-tests/pom.xml
+++ b/tez-ext-service-tests/pom.xml
@@ -20,7 +20,7 @@
   <parent>
     <artifactId>tez</artifactId>
     <groupId>org.apache.tez</groupId>
-    <version>0.8.2-SNAPSHOT</version>
+    <version>0.8.3-SNAPSHOT</version>
   </parent>
 
   <artifactId>tez-ext-service-tests</artifactId>

http://git-wip-us.apache.org/repos/asf/tez/blob/b6561576/tez-mapreduce/pom.xml
----------------------------------------------------------------------
diff --git a/tez-mapreduce/pom.xml b/tez-mapreduce/pom.xml
index ea8b954..909a9f6 100644
--- a/tez-mapreduce/pom.xml
+++ b/tez-mapreduce/pom.xml
@@ -20,7 +20,7 @@
   <parent>
     <groupId>org.apache.tez</groupId>
     <artifactId>tez</artifactId>
-    <version>0.8.2-SNAPSHOT</version>
+    <version>0.8.3-SNAPSHOT</version>
   </parent>
   <artifactId>tez-mapreduce</artifactId>
 

http://git-wip-us.apache.org/repos/asf/tez/blob/b6561576/tez-plugins/pom.xml
----------------------------------------------------------------------
diff --git a/tez-plugins/pom.xml b/tez-plugins/pom.xml
index 04e95b7..6d1c88a 100644
--- a/tez-plugins/pom.xml
+++ b/tez-plugins/pom.xml
@@ -21,7 +21,7 @@
   <parent>
     <groupId>org.apache.tez</groupId>
     <artifactId>tez</artifactId>
-    <version>0.8.2-SNAPSHOT</version>
+    <version>0.8.3-SNAPSHOT</version>
   </parent>
   <artifactId>tez-plugins</artifactId>
   <packaging>pom</packaging>

http://git-wip-us.apache.org/repos/asf/tez/blob/b6561576/tez-plugins/tez-history-parser/pom.xml
----------------------------------------------------------------------
diff --git a/tez-plugins/tez-history-parser/pom.xml b/tez-plugins/tez-history-parser/pom.xml
index 66b87d4..56744ce 100644
--- a/tez-plugins/tez-history-parser/pom.xml
+++ b/tez-plugins/tez-history-parser/pom.xml
@@ -21,7 +21,7 @@
   <parent>
     <groupId>org.apache.tez</groupId>
     <artifactId>tez-plugins</artifactId>
-    <version>0.8.2-SNAPSHOT</version>
+    <version>0.8.3-SNAPSHOT</version>
   </parent>
   <artifactId>tez-history-parser</artifactId>
 

http://git-wip-us.apache.org/repos/asf/tez/blob/b6561576/tez-plugins/tez-yarn-timeline-history-with-acls/pom.xml
----------------------------------------------------------------------
diff --git a/tez-plugins/tez-yarn-timeline-history-with-acls/pom.xml b/tez-plugins/tez-yarn-timeline-history-with-acls/pom.xml
index 642633a..a1014b7 100644
--- a/tez-plugins/tez-yarn-timeline-history-with-acls/pom.xml
+++ b/tez-plugins/tez-yarn-timeline-history-with-acls/pom.xml
@@ -19,7 +19,7 @@
   <parent>
     <groupId>org.apache.tez</groupId>
     <artifactId>tez-plugins</artifactId>
-    <version>0.8.2-SNAPSHOT</version>
+    <version>0.8.3-SNAPSHOT</version>
   </parent>
   <artifactId>tez-yarn-timeline-history-with-acls</artifactId>
 

http://git-wip-us.apache.org/repos/asf/tez/blob/b6561576/tez-plugins/tez-yarn-timeline-history/pom.xml
----------------------------------------------------------------------
diff --git a/tez-plugins/tez-yarn-timeline-history/pom.xml b/tez-plugins/tez-yarn-timeline-history/pom.xml
index f704111..f91f27e 100644
--- a/tez-plugins/tez-yarn-timeline-history/pom.xml
+++ b/tez-plugins/tez-yarn-timeline-history/pom.xml
@@ -19,7 +19,7 @@
   <parent>
     <groupId>org.apache.tez</groupId>
     <artifactId>tez-plugins</artifactId>
-    <version>0.8.2-SNAPSHOT</version>
+    <version>0.8.3-SNAPSHOT</version>
   </parent>
   <artifactId>tez-yarn-timeline-history</artifactId>
 

http://git-wip-us.apache.org/repos/asf/tez/blob/b6561576/tez-runtime-internals/pom.xml
----------------------------------------------------------------------
diff --git a/tez-runtime-internals/pom.xml b/tez-runtime-internals/pom.xml
index 9c1cf2f..86869e3 100644
--- a/tez-runtime-internals/pom.xml
+++ b/tez-runtime-internals/pom.xml
@@ -20,7 +20,7 @@
   <parent>
     <groupId>org.apache.tez</groupId>
     <artifactId>tez</artifactId>
-    <version>0.8.2-SNAPSHOT</version>
+    <version>0.8.3-SNAPSHOT</version>
   </parent>
   <artifactId>tez-runtime-internals</artifactId>
 

http://git-wip-us.apache.org/repos/asf/tez/blob/b6561576/tez-runtime-library/pom.xml
----------------------------------------------------------------------
diff --git a/tez-runtime-library/pom.xml b/tez-runtime-library/pom.xml
index 49308e0..cb0786e 100644
--- a/tez-runtime-library/pom.xml
+++ b/tez-runtime-library/pom.xml
@@ -20,7 +20,7 @@
   <parent>
     <groupId>org.apache.tez</groupId>
     <artifactId>tez</artifactId>
-    <version>0.8.2-SNAPSHOT</version>
+    <version>0.8.3-SNAPSHOT</version>
   </parent>
   <artifactId>tez-runtime-library</artifactId>
 

http://git-wip-us.apache.org/repos/asf/tez/blob/b6561576/tez-tests/pom.xml
----------------------------------------------------------------------
diff --git a/tez-tests/pom.xml b/tez-tests/pom.xml
index 72538bf..464fecf 100644
--- a/tez-tests/pom.xml
+++ b/tez-tests/pom.xml
@@ -20,7 +20,7 @@
   <parent>
     <groupId>org.apache.tez</groupId>
     <artifactId>tez</artifactId>
-    <version>0.8.2-SNAPSHOT</version>
+    <version>0.8.3-SNAPSHOT</version>
   </parent>
   <artifactId>tez-tests</artifactId>
 

http://git-wip-us.apache.org/repos/asf/tez/blob/b6561576/tez-tools/analyzers/job-analyzer/pom.xml
----------------------------------------------------------------------
diff --git a/tez-tools/analyzers/job-analyzer/pom.xml b/tez-tools/analyzers/job-analyzer/pom.xml
index cea246e..0d55381 100644
--- a/tez-tools/analyzers/job-analyzer/pom.xml
+++ b/tez-tools/analyzers/job-analyzer/pom.xml
@@ -20,7 +20,7 @@
   <parent>
     <groupId>org.apache.tez</groupId>
     <artifactId>tez-perf-analyzer</artifactId>
-    <version>0.8.2-SNAPSHOT</version>
+    <version>0.8.3-SNAPSHOT</version>
   </parent>
   <artifactId>tez-job-analyzer</artifactId>
 

http://git-wip-us.apache.org/repos/asf/tez/blob/b6561576/tez-tools/analyzers/pom.xml
----------------------------------------------------------------------
diff --git a/tez-tools/analyzers/pom.xml b/tez-tools/analyzers/pom.xml
index 6c3d76e..dce6978 100644
--- a/tez-tools/analyzers/pom.xml
+++ b/tez-tools/analyzers/pom.xml
@@ -20,7 +20,7 @@
   <parent>
     <groupId>org.apache.tez</groupId>
     <artifactId>tez-tools</artifactId>
-    <version>0.8.2-SNAPSHOT</version>
+    <version>0.8.3-SNAPSHOT</version>
   </parent>
   <artifactId>tez-perf-analyzer</artifactId>
   <packaging>pom</packaging>

http://git-wip-us.apache.org/repos/asf/tez/blob/b6561576/tez-tools/pom.xml
----------------------------------------------------------------------
diff --git a/tez-tools/pom.xml b/tez-tools/pom.xml
index 9d017e9..3e265fb 100644
--- a/tez-tools/pom.xml
+++ b/tez-tools/pom.xml
@@ -21,7 +21,7 @@
   <parent>
     <groupId>org.apache.tez</groupId>
     <artifactId>tez</artifactId>
-    <version>0.8.2-SNAPSHOT</version>
+    <version>0.8.3-SNAPSHOT</version>
   </parent>
   <artifactId>tez-tools</artifactId>
   <packaging>pom</packaging>

http://git-wip-us.apache.org/repos/asf/tez/blob/b6561576/tez-tools/tez-javadoc-tools/pom.xml
----------------------------------------------------------------------
diff --git a/tez-tools/tez-javadoc-tools/pom.xml b/tez-tools/tez-javadoc-tools/pom.xml
index d5c41be..678be5d 100644
--- a/tez-tools/tez-javadoc-tools/pom.xml
+++ b/tez-tools/tez-javadoc-tools/pom.xml
@@ -20,7 +20,7 @@
   <parent>
     <groupId>org.apache.tez</groupId>
     <artifactId>tez-tools</artifactId>
-    <version>0.8.2-SNAPSHOT</version>
+    <version>0.8.3-SNAPSHOT</version>
   </parent>
   <artifactId>tez-javadoc-tools</artifactId>
 

http://git-wip-us.apache.org/repos/asf/tez/blob/b6561576/tez-tools/tez-tfile-parser/pom.xml
----------------------------------------------------------------------
diff --git a/tez-tools/tez-tfile-parser/pom.xml b/tez-tools/tez-tfile-parser/pom.xml
index 5afbe48..601ff24 100644
--- a/tez-tools/tez-tfile-parser/pom.xml
+++ b/tez-tools/tez-tfile-parser/pom.xml
@@ -20,7 +20,7 @@
   <parent>
     <groupId>org.apache.tez</groupId>
     <artifactId>tez-tools</artifactId>
-    <version>0.8.2-SNAPSHOT</version>
+    <version>0.8.3-SNAPSHOT</version>
   </parent>
   <artifactId>tez-tfile-parser</artifactId>
 

http://git-wip-us.apache.org/repos/asf/tez/blob/b6561576/tez-ui/pom.xml
----------------------------------------------------------------------
diff --git a/tez-ui/pom.xml b/tez-ui/pom.xml
index 7e34c07..ef6f86a 100644
--- a/tez-ui/pom.xml
+++ b/tez-ui/pom.xml
@@ -21,7 +21,7 @@
   <parent>
     <groupId>org.apache.tez</groupId>
     <artifactId>tez</artifactId>
-    <version>0.8.2-SNAPSHOT</version>
+    <version>0.8.3-SNAPSHOT</version>
   </parent>
   <artifactId>tez-ui</artifactId>
   <packaging>war</packaging>


[28/50] [abbrv] tez git commit: TEZ-3018. Tez UI 2: Add config.env (sree)

Posted by sr...@apache.org.
TEZ-3018. Tez UI 2: Add config.env (sree)


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

Branch: refs/heads/TEZ-2980
Commit: 539157744e0552e923ebf44feaa99b3fa3f606cf
Parents: 1c23839
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Tue Dec 29 22:37:26 2015 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Wed Jan 20 22:26:20 2016 +0530

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


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

http://git-wip-us.apache.org/repos/asf/tez/blob/53915774/tez-ui2/src/main/webapp/app/app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/app.js b/tez-ui2/src/main/webapp/app/app.js
index 8b234d6..fb4695c 100644
--- a/tez-ui2/src/main/webapp/app/app.js
+++ b/tez-ui2/src/main/webapp/app/app.js
@@ -1,5 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 import Ember from 'ember';
-import Resolver from 'ember/resolver';
+import Resolver from 'ember-resolver';
 import loadInitializers from 'ember/load-initializers';
 import config from './config/environment';
 

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

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

http://git-wip-us.apache.org/repos/asf/tez/blob/53915774/tez-ui2/src/main/webapp/app/templates/application.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/application.hbs b/tez-ui2/src/main/webapp/app/templates/application.hbs
index f8bc38e..c1c380d 100644
--- a/tez-ui2/src/main/webapp/app/templates/application.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/application.hbs
@@ -1,3 +1,23 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+}}
+
 <h2 id="title">Welcome to Ember</h2>
 
 {{outlet}}
+
+{{hosts.timelineBaseURL}}

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

http://git-wip-us.apache.org/repos/asf/tez/blob/53915774/tez-ui2/src/main/webapp/ember-cli-build.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/ember-cli-build.js b/tez-ui2/src/main/webapp/ember-cli-build.js
index 9f33b64..ede63b3 100644
--- a/tez-ui2/src/main/webapp/ember-cli-build.js
+++ b/tez-ui2/src/main/webapp/ember-cli-build.js
@@ -19,28 +19,20 @@
  * limitations under the License.
  */
 
+var Funnel = require("broccoli-funnel");
 var EmberApp = require('ember-cli/lib/broccoli/ember-app');
 
 module.exports = function(defaults) {
-  var app = new EmberApp(defaults, {
-    // Add options here
-  });
+  var app = new EmberApp(defaults, {});
 
-  // Use `app.import` to add additional libraries to the generated
-  // output files.
-  //
-  // If you need to use different assets in different
-  // environments, specify an object as the first parameter. That
-  // object's keys should be the environment name and the values
-  // should be the asset to use in that environment.
-  //
-  // If the library that you are including contains AMD or ES6
-  // modules that you would like to import into your application
-  // please specify an object with the list of modules as keys
-  // along with the exports of each module as its value.
+  var extraAssets = new Funnel('config', {
+     srcDir: '/',
+     include: ['*.env'],
+     destDir: '/config'
+  });
 
   app.import('bower_components/jquery-ui/jquery-ui.js');
   app.import('bower_components/jquery-ui/ui/tooltip.js');
 
-  return app.toTree();
+  return app.toTree(extraAssets);
 };

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

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


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

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


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

Branch: refs/heads/TEZ-2980
Commit: 055d469e5d90ed0069f2b9f3400dfe5c4e125669
Parents: 5391577
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Tue Dec 29 23:00:20 2015 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Wed Jan 20 22:26:20 2016 +0530

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


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

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

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

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

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


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

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


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

Branch: refs/heads/TEZ-2980
Commit: dd0e36db68c75ead6f7d1250bd080ec14bfe3df2
Parents: 869d712
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Wed Jan 20 03:55:24 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Wed Jan 20 22:30:08 2016 +0530

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


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

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

http://git-wip-us.apache.org/repos/asf/tez/blob/dd0e36db/tez-ui2/src/main/webapp/app/components/table-controls.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/components/table-controls.js b/tez-ui2/src/main/webapp/app/components/table-controls.js
new file mode 100644
index 0000000..9923711
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/components/table-controls.js
@@ -0,0 +1,29 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+  classNames: ['table-controls'],
+
+  actions: {
+    cogClicked: function () {
+      this.get('targetObject.targetObject').send('openColumnSelector');
+    }
+  }
+});

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

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

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

http://git-wip-us.apache.org/repos/asf/tez/blob/dd0e36db/tez-ui2/src/main/webapp/app/styles/column-selector.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/column-selector.less b/tez-ui2/src/main/webapp/app/styles/column-selector.less
new file mode 100644
index 0000000..2e39995
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/styles/column-selector.less
@@ -0,0 +1,65 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+.column-selector {
+  .message {
+    text-align: right;
+    font-size: 10px;
+  }
+
+  .selection-list {
+    border-bottom: 1px solid @border-color;
+
+    .highlight {
+      background-color: @bg-lite;
+    }
+    .select-option, .search-option {
+      border-top: 1px dotted @border-color;
+      padding: 5px 15px;
+
+      .checkbox {
+        display: inline-block;
+
+        margin-right: 10px;
+        float: left;
+        vertical-align: middle;
+      }
+    }
+    .search-option {
+      border: none;
+
+      .form-group {
+        display: inline-block;
+
+        width: 100%;
+        margin: 0px;
+      }
+
+      .select-all {
+        display: inline-block;
+
+        height: 15px;
+        margin-top: 3px;
+      }
+    }
+  }
+}
+.form-actions {
+  padding: 10px;
+  text-align: right;
+}

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

http://git-wip-us.apache.org/repos/asf/tez/blob/dd0e36db/tez-ui2/src/main/webapp/app/styles/table-controls.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/table-controls.less b/tez-ui2/src/main/webapp/app/styles/table-controls.less
new file mode 100644
index 0000000..aa9f9e6
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/styles/table-controls.less
@@ -0,0 +1,28 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@import "shared";
+
+.table-controls {
+  .left-delim;
+
+  cursor: pointer;
+
+  float: right;
+  font-size: 24px;
+}

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

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

http://git-wip-us.apache.org/repos/asf/tez/blob/dd0e36db/tez-ui2/src/main/webapp/app/templates/components/column-selector.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/components/column-selector.hbs b/tez-ui2/src/main/webapp/app/templates/components/column-selector.hbs
new file mode 100644
index 0000000..d9be633
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/components/column-selector.hbs
@@ -0,0 +1,48 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+}}
+
+<div class="message">
+  {{{content.message}}}
+</div>
+<div class="selection-list">
+  <div class="search-option highlight">
+    <div class="form-group">
+      {{input class="form-control" placeholder="Filter..." value=searchText}}
+    </div>
+    <div class="select-all">
+      <input type="checkbox"
+             checked={{selectAll}}
+             onclick={{action "selectAll" value="target.checked"}} />
+      &nbsp;Select All
+    </div>
+  </div>
+  {{#if filteredOptions.length}}
+    {{#each filteredOptions as |option|}}
+      <div class="select-option {{option.css}}">
+        {{input type="checkbox" classNames='checkbox' checked=option.selected}}
+        {{option.displayText}}
+      </div>
+    {{/each}}
+  {{else}}
+    <h4>&nbsp;No options available...</h4>
+  {{/if}}
+</div>
+<div class="form-actions">
+  <button type="button" class="btn btn-primary" {{action "ok"}} data-dismiss="modal" aria-label="Close">Ok</button>
+  <button type="button" class="btn" data-dismiss="modal" aria-label="Close">Cancel</button>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/dd0e36db/tez-ui2/src/main/webapp/app/templates/components/table-controls.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/components/table-controls.hbs b/tez-ui2/src/main/webapp/app/templates/components/table-controls.hbs
new file mode 100644
index 0000000..b70d19d
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/components/table-controls.hbs
@@ -0,0 +1,19 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+}}
+
+<i class='fa fa-cog' {{action 'cogClicked'}}></i>

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

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

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

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

http://git-wip-us.apache.org/repos/asf/tez/blob/dd0e36db/tez-ui2/src/main/webapp/app/templates/simple-modal.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/simple-modal.hbs b/tez-ui2/src/main/webapp/app/templates/simple-modal.hbs
new file mode 100644
index 0000000..59b3aaa
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/simple-modal.hbs
@@ -0,0 +1,33 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+}}
+
+<div class="modal fade simple-modal" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel">
+  <div class="modal-dialog">
+    <div class="modal-content">
+      <div class="modal-header">
+        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+          <span aria-hidden="true">&times;</span>
+        </button>
+        <h4 class="modal-title">{{model.title}}</h4>
+      </div>
+      {{#if model.componentName}}
+        {{component model.componentName content=model.content targetObject=model.targetObject}}
+      {{/if}}
+    </div>
+  </div>
+</div>
\ No newline at end of file

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

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

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

http://git-wip-us.apache.org/repos/asf/tez/blob/dd0e36db/tez-ui2/src/main/webapp/app/utils/misc.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/utils/misc.js b/tez-ui2/src/main/webapp/app/utils/misc.js
new file mode 100644
index 0000000..5e2ecf1
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/utils/misc.js
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default function isIOCounter(name) {
+  name = name.split('/')[0];
+  return name.match('_INPUT_') || name.match('_OUTPUT_');
+}

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

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

http://git-wip-us.apache.org/repos/asf/tez/blob/dd0e36db/tez-ui2/src/main/webapp/tests/integration/components/table-controls-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/integration/components/table-controls-test.js b/tez-ui2/src/main/webapp/tests/integration/components/table-controls-test.js
new file mode 100644
index 0000000..79170ee
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/integration/components/table-controls-test.js
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleForComponent, test } from 'ember-qunit';
+import hbs from 'htmlbars-inline-precompile';
+
+moduleForComponent('table-controls', 'Integration | Component | table controls', {
+  integration: true
+});
+
+test('Basic creation test', function(assert) {
+
+  // Set any properties with this.set('myProperty', 'value');
+  // Handle any actions with this.on('myAction', function(val) { ... });" + EOL + EOL +
+
+  this.render(hbs`{{table-controls}}`);
+
+  assert.equal(this.$().text().trim(), '');
+
+  // Template block usage:" + EOL +
+  this.render(hbs`
+    {{#table-controls}}
+      template block text
+    {{/table-controls}}
+  `);
+
+  assert.equal(this.$().text().trim(), '');
+});

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

http://git-wip-us.apache.org/repos/asf/tez/blob/dd0e36db/tez-ui2/src/main/webapp/tests/unit/utils/misc-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/utils/misc-test.js b/tez-ui2/src/main/webapp/tests/unit/utils/misc-test.js
new file mode 100644
index 0000000..7e282cd
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/utils/misc-test.js
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import isIOCounter from '../../../utils/misc';
+import { module, test } from 'qunit';
+
+module('Unit | Utility | misc');
+
+test('Basic creation test', function(assert) {
+  assert.ok(isIOCounter);
+});


[36/50] [abbrv] tez git commit: TEZ-3026. Tez UI 2: Add adapters for RM & AM (sree)

Posted by sr...@apache.org.
TEZ-3026. Tez UI 2: Add adapters for RM & AM (sree)


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

Branch: refs/heads/TEZ-2980
Commit: a4f6831b4de5b0ff1c08fef57880b67548118ba8
Parents: 7a9f38b
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Wed Jan 6 18:25:29 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Wed Jan 20 22:30:06 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |  1 +
 .../src/main/webapp/app/adapters/abstract.js    | 11 +++----
 tez-ui2/src/main/webapp/app/adapters/am.js      | 25 ++++++++++++++++
 tez-ui2/src/main/webapp/app/adapters/rm.js      | 25 ++++++++++++++++
 .../src/main/webapp/app/adapters/timeline.js    |  2 ++
 tez-ui2/src/main/webapp/app/services/env.js     | 24 +++++++--------
 tez-ui2/src/main/webapp/app/services/hosts.js   |  6 ++--
 .../src/main/webapp/config/default-app-conf.js  | 11 +++----
 .../webapp/tests/unit/adapters/abstract-test.js | 28 ++++++++++++++++++
 .../main/webapp/tests/unit/adapters/am-test.js  | 31 ++++++++++++++++++++
 .../main/webapp/tests/unit/adapters/rm-test.js  | 31 ++++++++++++++++++++
 .../main/webapp/tests/unit/services/env-test.js | 29 ++++++++++--------
 12 files changed, 179 insertions(+), 45 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/a4f6831b/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index c8f9d0f..28584a8 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -10,3 +10,4 @@ ALL CHANGES:
   TEZ-3021. Tez UI 2: Add env service & initializer
   TEZ-3023. Tez UI 2: Abstract adapter and route
   TEZ-3022. Tez UI 2: Add serializer & adapter for timeline server
+  TEZ-3026. Tez UI 2: Add adapters for RM & AM

http://git-wip-us.apache.org/repos/asf/tez/blob/a4f6831b/tez-ui2/src/main/webapp/app/adapters/abstract.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/abstract.js b/tez-ui2/src/main/webapp/app/adapters/abstract.js
index b412a46..6cb701b 100644
--- a/tez-ui2/src/main/webapp/app/adapters/abstract.js
+++ b/tez-ui2/src/main/webapp/app/adapters/abstract.js
@@ -28,15 +28,12 @@ export default LoaderAdapter.extend({
     return this.get(`hosts.${serverName}`);
   }),
   namespace: Ember.computed("serverName", function () {
-    var serverName = this.get("serverName"),
-        env = this.get("env");
-    return env.getAppConfig(`namespaces.webService.${serverName}`);
+    var serverName = this.get("serverName");
+    return this.get(`env.app.namespaces.webService.${serverName}`);
   }),
   pathTypeHash: Ember.computed("serverName", function () {
-    var serverName = this.get("serverName"),
-        env = this.get("env");
-
-    return env.getAppConfig(`paths.${serverName}`);
+    var serverName = this.get("serverName");
+    return this.get(`env.app.paths.${serverName}`);
   }),
 
   ajaxOptions: function(url, method, options) {

http://git-wip-us.apache.org/repos/asf/tez/blob/a4f6831b/tez-ui2/src/main/webapp/app/adapters/am.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/am.js b/tez-ui2/src/main/webapp/app/adapters/am.js
new file mode 100644
index 0000000..f80cdd5
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/adapters/am.js
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import AbstractAdapter from './abstract';
+
+export default AbstractAdapter.extend({
+  serverName: "am",
+
+  // Any am specific adapter changes must be added here
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a4f6831b/tez-ui2/src/main/webapp/app/adapters/rm.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/rm.js b/tez-ui2/src/main/webapp/app/adapters/rm.js
new file mode 100644
index 0000000..b87c77d
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/adapters/rm.js
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import AbstractAdapter from './abstract';
+
+export default AbstractAdapter.extend({
+  serverName: "rm",
+
+  // Any rm specific adapter changes must be added here
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a4f6831b/tez-ui2/src/main/webapp/app/adapters/timeline.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/timeline.js b/tez-ui2/src/main/webapp/app/adapters/timeline.js
index aba7e1e..454cbc9 100644
--- a/tez-ui2/src/main/webapp/app/adapters/timeline.js
+++ b/tez-ui2/src/main/webapp/app/adapters/timeline.js
@@ -20,4 +20,6 @@ import AbstractAdapter from './abstract';
 
 export default AbstractAdapter.extend({
   serverName: "timeline",
+
+  // Any timeline specific adapter changes must be added here
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/a4f6831b/tez-ui2/src/main/webapp/app/services/env.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/services/env.js b/tez-ui2/src/main/webapp/app/services/env.js
index 397293d..bd7dde7 100644
--- a/tez-ui2/src/main/webapp/app/services/env.js
+++ b/tez-ui2/src/main/webapp/app/services/env.js
@@ -24,32 +24,28 @@ import environment from '../config/environment';
 var MoreObject = more.Object;
 
 export default Ember.Service.extend({
-  _configs: null,
+  ENV: null,
 
   init: function () {
     this.collateConfigs();
   },
 
   collateConfigs: function () {
-    var configs = {},
+    var collatedENV = {
+          APP: {}
+        },
         ENV = window.ENV;
 
-    MoreObject.merge(configs, environment);
+    MoreObject.merge(collatedENV, environment);
 
     if(ENV) {
-      MoreObject.merge(configs.APP, ENV);
+      MoreObject.merge(collatedENV.APP, ENV);
     }
 
-    this.set("_configs", configs);
+    this.set("ENV", collatedENV);
   },
 
-  getConfig: function (path) {
-    var configs = this.get("_configs");
-    return Ember.get(configs, path);
-  },
-
-  getAppConfig: function (path) {
-    var configs = this.get("_configs.APP");
-    return Ember.get(configs, path);
-  }
+  app: Ember.computed("ENV.APP", function () {
+    return this.get("ENV.APP");
+  })
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/a4f6831b/tez-ui2/src/main/webapp/app/services/hosts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/services/hosts.js b/tez-ui2/src/main/webapp/app/services/hosts.js
index 07de04d..a3dc1f3 100644
--- a/tez-ui2/src/main/webapp/app/services/hosts.js
+++ b/tez-ui2/src/main/webapp/app/services/hosts.js
@@ -56,13 +56,11 @@ export default Ember.Service.extend({
   },
 
   timeline: Ember.computed(function () {
-    var env = this.get("env");
-    return this.normalizeURL(env.getAppConfig("hosts.timeline"));
+    return this.normalizeURL(this.get("env.app.hosts.timeline"));
   }),
 
   rm: Ember.computed(function () {
-    var env = this.get("env");
-    return this.normalizeURL(env.getAppConfig("hosts.rm"));
+    return this.normalizeURL(this.get("env.app.hosts.rm"));
   }),
 
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/a4f6831b/tez-ui2/src/main/webapp/config/default-app-conf.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/config/default-app-conf.js b/tez-ui2/src/main/webapp/config/default-app-conf.js
index 51a2e81..31a946f 100644
--- a/tez-ui2/src/main/webapp/config/default-app-conf.js
+++ b/tez-ui2/src/main/webapp/config/default-app-conf.js
@@ -24,15 +24,12 @@ module.exports = { // Tez App configurations
   namespaces: {
     webService: {
       timeline: 'ws/v1/timeline',
-      history: 'ws/v1/applicationhistory',
-      am: {
-        v1: 'proxy/__app_id__/ws/v1/tez',
-        v2: 'proxy/__app_id__/ws/v2/tez',
-      },
-      cluster: 'ws/v1/cluster',
+      appHistory: 'ws/v1/applicationhistory',
+      rm: 'ws/v1/cluster',
+      am: 'proxy/{app_id}/ws/v{version}/tez',
     },
     web: {
-      cluster: 'cluster'
+      rm: 'cluster'
     },
   },
   paths: {

http://git-wip-us.apache.org/repos/asf/tez/blob/a4f6831b/tez-ui2/src/main/webapp/tests/unit/adapters/abstract-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/abstract-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/abstract-test.js
index bc00679..5ff39e7 100644
--- a/tez-ui2/src/main/webapp/tests/unit/adapters/abstract-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/adapters/abstract-test.js
@@ -37,6 +37,34 @@ test('Basic creation test', function(assert) {
   assert.ok(adapter.pathForType);
 });
 
+test('host, namespace & pathTypeHash test', function(assert) {
+  let adapter = this.subject(),
+      testServerName = "sn",
+      testHosts = {
+        sn: "foo.bar",
+      },
+      testENV = {
+        app: {
+          namespaces: {
+            webService: {
+              sn: "ws"
+            }
+          },
+          paths: {
+            sn: "path"
+          }
+        }
+      };
+
+  adapter.hosts = testHosts;
+  adapter.env = testENV;
+  adapter.set("serverName", testServerName);
+
+  assert.equal(adapter.get("host"), testHosts.sn);
+  assert.equal(adapter.get("namespace"), testENV.app.namespaces.webService.sn);
+  assert.equal(adapter.get("pathTypeHash"), testENV.app.paths.sn);
+});
+
 test('ajaxOptions test', function(assert) {
   let adapter = this.subject(),
       testUrl = "foo.bar",

http://git-wip-us.apache.org/repos/asf/tez/blob/a4f6831b/tez-ui2/src/main/webapp/tests/unit/adapters/am-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/am-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/am-test.js
new file mode 100644
index 0000000..a452467
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/adapters/am-test.js
@@ -0,0 +1,31 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('adapter:am', 'Unit | Adapter | am', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let adapter = this.subject();
+
+  assert.ok(adapter);
+  assert.equal(adapter.serverName, "am");
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a4f6831b/tez-ui2/src/main/webapp/tests/unit/adapters/rm-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/rm-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/rm-test.js
new file mode 100644
index 0000000..0b0445e
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/adapters/rm-test.js
@@ -0,0 +1,31 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('adapter:rm', 'Unit | Adapter | rm', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let adapter = this.subject();
+
+  assert.ok(adapter);
+  assert.equal(adapter.serverName, "rm");
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a4f6831b/tez-ui2/src/main/webapp/tests/unit/services/env-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/services/env-test.js b/tez-ui2/src/main/webapp/tests/unit/services/env-test.js
index a8a064b..5064fc3 100644
--- a/tez-ui2/src/main/webapp/tests/unit/services/env-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/services/env-test.js
@@ -29,9 +29,9 @@ test('Basic creation test', function(assert) {
   let service = this.subject();
 
   assert.ok(service);
+  assert.ok(service.ENV);
   assert.ok(service.collateConfigs);
-  assert.ok(service.getConfig);
-  assert.ok(service.getAppConfig);
+  assert.ok(service.app);
 });
 
 test('collateConfigs test', function(assert) {
@@ -46,25 +46,28 @@ test('collateConfigs test', function(assert) {
 
   service.collateConfigs();
 
-  APP = service._configs.APP;
+  APP = service.get("app");
   assert.equal(APP.a, 1, "Test window.ENV merge onto environment.APP");
   assert.equal(APP.b, 22);
 });
 
-test('getConfig test', function(assert) {
-  let service = this.subject();
+test('app computed property test', function(assert) {
+  let service = this.subject(),
+      ENV = {
+        b: 2
+      };
 
-  window.ENV = {};
-  environment.a = 11;
+  window.ENV = ENV;
+  environment.APP.a = 11;
   service.collateConfigs();
-  assert.equal(service.getConfig("a"), environment.a);
+  assert.equal(service.get("app.a"), environment.APP.a);
+  assert.equal(service.get("app.b"), ENV.b);
 });
 
-test('getAppConfig test', function(assert) {
+test('Validate config/default-app-conf.js', function(assert) {
   let service = this.subject();
 
-  window.ENV = {};
-  environment.APP.a = 11;
-  service.collateConfigs();
-  assert.equal(service.getAppConfig("a"), environment.APP.a);
+  assert.equal(service.get("app.hosts.timeline"), "localhost:8188");
+  assert.equal(service.get("app.namespaces.webService.timeline"), "ws/v1/timeline");
+  assert.equal(service.get("app.paths.timeline.dag"), "TEZ_DAG_ID");
 });


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

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


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

Branch: refs/heads/TEZ-2980
Commit: fd75e332f0e35dfe67c5bc8e7e7b4b5c4ed789ac
Parents: 055d469
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Wed Dec 30 16:59:14 2015 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Wed Jan 20 22:26:20 2016 +0530

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


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

http://git-wip-us.apache.org/repos/asf/tez/blob/fd75e332/tez-ui2/src/main/webapp/app/adapters/abstract.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/abstract.js b/tez-ui2/src/main/webapp/app/adapters/abstract.js
new file mode 100644
index 0000000..aca0faf
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/adapters/abstract.js
@@ -0,0 +1,54 @@
+/*global more*/
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import DS from 'ember-data';
+
+var MoreString = more.String;
+
+export default DS.RESTAdapter.extend({
+  ajax: function(url, method, hash) {
+    return this._super(url, method, Ember.$.extend(hash || {}, {
+      crossDomain: true,
+      xhrFields: {
+        withCredentials: true
+      }
+    }));
+  },
+  buildURL: function(type, id, record) {
+    var url = this._super(type, undefined, record);
+    return MoreString.fmt(url, record);
+  },
+  findQuery: function(store, type, query) {
+    var record = query.metadata;
+    delete query.metadata;
+
+    return this.ajax(this.buildURL(
+        Ember.String.pluralize(type.typeKey),
+        record.id,
+        Ember.Object.create(record)
+      ),
+      'GET',
+      {
+        data: query
+      }
+    );
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/fd75e332/tez-ui2/src/main/webapp/app/initializers/local-storage.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/initializers/local-storage.js b/tez-ui2/src/main/webapp/app/initializers/local-storage.js
new file mode 100644
index 0000000..8504c35
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/initializers/local-storage.js
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export function initialize(application) {
+  application.inject('controller', 'localStorage', 'service:localStorage');
+}
+
+export default {
+  name: 'local-storage',
+  initialize
+};

http://git-wip-us.apache.org/repos/asf/tez/blob/fd75e332/tez-ui2/src/main/webapp/app/models/abstract.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/abstract.js b/tez-ui2/src/main/webapp/app/models/abstract.js
new file mode 100644
index 0000000..2191d18
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/models/abstract.js
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import DS from 'ember-data';
+
+export default DS.Model.extend({
+  timeStamp: null,
+
+  refreshTimestamp: function () {
+    this.set('timeStamp', new Date());
+  },
+
+  actions: {
+    didUpdate: function () {
+      this.refreshTimestamp();
+    }
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/fd75e332/tez-ui2/src/main/webapp/app/routes/abstract.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/abstract.js b/tez-ui2/src/main/webapp/app/routes/abstract.js
new file mode 100644
index 0000000..a4d2bb5
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/abstract.js
@@ -0,0 +1,32 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Route.extend({
+  title: null, // Must be set by inheriting class
+
+  setDocTitle: function () {
+    Ember.$(document).attr('title', this.get('title'));
+  },
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    this.setDocTitle();
+  }
+});

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

http://git-wip-us.apache.org/repos/asf/tez/blob/fd75e332/tez-ui2/src/main/webapp/app/services/local-storage.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/services/local-storage.js b/tez-ui2/src/main/webapp/app/services/local-storage.js
new file mode 100644
index 0000000..d25ef9d
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/services/local-storage.js
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Service.extend({
+  getStoreKey: function (key) {
+    return "tez-ui:" + key;
+  },
+  set: function (key, value) {
+    try {
+      localStorage.setItem(this.getStoreKey(key) , JSON.stringify(value));
+    }catch(e){
+      return e;
+    }
+    return value;
+  },
+  get: function (key) {
+    try {
+      return JSON.parse(localStorage.getItem(this.getStoreKey(key)));
+    }catch(e){}
+    return undefined;
+  }
+});

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

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

http://git-wip-us.apache.org/repos/asf/tez/blob/fd75e332/tez-ui2/src/main/webapp/tests/unit/adapters/abstract-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/abstract-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/abstract-test.js
new file mode 100644
index 0000000..00be0ac
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/adapters/abstract-test.js
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('adapter:abstract', 'Unit | Adapter | abstract', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:foo']
+});
+
+test('Basic creation', function(assert) {
+  let adapter = this.subject();
+
+  assert.ok(adapter);
+});
+
+test('buildURL test', function(assert) {
+  let adapter = this.subject();
+
+  assert.equal(adapter.buildURL("{x}/{y}/type", null, {
+    x: "x_x",
+    y: "y_y"
+  }), "/x_x/y_y/types");
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/fd75e332/tez-ui2/src/main/webapp/tests/unit/initializers/local-storage-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/initializers/local-storage-test.js b/tez-ui2/src/main/webapp/tests/unit/initializers/local-storage-test.js
new file mode 100644
index 0000000..f600fdc
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/initializers/local-storage-test.js
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import LocalStorageInitializer from '../../../initializers/local-storage';
+import { module, test } from 'qunit';
+
+let application;
+
+module('Unit | Initializer | local storage', {
+  beforeEach() {
+    Ember.run(function() {
+      application = Ember.Application.create();
+      application.deferReadiness();
+    });
+  }
+});
+
+test('it works', function(assert) {
+  LocalStorageInitializer.initialize(application);
+
+  // you would normally confirm the results of the initializer here
+  assert.ok(true);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/fd75e332/tez-ui2/src/main/webapp/tests/unit/models/abstract-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/abstract-test.js b/tez-ui2/src/main/webapp/tests/unit/models/abstract-test.js
new file mode 100644
index 0000000..42fe21c
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/models/abstract-test.js
@@ -0,0 +1,29 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleForModel, test } from 'ember-qunit';
+
+moduleForModel('abstract', 'Unit | Model | abstract', {
+  // Specify the other units that are required for this test.
+  needs: []
+});
+
+test('Basic test for existence', function(assert) {
+  let model = this.subject();
+  assert.ok(model);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/fd75e332/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js
new file mode 100644
index 0000000..e11183e
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/abstract-test.js
@@ -0,0 +1,29 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:abstract', 'Unit | Route | abstract', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic test for existence', function(assert) {
+  let route = this.subject();
+  assert.ok(route);
+});

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

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

http://git-wip-us.apache.org/repos/asf/tez/blob/fd75e332/tez-ui2/src/main/webapp/tests/unit/services/local-storage-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/services/local-storage-test.js b/tez-ui2/src/main/webapp/tests/unit/services/local-storage-test.js
new file mode 100644
index 0000000..6f9a1af
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/services/local-storage-test.js
@@ -0,0 +1,42 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('service:local-storage', 'Unit | Service | local storage', {
+  // Specify the other units that are required for this test.
+  // needs: ['service:foo']
+});
+
+test('Test creation', function(assert) {
+  let service = this.subject();
+  assert.ok(service);
+});
+
+test('getStoreKey test', function(assert) {
+  let service = this.subject();
+
+  assert.equal(service.getStoreKey("abc"), "tez-ui:abc");
+});
+
+test('Set & get test', function(assert) {
+  let service = this.subject();
+
+  service.set("abc", "value");
+  assert.equal(service.get("abc"), "value");
+});


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

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


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

Branch: refs/heads/TEZ-2980
Commit: 025bbb718f29debcb14a1d94d246f3bafe2f8b34
Parents: e673284
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Mon Jan 4 16:28:41 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Wed Jan 20 22:26:20 2016 +0530

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


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

http://git-wip-us.apache.org/repos/asf/tez/blob/025bbb71/tez-ui2/src/main/webapp/app/initializers/env.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/initializers/env.js b/tez-ui2/src/main/webapp/app/initializers/env.js
new file mode 100644
index 0000000..43bc291
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/initializers/env.js
@@ -0,0 +1,28 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export function initialize(application) {
+  application.inject('controller', 'env', 'service:env');
+  application.inject('route', 'env', 'service:env');
+  application.inject('adapter', 'env', 'service:env');
+}
+
+export default {
+  name: 'env',
+  initialize
+};

http://git-wip-us.apache.org/repos/asf/tez/blob/025bbb71/tez-ui2/src/main/webapp/app/services/env.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/services/env.js b/tez-ui2/src/main/webapp/app/services/env.js
new file mode 100644
index 0000000..397293d
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/services/env.js
@@ -0,0 +1,55 @@
+/*global more*/
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import environment from '../config/environment';
+
+var MoreObject = more.Object;
+
+export default Ember.Service.extend({
+  _configs: null,
+
+  init: function () {
+    this.collateConfigs();
+  },
+
+  collateConfigs: function () {
+    var configs = {},
+        ENV = window.ENV;
+
+    MoreObject.merge(configs, environment);
+
+    if(ENV) {
+      MoreObject.merge(configs.APP, ENV);
+    }
+
+    this.set("_configs", configs);
+  },
+
+  getConfig: function (path) {
+    var configs = this.get("_configs");
+    return Ember.get(configs, path);
+  },
+
+  getAppConfig: function (path) {
+    var configs = this.get("_configs.APP");
+    return Ember.get(configs, path);
+  }
+});

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

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

http://git-wip-us.apache.org/repos/asf/tez/blob/025bbb71/tez-ui2/src/main/webapp/config/default-app-conf.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/config/default-app-conf.js b/tez-ui2/src/main/webapp/config/default-app-conf.js
new file mode 100644
index 0000000..c8f6dd9
--- /dev/null
+++ b/tez-ui2/src/main/webapp/config/default-app-conf.js
@@ -0,0 +1,38 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module.exports = { // Tez App configurations
+  hosts: {
+    timeline: 'localhost:8188',
+    rm: 'localhost:8088',
+  },
+  namespaces: {
+    webService: {
+      timeline: 'ws/v1/timeline',
+      history: 'ws/v1/applicationhistory',
+      am: {
+        v1: 'proxy/__app_id__/ws/v1/tez',
+        v2: 'proxy/__app_id__/ws/v2/tez',
+      },
+      cluster: 'ws/v1/cluster',
+    },
+    web: {
+      cluster: 'cluster'
+    },
+  },
+};

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

http://git-wip-us.apache.org/repos/asf/tez/blob/025bbb71/tez-ui2/src/main/webapp/tests/unit/initializers/env-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/initializers/env-test.js b/tez-ui2/src/main/webapp/tests/unit/initializers/env-test.js
new file mode 100644
index 0000000..7f6f287
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/initializers/env-test.js
@@ -0,0 +1,40 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import EnvInitializer from '../../../initializers/env';
+import { module, test } from 'qunit';
+
+let application;
+
+module('Unit | Initializer | env', {
+  beforeEach() {
+    Ember.run(function() {
+      application = Ember.Application.create();
+      application.deferReadiness();
+    });
+  }
+});
+
+// Replace this with your real tests.
+test('it works', function(assert) {
+  EnvInitializer.initialize(application);
+
+  // you would normally confirm the results of the initializer here
+  assert.ok(true);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/025bbb71/tez-ui2/src/main/webapp/tests/unit/services/env-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/services/env-test.js b/tez-ui2/src/main/webapp/tests/unit/services/env-test.js
new file mode 100644
index 0000000..a8a064b
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/services/env-test.js
@@ -0,0 +1,70 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+import environment from '../../../config/environment';
+
+moduleFor('service:env', 'Unit | Service | env', {
+  // Specify the other units that are required for this test.
+  // needs: ['service:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let service = this.subject();
+
+  assert.ok(service);
+  assert.ok(service.collateConfigs);
+  assert.ok(service.getConfig);
+  assert.ok(service.getAppConfig);
+});
+
+test('collateConfigs test', function(assert) {
+  let service = this.subject(),
+      APP = environment.APP;
+
+  APP.a = 11;
+  APP.b = 22;
+  window.ENV = {
+    a: 1
+  };
+
+  service.collateConfigs();
+
+  APP = service._configs.APP;
+  assert.equal(APP.a, 1, "Test window.ENV merge onto environment.APP");
+  assert.equal(APP.b, 22);
+});
+
+test('getConfig test', function(assert) {
+  let service = this.subject();
+
+  window.ENV = {};
+  environment.a = 11;
+  service.collateConfigs();
+  assert.equal(service.getConfig("a"), environment.a);
+});
+
+test('getAppConfig test', function(assert) {
+  let service = this.subject();
+
+  window.ENV = {};
+  environment.APP.a = 11;
+  service.collateConfigs();
+  assert.equal(service.getAppConfig("a"), environment.APP.a);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/025bbb71/tez-ui2/src/main/webapp/tests/unit/services/hosts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/services/hosts-test.js b/tez-ui2/src/main/webapp/tests/unit/services/hosts-test.js
index 055fccd..026f21b 100644
--- a/tez-ui2/src/main/webapp/tests/unit/services/hosts-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/services/hosts-test.js
@@ -20,7 +20,7 @@ import { moduleFor, test } from 'ember-qunit';
 
 moduleFor('service:hosts', 'Unit | Service | hosts', {
   // Specify the other units that are required for this test.
-  // needs: ['service:foo']
+  needs: ['service:env']
 });
 
 test('Test creation', function(assert) {
@@ -67,8 +67,10 @@ test('Test host URLs with ENV set', function(assert) {
   let service = this.subject();
 
   window.ENV = {
-    timelineHost: "https://localhost:3333",
-    rmHost: "https://localhost:4444"
+    hosts: {
+      timeline: "https://localhost:3333",
+      rm: "https://localhost:4444"
+    }
   };
   assert.equal(service.get("timeline"), "http://localhost:3333");
   assert.equal(service.get("rm"), "http://localhost:4444");


[50/50] [abbrv] tez git commit: Merge branch 'TEZ-2980' of https://git-wip-us.apache.org/repos/asf/tez into TEZ-2980

Posted by sr...@apache.org.
Merge branch 'TEZ-2980' of https://git-wip-us.apache.org/repos/asf/tez into TEZ-2980


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

Branch: refs/heads/TEZ-2980
Commit: 8d80272ca0e27287aa2b95eb3b23e75a67b957c7
Parents: 62deacb d36f906
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Wed Jan 20 22:34:39 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Wed Jan 20 22:34:39 2016 +0530

----------------------------------------------------------------------

----------------------------------------------------------------------



[09/50] [abbrv] tez git commit: TEZ-3025. InputInitializer creation should use the dag ugi. (sseth)

Posted by sr...@apache.org.
TEZ-3025. InputInitializer creation should use the dag ugi. (sseth)


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

Branch: refs/heads/TEZ-2980
Commit: d5c9649e5849021dd1bfdb796d821f7a1524aaf0
Parents: 9816a49
Author: Siddharth Seth <ss...@apache.org>
Authored: Thu Jan 7 17:38:40 2016 -0800
Committer: Siddharth Seth <ss...@apache.org>
Committed: Thu Jan 7 17:38:40 2016 -0800

----------------------------------------------------------------------
 CHANGES.txt                                     |  2 +
 .../app/dag/RootInputInitializerManager.java    | 32 +++++++--
 .../dag/TestRootInputInitializerManager.java    | 71 ++++++++++++++++++++
 3 files changed, 98 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/d5c9649e/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index ce35fd1..5e944b6 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -11,6 +11,7 @@ INCOMPATIBLE CHANGES
   TEZ-2972. Avoid task rescheduling when a node turns unhealthy
 
 ALL CHANGES:
+  TEZ-3025. InputInitializer creation should use the dag ugi.
   TEZ-3017. HistoryACLManager does not have a close method for cleanup
   TEZ-2914. Ability to limit vertex concurrency
   TEZ-3011. Link Vertex Name in Dag Tasks/Task Attempts to Vertex
@@ -301,6 +302,7 @@ INCOMPATIBLE CHANGES
   TEZ-2949. Allow duplicate dag names within session for Tez.
 
 ALL CHANGES
+  TEZ-3025. InputInitializer creation should use the dag ugi.
   TEZ-3017. HistoryACLManager does not have a close method for cleanup
   TEZ-2914. Ability to limit vertex concurrency
   TEZ-2918. Make progress notifications in IOs

http://git-wip-us.apache.org/repos/asf/tez/blob/d5c9649e/tez-dag/src/main/java/org/apache/tez/dag/app/dag/RootInputInitializerManager.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/RootInputInitializerManager.java b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/RootInputInitializerManager.java
index 57a7172..e03b469 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/RootInputInitializerManager.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/RootInputInitializerManager.java
@@ -20,6 +20,7 @@ package org.apache.tez.dag.app.dag;
 
 import javax.annotation.Nullable;
 
+import java.io.IOException;
 import java.lang.reflect.UndeclaredThrowableException;
 import java.security.PrivilegedExceptionAction;
 import java.util.Collection;
@@ -107,7 +108,7 @@ public class RootInputInitializerManager {
     this.entityStateTracker = stateTracker;
   }
   
-  public void runInputInitializers(List<RootInputLeafOutput<InputDescriptor, InputInitializerDescriptor>> 
+  public void runInputInitializers(List<RootInputLeafOutput<InputDescriptor, InputInitializerDescriptor>>
       inputs) throws TezException {
     for (RootInputLeafOutput<InputDescriptor, InputInitializerDescriptor> input : inputs) {
 
@@ -141,12 +142,29 @@ public class RootInputInitializerManager {
   }
 
   @VisibleForTesting
-  protected InputInitializer createInitializer(RootInputLeafOutput<InputDescriptor, InputInitializerDescriptor>
-      input, InputInitializerContext context) throws TezException {
-    InputInitializer initializer = ReflectionUtils
-        .createClazzInstance(input.getControllerDescriptor().getClassName(),
-            new Class[]{InputInitializerContext.class}, new Object[]{context});
-    return initializer;
+  protected InputInitializer createInitializer(final RootInputLeafOutput<InputDescriptor, InputInitializerDescriptor>
+      input, final InputInitializerContext context) throws TezException {
+    try {
+      return dagUgi.doAs(new PrivilegedExceptionAction<InputInitializer>() {
+        @Override
+        public InputInitializer run() throws Exception {
+          InputInitializer initializer = ReflectionUtils
+              .createClazzInstance(input.getControllerDescriptor().getClassName(),
+                  new Class[]{InputInitializerContext.class}, new Object[]{context});
+          return initializer;
+        }
+      });
+    } catch (IOException e) {
+      throw new TezException(e);
+    } catch (InterruptedException e) {
+      throw new TezException(e);
+    } catch (UndeclaredThrowableException e) {
+      if (e.getCause() instanceof TezException) {
+        throw (TezException) e.getCause();
+      } else {
+        throw e;
+      }
+    }
   }
 
   public void handleInitializerEvents(List<TezEvent> events) {

http://git-wip-us.apache.org/repos/asf/tez/blob/d5c9649e/tez-dag/src/test/java/org/apache/tez/dag/app/dag/TestRootInputInitializerManager.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/dag/TestRootInputInitializerManager.java b/tez-dag/src/test/java/org/apache/tez/dag/app/dag/TestRootInputInitializerManager.java
index 89eb2a6..b79b4af 100644
--- a/tez-dag/src/test/java/org/apache/tez/dag/app/dag/TestRootInputInitializerManager.java
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/dag/TestRootInputInitializerManager.java
@@ -25,19 +25,26 @@ import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import java.io.IOException;
+import java.util.Collections;
 import java.util.List;
 
 import com.google.common.collect.Lists;
+import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.hadoop.yarn.api.records.ApplicationId;
+import org.apache.hadoop.yarn.event.EventHandler;
 import org.apache.tez.dag.api.InputDescriptor;
 import org.apache.tez.dag.api.InputInitializerDescriptor;
 import org.apache.tez.dag.api.RootInputLeafOutput;
+import org.apache.tez.dag.api.TezException;
 import org.apache.tez.dag.api.oldrecords.TaskState;
 import org.apache.tez.dag.app.AppContext;
 import org.apache.tez.dag.records.TezDAGID;
 import org.apache.tez.dag.records.TezTaskAttemptID;
 import org.apache.tez.dag.records.TezTaskID;
 import org.apache.tez.dag.records.TezVertexID;
+import org.apache.tez.hadoop.shim.DefaultHadoopShim;
+import org.apache.tez.runtime.api.Event;
 import org.apache.tez.runtime.api.InputInitializer;
 import org.apache.tez.runtime.api.InputInitializerContext;
 import org.apache.tez.runtime.api.events.InputInitializerEvent;
@@ -198,4 +205,68 @@ public class TestRootInputInitializerManager {
 
     verify(initializer, never()).handleInputInitializerEvent(any(List.class));
   }
+
+
+  @Test (timeout = 5000)
+  public void testCorrectUgiUsage() throws TezException, InterruptedException {
+    Vertex vertex = mock(Vertex.class);
+    doReturn(mock(TezVertexID.class)).when(vertex).getVertexId();
+    AppContext appContext = mock(AppContext.class);
+    doReturn(new DefaultHadoopShim()).when(appContext).getHadoopShim();
+    doReturn(mock(EventHandler.class)).when(appContext).getEventHandler();
+    UserGroupInformation dagUgi = UserGroupInformation.createRemoteUser("fakeuser");
+    StateChangeNotifier stateChangeNotifier = mock(StateChangeNotifier.class);
+    RootInputInitializerManager rootInputInitializerManager = new RootInputInitializerManager(vertex, appContext, dagUgi, stateChangeNotifier);
+
+    InputDescriptor id = mock(InputDescriptor.class);
+    InputInitializerDescriptor iid = InputInitializerDescriptor.create(InputInitializerForUgiTest.class.getName());
+    RootInputLeafOutput<InputDescriptor, InputInitializerDescriptor> rootInput =
+        new RootInputLeafOutput<>("InputName", id, iid);
+    rootInputInitializerManager.runInputInitializers(Collections.singletonList(rootInput));
+
+    InputInitializerForUgiTest.awaitInitialize();
+
+    assertEquals(dagUgi, InputInitializerForUgiTest.ctorUgi);
+    assertEquals(dagUgi, InputInitializerForUgiTest.initializeUgi);
+  }
+
+  public static class InputInitializerForUgiTest extends InputInitializer {
+
+    static volatile UserGroupInformation ctorUgi;
+    static volatile UserGroupInformation initializeUgi;
+
+    static boolean initialized = false;
+    static final Object initializeSync = new Object();
+
+    public InputInitializerForUgiTest(InputInitializerContext initializerContext) {
+      super(initializerContext);
+      try {
+        ctorUgi = UserGroupInformation.getCurrentUser();
+      } catch (IOException e) {
+        throw new RuntimeException(e);
+      }
+    }
+
+    @Override
+    public List<Event> initialize() throws Exception {
+      initializeUgi = UserGroupInformation.getCurrentUser();
+      synchronized (initializeSync) {
+        initialized = true;
+        initializeSync.notify();
+      }
+      return null;
+    }
+
+    @Override
+    public void handleInputInitializerEvent(List<InputInitializerEvent> events) throws Exception {
+    }
+
+    static void awaitInitialize() throws InterruptedException {
+      synchronized (initializeSync) {
+        while (!initialized) {
+          initializeSync.wait();
+        }
+      }
+    }
+  }
 }


[47/50] [abbrv] tez git commit: TEZ-3040. Tez UI 2: Create Vertex details page & sub tables (sree)

Posted by sr...@apache.org.
TEZ-3040. Tez UI 2: Create Vertex details page & sub tables (sree)


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

Branch: refs/heads/TEZ-2980
Commit: 04db54345114ae54e0db6e7aa61070e73c32356b
Parents: 7a8d826
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Tue Jan 19 00:23:31 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Wed Jan 20 22:30:07 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |   1 +
 tez-ui2/src/main/webapp/app/controllers/dag.js  |   4 +-
 .../main/webapp/app/controllers/dag/attempts.js |  12 +-
 .../main/webapp/app/controllers/dag/tasks.js    |  10 +-
 .../main/webapp/app/controllers/dag/vertices.js |  12 ++
 .../src/main/webapp/app/controllers/vertex.js   |  49 +++++++
 .../webapp/app/controllers/vertex/attempts.js   |  77 +++++++++++
 .../main/webapp/app/controllers/vertex/index.js |  22 ++++
 .../main/webapp/app/controllers/vertex/tasks.js |  65 ++++++++++
 tez-ui2/src/main/webapp/app/models/vertex.js    |  20 ++-
 tez-ui2/src/main/webapp/app/router.js           |   4 +
 .../src/main/webapp/app/routes/dag/attempts.js  |   2 +-
 tez-ui2/src/main/webapp/app/routes/vertex.js    |  31 +++++
 .../main/webapp/app/routes/vertex/attempts.js   |  35 +++++
 .../src/main/webapp/app/routes/vertex/index.js  |  33 +++++
 .../src/main/webapp/app/routes/vertex/tasks.js  |  35 +++++
 .../src/main/webapp/app/serializers/vertex.js   |  11 +-
 .../src/main/webapp/app/styles/page-layout.less |   5 +-
 .../src/main/webapp/app/templates/dag/index.hbs |  97 +++++++-------
 .../src/main/webapp/app/templates/vertex.hbs    |  20 +++
 .../webapp/app/templates/vertex/attempts.hbs    |  33 +++++
 .../main/webapp/app/templates/vertex/index.hbs  | 130 +++++++++++++++++++
 .../main/webapp/app/templates/vertex/tasks.hbs  |  33 +++++
 .../tests/unit/controllers/vertex-test.js       |  36 +++++
 .../unit/controllers/vertex/attempts-test.js    |  36 +++++
 .../tests/unit/controllers/vertex/index-test.js |  34 +++++
 .../tests/unit/controllers/vertex/tasks-test.js |  36 +++++
 .../webapp/tests/unit/routes/vertex-test.js     |  32 +++++
 .../tests/unit/routes/vertex/attempts-test.js   |  45 +++++++
 .../tests/unit/routes/vertex/index-test.js      |  45 +++++++
 .../tests/unit/routes/vertex/tasks-test.js      |  45 +++++++
 31 files changed, 987 insertions(+), 63 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/04db5434/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index 372369a..3389c46 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -15,3 +15,4 @@ ALL CHANGES:
   TEZ-2986. Tez UI 2: Implement All DAGs page
   TEZ-3038. Tez UI 2: Create DAG details page
   TEZ-3039. Tez UI 2: Create all sub-pages for DAG
+  TEZ-3040. Tez UI 2: Create Vertex details page & sub tables

http://git-wip-us.apache.org/repos/asf/tez/blob/04db5434/tez-ui2/src/main/webapp/app/controllers/dag.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag.js b/tez-ui2/src/main/webapp/app/controllers/dag.js
index f54d8cf..732a0df 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag.js
@@ -25,7 +25,7 @@ export default AbstractController.extend({
     var name = this.get("model.name");
 
     return [{
-      text: `DAG [${name}]`,
+      text: `DAG [ ${name} ]`,
       routeName: "dag.index",
       model: this.get("model.entityID")
     }];
@@ -41,7 +41,7 @@ export default AbstractController.extend({
     text: "All Tasks",
     routeName: "dag.tasks"
   }, {
-    text: "All Attempts",
+    text: "All Task Attempts",
     routeName: "dag.attempts"
   }]
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/04db5434/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js b/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
index 1ffc00c..c2e3950 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
@@ -21,7 +21,7 @@ import ColumnDefinition from 'em-table/utils/column-definition';
 
 export default TablePageController.extend({
   breadcrumbs: [{
-    text: "All Attempts",
+    text: "All Task Attempts",
     routeName: "dag.attempts",
   }],
 
@@ -36,7 +36,15 @@ export default TablePageController.extend({
   },{
     id: 'vertexName',
     headerTitle: 'Vertex Index',
-    contentPath: 'vertexName'
+    contentPath: 'vertexName',
+    cellComponentName: 'em-table-linked-cell',
+    getCellContent: function (row) {
+      return {
+        routeName: "vertex",
+        model: row.get("vertexID"),
+        text: row.get("vertexName")
+      };
+    }
   },{
     id: 'status',
     headerTitle: 'Status',

http://git-wip-us.apache.org/repos/asf/tez/blob/04db5434/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js b/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
index 7c91deb..4721b81 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
@@ -32,7 +32,15 @@ export default TablePageController.extend({
   },{
     id: 'vertexName',
     headerTitle: 'Vertex Name',
-    contentPath: 'vertexName'
+    contentPath: 'vertexName',
+    cellComponentName: 'em-table-linked-cell',
+    getCellContent: function (row) {
+      return {
+        routeName: "vertex",
+        model: row.get("vertexID"),
+        text: row.get("vertexName")
+      };
+    }
   },{
     id: 'status',
     headerTitle: 'Status',

http://git-wip-us.apache.org/repos/asf/tez/blob/04db5434/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js b/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
index 7bdc229..b20a558 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
@@ -29,6 +29,14 @@ export default TablePageController.extend({
     id: 'name',
     headerTitle: 'Vertex Name',
     contentPath: 'name',
+    cellComponentName: 'em-table-linked-cell',
+    getCellContent: function (row) {
+      return {
+        routeName: "vertex",
+        model: row.get("entityID"),
+        text: row.get("name")
+      };
+    }
   },{
     id: 'entityID',
     headerTitle: 'Vertex Id',
@@ -73,6 +81,10 @@ export default TablePageController.extend({
      type: 'date'
     }
   },{
+    id: 'totalTasks',
+    headerTitle: 'Tasks',
+    contentPath: 'totalTasks',
+  },{
     id: 'processorClassName',
     headerTitle: 'Processor Class',
     contentPath: 'processorClassName',

http://git-wip-us.apache.org/repos/asf/tez/blob/04db5434/tez-ui2/src/main/webapp/app/controllers/vertex.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/vertex.js b/tez-ui2/src/main/webapp/app/controllers/vertex.js
new file mode 100644
index 0000000..946eaa5
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/vertex.js
@@ -0,0 +1,49 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import AbstractController from './abstract';
+
+export default AbstractController.extend({
+  breadcrumbs: Ember.computed("model.dag", function () {
+    var dagName = this.get("model.dag.name"),
+        vertexName = this.get("model.name");
+
+    return [{
+      text: `DAG [ ${dagName} ]`,
+      routeName: "dag.index",
+      model: this.get("model.dagID")
+    },{
+      text: `Vertex [ ${vertexName} ]`,
+      routeName: "vertex.index",
+      model: this.get("model.vertexID")
+    }];
+  }),
+
+  tabs: [{
+    text: "Vertex Details",
+    routeName: "vertex.index"
+  }, {
+    text: "Tasks",
+    routeName: "vertex.tasks"
+  }, {
+    text: "Task Attempts",
+    routeName: "vertex.attempts"
+  }]
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/04db5434/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js b/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js
new file mode 100644
index 0000000..61a6a63
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/vertex/attempts.js
@@ -0,0 +1,77 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import TablePageController from '../table-page';
+import ColumnDefinition from 'em-table/utils/column-definition';
+
+export default TablePageController.extend({
+  breadcrumbs: [{
+    text: "Task Attempts",
+    routeName: "vertex.attempts",
+  }],
+
+  columns: ColumnDefinition.make([{
+    id: 'index',
+    headerTitle: 'Attempt No',
+    contentPath: 'index'
+  },{
+    id: 'taskIndex',
+    headerTitle: 'Task Index',
+    contentPath: 'taskIndex'
+  },{
+    id: 'status',
+    headerTitle: 'Status',
+    contentPath: 'status',
+    cellComponentName: 'em-table-status-cell'
+  },{
+    id: 'progress',
+    headerTitle: 'Progress',
+    contentPath: 'progress',
+    cellComponentName: 'em-table-progress-cell',
+    observePath: true
+  },{
+    id: 'startTime',
+    headerTitle: 'Start Time',
+    contentPath: 'startTime',
+    cellDefinition: {
+      type: 'date'
+    }
+  },{
+    id: 'endTime',
+    headerTitle: 'End Time',
+    contentPath: 'endTime',
+    cellDefinition: {
+      type: 'date'
+    }
+  },{
+    id: 'duration',
+    headerTitle: 'Duration',
+    contentPath: 'duration',
+    cellDefinition: {
+      type: 'duration'
+    }
+  },{
+    id: 'containerID',
+    headerTitle: 'Container',
+    contentPath: 'containerID'
+  },{
+    id: 'nodeID',
+    headerTitle: 'Node',
+    contentPath: 'nodeID'
+  }])
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/04db5434/tez-ui2/src/main/webapp/app/controllers/vertex/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/vertex/index.js b/tez-ui2/src/main/webapp/app/controllers/vertex/index.js
new file mode 100644
index 0000000..9745328
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/vertex/index.js
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import PageController from '../page';
+
+export default PageController.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/04db5434/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.js b/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.js
new file mode 100644
index 0000000..ce67150
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/vertex/tasks.js
@@ -0,0 +1,65 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import TablePageController from '../table-page';
+import ColumnDefinition from 'em-table/utils/column-definition';
+
+export default TablePageController.extend({
+  breadcrumbs: [{
+    text: "Tasks",
+    routeName: "vertex.tasks",
+  }],
+
+  columns: ColumnDefinition.make([{
+    id: 'index',
+    headerTitle: 'Task Index',
+    contentPath: 'index'
+  },{
+    id: 'status',
+    headerTitle: 'Status',
+    contentPath: 'status',
+    cellComponentName: 'em-table-status-cell'
+  },{
+    id: 'progress',
+    headerTitle: 'Progress',
+    contentPath: 'progress',
+    cellComponentName: 'em-table-progress-cell',
+    observePath: true
+  },{
+    id: 'startTime',
+    headerTitle: 'Start Time',
+    contentPath: 'startTime',
+    cellDefinition: {
+      type: 'date'
+    }
+  },{
+    id: 'endTime',
+    headerTitle: 'End Time',
+    contentPath: 'endTime',
+    cellDefinition: {
+      type: 'date'
+    }
+  },{
+    id: 'duration',
+    headerTitle: 'Duration',
+    contentPath: 'duration',
+    cellDefinition: {
+      type: 'duration'
+    }
+  }])
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/04db5434/tez-ui2/src/main/webapp/app/models/vertex.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/vertex.js b/tez-ui2/src/main/webapp/app/models/vertex.js
index dcdb0f2..4192771 100644
--- a/tez-ui2/src/main/webapp/app/models/vertex.js
+++ b/tez-ui2/src/main/webapp/app/models/vertex.js
@@ -38,13 +38,22 @@ import TimelineModel from './timeline';
 */
 
 export default TimelineModel.extend({
+  needs: {
+    dag: {
+      type: "dag",
+      idKey: "dagID",
+      silent: true
+    }
+  },
+
   name: DS.attr('string'),
 
   firstTaskStartTime: DS.attr('number'),
+  lastTaskFinishTime: DS.attr('number'),
 
-  numTasks: DS.attr('number'),
+  totalTasks: DS.attr('number'),
   failedTasks: DS.attr('number'),
-  sucessfulTasks: DS.attr('number'),
+  successfulTasks: DS.attr('number'),
   killedTasks: DS.attr('number'),
 
   runningTasks: Ember.computed("status", function () {
@@ -57,5 +66,12 @@ export default TimelineModel.extend({
   failedTaskAttempts: DS.attr('number'),
   killedTaskAttempts: DS.attr('number'),
 
+  minDuration: DS.attr('number'),
+  maxDuration: DS.attr('number'),
+  avgDuration: DS.attr('number'),
+
   processorClassName: DS.attr('string'),
+
+  dagID: DS.attr('string'),
+  dag: DS.attr('object'), // Auto-loaded by need
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/04db5434/tez-ui2/src/main/webapp/app/router.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/router.js b/tez-ui2/src/main/webapp/app/router.js
index d94a837..e80c817 100644
--- a/tez-ui2/src/main/webapp/app/router.js
+++ b/tez-ui2/src/main/webapp/app/router.js
@@ -31,6 +31,10 @@ Router.map(function() {
     this.route('attempts');
   });
   this.route('app', {path: '/app/:app_id'});
+  this.route('vertex', {path: '/vertex/:vertex_id'}, function() {
+    this.route('tasks');
+    this.route('attempts');
+  });
 });
 
 export default Router;

http://git-wip-us.apache.org/repos/asf/tez/blob/04db5434/tez-ui2/src/main/webapp/app/routes/dag/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag/attempts.js b/tez-ui2/src/main/webapp/app/routes/dag/attempts.js
index 3a05867..f438b95 100644
--- a/tez-ui2/src/main/webapp/app/routes/dag/attempts.js
+++ b/tez-ui2/src/main/webapp/app/routes/dag/attempts.js
@@ -20,7 +20,7 @@ import Ember from 'ember';
 import AbstractRoute from '../abstract';
 
 export default AbstractRoute.extend({
-  title: "All Attempts",
+  title: "All Task Attempts",
 
   setupController: function (controller, model) {
     this._super(controller, model);

http://git-wip-us.apache.org/repos/asf/tez/blob/04db5434/tez-ui2/src/main/webapp/app/routes/vertex.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/vertex.js b/tez-ui2/src/main/webapp/app/routes/vertex.js
new file mode 100644
index 0000000..2a38001
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/vertex.js
@@ -0,0 +1,31 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+  title: "Vertex",
+
+  loaderQueryParams: {
+    id: "vertex_id"
+  },
+
+  model: function (params) {
+    return this.get("loader").queryRecord('vertex', this.queryFromParams(params).id);
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/04db5434/tez-ui2/src/main/webapp/app/routes/vertex/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/vertex/attempts.js b/tez-ui2/src/main/webapp/app/routes/vertex/attempts.js
new file mode 100644
index 0000000..cead8a2
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/vertex/attempts.js
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  title: "Task Attempts",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (/*value, query*/) {
+    return this.get("loader").query('attempt', {
+      vertexID: this.modelFor("vertex").id
+    });
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/04db5434/tez-ui2/src/main/webapp/app/routes/vertex/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/vertex/index.js b/tez-ui2/src/main/webapp/app/routes/vertex/index.js
new file mode 100644
index 0000000..d05e5f6
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/vertex/index.js
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  title: "DAG Details",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (/*value, query*/) {
+    return this.get("loader").queryRecord('vertex', this.modelFor("vertex").id);
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/04db5434/tez-ui2/src/main/webapp/app/routes/vertex/tasks.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/vertex/tasks.js b/tez-ui2/src/main/webapp/app/routes/vertex/tasks.js
new file mode 100644
index 0000000..e959fef
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/vertex/tasks.js
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  title: "All Tasks",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (/*value, query*/) {
+    return this.get("loader").query('task', {
+      vertexID: this.modelFor("vertex").id
+    });
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/04db5434/tez-ui2/src/main/webapp/app/serializers/vertex.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/vertex.js b/tez-ui2/src/main/webapp/app/serializers/vertex.js
index 88ee5d3..7c36074 100644
--- a/tez-ui2/src/main/webapp/app/serializers/vertex.js
+++ b/tez-ui2/src/main/webapp/app/serializers/vertex.js
@@ -30,15 +30,22 @@ export default TimelineSerializer.extend({
     name: 'otherinfo.vertexName',
 
     firstTaskStartTime: 'otherinfo.stats.firstTaskStartTime',
+    lastTaskFinishTime: 'otherinfo.stats.lastTaskFinishTime',
 
-    numTasks: 'otherinfo.numTasks',
+    totalTasks: 'otherinfo.numTasks',
     failedTasks: 'otherinfo.numFailedTasks',
-    sucessfulTasks: 'otherinfo.numSucceededTasks',
+    successfulTasks: 'otherinfo.numSucceededTasks',
     killedTasks: 'otherinfo.numKilledTasks',
 
     failedTaskAttempts: 'otherinfo.numFailedTaskAttempts',
     killedTaskAttempts: 'otherinfo.numKilledTaskAttempts',
 
+    minDuration:  'otherinfo.stats.minTaskDuration',
+    maxDuration:  'otherinfo.stats.maxTaskDuration',
+    avgDuration:  'otherinfo.stats.avgTaskDuration',
+
     processorClassName: getProcessorClass,
+
+    dagID: 'primaryfilters.TEZ_DAG_ID.0',
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/04db5434/tez-ui2/src/main/webapp/app/styles/page-layout.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/page-layout.less b/tez-ui2/src/main/webapp/app/styles/page-layout.less
index c3530ff..5a49abc 100644
--- a/tez-ui2/src/main/webapp/app/styles/page-layout.less
+++ b/tez-ui2/src/main/webapp/app/styles/page-layout.less
@@ -124,7 +124,10 @@ body, html {
     color: @logo-orange;
   }
 
-  .footer, .footer-frame {
+  .footer-frame {
+    height: 60px;
+  }
+  .footer {
     height: 40px;
   }
 

http://git-wip-us.apache.org/repos/asf/tez/blob/04db5434/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/index.hbs b/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
index 2811a35..1bd3c21 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
@@ -24,58 +24,51 @@
       </tr>
     </thead>
     <tbody>
-    <tr>
-      <td colspan="2">
-        {{bs-button icon="fa fa-download" title="Download data" defaultText="Download data" type="info" clicked="downloadDagJson"}}
-      </td>
-    </tr>
-    <tr>
-      <td>Application ID</td>
-      <td>
-        {{#link-to 'app' model.appID class='ember-table-content'}}
-          {{model.appID}}
-        {{/link-to}}
-      </td>
-    </tr>
-    <tr>
-      <td>ID</td>
-      <td>{{model.entityID}}</td>
-    </tr>
-    <tr>
-      <td>Submitter</td>
-      <td>{{model.user}}</td>
-    </tr>
-    <tr>
-      <td>Status</td>
-      <td>
-        {{em-table-status-cell content=model.status}}
-        {{#if progressStr}} {{bs-badge content=progressStr}}{{/if}}
-        {{#if hasFailedTasks}}
-          [ <a href='{{unbound failedTasksLink}}'>Failed Tasks</a> ]
-        {{/if}}
-        {{#if hasFailedTaskAttempts}}
-          [ <a href='{{unbound failedTaskAttemptsLink}}'>Failed TaskAttempts</a> ]
-        {{/if}}
-      </td>
-    </tr>
-    <tr>
-      <td>Start Time</td>
-      <td>{{txt model.startTime type="date"}}</td>
-    </tr>
-    <tr>
-      <td>End Time</td>
-      <td>{{txt model.endTime type="date"}}</td>
-    </tr>
-    <tr>
-      <td>Duration</td>
-      <td>{{txt model.duration type="duration"}}</td>
-    </tr>
-    <tr>
-      <td>Logs</td>
-      <td>
-        {{em-table-linked-cell content=model.containerLogs}}
-      </td>
-    </tr>
+      <tr>
+        <td colspan="2">
+          {{bs-button icon="fa fa-download" title="Download data" defaultText="Download data" type="info" clicked="downloadDagJson"}}
+        </td>
+      </tr>
+      <tr>
+        <td>Application ID</td>
+        <td>
+          {{#link-to 'app' model.appID class='ember-table-content'}}
+            {{model.appID}}
+          {{/link-to}}
+        </td>
+      </tr>
+      <tr>
+        <td>ID</td>
+        <td>{{model.entityID}}</td>
+      </tr>
+      <tr>
+        <td>Submitter</td>
+        <td>{{model.user}}</td>
+      </tr>
+      <tr>
+        <td>Status</td>
+        <td>
+          {{em-table-status-cell content=model.status}}
+        </td>
+      </tr>
+      <tr>
+        <td>Start Time</td>
+        <td>{{txt model.startTime type="date"}}</td>
+      </tr>
+      <tr>
+        <td>End Time</td>
+        <td>{{txt model.endTime type="date"}}</td>
+      </tr>
+      <tr>
+        <td>Duration</td>
+        <td>{{txt model.duration type="duration"}}</td>
+      </tr>
+      <tr>
+        <td>Logs</td>
+        <td>
+          {{em-table-linked-cell content=model.containerLogs}}
+        </td>
+      </tr>
     </tbody>
   </table>
 {{else}}

http://git-wip-us.apache.org/repos/asf/tez/blob/04db5434/tez-ui2/src/main/webapp/app/templates/vertex.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/vertex.hbs b/tez-ui2/src/main/webapp/app/templates/vertex.hbs
new file mode 100644
index 0000000..308b905
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/vertex.hbs
@@ -0,0 +1,20 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+}}
+
+{{tab-n-refresh tabs=tabs}}
+{{outlet}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/04db5434/tez-ui2/src/main/webapp/app/templates/vertex/attempts.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/vertex/attempts.hbs b/tez-ui2/src/main/webapp/app/templates/vertex/attempts.hbs
new file mode 100644
index 0000000..cdb28aa
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/vertex/attempts.hbs
@@ -0,0 +1,33 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+}}
+
+{{#if loaded}}
+  {{em-table
+  columns=columns
+  rows=model
+
+  definition=definition
+
+  searchAction="searchChanged"
+  sortAction="sortChanged"
+  rowAction="rowsChanged"
+  pageAction="pageChanged"
+  }}
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/04db5434/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs b/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs
new file mode 100644
index 0000000..8183842
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/vertex/index.hbs
@@ -0,0 +1,130 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+}}
+
+{{#if loaded}}
+  <table class='detail-list'>
+    <thead>
+      <tr>
+        <th colspan=2>Description</th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>Vertex ID</td>
+        <td>{{model.entityID}}</td>
+      </tr>
+      <tr>
+        <td>Vertex Name</td>
+        <td>{{model.name}}</td>
+      </tr>
+      <tr>
+        <td>Processor Class</td>
+        <td>{{model.processorClassName}}</td>
+      </tr>
+    </tbody>
+  </table>
+
+  <br/>
+
+  <table class='detail-list'>
+    <thead>
+      <tr>
+        <th colspan=2>Details</th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>Status</td>
+        <td>{{em-table-status-cell content=model.status}}</td>
+      </tr>
+      <tr>
+        <td>Start Time</td>
+        <td>{{txt model.startTime type="date"}}</td>
+      </tr>
+      <tr>
+        <td>End Time</td>
+        <td>{{txt model.endTime type="date"}}</td>
+      </tr>
+      <tr>
+        <td>Duration</td>
+        <td>{{txt model.duration type="duration"}}</td>
+      </tr>
+      <tr>
+        <td>First Task Start Time</td>
+        <td>
+          {{txt model.firstTaskStartTime type="date"}}
+        </td>
+      </tr>
+      <tr>
+        <td>Last Task Finish Time</td>
+        <td>
+          {{txt model.lastTaskFinishTime type="date"}}
+        </td>
+      </tr>
+    </tbody>
+  </table>
+
+  <br/>
+
+  <table class='detail-list'>
+    <thead>
+      <tr>
+        <th colspan=2>Tasks of this Vertex</th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>Total Tasks</td>
+        <td>{{txt model.totalTasks type="number"}}</td>
+      </tr>
+      <tr>
+        <td>Successful Tasks</td>
+        <td>{{txt model.successfulTasks type="number"}}</td>
+      </tr>
+      <tr>
+        <td>Failed Tasks</td>
+        <td>{{txt model.failedTasks type="number"}}</td>
+      </tr>
+      <tr>
+        <td>Killed Tasks</td>
+        <td>{{txt model.killedTasks type="number"}}</td>
+      </tr>
+      <tr>
+        <td>Average Duration</td>
+        <td>
+          {{txt model.avgDuration type="duration"}}
+        </td>
+      </tr>
+      <tr>
+        <td>Minimum Duration</td>
+        <td>
+          {{txt model.minDuration type="duration"}}
+        </td>
+      </tr>
+      <tr>
+        <td>Maximum Duration</td>
+        <td>
+          {{txt model.maxDuration type="duration"}}
+        </td>
+      </tr>
+    </tbody>
+  </table>
+
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/04db5434/tez-ui2/src/main/webapp/app/templates/vertex/tasks.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/vertex/tasks.hbs b/tez-ui2/src/main/webapp/app/templates/vertex/tasks.hbs
new file mode 100644
index 0000000..cdb28aa
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/vertex/tasks.hbs
@@ -0,0 +1,33 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+}}
+
+{{#if loaded}}
+  {{em-table
+  columns=columns
+  rows=model
+
+  definition=definition
+
+  searchAction="searchChanged"
+  sortAction="sortChanged"
+  rowAction="rowsChanged"
+  pageAction="pageChanged"
+  }}
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/04db5434/tez-ui2/src/main/webapp/tests/unit/controllers/vertex-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex-test.js
new file mode 100644
index 0000000..0061f74
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex-test.js
@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:vertex', 'Unit | Controller | vertex', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+  assert.ok(controller.tabs);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/04db5434/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/attempts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/attempts-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/attempts-test.js
new file mode 100644
index 0000000..933096e
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/attempts-test.js
@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:vertex/attempts', 'Unit | Controller | vertex/attempts', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+  assert.ok(controller.columns);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/04db5434/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/index-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/index-test.js
new file mode 100644
index 0000000..e9b46b5
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/index-test.js
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:vertex/index', 'Unit | Controller | vertex/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/04db5434/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/tasks-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/tasks-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/tasks-test.js
new file mode 100644
index 0000000..a449dc2
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/vertex/tasks-test.js
@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:vertex/tasks', 'Unit | Controller | vertex/tasks', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+  assert.ok(controller.columns);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/04db5434/tez-ui2/src/main/webapp/tests/unit/routes/vertex-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/vertex-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/vertex-test.js
new file mode 100644
index 0000000..79cef72
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/vertex-test.js
@@ -0,0 +1,32 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:vertex', 'Unit | Route | vertex', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.loaderQueryParams);
+  assert.ok(route.model);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/04db5434/tez-ui2/src/main/webapp/tests/unit/routes/vertex/attempts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/vertex/attempts-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/vertex/attempts-test.js
new file mode 100644
index 0000000..9ba3cf0
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/vertex/attempts-test.js
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:vertex/attempts', 'Unit | Route | vertex/attempts', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+  assert.ok(route.load);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/04db5434/tez-ui2/src/main/webapp/tests/unit/routes/vertex/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/vertex/index-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/vertex/index-test.js
new file mode 100644
index 0000000..cc7e9de
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/vertex/index-test.js
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:vertex/index', 'Unit | Route | vertex/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+  assert.ok(route.load);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/04db5434/tez-ui2/src/main/webapp/tests/unit/routes/vertex/tasks-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/vertex/tasks-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/vertex/tasks-test.js
new file mode 100644
index 0000000..e70434f
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/vertex/tasks-test.js
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:vertex/tasks', 'Unit | Route | vertex/tasks', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+  assert.ok(route.load);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});


[23/50] [abbrv] tez git commit: TEZ-2898. tez tools : swimlanes.py is broken in master (rbalamohan)

Posted by sr...@apache.org.
TEZ-2898. tez tools : swimlanes.py is broken in master (rbalamohan)


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

Branch: refs/heads/TEZ-2980
Commit: cc06400139f9a16d2f0b0c53b0a8589f6f3b2ad8
Parents: 9e47c63
Author: Rajesh Balamohan <rb...@apache.org>
Authored: Wed Jan 20 05:45:06 2016 +0530
Committer: Rajesh Balamohan <rb...@apache.org>
Committed: Wed Jan 20 05:45:06 2016 +0530

----------------------------------------------------------------------
 CHANGES.txt                        | 1 +
 tez-tools/swimlanes/amlogparser.py | 2 +-
 tez-tools/swimlanes/swimlane.py    | 3 ++-
 3 files changed, 4 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/cc064001/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 5226ea6..f1cc292 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -6,6 +6,7 @@ Release 0.8.3: Unreleased
 INCOMPATIBLE CHANGES
 
 ALL CHANGES:
+  TEZ-2898. tez tools : swimlanes.py is broken.
   TEZ-2937. Can Processor.close() be called after closing inputs and outputs?
   TEZ-3037. History URL should be set regardless of which history logging service is enabled.
   TEZ-3032. DAG start time getting logged using system time instead of recorded time in startTime field.

http://git-wip-us.apache.org/repos/asf/tez/blob/cc064001/tez-tools/swimlanes/amlogparser.py
----------------------------------------------------------------------
diff --git a/tez-tools/swimlanes/amlogparser.py b/tez-tools/swimlanes/amlogparser.py
index 6e29bba..71db145 100644
--- a/tez-tools/swimlanes/amlogparser.py
+++ b/tez-tools/swimlanes/amlogparser.py
@@ -197,7 +197,7 @@ class AMLog(object):
 	def init(self):
 		ID=r'[^\]]*'
 		TS=r'[0-9:\-, ]*'
-		MAIN_RE=r'^(?P<ts>%(ts)s) INFO [(?P<thread>%(id)s)] (org.apache.tez.dag.)?history.HistoryEventHandler: [HISTORY][DAG:(?P<dag>%(id)s)][Event:(?P<event>%(id)s)]: (?P<args>.*)'
+		MAIN_RE=r'^(?P<ts>%(ts)s) [?INFO]? [(?P<thread>%(id)s)] \|?(org.apache.tez.dag.)?history.HistoryEventHandler\|?: [HISTORY][DAG:(?P<dag>%(id)s)][Event:(?P<event>%(id)s)]: (?P<args>.*)'
 		MAIN_RE = MAIN_RE.replace('[','\[').replace(']','\]')
 		MAIN_RE = MAIN_RE % {'ts' : TS, 'id' : ID}
 		self.MAIN_RE = re.compile(MAIN_RE)

http://git-wip-us.apache.org/repos/asf/tez/blob/cc064001/tez-tools/swimlanes/swimlane.py
----------------------------------------------------------------------
diff --git a/tez-tools/swimlanes/swimlane.py b/tez-tools/swimlanes/swimlane.py
index dc8dc6f..bbd54df 100644
--- a/tez-tools/swimlanes/swimlane.py
+++ b/tez-tools/swimlanes/swimlane.py
@@ -179,7 +179,8 @@ def main(argv):
 			x2 = marginRight+xdomain(c.finish)
 			y2 = y1 + laneSize - 2
 			locality = (c.kvs.has_key("DATA_LOCAL_TASKS") * 1) + (c.kvs.has_key("RACK_LOCAL_TASKS")*2)
-			link = c.kvs["completedLogs"]
+			#CompletedLogs may not be present in latest tez logs
+			link = c.kvs.get("completedLogs", "")
 			svg.rect(x1, y1, x2, y2, title=c.name, style="fill: %s; stroke: #ccc;" % (colour), link=link)
 			if locality > 1: # rack-local (no-locality isn't counted)
 				svg.rect(x1, y2-4, x2, y2, style="fill: #f00; fill-opacity: 0.5;", link=link)


[12/50] [abbrv] tez git commit: TEZ-2669. Propagation of errors from plugins to the AM for error reporting. Contributed by Hitesh Shah and Siddharth Seth.

Posted by sr...@apache.org.
http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-ext-service-tests/src/test/java/org/apache/tez/tests/ExternalTezServiceTestHelper.java
----------------------------------------------------------------------
diff --git a/tez-ext-service-tests/src/test/java/org/apache/tez/tests/ExternalTezServiceTestHelper.java b/tez-ext-service-tests/src/test/java/org/apache/tez/tests/ExternalTezServiceTestHelper.java
new file mode 100644
index 0000000..14c19b5
--- /dev/null
+++ b/tez-ext-service-tests/src/test/java/org/apache/tez/tests/ExternalTezServiceTestHelper.java
@@ -0,0 +1,194 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tez.tests;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.util.Map;
+
+import com.google.common.base.Preconditions;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hdfs.MiniDFSCluster;
+import org.apache.tez.client.TezClient;
+import org.apache.tez.dag.api.TezConfiguration;
+import org.apache.tez.dag.api.TezException;
+import org.apache.tez.examples.HashJoinExample;
+import org.apache.tez.examples.JoinDataGen;
+import org.apache.tez.runtime.library.api.TezRuntimeConfiguration;
+import org.apache.tez.service.MiniTezTestServiceCluster;
+import org.apache.tez.serviceplugins.api.ServicePluginsDescriptor;
+import org.apache.tez.test.MiniTezCluster;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ExternalTezServiceTestHelper {
+
+  private static final Logger LOG = LoggerFactory.getLogger(ExternalTezServiceTestHelper.class);
+
+  private volatile MiniTezCluster tezCluster;
+  private volatile MiniDFSCluster dfsCluster;
+  private volatile MiniTezTestServiceCluster tezTestServiceCluster;
+
+  private volatile Configuration clusterConf = new Configuration();
+  private volatile Configuration confForJobs;
+
+  private volatile FileSystem remoteFs;
+
+  private volatile TezClient sharedTezClient;
+
+  /**
+   * Current usage: Create. setupSharedTezClient - during setup (beforeClass). Invoke tearDownAll when done (afterClass)
+   * Alternately tearDown the sharedTezClient independently
+   */
+  public ExternalTezServiceTestHelper(String testRootDir) throws
+      IOException {
+    try {
+      clusterConf.set(MiniDFSCluster.HDFS_MINIDFS_BASEDIR, testRootDir);
+      dfsCluster =
+          new MiniDFSCluster.Builder(clusterConf).numDataNodes(1).format(true).racks(null).build();
+      remoteFs = dfsCluster.getFileSystem();
+      LOG.info("MiniDFSCluster started");
+    } catch (IOException io) {
+      throw new RuntimeException("problem starting mini dfs cluster", io);
+    }
+
+    tezCluster = new MiniTezCluster(TestExternalTezServices.class.getName(), 1, 1, 1);
+    Configuration conf = new Configuration();
+    conf.set("fs.defaultFS", remoteFs.getUri().toString()); // use HDFS
+    tezCluster.init(conf);
+    tezCluster.start();
+    LOG.info("MiniTezCluster started");
+
+    clusterConf.set("fs.defaultFS", remoteFs.getUri().toString()); // use HDFS
+    for (Map.Entry<String, String> entry : tezCluster.getConfig()) {
+      clusterConf.set(entry.getKey(), entry.getValue());
+    }
+    long jvmMax = Runtime.getRuntime().maxMemory();
+
+    tezTestServiceCluster = MiniTezTestServiceCluster
+        .create(TestExternalTezServices.class.getSimpleName(), 3, ((long) (jvmMax * 0.5d)), 1);
+    tezTestServiceCluster.init(clusterConf);
+    tezTestServiceCluster.start();
+    LOG.info("MiniTezTestServer started");
+
+    confForJobs = new Configuration(clusterConf);
+    for (Map.Entry<String, String> entry : tezTestServiceCluster
+        .getClusterSpecificConfiguration()) {
+      confForJobs.set(entry.getKey(), entry.getValue());
+    }
+
+    Path stagingDirPath = new Path("/tmp/tez-staging-dir");
+    remoteFs.mkdirs(stagingDirPath);
+    // This is currently configured to push tasks into the Service, and then use the standard RPC
+    confForJobs.set(TezConfiguration.TEZ_AM_STAGING_DIR, stagingDirPath.toString());
+    confForJobs.setBoolean(TezRuntimeConfiguration.TEZ_RUNTIME_OPTIMIZE_LOCAL_FETCH, false);
+  }
+
+  public void setupSharedTezClient(ServicePluginsDescriptor servicePluginsDescriptor) throws
+      IOException, TezException, InterruptedException {
+    // Create a session to use for all tests.
+    TezConfiguration tezClientConf = new TezConfiguration(confForJobs);
+
+    sharedTezClient = TezClient
+        .newBuilder(TestExternalTezServices.class.getSimpleName() + "_session", tezClientConf)
+        .setIsSession(true).setServicePluginDescriptor(servicePluginsDescriptor).build();
+
+    sharedTezClient.start();
+    LOG.info("Shared TezSession started");
+    sharedTezClient.waitTillReady();
+    LOG.info("Shared TezSession ready for submission");
+  }
+
+  public void tearDownAll() throws IOException, TezException {
+    if (sharedTezClient != null) {
+      sharedTezClient.stop();
+      sharedTezClient = null;
+    }
+
+    if (tezTestServiceCluster != null) {
+      tezTestServiceCluster.stop();
+      tezTestServiceCluster = null;
+    }
+
+    if (tezCluster != null) {
+      tezCluster.stop();
+      tezCluster = null;
+    }
+    if (dfsCluster != null) {
+      dfsCluster.shutdown();
+      dfsCluster = null;
+    }
+  }
+
+  public void shutdownSharedTezClient() throws IOException, TezException {
+    if (sharedTezClient != null) {
+      sharedTezClient.stop();
+      sharedTezClient = null;
+    }
+  }
+
+
+  public void setupHashJoinData(Path srcDataDir, Path dataPath1, Path dataPath2,
+                                Path expectedResultPath, Path outputPath) throws
+      Exception {
+    remoteFs.mkdirs(srcDataDir);
+    TezConfiguration tezConf = new TezConfiguration(confForJobs);
+    //   Generate join data - with 2 tasks.
+    JoinDataGen dataGen = new JoinDataGen();
+    String[] dataGenArgs = new String[]{
+        dataPath1.toString(), "1048576", dataPath2.toString(), "524288",
+        expectedResultPath.toString(), "2"};
+    assertEquals(0, dataGen.run(tezConf, dataGenArgs, sharedTezClient));
+    //    Run the actual join - with 2 reducers
+    HashJoinExample joinExample = new HashJoinExample();
+    String[] args = new String[]{
+        dataPath1.toString(), dataPath2.toString(), "2", outputPath.toString()};
+    assertEquals(0, joinExample.run(tezConf, args, sharedTezClient));
+    LOG.info("Completed generating Data - Expected Hash Result and Actual Join Result");
+  }
+
+
+  public MiniTezCluster getTezCluster() {
+    return tezCluster;
+  }
+
+  public MiniDFSCluster getDfsCluster() {
+    return dfsCluster;
+  }
+
+  public MiniTezTestServiceCluster getTezTestServiceCluster() {
+    return tezTestServiceCluster;
+  }
+
+  public Configuration getClusterConf() {
+    return clusterConf;
+  }
+
+  public Configuration getConfForJobs() {
+    return confForJobs;
+  }
+
+  public FileSystem getRemoteFs() {
+    return remoteFs;
+  }
+
+  public TezClient getSharedTezClient() {
+    Preconditions.checkNotNull(sharedTezClient);
+    return sharedTezClient;
+  }
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-ext-service-tests/src/test/java/org/apache/tez/tests/TestExternalTezServices.java
----------------------------------------------------------------------
diff --git a/tez-ext-service-tests/src/test/java/org/apache/tez/tests/TestExternalTezServices.java b/tez-ext-service-tests/src/test/java/org/apache/tez/tests/TestExternalTezServices.java
index 3701455..920534a 100644
--- a/tez-ext-service-tests/src/test/java/org/apache/tez/tests/TestExternalTezServices.java
+++ b/tez-ext-service-tests/src/test/java/org/apache/tez/tests/TestExternalTezServices.java
@@ -17,13 +17,8 @@ package org.apache.tez.tests;
 import static org.junit.Assert.assertEquals;
 
 import java.io.IOException;
-import java.util.Map;
 
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
-import org.apache.hadoop.hdfs.MiniDFSCluster;
-import org.apache.tez.client.TezClient;
 import org.apache.tez.common.TezUtils;
 import org.apache.tez.dag.api.DAG;
 import org.apache.tez.dag.api.ProcessorDescriptor;
@@ -37,18 +32,13 @@ import org.apache.tez.dag.api.client.DAGStatus;
 import org.apache.tez.dag.app.launcher.TezTestServiceNoOpContainerLauncher;
 import org.apache.tez.dag.app.rm.TezTestServiceTaskSchedulerService;
 import org.apache.tez.dag.app.taskcomm.TezTestServiceTaskCommunicatorImpl;
-import org.apache.tez.examples.HashJoinExample;
-import org.apache.tez.examples.JoinDataGen;
 import org.apache.tez.examples.JoinValidateConfigured;
-import org.apache.tez.runtime.library.api.TezRuntimeConfiguration;
 import org.apache.tez.runtime.library.processor.SleepProcessor;
-import org.apache.tez.service.MiniTezTestServiceCluster;
 import org.apache.tez.service.impl.ContainerRunnerImpl;
 import org.apache.tez.serviceplugins.api.ContainerLauncherDescriptor;
 import org.apache.tez.serviceplugins.api.ServicePluginsDescriptor;
 import org.apache.tez.serviceplugins.api.TaskCommunicatorDescriptor;
 import org.apache.tez.serviceplugins.api.TaskSchedulerDescriptor;
-import org.apache.tez.test.MiniTezCluster;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -61,17 +51,7 @@ public class TestExternalTezServices {
 
   private static final String EXT_PUSH_ENTITY_NAME = "ExtServiceTestPush";
 
-  private static volatile MiniTezCluster tezCluster;
-  private static volatile MiniDFSCluster dfsCluster;
-  private static volatile MiniTezTestServiceCluster tezTestServiceCluster;
-
-  private static volatile Configuration clusterConf = new Configuration();
-  private static volatile Configuration confForJobs;
-
-  private static volatile FileSystem remoteFs;
-  private static volatile FileSystem localFs;
-
-  private static volatile TezClient sharedTezClient;
+  private static ExternalTezServiceTestHelper extServiceTestHelper;
 
   private static final Path SRC_DATA_DIR = new Path("/tmp/" + TestExternalTezServices.class.getSimpleName());
   private static final Path HASH_JOIN_EXPECTED_RESULT_PATH = new Path(SRC_DATA_DIR, "expectedOutputPath");
@@ -93,50 +73,8 @@ public class TestExternalTezServices {
   @BeforeClass
   public static void setup() throws Exception {
 
-    localFs = FileSystem.getLocal(clusterConf);
-
-    try {
-      clusterConf.set(MiniDFSCluster.HDFS_MINIDFS_BASEDIR, TEST_ROOT_DIR);
-      dfsCluster =
-          new MiniDFSCluster.Builder(clusterConf).numDataNodes(1).format(true).racks(null).build();
-      remoteFs = dfsCluster.getFileSystem();
-      LOG.info("MiniDFSCluster started");
-    } catch (IOException io) {
-      throw new RuntimeException("problem starting mini dfs cluster", io);
-    }
-
-    tezCluster = new MiniTezCluster(TestExternalTezServices.class.getName(), 1, 1, 1);
-    Configuration conf = new Configuration();
-    conf.set("fs.defaultFS", remoteFs.getUri().toString()); // use HDFS
-    tezCluster.init(conf);
-    tezCluster.start();
-    LOG.info("MiniTezCluster started");
-
-    clusterConf.set("fs.defaultFS", remoteFs.getUri().toString()); // use HDFS
-    for (Map.Entry<String, String> entry : tezCluster.getConfig()) {
-      clusterConf.set(entry.getKey(), entry.getValue());
-    }
-    long jvmMax = Runtime.getRuntime().maxMemory();
-
-    tezTestServiceCluster = MiniTezTestServiceCluster
-        .create(TestExternalTezServices.class.getSimpleName(), 3, ((long) (jvmMax * 0.5d)), 1);
-    tezTestServiceCluster.init(clusterConf);
-    tezTestServiceCluster.start();
-    LOG.info("MiniTezTestServer started");
-
-    confForJobs = new Configuration(clusterConf);
-    for (Map.Entry<String, String> entry : tezTestServiceCluster
-        .getClusterSpecificConfiguration()) {
-      confForJobs.set(entry.getKey(), entry.getValue());
-    }
-
-    Path stagingDirPath = new Path("/tmp/tez-staging-dir");
-    remoteFs.mkdirs(stagingDirPath);
-    // This is currently configured to push tasks into the Service, and then use the standard RPC
-    confForJobs.set(TezConfiguration.TEZ_AM_STAGING_DIR, stagingDirPath.toString());
-    confForJobs.setBoolean(TezRuntimeConfiguration.TEZ_RUNTIME_OPTIMIZE_LOCAL_FETCH, false);
-
-    UserPayload userPayload = TezUtils.createUserPayloadFromConf(confForJobs);
+    extServiceTestHelper = new ExternalTezServiceTestHelper(TEST_ROOT_DIR);
+    UserPayload userPayload = TezUtils.createUserPayloadFromConf(extServiceTestHelper.getConfForJobs());
 
     TaskSchedulerDescriptor[] taskSchedulerDescriptors = new TaskSchedulerDescriptor[]{
         TaskSchedulerDescriptor
@@ -156,60 +94,21 @@ public class TestExternalTezServices {
     ServicePluginsDescriptor servicePluginsDescriptor = ServicePluginsDescriptor.create(true, true,
         taskSchedulerDescriptors, containerLauncherDescriptors, taskCommunicatorDescriptors);
 
-    // Create a session to use for all tests.
-    TezConfiguration tezClientConf = new TezConfiguration(confForJobs);
 
-    sharedTezClient = TezClient
-        .newBuilder(TestExternalTezServices.class.getSimpleName() + "_session", tezClientConf)
-        .setIsSession(true).setServicePluginDescriptor(servicePluginsDescriptor).build();
+    extServiceTestHelper.setupSharedTezClient(servicePluginsDescriptor);
 
-    sharedTezClient.start();
-    LOG.info("Shared TezSession started");
-    sharedTezClient.waitTillReady();
-    LOG.info("Shared TezSession ready for submission");
 
     // Generate the join data set used for each run.
     // Can a timeout be enforced here ?
-    remoteFs.mkdirs(SRC_DATA_DIR);
     Path dataPath1 = new Path(SRC_DATA_DIR, "inPath1");
     Path dataPath2 = new Path(SRC_DATA_DIR, "inPath2");
-    TezConfiguration tezConf = new TezConfiguration(confForJobs);
-    //   Generate join data - with 2 tasks.
-    JoinDataGen dataGen = new JoinDataGen();
-    String[] dataGenArgs = new String[]{
-        dataPath1.toString(), "1048576", dataPath2.toString(), "524288",
-        HASH_JOIN_EXPECTED_RESULT_PATH.toString(), "2"};
-    assertEquals(0, dataGen.run(tezConf, dataGenArgs, sharedTezClient));
-    //    Run the actual join - with 2 reducers
-    HashJoinExample joinExample = new HashJoinExample();
-    String[] args = new String[]{
-        dataPath1.toString(), dataPath2.toString(), "2", HASH_JOIN_OUTPUT_PATH.toString()};
-    assertEquals(0, joinExample.run(tezConf, args, sharedTezClient));
-
-    LOG.info("Completed generating Data - Expected Hash Result and Actual Join Result");
+    extServiceTestHelper
+        .setupHashJoinData(SRC_DATA_DIR, dataPath1, dataPath2, HASH_JOIN_EXPECTED_RESULT_PATH, HASH_JOIN_OUTPUT_PATH);
   }
 
   @AfterClass
   public static void tearDown() throws IOException, TezException {
-    if (sharedTezClient != null) {
-      sharedTezClient.stop();
-      sharedTezClient = null;
-    }
-
-    if (tezTestServiceCluster != null) {
-      tezTestServiceCluster.stop();
-      tezTestServiceCluster = null;
-    }
-
-    if (tezCluster != null) {
-      tezCluster.stop();
-      tezCluster = null;
-    }
-    if (dfsCluster != null) {
-      dfsCluster.shutdown();
-      dfsCluster = null;
-    }
-    // TODO Add cleanup code.
+    extServiceTestHelper.tearDownAll();
   }
 
 
@@ -297,7 +196,7 @@ public class TestExternalTezServices {
     v.setExecutionContext(EXECUTION_CONTEXT_EXT_SERVICE_PUSH);
     dag.addVertex(v);
 
-    DAGClient dagClient = sharedTezClient.submitDAG(dag);
+    DAGClient dagClient = extServiceTestHelper.getSharedTezClient().submitDAG(dag);
     DAGStatus dagStatus = dagClient.waitForCompletion();
     assertEquals(DAGStatus.State.SUCCEEDED, dagStatus.getState());
     assertEquals(1, dagStatus.getDAGProgress().getFailedTaskAttemptCount());
@@ -309,18 +208,18 @@ public class TestExternalTezServices {
                                VertexExecutionContext rhsContext,
                                VertexExecutionContext validateContext) throws
       Exception {
-    int externalSubmissionCount = tezTestServiceCluster.getNumSubmissions();
+    int externalSubmissionCount = extServiceTestHelper.getTezTestServiceCluster().getNumSubmissions();
 
-    TezConfiguration tezConf = new TezConfiguration(confForJobs);
+    TezConfiguration tezConf = new TezConfiguration(extServiceTestHelper.getConfForJobs());
     JoinValidateConfigured joinValidate =
         new JoinValidateConfigured(EXECUTION_CONTEXT_DEFAULT, lhsContext, rhsContext,
             validateContext, name);
     String[] validateArgs = new String[]{"-disableSplitGrouping",
         HASH_JOIN_EXPECTED_RESULT_PATH.toString(), HASH_JOIN_OUTPUT_PATH.toString(), "3"};
-    assertEquals(0, joinValidate.run(tezConf, validateArgs, sharedTezClient));
+    assertEquals(0, joinValidate.run(tezConf, validateArgs, extServiceTestHelper.getSharedTezClient()));
 
     // Ensure this was actually submitted to the external cluster
     assertEquals(extExpectedCount,
-        (tezTestServiceCluster.getNumSubmissions() - externalSubmissionCount));
+        (extServiceTestHelper.getTezTestServiceCluster().getNumSubmissions() - externalSubmissionCount));
   }
 }

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-ext-service-tests/src/test/java/org/apache/tez/tests/TestExternalTezServicesErrors.java
----------------------------------------------------------------------
diff --git a/tez-ext-service-tests/src/test/java/org/apache/tez/tests/TestExternalTezServicesErrors.java b/tez-ext-service-tests/src/test/java/org/apache/tez/tests/TestExternalTezServicesErrors.java
new file mode 100644
index 0000000..bfd3ed2
--- /dev/null
+++ b/tez-ext-service-tests/src/test/java/org/apache/tez/tests/TestExternalTezServicesErrors.java
@@ -0,0 +1,235 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tez.tests;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.EnumSet;
+
+import com.google.common.collect.Sets;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
+import org.apache.hadoop.yarn.api.records.ApplicationAttemptReport;
+import org.apache.hadoop.yarn.api.records.ApplicationId;
+import org.apache.hadoop.yarn.api.records.ApplicationReport;
+import org.apache.hadoop.yarn.api.records.FinalApplicationStatus;
+import org.apache.hadoop.yarn.api.records.YarnApplicationState;
+import org.apache.hadoop.yarn.client.api.YarnClient;
+import org.apache.hadoop.yarn.exceptions.YarnException;
+import org.apache.tez.client.TezClient;
+import org.apache.tez.common.TezUtils;
+import org.apache.tez.dag.api.DAG;
+import org.apache.tez.dag.api.TezConfiguration;
+import org.apache.tez.dag.api.TezException;
+import org.apache.tez.dag.api.UserPayload;
+import org.apache.tez.dag.api.Vertex;
+import org.apache.tez.dag.api.client.DAGClient;
+import org.apache.tez.dag.api.client.DAGStatus;
+import org.apache.tez.dag.api.client.StatusGetOpts;
+import org.apache.tez.dag.app.dag.event.DAGAppMasterEventType;
+import org.apache.tez.dag.app.launcher.TezTestServiceContainerLauncherWithErrors;
+import org.apache.tez.dag.app.launcher.TezTestServiceNoOpContainerLauncher;
+import org.apache.tez.dag.app.rm.TezTestServiceTaskSchedulerService;
+import org.apache.tez.dag.app.rm.TezTestServiceTaskSchedulerServiceWithErrors;
+import org.apache.tez.dag.app.taskcomm.TezTestServiceTaskCommunicatorImpl;
+import org.apache.tez.dag.app.taskcomm.TezTestServiceTaskCommunicatorWithErrors;
+import org.apache.tez.examples.JoinValidateConfigured;
+import org.apache.tez.serviceplugins.api.ContainerLauncherDescriptor;
+import org.apache.tez.serviceplugins.api.ServicePluginsDescriptor;
+import org.apache.tez.serviceplugins.api.TaskCommunicatorDescriptor;
+import org.apache.tez.serviceplugins.api.TaskSchedulerDescriptor;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TestExternalTezServicesErrors {
+
+  private static final Logger LOG = LoggerFactory.getLogger(TestExternalTezServicesErrors.class);
+
+  private static final String EXT_PUSH_ENTITY_NAME = "ExtServiceTestPush";
+  private static final String EXT_FAIL_ENTITY_NAME = "ExtServiceTestFail";
+
+  private static ExternalTezServiceTestHelper extServiceTestHelper;
+
+  private static ServicePluginsDescriptor servicePluginsDescriptor;
+
+  private static final Path SRC_DATA_DIR = new Path("/tmp/" + TestExternalTezServicesErrors.class.getSimpleName());
+  private static final Path HASH_JOIN_EXPECTED_RESULT_PATH = new Path(SRC_DATA_DIR, "expectedOutputPath");
+  private static final Path HASH_JOIN_OUTPUT_PATH = new Path(SRC_DATA_DIR, "outPath");
+
+  private static final Vertex.VertexExecutionContext EXECUTION_CONTEXT_EXT_SERVICE_PUSH =
+      Vertex.VertexExecutionContext.create(
+          EXT_PUSH_ENTITY_NAME, EXT_PUSH_ENTITY_NAME, EXT_PUSH_ENTITY_NAME);
+  private static final Vertex.VertexExecutionContext EXECUTION_CONTEXT_LAUNCHER_FAIL =
+      Vertex.VertexExecutionContext.create(EXT_PUSH_ENTITY_NAME, EXT_FAIL_ENTITY_NAME, EXT_PUSH_ENTITY_NAME);
+  private static final Vertex.VertexExecutionContext EXECUTION_CONTEXT_TASKCOMM_FAIL =
+      Vertex.VertexExecutionContext.create(EXT_PUSH_ENTITY_NAME, EXT_PUSH_ENTITY_NAME, EXT_FAIL_ENTITY_NAME);
+  private static final Vertex.VertexExecutionContext EXECUTION_CONTEXT_SCHEDULER_FAIL =
+      Vertex.VertexExecutionContext.create(EXT_FAIL_ENTITY_NAME, EXT_PUSH_ENTITY_NAME, EXT_PUSH_ENTITY_NAME);
+
+
+  private static final Vertex.VertexExecutionContext EXECUTION_CONTEXT_DEFAULT = EXECUTION_CONTEXT_EXT_SERVICE_PUSH;
+
+  private static String TEST_ROOT_DIR = "target" + Path.SEPARATOR + TestExternalTezServicesErrors.class.getName()
+      + "-tmpDir";
+
+  @BeforeClass
+  public static void setup() throws Exception {
+
+    extServiceTestHelper = new ExternalTezServiceTestHelper(TEST_ROOT_DIR);
+    UserPayload userPayload = TezUtils.createUserPayloadFromConf(extServiceTestHelper.getConfForJobs());
+
+    TaskSchedulerDescriptor[] taskSchedulerDescriptors = new TaskSchedulerDescriptor[]{
+        TaskSchedulerDescriptor
+            .create(EXT_PUSH_ENTITY_NAME, TezTestServiceTaskSchedulerService.class.getName())
+            .setUserPayload(userPayload),
+        TaskSchedulerDescriptor.create(EXT_FAIL_ENTITY_NAME,
+            TezTestServiceTaskSchedulerServiceWithErrors.class.getName()).setUserPayload(
+            userPayload)};
+
+    ContainerLauncherDescriptor[] containerLauncherDescriptors = new ContainerLauncherDescriptor[]{
+        ContainerLauncherDescriptor
+            .create(EXT_PUSH_ENTITY_NAME, TezTestServiceNoOpContainerLauncher.class.getName())
+            .setUserPayload(userPayload),
+        ContainerLauncherDescriptor.create(EXT_FAIL_ENTITY_NAME,
+            TezTestServiceContainerLauncherWithErrors.class.getName()).setUserPayload(userPayload)};
+
+    TaskCommunicatorDescriptor[] taskCommunicatorDescriptors = new TaskCommunicatorDescriptor[]{
+        TaskCommunicatorDescriptor
+            .create(EXT_PUSH_ENTITY_NAME, TezTestServiceTaskCommunicatorImpl.class.getName())
+            .setUserPayload(userPayload),
+        TaskCommunicatorDescriptor.create(EXT_FAIL_ENTITY_NAME,
+            TezTestServiceTaskCommunicatorWithErrors.class.getName()).setUserPayload(userPayload)};
+
+    servicePluginsDescriptor = ServicePluginsDescriptor.create(true, true,
+        taskSchedulerDescriptors, containerLauncherDescriptors, taskCommunicatorDescriptors);
+
+    extServiceTestHelper.setupSharedTezClient(servicePluginsDescriptor);
+
+    // Generate the join data set used for each run.
+    // Can a timeout be enforced here ?
+    Path dataPath1 = new Path(SRC_DATA_DIR, "inPath1");
+    Path dataPath2 = new Path(SRC_DATA_DIR, "inPath2");
+    extServiceTestHelper
+        .setupHashJoinData(SRC_DATA_DIR, dataPath1, dataPath2, HASH_JOIN_EXPECTED_RESULT_PATH, HASH_JOIN_OUTPUT_PATH);
+
+    extServiceTestHelper.shutdownSharedTezClient();
+  }
+
+  @AfterClass
+  public static void tearDown() throws IOException, TezException {
+    extServiceTestHelper.tearDownAll();
+  }
+
+  @Test (timeout = 90000)
+  public void testContainerLauncherError() throws Exception {
+    testServiceError("_testContainerLauncherError_", EXECUTION_CONTEXT_LAUNCHER_FAIL,
+        DAGAppMasterEventType.CONTAINER_LAUNCHER_SERVICE_FATAL_ERROR);
+  }
+
+  @Test (timeout = 90000)
+  public void testTaskCommunicatorError() throws Exception {
+    testServiceError("_testTaskCommunicatorError_", EXECUTION_CONTEXT_TASKCOMM_FAIL,
+        DAGAppMasterEventType.TASK_COMMUNICATOR_SERVICE_FATAL_ERROR);
+  }
+
+  @Test (timeout = 90000)
+  public void testTaskSchedulerError() throws Exception {
+    testServiceError("_testTaskSchedulerError_", EXECUTION_CONTEXT_SCHEDULER_FAIL,
+        DAGAppMasterEventType.TASK_SCHEDULER_SERVICE_FATAL_ERROR);
+  }
+
+  private void testServiceError(String methodName,
+                                Vertex.VertexExecutionContext lhsExecutionContext,
+                                DAGAppMasterEventType expectedEventType) throws
+      IOException, TezException, InterruptedException, YarnException {
+    TezConfiguration tezClientConf = new TezConfiguration(extServiceTestHelper.getConfForJobs());
+    TezClient tezClient = TezClient
+        .newBuilder(TestExternalTezServicesErrors.class.getSimpleName() + methodName + "_session",
+            tezClientConf)
+        .setIsSession(true).setServicePluginDescriptor(servicePluginsDescriptor).build();
+
+    ApplicationId appId;
+    try {
+      tezClient.start();
+      LOG.info("TezSessionStarted for " + methodName);
+      tezClient.waitTillReady();
+      LOG.info("TezSession ready for submission for " + methodName);
+
+      JoinValidateConfigured joinValidate =
+          new JoinValidateConfigured(EXECUTION_CONTEXT_DEFAULT, lhsExecutionContext,
+              EXECUTION_CONTEXT_EXT_SERVICE_PUSH,
+              EXECUTION_CONTEXT_EXT_SERVICE_PUSH, "LauncherFailTest");
+
+      DAG dag = joinValidate
+          .createDag(new TezConfiguration(extServiceTestHelper.getConfForJobs()), HASH_JOIN_EXPECTED_RESULT_PATH,
+              HASH_JOIN_OUTPUT_PATH, 3);
+
+      DAGClient dagClient = tezClient.submitDAG(dag);
+
+      DAGStatus dagStatus =
+          dagClient.waitForCompletionWithStatusUpdates(Sets.newHashSet(StatusGetOpts.GET_COUNTERS));
+      assertEquals(DAGStatus.State.ERROR, dagStatus.getState());
+      boolean foundDiag = false;
+      for (String diag : dagStatus.getDiagnostics()) {
+        if (diag.contains("Service Error") && diag.contains(
+            expectedEventType.toString()) &&
+            diag.contains("Simulated Error")) {
+          foundDiag = true;
+        }
+      }
+      appId = tezClient.getAppMasterApplicationId();
+      assertTrue(foundDiag);
+    } finally {
+      tezClient.stop();
+    }
+    // Verify the state of the application.
+    if (appId != null) {
+      YarnClient yarnClient = YarnClient.createYarnClient();
+      try {
+        yarnClient.init(tezClientConf);
+        yarnClient.start();
+
+        ApplicationReport appReport = yarnClient.getApplicationReport(appId);
+        YarnApplicationState appState = appReport.getYarnApplicationState();
+        while (!EnumSet.of(YarnApplicationState.FINISHED, YarnApplicationState.FAILED,
+            YarnApplicationState.KILLED).contains(appState)) {
+          Thread.sleep(200L);
+          appReport = yarnClient.getApplicationReport(appId);
+          appState = appReport.getYarnApplicationState();
+        }
+
+        // TODO Workaround for YARN-4554. AppReport does not provide diagnostics - need to fetch them from ApplicationAttemptReport
+        ApplicationAttemptId appAttemptId = appReport.getCurrentApplicationAttemptId();
+        ApplicationAttemptReport appAttemptReport =
+            yarnClient.getApplicationAttemptReport(appAttemptId);
+        String diag = appAttemptReport.getDiagnostics();
+        assertEquals(FinalApplicationStatus.FAILED, appReport.getFinalApplicationStatus());
+        assertEquals(YarnApplicationState.FINISHED, appReport.getYarnApplicationState());
+        assertTrue(diag.contains("Service Error") && diag.contains(
+            expectedEventType.toString()) &&
+            diag.contains("Simulated Error"));
+
+      } finally {
+        yarnClient.stop();
+      }
+    }
+  }
+
+}


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

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


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

Branch: refs/heads/TEZ-2980
Commit: 1c23839a8e97e63e120ae234e432684ff0f2827b
Parents: 17ab6f5
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Tue Dec 29 20:32:23 2015 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Wed Jan 20 22:26:20 2016 +0530

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


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

http://git-wip-us.apache.org/repos/asf/tez/blob/1c23839a/tez-ui2/src/main/webapp/app/initializers/hosts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/initializers/hosts.js b/tez-ui2/src/main/webapp/app/initializers/hosts.js
new file mode 100644
index 0000000..8791fc7
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/initializers/hosts.js
@@ -0,0 +1,27 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export function initialize(application) {
+  application.inject('controller', 'hosts', 'service:hosts');
+  application.inject('adapter', 'hosts', 'service:hosts');
+}
+
+export default {
+  name: 'hosts',
+  initialize
+};

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

http://git-wip-us.apache.org/repos/asf/tez/blob/1c23839a/tez-ui2/src/main/webapp/app/initializers/object-transform.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/initializers/object-transform.js b/tez-ui2/src/main/webapp/app/initializers/object-transform.js
new file mode 100644
index 0000000..57502cf
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/initializers/object-transform.js
@@ -0,0 +1,37 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import DS from "ember-data";
+
+export function initialize(application) {
+  application.register('transform:object', DS.Transform.extend({
+    deserialize: function(serialized) {
+      return Ember.none(serialized) ? {} : serialized;
+    },
+
+    serialized: function(deserialized) {
+      return Ember.none(deserialized) ? {} : deserialized;
+    }
+  }));
+}
+
+export default {
+  name: 'object-transform',
+  initialize
+};

http://git-wip-us.apache.org/repos/asf/tez/blob/1c23839a/tez-ui2/src/main/webapp/app/services/hosts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/services/hosts.js b/tez-ui2/src/main/webapp/app/services/hosts.js
new file mode 100644
index 0000000..5bdc6d1
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/services/hosts.js
@@ -0,0 +1,58 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import environment from '../config/environment';
+
+export default Ember.Service.extend({
+
+  correctProtocol: function (url) {
+    var proto = window.location.protocol;
+
+    if(proto === "file:") {
+      proto = "http:";
+    }
+
+    if(url.match("://")) {
+      url = url.substr(url.indexOf("://") + 3);
+    }
+
+    return proto + "//" + url;
+  },
+
+  normalizeURL: function (url) {
+    url = this.correctProtocol(url);
+
+    // Remove trailing slash
+    if(url && url.charAt(url.length - 1) === '/') {
+      url = url.slice(0, -1);
+    }
+    return url;
+  },
+
+  timelineBaseURL: Ember.computed(function () {
+    // Todo: Use global ENV if available
+    // Todo: Use loaded host if protocol is != file
+    return this.normalizeURL(environment.hosts.timeline);
+  }),
+
+  rmBaseURL: Ember.computed(function () {
+    return this.normalizeURL(environment.hosts.RM);
+  }),
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/1c23839a/tez-ui2/src/main/webapp/app/styles/app.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/app.less b/tez-ui2/src/main/webapp/app/styles/app.less
index 8b13789..8a21537 100644
--- a/tez-ui2/src/main/webapp/app/styles/app.less
+++ b/tez-ui2/src/main/webapp/app/styles/app.less
@@ -1 +1,24 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
+.generic-tooltip {
+  padding: 3px 5px !important;
+  background: rgba(0,0,0,.8) !important;
+  color: white !important;
+  border: none !important;
+}

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

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

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

http://git-wip-us.apache.org/repos/asf/tez/blob/1c23839a/tez-ui2/src/main/webapp/tests/unit/initializers/hosts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/initializers/hosts-test.js b/tez-ui2/src/main/webapp/tests/unit/initializers/hosts-test.js
new file mode 100644
index 0000000..5244c77
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/initializers/hosts-test.js
@@ -0,0 +1,38 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import HostsInitializer from '../../../initializers/hosts';
+import { module, test } from 'qunit';
+
+let application;
+
+module('Unit | Initializer | hosts', {
+  beforeEach() {
+    Ember.run(function() {
+      application = Ember.Application.create();
+      application.deferReadiness();
+    });
+  }
+});
+
+test('it works', function(assert) {
+  HostsInitializer.initialize(application);
+
+  assert.ok(true);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/1c23839a/tez-ui2/src/main/webapp/tests/unit/initializers/jquery-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/initializers/jquery-test.js b/tez-ui2/src/main/webapp/tests/unit/initializers/jquery-test.js
new file mode 100644
index 0000000..e30f427
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/initializers/jquery-test.js
@@ -0,0 +1,38 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import JqueryInitializer from '../../../initializers/jquery';
+import { module, test } from 'qunit';
+
+let application;
+
+module('Unit | Initializer | jquery', {
+  beforeEach() {
+    Ember.run(function() {
+      application = Ember.Application.create();
+      application.deferReadiness();
+    });
+  }
+});
+
+test('it works', function(assert) {
+  JqueryInitializer.initialize(application);
+
+  assert.ok(true);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/1c23839a/tez-ui2/src/main/webapp/tests/unit/initializers/object-transform-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/initializers/object-transform-test.js b/tez-ui2/src/main/webapp/tests/unit/initializers/object-transform-test.js
new file mode 100644
index 0000000..a52a7bd
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/initializers/object-transform-test.js
@@ -0,0 +1,38 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import ObjectTransformInitializer from '../../../initializers/object-transform';
+import { module, test } from 'qunit';
+
+let application;
+
+module('Unit | Initializer | object transform', {
+  beforeEach() {
+    Ember.run(function() {
+      application = Ember.Application.create();
+      application.deferReadiness();
+    });
+  }
+});
+
+test('it works', function(assert) {
+  ObjectTransformInitializer.initialize(application);
+
+  assert.ok(true);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/1c23839a/tez-ui2/src/main/webapp/tests/unit/services/hosts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/services/hosts-test.js b/tez-ui2/src/main/webapp/tests/unit/services/hosts-test.js
new file mode 100644
index 0000000..8136ae4
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/services/hosts-test.js
@@ -0,0 +1,42 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('service:hosts', 'Unit | Service | hosts', {
+  // Specify the other units that are required for this test.
+  // needs: ['service:foo']
+});
+
+// Replace this with your real tests.
+test('Test creation', function(assert) {
+  let service = this.subject();
+  assert.ok(service);
+});
+
+test('Test correctProtocol', function(assert) {
+  let service = this.subject();
+
+  //No correction
+  assert.equal(service.correctProtocol("http://localhost:8088"), "http://localhost:8088");
+
+  // Correction
+  assert.equal(service.correctProtocol("localhost:8088"), "http://localhost:8088");
+  assert.equal(service.correctProtocol("https://localhost:8088"), "http://localhost:8088");
+  assert.equal(service.correctProtocol("file://localhost:8088"), "http://localhost:8088");
+});


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

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


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

Branch: refs/heads/TEZ-2980
Commit: 31baf3ce2d430e149219facfbc6a3a3c83a32012
Parents: bfc4aeb
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Tue Jan 5 00:07:05 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Wed Jan 20 22:26:21 2016 +0530

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


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

http://git-wip-us.apache.org/repos/asf/tez/blob/31baf3ce/tez-ui2/src/main/webapp/app/adapters/timeline.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/timeline.js b/tez-ui2/src/main/webapp/app/adapters/timeline.js
new file mode 100644
index 0000000..aba7e1e
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/adapters/timeline.js
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import AbstractAdapter from './abstract';
+
+export default AbstractAdapter.extend({
+  serverName: "timeline",
+});

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

http://git-wip-us.apache.org/repos/asf/tez/blob/31baf3ce/tez-ui2/src/main/webapp/app/serializers/timeline.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/timeline.js b/tez-ui2/src/main/webapp/app/serializers/timeline.js
new file mode 100644
index 0000000..8963dc2
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/serializers/timeline.js
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import LoaderSerializer from './loader';
+
+export default LoaderSerializer.extend({
+  extractArrayPayload: function (payload) {
+    return payload.entities;
+  }
+});

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

http://git-wip-us.apache.org/repos/asf/tez/blob/31baf3ce/tez-ui2/src/main/webapp/tests/unit/adapters/timeline-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/timeline-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/timeline-test.js
new file mode 100644
index 0000000..9b1a8de
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/adapters/timeline-test.js
@@ -0,0 +1,31 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('adapter:timeline', 'Unit | Adapter | timeline', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let adapter = this.subject();
+
+  assert.ok(adapter);
+  assert.equal(adapter.serverName, "timeline");
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/31baf3ce/tez-ui2/src/main/webapp/tests/unit/serializers/timeline-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/serializers/timeline-test.js b/tez-ui2/src/main/webapp/tests/unit/serializers/timeline-test.js
new file mode 100644
index 0000000..53f0b06
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/serializers/timeline-test.js
@@ -0,0 +1,40 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('serializer:timeline', 'Unit | Serializer | timeline', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:timeline']
+});
+
+test('Basic creation test', function(assert) {
+  let serializer = this.subject();
+
+  assert.ok(serializer);
+  assert.ok(serializer.extractArrayPayload);
+});
+
+test('extractArrayPayload test', function(assert) {
+  let serializer = this.subject(),
+      testPayload = {
+        entities: []
+      };
+
+  assert.equal(serializer.extractArrayPayload(testPayload), testPayload.entities);
+});


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

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


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

Branch: refs/heads/TEZ-2980
Commit: da115b9f7a991826ea078907e0935621d4ec9edd
Parents: 04db543
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Tue Jan 19 01:31:55 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Wed Jan 20 22:30:07 2016 +0530

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


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

http://git-wip-us.apache.org/repos/asf/tez/blob/da115b9f/tez-ui2/src/main/webapp/app/controllers/attempt.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/attempt.js b/tez-ui2/src/main/webapp/app/controllers/attempt.js
new file mode 100644
index 0000000..f17e317
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/attempt.js
@@ -0,0 +1,53 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import AbstractController from './abstract';
+
+export default AbstractController.extend({
+  breadcrumbs: Ember.computed("model.dag", function () {
+    var dagName = this.get("model.dag.name"),
+        vertexName = this.get("model.vertexName"),
+        taskIndex = this.get("model.taskIndex"),
+        attemptNo = this.get("model.index");
+
+    return [{
+      text: `DAG [ ${dagName} ]`,
+      routeName: "dag.index",
+      model: this.get("model.dagID")
+    },{
+      text: `Vertex [ ${vertexName} ]`,
+      routeName: "vertex.index",
+      model: this.get("model.vertexID")
+    },{
+      text: `Task [ ${taskIndex} ]`,
+      routeName: "task.index",
+      model: this.get("model.taskID")
+    },{
+      text: `Attempt [ ${attemptNo} ]`,
+      routeName: "attempt.index",
+      model: this.get("model.entityID")
+    }];
+  }),
+
+  tabs: [{
+    text: "Attempt Details",
+    routeName: "attempt.index"
+  }]
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/da115b9f/tez-ui2/src/main/webapp/app/controllers/attempt/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/attempt/index.js b/tez-ui2/src/main/webapp/app/controllers/attempt/index.js
new file mode 100644
index 0000000..9745328
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/attempt/index.js
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import PageController from '../page';
+
+export default PageController.extend({
+});

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

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

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

http://git-wip-us.apache.org/repos/asf/tez/blob/da115b9f/tez-ui2/src/main/webapp/app/controllers/task/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/task/attempts.js b/tez-ui2/src/main/webapp/app/controllers/task/attempts.js
new file mode 100644
index 0000000..5b97033
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/task/attempts.js
@@ -0,0 +1,81 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import TablePageController from '../table-page';
+import ColumnDefinition from 'em-table/utils/column-definition';
+
+export default TablePageController.extend({
+  breadcrumbs: [{
+    text: "Task Attempts",
+    routeName: "task.attempts",
+  }],
+
+  columns: ColumnDefinition.make([{
+    id: 'index',
+    headerTitle: 'Attempt No',
+    contentPath: 'index',
+    cellComponentName: 'em-table-linked-cell',
+    getCellContent: function (row) {
+      return {
+        routeName: "attempt",
+        model: row.get("entityID"),
+        text: row.get("index")
+      };
+    }
+  },{
+    id: 'status',
+    headerTitle: 'Status',
+    contentPath: 'status',
+    cellComponentName: 'em-table-status-cell'
+  },{
+    id: 'progress',
+    headerTitle: 'Progress',
+    contentPath: 'progress',
+    cellComponentName: 'em-table-progress-cell',
+    observePath: true
+  },{
+    id: 'startTime',
+    headerTitle: 'Start Time',
+    contentPath: 'startTime',
+    cellDefinition: {
+      type: 'date'
+    }
+  },{
+    id: 'endTime',
+    headerTitle: 'End Time',
+    contentPath: 'endTime',
+    cellDefinition: {
+      type: 'date'
+    }
+  },{
+    id: 'duration',
+    headerTitle: 'Duration',
+    contentPath: 'duration',
+    cellDefinition: {
+      type: 'duration'
+    }
+  },{
+    id: 'containerID',
+    headerTitle: 'Container',
+    contentPath: 'containerID'
+  },{
+    id: 'nodeID',
+    headerTitle: 'Node',
+    contentPath: 'nodeID'
+  }])
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/da115b9f/tez-ui2/src/main/webapp/app/controllers/task/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/task/index.js b/tez-ui2/src/main/webapp/app/controllers/task/index.js
new file mode 100644
index 0000000..9745328
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/task/index.js
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import PageController from '../page';
+
+export default PageController.extend({
+});

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

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

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

http://git-wip-us.apache.org/repos/asf/tez/blob/da115b9f/tez-ui2/src/main/webapp/app/routes/attempt.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/attempt.js b/tez-ui2/src/main/webapp/app/routes/attempt.js
new file mode 100644
index 0000000..71be6d2
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/attempt.js
@@ -0,0 +1,31 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+  title: "Vertex",
+
+  loaderQueryParams: {
+    id: "attempt_id"
+  },
+
+  model: function (params) {
+    return this.get("loader").queryRecord('attempt', this.queryFromParams(params).id);
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/da115b9f/tez-ui2/src/main/webapp/app/routes/attempt/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/attempt/index.js b/tez-ui2/src/main/webapp/app/routes/attempt/index.js
new file mode 100644
index 0000000..f88737d
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/attempt/index.js
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  title: "DAG Details",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (/*value, query*/) {
+    return this.get("loader").queryRecord('attempt', this.modelFor("attempt").id);
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/da115b9f/tez-ui2/src/main/webapp/app/routes/task.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/task.js b/tez-ui2/src/main/webapp/app/routes/task.js
new file mode 100644
index 0000000..42809c9
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/task.js
@@ -0,0 +1,31 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+  title: "Vertex",
+
+  loaderQueryParams: {
+    id: "task_id"
+  },
+
+  model: function (params) {
+    return this.get("loader").queryRecord('task', this.queryFromParams(params).id);
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/da115b9f/tez-ui2/src/main/webapp/app/routes/task/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/task/attempts.js b/tez-ui2/src/main/webapp/app/routes/task/attempts.js
new file mode 100644
index 0000000..bc7af27
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/task/attempts.js
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  title: "Task Attempts",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (/*value, query*/) {
+    return this.get("loader").query('attempt', {
+      taskID: this.modelFor("task").id
+    });
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/da115b9f/tez-ui2/src/main/webapp/app/routes/task/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/task/index.js b/tez-ui2/src/main/webapp/app/routes/task/index.js
new file mode 100644
index 0000000..fd76df9
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/task/index.js
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  title: "DAG Details",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (/*value, query*/) {
+    return this.get("loader").queryRecord('task', this.modelFor("task").id);
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/da115b9f/tez-ui2/src/main/webapp/app/templates/attempt.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/attempt.hbs b/tez-ui2/src/main/webapp/app/templates/attempt.hbs
new file mode 100644
index 0000000..308b905
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/attempt.hbs
@@ -0,0 +1,20 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+}}
+
+{{tab-n-refresh tabs=tabs}}
+{{outlet}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/da115b9f/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs b/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs
new file mode 100644
index 0000000..cf83afe
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/attempt/index.hbs
@@ -0,0 +1,65 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+}}
+
+{{#if loaded}}
+  <table class='detail-list'>
+    <thead>
+      <tr>
+        <th colspan=2>Details</th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>Task Attempt ID</td>
+        <td>{{model.entityID}}</td>
+      </tr>
+      <tr>
+        <td>Task ID</td>
+        <td>{{model.taskID}}</td>
+      </tr>
+      <tr>
+        <td>Container ID</td>
+        <td>{{model.containerID}}</td>
+      </tr>
+      <tr>
+        <td>Node ID</td>
+        <td>{{model.nodeID}}</td>
+      </tr>
+      <tr>
+        <td>Status</td>
+        <td>
+          {{em-table-status-cell content=model.status}}
+        </td>
+      </tr>
+      <tr>
+        <td>Start Time</td>
+        <td>{{txt model.startTime type="date"}}</td>
+      </tr>
+      <tr>
+        <td>End Time</td>
+        <td>{{txt model.endTime type="date"}}</td>
+      </tr>
+      <tr>
+        <td>Duration</td>
+        <td>{{txt model.duration type="duration"}}</td>
+      </tr>
+    </tbody>
+  </table>
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/da115b9f/tez-ui2/src/main/webapp/app/templates/task.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/task.hbs b/tez-ui2/src/main/webapp/app/templates/task.hbs
new file mode 100644
index 0000000..308b905
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/task.hbs
@@ -0,0 +1,20 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+}}
+
+{{tab-n-refresh tabs=tabs}}
+{{outlet}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/da115b9f/tez-ui2/src/main/webapp/app/templates/task/attempts.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/task/attempts.hbs b/tez-ui2/src/main/webapp/app/templates/task/attempts.hbs
new file mode 100644
index 0000000..cdb28aa
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/task/attempts.hbs
@@ -0,0 +1,33 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+}}
+
+{{#if loaded}}
+  {{em-table
+  columns=columns
+  rows=model
+
+  definition=definition
+
+  searchAction="searchChanged"
+  sortAction="sortChanged"
+  rowAction="rowsChanged"
+  pageAction="pageChanged"
+  }}
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/da115b9f/tez-ui2/src/main/webapp/app/templates/task/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/task/index.hbs b/tez-ui2/src/main/webapp/app/templates/task/index.hbs
new file mode 100644
index 0000000..b559203
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/task/index.hbs
@@ -0,0 +1,57 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+}}
+
+{{#if loaded}}
+  <table class='detail-list'>
+    <thead>
+      <tr>
+        <th colspan=2>Details</th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>Task ID</td>
+        <td>{{model.entityID}}</td>
+      </tr>
+      <tr>
+        <td>Vertex ID</td>
+        <td>{{model.vertexID}}</td>
+      </tr>
+      <tr>
+        <td>Status</td>
+        <td>
+          {{em-table-status-cell content=model.status}}
+        </td>
+      </tr>
+      <tr>
+        <td>Start Time</td>
+        <td>{{txt model.startTime type="date"}}</td>
+      </tr>
+      <tr>
+        <td>End Time</td>
+        <td>{{txt model.endTime type="date"}}</td>
+      </tr>
+      <tr>
+        <td>Duration</td>
+        <td>{{txt model.duration type="duration"}}</td>
+      </tr>
+    </tbody>
+  </table>
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/da115b9f/tez-ui2/src/main/webapp/tests/unit/controllers/attempt-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/attempt-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/attempt-test.js
new file mode 100644
index 0000000..32c6347
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/attempt-test.js
@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:attempt', 'Unit | Controller | vertex', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+  assert.ok(controller.tabs);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/da115b9f/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/index-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/index-test.js
new file mode 100644
index 0000000..b20e402
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/attempt/index-test.js
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:attempt/index', 'Unit | Controller | vertex/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/da115b9f/tez-ui2/src/main/webapp/tests/unit/controllers/task-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/task-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/task-test.js
new file mode 100644
index 0000000..f59817e
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/task-test.js
@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:task', 'Unit | Controller | vertex', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+  assert.ok(controller.tabs);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/da115b9f/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.js
new file mode 100644
index 0000000..bf389da
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/task/attempts-test.js
@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:task/attempts', 'Unit | Controller | vertex/attempts', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+  assert.ok(controller.columns);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/da115b9f/tez-ui2/src/main/webapp/tests/unit/controllers/task/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/task/index-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/task/index-test.js
new file mode 100644
index 0000000..e3014ae
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/task/index-test.js
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:task/index', 'Unit | Controller | vertex/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/da115b9f/tez-ui2/src/main/webapp/tests/unit/routes/attempt-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/attempt-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/attempt-test.js
new file mode 100644
index 0000000..dbfe590
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/attempt-test.js
@@ -0,0 +1,32 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:attempt', 'Unit | Route | vertex', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.loaderQueryParams);
+  assert.ok(route.model);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/da115b9f/tez-ui2/src/main/webapp/tests/unit/routes/attempt/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/attempt/index-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/attempt/index-test.js
new file mode 100644
index 0000000..8576090
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/attempt/index-test.js
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:attempt/index', 'Unit | Route | vertex/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+  assert.ok(route.load);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/da115b9f/tez-ui2/src/main/webapp/tests/unit/routes/task-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/task-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/task-test.js
new file mode 100644
index 0000000..af802b8
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/task-test.js
@@ -0,0 +1,32 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:task', 'Unit | Route | vertex', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.loaderQueryParams);
+  assert.ok(route.model);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/da115b9f/tez-ui2/src/main/webapp/tests/unit/routes/task/attempts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/task/attempts-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/task/attempts-test.js
new file mode 100644
index 0000000..1209012
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/task/attempts-test.js
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:task/attempts', 'Unit | Route | vertex/attempts', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+  assert.ok(route.load);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/da115b9f/tez-ui2/src/main/webapp/tests/unit/routes/task/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/task/index-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/task/index-test.js
new file mode 100644
index 0000000..8f4f6b9
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/task/index-test.js
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:task/index', 'Unit | Route | vertex/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+  assert.ok(route.load);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});


[22/50] [abbrv] tez git commit: TEZ-3033 part2. Update documentation for 0.8.2 release.

Posted by sr...@apache.org.
TEZ-3033 part2. Update documentation for 0.8.2 release.


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

Branch: refs/heads/TEZ-2980
Commit: 9e47c635cb34149ca31eebdbd836410957e7782b
Parents: b0ba133
Author: Siddharth Seth <ss...@apache.org>
Authored: Tue Jan 19 15:18:42 2016 -0800
Committer: Siddharth Seth <ss...@apache.org>
Committed: Tue Jan 19 15:18:42 2016 -0800

----------------------------------------------------------------------
 Tez_DOAP.rdf                                    |  7 +++++
 .../site/markdown/releases/apache-tez-0-8-2.md  | 29 ++++++++++++++++++++
 docs/src/site/markdown/releases/index.md        |  1 +
 docs/src/site/site.xml                          |  2 +-
 4 files changed, 38 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/9e47c635/Tez_DOAP.rdf
----------------------------------------------------------------------
diff --git a/Tez_DOAP.rdf b/Tez_DOAP.rdf
index 96b41b0..cc8abb3 100644
--- a/Tez_DOAP.rdf
+++ b/Tez_DOAP.rdf
@@ -36,6 +36,13 @@
     <category rdf:resource="http://projects.apache.org/category/big-data" />
     <release>
       <Version>
+        <name>Version 0.8.2</name>
+        <created>2016-01-19</created>
+        <revision>0.8.2</revision>
+      </Version>
+    </release>
+    <release>
+      <Version>
         <name>Version 0.8.1-alpha</name>
         <created>2015-10-12</created>
         <revision>0.8.1-alpha</revision>

http://git-wip-us.apache.org/repos/asf/tez/blob/9e47c635/docs/src/site/markdown/releases/apache-tez-0-8-2.md
----------------------------------------------------------------------
diff --git a/docs/src/site/markdown/releases/apache-tez-0-8-2.md b/docs/src/site/markdown/releases/apache-tez-0-8-2.md
new file mode 100644
index 0000000..984e507
--- /dev/null
+++ b/docs/src/site/markdown/releases/apache-tez-0-8-2.md
@@ -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.
+-->
+
+<head><title>Apache Tez 0.8.2</title></head>
+
+Apache Tez 0.8.2
+----------------------
+
+- [Release Artifacts](http://www.apache.org/dyn/closer.lua/tez/0.8.2/)
+- [Release Notes](0.8.2/release-notes.txt)
+- Documentation
+    - [API Javadocs](0.8.2/tez-api-javadocs/index.html) : Documentation for the Tez APIs
+    - [Runtime Library Javadocs](0.8.2/tez-runtime-library-javadocs/index.html) : Documentation for built-in implementations of useful Inputs, Outputs, Processors etc. written based on the Tez APIs 
+    - [Tez Mapreduce Javadocs](0.8.2/tez-mapreduce-javadocs/index.html) : Documentation for built-in implementations of Mapreduce compatible Inputs, Outputs, Processors etc. written based on the Tez APIs 
+

http://git-wip-us.apache.org/repos/asf/tez/blob/9e47c635/docs/src/site/markdown/releases/index.md
----------------------------------------------------------------------
diff --git a/docs/src/site/markdown/releases/index.md b/docs/src/site/markdown/releases/index.md
index 2152de6..3822e07 100644
--- a/docs/src/site/markdown/releases/index.md
+++ b/docs/src/site/markdown/releases/index.md
@@ -19,6 +19,7 @@
 
 Releases
 ------------
+-   [Apache Tez 0.8.2](./apache-tez-0-8-2.html) (Jan 19, 2016)
 -   [Apache Tez 0.8.1-alpha](./apache-tez-0-8-1-alpha.html) (Oct 12, 2015)
 -   [Apache Tez 0.8.0-alpha](./apache-tez-0-8-0-alpha.html) (Sep 01, 2015)
 -   [Apache Tez 0.7.0](./apache-tez-0-7-0.html) (May 18, 2015)

http://git-wip-us.apache.org/repos/asf/tez/blob/9e47c635/docs/src/site/site.xml
----------------------------------------------------------------------
diff --git a/docs/src/site/site.xml b/docs/src/site/site.xml
index d313810..dc4cec8 100644
--- a/docs/src/site/site.xml
+++ b/docs/src/site/site.xml
@@ -125,7 +125,7 @@
       <item name="0.6.1" href="./releases/apache-tez-0-6-1.html"/>
       <item name="0.6.2" href="./releases/apache-tez-0-6-2.html"/>
       <item name="0.7.0" href="./releases/apache-tez-0-7-0.html"/>
-      <item name="0.8.1-alpha" href="./releases/apache-tez-0-8-1-alpha.html"/>
+      <item name="0.8.2" href="./releases/apache-tez-0-8-2.html"/>
       <item name="All Releases" href="./releases/index.html"/>
     </menu>
 


[02/50] [abbrv] tez git commit: Updating CHANGES.txt (rbalamohan)

Posted by sr...@apache.org.
Updating CHANGES.txt (rbalamohan)


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

Branch: refs/heads/TEZ-2980
Commit: 64864352bbe327d3bfcf848de0670cfe4e2f5e2f
Parents: eee485a
Author: Rajesh Balamohan <rb...@apache.org>
Authored: Thu Dec 17 04:16:11 2015 +0530
Committer: Rajesh Balamohan <rb...@apache.org>
Committed: Thu Dec 17 04:16:11 2015 +0530

----------------------------------------------------------------------
 CHANGES.txt | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/64864352/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 2a2addc..17142ce 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -296,6 +296,7 @@ INCOMPATIBLE CHANGES
   TEZ-2949. Allow duplicate dag names within session for Tez.
 
 ALL CHANGES
+  TEZ-2538. ADDITIONAL_SPILL_COUNT wrongly populated for DefaultSorter with multiple partitions.
   TEZ-3006. Remove unused import in TestHistoryParser.
   TEZ-2979. FlakyTest: org.apache.tez.history.TestHistoryParser.
   TEZ-2684. ShuffleVertexManager.parsePartitionStats throws IllegalStateException: Stats should be initialized.


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

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


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

Branch: refs/heads/TEZ-2980
Commit: a94aeb268afb5e28b9c8205af3b3967284f71763
Parents: b272c1a
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Mon Jan 18 15:28:53 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Wed Jan 20 22:30:07 2016 +0530

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


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

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/app/components/tab-n-refresh.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/components/tab-n-refresh.js b/tez-ui2/src/main/webapp/app/components/tab-n-refresh.js
new file mode 100644
index 0000000..3f05371
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/components/tab-n-refresh.js
@@ -0,0 +1,44 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+  init: function () {
+    this._super();
+    this.setApplication();
+  },
+
+  setApplication: function () {
+    var application = this.get("targetObject.container").lookup('controller:application');
+    this.set("application", application);
+  },
+
+  normalizedTabs: Ember.computed("tabs", "application.currentPath", function () {
+    var tabs = this.get("tabs"),
+        activeRouteName = this.get("application.currentPath");
+
+    return tabs.map(function (tab) {
+      return {
+        text: tab.text,
+        routeName: tab.routeName,
+        active: tab.routeName === activeRouteName
+      };
+    });
+  })
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/app/controllers/abstract.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/abstract.js b/tez-ui2/src/main/webapp/app/controllers/abstract.js
new file mode 100644
index 0000000..c077914
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/abstract.js
@@ -0,0 +1,42 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import NameMixin from '../mixins/name';
+
+export default Ember.Controller.extend(NameMixin, {
+  // Must be set by inheriting classes
+  breadcrumbs: null,
+
+  init: function () {
+    this._super();
+    Ember.run.later(this, "setBreadcrumbs");
+  },
+
+  crumbObserver: Ember.observer("breadcrumbs", function () {
+    Ember.run.later(this, "setBreadcrumbs");
+  }),
+
+  setBreadcrumbs: function () {
+    var crumbs = {},
+        name = this.get("name");
+    crumbs[name] = this.get("breadcrumbs");
+    this.send("setBreadcrumbs", crumbs);
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/app/controllers/dag.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag.js b/tez-ui2/src/main/webapp/app/controllers/dag.js
new file mode 100644
index 0000000..f54d8cf
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/dag.js
@@ -0,0 +1,47 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import AbstractController from './abstract';
+
+export default AbstractController.extend({
+  breadcrumbs: Ember.computed("model", function () {
+    var name = this.get("model.name");
+
+    return [{
+      text: `DAG [${name}]`,
+      routeName: "dag.index",
+      model: this.get("model.entityID")
+    }];
+  }),
+
+  tabs: [{
+    text: "DAG Details",
+    routeName: "dag.index"
+  }, {
+    text: "All Vertices",
+    routeName: "dag.vertices"
+  }, {
+    text: "All Tasks",
+    routeName: "dag.tasks"
+  }, {
+    text: "All Attempts",
+    routeName: "dag.attempts"
+  }]
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js b/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
new file mode 100644
index 0000000..d5efc50
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import PageController from '../page';
+
+export default PageController.extend({
+  breadcrumbs: [{
+    text: "All Attempts",
+    routeName: "dag.attempts",
+  }]
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/app/controllers/dag/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/index.js b/tez-ui2/src/main/webapp/app/controllers/dag/index.js
new file mode 100644
index 0000000..9745328
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/index.js
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import PageController from '../page';
+
+export default PageController.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js b/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
new file mode 100644
index 0000000..e83df5d
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import PageController from '../page';
+
+export default PageController.extend({
+  breadcrumbs: [{
+    text: "All Tasks",
+    routeName: "dag.tasks",
+  }]
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js b/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
new file mode 100644
index 0000000..e001652
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import PageController from '../page';
+
+export default PageController.extend({
+  breadcrumbs: [{
+    text: "All Vertices",
+    routeName: "dag.vertices",
+  }]
+});

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

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/app/controllers/page.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/page.js b/tez-ui2/src/main/webapp/app/controllers/page.js
new file mode 100644
index 0000000..84882a8
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/page.js
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import AbstractController from './abstract';
+
+export default AbstractController.extend({
+  // Must be set from route
+  isLoading: false,
+
+  loaded: Ember.computed("model", "isLoading", function () {
+    return this.get("model") && !this.get("isLoading");
+  }),
+});

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

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/app/mixins/name.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/mixins/name.js b/tez-ui2/src/main/webapp/app/mixins/name.js
new file mode 100644
index 0000000..fe0c524
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/mixins/name.js
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Mixin.create({
+
+  name: Ember.computed(function () {
+    var name = this.toString();
+    name = name.substr(0, name.indexOf("::"));
+    name = name.substr(name.indexOf(":") + 1);
+    return name;
+  }),
+
+});

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

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

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/app/routes/app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/app.js b/tez-ui2/src/main/webapp/app/routes/app.js
new file mode 100644
index 0000000..8719170
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/app.js
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Route.extend({
+});

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

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/app/routes/dag.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag.js b/tez-ui2/src/main/webapp/app/routes/dag.js
new file mode 100644
index 0000000..71ff019
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/dag.js
@@ -0,0 +1,31 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+  title: "DAG",
+
+  loaderQueryParams: {
+    id: "dag_id"
+  },
+
+  model: function (params) {
+    return this.get("loader").queryRecord('dag', this.queryFromParams(params).id);
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/app/routes/dag/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag/attempts.js b/tez-ui2/src/main/webapp/app/routes/dag/attempts.js
new file mode 100644
index 0000000..5de1cab
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/dag/attempts.js
@@ -0,0 +1,29 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  title: "DAG Details",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/app/routes/dag/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag/index.js b/tez-ui2/src/main/webapp/app/routes/dag/index.js
new file mode 100644
index 0000000..90929d0
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/dag/index.js
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  title: "DAG Details",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (/*value, query*/) {
+    return this.get("loader").queryRecord('dag', this.modelFor("dag").id);
+  },
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/app/routes/dag/tasks.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag/tasks.js b/tez-ui2/src/main/webapp/app/routes/dag/tasks.js
new file mode 100644
index 0000000..5de1cab
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/dag/tasks.js
@@ -0,0 +1,29 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  title: "DAG Details",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/app/routes/dag/vertices.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag/vertices.js b/tez-ui2/src/main/webapp/app/routes/dag/vertices.js
new file mode 100644
index 0000000..5de1cab
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/dag/vertices.js
@@ -0,0 +1,29 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  title: "DAG Details",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+});

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

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

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/app/styles/details-page.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/details-page.less b/tez-ui2/src/main/webapp/app/styles/details-page.less
new file mode 100644
index 0000000..8c85d1f
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/styles/details-page.less
@@ -0,0 +1,49 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+.detail-list {
+  table-layout: fixed;
+  white-space: nowrap;
+
+  .progress {
+    margin-bottom: 0px;
+  }
+
+  tr {
+    margin: 0px 0px 0px 15px;
+    overflow: hidden;
+  }
+
+  thead {
+    background-color: @bg-lite;
+    font-weight: bold;
+  }
+
+  td {
+    padding: 0px 20px 0px 0px;
+  }
+
+  td:first-child {
+    width:120px;
+  }
+
+  th, td {
+    border: 1px solid @border-lite;
+    padding: 5px;
+  }
+}

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

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

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/app/styles/tab-n-refresh.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/tab-n-refresh.less b/tez-ui2/src/main/webapp/app/styles/tab-n-refresh.less
new file mode 100644
index 0000000..698f8f3
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/styles/tab-n-refresh.less
@@ -0,0 +1,42 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@import "./shared";
+
+.tab-n-refresh {
+  margin-bottom: 10px;
+  position: relative;
+
+  .refresh-ui {
+    position: absolute;
+    right: 0px;
+    top: -10px;
+
+    .text-elements {
+      display: inline-block;
+      position: relative;
+
+      line-height: 18px;
+      top: 12px;
+      text-align: right;
+      font-size: .95em;
+
+      .align-checknradio;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/app/templates/app.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/app.hbs b/tez-ui2/src/main/webapp/app/templates/app.hbs
new file mode 100644
index 0000000..c1a05b4
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/app.hbs
@@ -0,0 +1,19 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+}}
+
+{{outlet}}

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs b/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs
new file mode 100644
index 0000000..4075c54
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/components/tab-n-refresh.hbs
@@ -0,0 +1,42 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+}}
+
+<ul class="nav nav-tabs tab-n-refresh">
+  {{#each normalizedTabs as |tab|}}
+    <li class="{{if tab.active 'active'}}">
+      {{#link-to tab.routeName}}
+        {{tab.text}}
+      {{/link-to}}
+    </li>
+  {{/each}}
+  <span class="refresh-ui">
+    <span class="text-elements">
+      {{input type="checkbox" name="autoEnabled" checked=autoEnabled}}
+      Auto Refresh
+      <br/>
+      {{#if displayTime}}
+        Last refreshed at <b>{{displayTime}}</b>
+      {{else}}
+        Load time not available!
+      {{/if}}
+    </span>
+    <button type="button" class="btn btn-success">
+      <i class='fa fa-refresh'></i> Refresh
+    </button>
+  </span>
+</ul>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/app/templates/dag.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag.hbs b/tez-ui2/src/main/webapp/app/templates/dag.hbs
new file mode 100644
index 0000000..308b905
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/dag.hbs
@@ -0,0 +1,20 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+}}
+
+{{tab-n-refresh tabs=tabs}}
+{{outlet}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/app/templates/dag/attempts.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/attempts.hbs b/tez-ui2/src/main/webapp/app/templates/dag/attempts.hbs
new file mode 100644
index 0000000..63840f5
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/dag/attempts.hbs
@@ -0,0 +1,19 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+}}
+
+Attempts
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/index.hbs b/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
new file mode 100644
index 0000000..2811a35
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
@@ -0,0 +1,83 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+}}
+
+{{#if loaded}}
+  <table class='detail-list'>
+    <thead>
+      <tr>
+        <th colspan=2>Details</th>
+      </tr>
+    </thead>
+    <tbody>
+    <tr>
+      <td colspan="2">
+        {{bs-button icon="fa fa-download" title="Download data" defaultText="Download data" type="info" clicked="downloadDagJson"}}
+      </td>
+    </tr>
+    <tr>
+      <td>Application ID</td>
+      <td>
+        {{#link-to 'app' model.appID class='ember-table-content'}}
+          {{model.appID}}
+        {{/link-to}}
+      </td>
+    </tr>
+    <tr>
+      <td>ID</td>
+      <td>{{model.entityID}}</td>
+    </tr>
+    <tr>
+      <td>Submitter</td>
+      <td>{{model.user}}</td>
+    </tr>
+    <tr>
+      <td>Status</td>
+      <td>
+        {{em-table-status-cell content=model.status}}
+        {{#if progressStr}} {{bs-badge content=progressStr}}{{/if}}
+        {{#if hasFailedTasks}}
+          [ <a href='{{unbound failedTasksLink}}'>Failed Tasks</a> ]
+        {{/if}}
+        {{#if hasFailedTaskAttempts}}
+          [ <a href='{{unbound failedTaskAttemptsLink}}'>Failed TaskAttempts</a> ]
+        {{/if}}
+      </td>
+    </tr>
+    <tr>
+      <td>Start Time</td>
+      <td>{{txt model.startTime type="date"}}</td>
+    </tr>
+    <tr>
+      <td>End Time</td>
+      <td>{{txt model.endTime type="date"}}</td>
+    </tr>
+    <tr>
+      <td>Duration</td>
+      <td>{{txt model.duration type="duration"}}</td>
+    </tr>
+    <tr>
+      <td>Logs</td>
+      <td>
+        {{em-table-linked-cell content=model.containerLogs}}
+      </td>
+    </tr>
+    </tbody>
+  </table>
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/app/templates/dag/tasks.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/tasks.hbs b/tez-ui2/src/main/webapp/app/templates/dag/tasks.hbs
new file mode 100644
index 0000000..daee5b5
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/dag/tasks.hbs
@@ -0,0 +1,19 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+}}
+
+Tasks
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/app/templates/dag/vertices.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/vertices.hbs b/tez-ui2/src/main/webapp/app/templates/dag/vertices.hbs
new file mode 100644
index 0000000..7f0bd85
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/dag/vertices.hbs
@@ -0,0 +1,19 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+}}
+
+Vertices
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/tests/integration/components/tab-n-refresh-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/integration/components/tab-n-refresh-test.js b/tez-ui2/src/main/webapp/tests/integration/components/tab-n-refresh-test.js
new file mode 100644
index 0000000..e45b461
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/integration/components/tab-n-refresh-test.js
@@ -0,0 +1,50 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleForComponent, test } from 'ember-qunit';
+import hbs from 'htmlbars-inline-precompile';
+
+moduleForComponent('tab-n-refresh', 'Integration | Component | tab n refresh', {
+  integration: true
+});
+
+test('Basic creation test', function(assert) {
+  var testTabs = [{
+    text: "Tab 1",
+    routeName: "route_1",
+  },{
+    text: "Tab 2",
+    routeName: "route_2",
+  }];
+
+  this.set("tabs", testTabs);
+
+  this.render(hbs`{{tab-n-refresh tabs=tabs}}`);
+
+  assert.equal(this.$("button").text().trim(), 'Refresh');
+  assert.equal($(this.$("li")[0]).text().trim(), testTabs[0].text);
+  assert.equal($(this.$("li")[1]).text().trim(), testTabs[1].text);
+
+  this.render(hbs`
+    {{#tab-n-refresh tabs=tabs}}
+      template block text
+    {{/tab-n-refresh}}
+  `);
+
+  assert.equal(this.$("button").text().trim(), 'Refresh');
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/tests/unit/controllers/abstract-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/abstract-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/abstract-test.js
new file mode 100644
index 0000000..640e1e5
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/abstract-test.js
@@ -0,0 +1,74 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:abstract', 'Unit | Controller | abstract', {
+  // Specify the other units that are required for this test.
+  // needs: ['route:abstract']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller.name);
+  assert.ok(controller.crumbObserver);
+  assert.ok(controller.setBreadcrumbs);
+});
+
+test('init test', function(assert) {
+  assert.expect(1);
+
+  this.subject({
+    send: function (name) {
+      assert.equal(name, "setBreadcrumbs");
+    }
+  });
+});
+
+test('crumbObserver test', function(assert) {
+  assert.expect(1 + 1); // Init and fired
+
+  let controller = this.subject({
+    send: function (name) {
+      assert.equal(name, "setBreadcrumbs");
+    }
+  });
+
+  controller.set("breadcrumbs", []);
+});
+
+test('setBreadcrumbs test', function(assert) {
+  let testName = "Abc", // Because all controllers are pointing to the leaf rout
+      testBreadCrumbs = [];
+
+  assert.expect(3);
+  this.subject({
+    name: testName,
+    breadcrumbs: testBreadCrumbs,
+    send: function (name, crumbs) {
+      assert.equal(name, "setBreadcrumbs");
+      assert.ok(crumbs.hasOwnProperty(testName));
+      assert.equal(crumbs[testName], testBreadCrumbs);
+    }
+  });
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/tests/unit/controllers/dag-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag-test.js
new file mode 100644
index 0000000..304321e
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag-test.js
@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:dag', 'Unit | Controller | dag', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+  assert.ok(controller.tabs);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js
new file mode 100644
index 0000000..1908e69
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:dag/attempts', 'Unit | Controller | dag/attempts', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/tests/unit/controllers/dag/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/index-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/index-test.js
new file mode 100644
index 0000000..0b64e86
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/index-test.js
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:dag/index', 'Unit | Controller | dag/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js
new file mode 100644
index 0000000..9d22331
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:dag/tasks', 'Unit | Controller | dag/tasks', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
new file mode 100644
index 0000000..ca6d3d9
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:dag/vertices', 'Unit | Controller | dag/vertices', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+});

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

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/tests/unit/controllers/page-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/page-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/page-test.js
new file mode 100644
index 0000000..ffbdd60
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/page-test.js
@@ -0,0 +1,49 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:page', 'Unit | Controller | page', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.loaded);
+
+  assert.equal(controller.isLoading, false);
+});
+
+test('loaded test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.notOk(controller.get("loaded"));
+  controller.set("model", true);
+  assert.ok(controller.get("loaded"));
+  controller.set("isLoading", true);
+  assert.notOk(controller.get("loaded"));
+});

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

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/tests/unit/mixins/name-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/mixins/name-test.js b/tez-ui2/src/main/webapp/tests/unit/mixins/name-test.js
new file mode 100644
index 0000000..aedd0cd
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/mixins/name-test.js
@@ -0,0 +1,44 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import NameMixin from '../../../mixins/name';
+import { module, test } from 'qunit';
+
+module('Unit | Mixin | name');
+
+test('Basic creation', function(assert) {
+  let NameObject = Ember.Object.extend(NameMixin);
+  let subject = NameObject.create();
+
+  assert.ok(subject);
+  assert.ok(subject.name);
+});
+
+test('name test', function(assert) {
+  let NameObject = Ember.Object.extend(NameMixin),
+      testName = "ts";
+
+  let subject = NameObject.create({
+    toString: function () {
+      return `<tez-ui@test:${testName}::ember427>`;
+    }
+  });
+
+  assert.equal(subject.get("name"), testName);
+});

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

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/tests/unit/routes/app-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/app-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/app-test.js
new file mode 100644
index 0000000..8e361ea
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/app-test.js
@@ -0,0 +1,29 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:app', 'Unit | Route | app', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('it exists', function(assert) {
+  let route = this.subject();
+  assert.ok(route);
+});

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

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/tests/unit/routes/dag-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/dag-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/dag-test.js
new file mode 100644
index 0000000..dc1c012
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/dag-test.js
@@ -0,0 +1,32 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:dag', 'Unit | Route | dag', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('it exists', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.loaderQueryParams);
+  assert.ok(route.model);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/tests/unit/routes/dag/attempts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/dag/attempts-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/dag/attempts-test.js
new file mode 100644
index 0000000..f997891
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/dag/attempts-test.js
@@ -0,0 +1,44 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:dag/attempts', 'Unit | Route | dag/attempts', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/tests/unit/routes/dag/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/dag/index-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/dag/index-test.js
new file mode 100644
index 0000000..aef7031
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/dag/index-test.js
@@ -0,0 +1,46 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:dag/index', 'Unit | Route | dag/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+  assert.ok(route.load);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});
+

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/tests/unit/routes/dag/tasks-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/dag/tasks-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/dag/tasks-test.js
new file mode 100644
index 0000000..3e283ca
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/dag/tasks-test.js
@@ -0,0 +1,44 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:dag/tasks', 'Unit | Route | dag/tasks', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/a94aeb26/tez-ui2/src/main/webapp/tests/unit/routes/dag/vertices-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/dag/vertices-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/dag/vertices-test.js
new file mode 100644
index 0000000..e55e184
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/dag/vertices-test.js
@@ -0,0 +1,44 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:dag/vertices', 'Unit | Route | dag/vertices', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});

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


[14/50] [abbrv] tez git commit: TEZ-2669. Propagation of errors from plugins to the AM for error reporting. Contributed by Hitesh Shah and Siddharth Seth.

Posted by sr...@apache.org.
TEZ-2669. Propagation of errors from plugins to the AM for error
reporting. Contributed by Hitesh Shah and Siddharth Seth.


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

Branch: refs/heads/TEZ-2980
Commit: 1d765431601fb8ab7cca248baa973684d828afaa
Parents: 0c08577
Author: Siddharth Seth <ss...@apache.org>
Authored: Tue Jan 12 15:19:22 2016 -0800
Committer: Siddharth Seth <ss...@apache.org>
Committed: Tue Jan 12 15:19:22 2016 -0800

----------------------------------------------------------------------
 CHANGES.txt                                     |   1 +
 .../serviceplugins/api/ContainerLauncher.java   |  12 +-
 .../api/ContainerLauncherContext.java           |   3 +-
 .../api/ServicePluginException.java             |  36 +++
 .../tez/serviceplugins/api/TaskScheduler.java   |  48 +++-
 tez-dag/src/main/java/org/apache/tez/Utils.java |  66 +++++
 .../apache/tez/dag/api/TaskCommunicator.java    |  39 ++-
 .../dag/app/ContainerLauncherContextImpl.java   |  18 +-
 .../org/apache/tez/dag/app/DAGAppMaster.java    |  68 +++--
 .../dag/app/TaskCommunicatorContextImpl.java    |   6 +-
 .../tez/dag/app/TaskCommunicatorManager.java    | 151 +++++++++--
 .../app/TaskCommunicatorManagerInterface.java   |   3 +-
 .../tez/dag/app/TaskCommunicatorWrapper.java    |  83 ++++++
 .../tez/dag/app/TezTaskCommunicatorImpl.java    |   2 +-
 .../tez/dag/app/dag/StateChangeNotifier.java    |   7 +-
 .../app/dag/event/DAGAppMasterEventType.java    |   3 +
 .../DAGAppMasterEventUserServiceFatalError.java |  46 ++++
 .../app/dag/event/DAGEventInternalError.java    |  32 +++
 .../apache/tez/dag/app/dag/impl/DAGImpl.java    |  22 +-
 .../tez/dag/app/dag/impl/VertexManager.java     |   8 +-
 .../app/launcher/ContainerLauncherManager.java  |  49 +++-
 .../app/launcher/ContainerLauncherWrapper.java  |  40 +++
 .../app/launcher/LocalContainerLauncher.java    |   2 +-
 .../tez/dag/app/rm/TaskSchedulerManager.java    | 271 ++++++++++++++++---
 .../tez/dag/app/rm/TaskSchedulerWrapper.java    |  90 ++++++
 .../dag/app/rm/container/AMContainerImpl.java   |  30 +-
 .../apache/tez/dag/app/MockDAGAppMaster.java    |   2 +-
 .../tez/dag/app/PluginWrapperTestHelpers.java   | 149 ++++++++++
 .../dag/app/TestTaskCommunicatorManager.java    |  99 ++++++-
 .../dag/app/TestTaskCommunicatorManager1.java   |   6 +-
 .../dag/app/TestTaskCommunicatorWrapper.java    |  43 +++
 .../tez/dag/app/dag/impl/TestTaskAttempt.java   |   9 +-
 .../launcher/TestContainerLauncherManager.java  |  83 +++++-
 .../launcher/TestContainerLauncherWrapper.java  |  30 ++
 .../tez/dag/app/rm/TestContainerReuse.java      |   8 +-
 .../dag/app/rm/TestTaskSchedulerHelpers.java    |  14 +-
 .../dag/app/rm/TestTaskSchedulerManager.java    | 106 +++++++-
 .../dag/app/rm/TestTaskSchedulerWrapper.java    |  29 ++
 .../dag/app/rm/container/TestAMContainer.java   |  10 +-
 .../app/rm/container/TestAMContainerMap.java    |   3 +-
 .../org/apache/tez/examples/JoinValidate.java   |   4 +-
 ...zTestServiceContainerLauncherWithErrors.java |  37 +++
 ...stServiceTaskSchedulerServiceWithErrors.java |  93 +++++++
 ...ezTestServiceTaskCommunicatorWithErrors.java |  83 ++++++
 .../tez/examples/JoinValidateConfigured.java    |  10 +
 .../tez/tests/ExternalTezServiceTestHelper.java | 194 +++++++++++++
 .../tez/tests/TestExternalTezServices.java      | 125 +--------
 .../tests/TestExternalTezServicesErrors.java    | 235 ++++++++++++++++
 48 files changed, 2231 insertions(+), 277 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 6cdc037..d39cbb8 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -11,6 +11,7 @@ INCOMPATIBLE CHANGES
   TEZ-2972. Avoid task rescheduling when a node turns unhealthy
 
 ALL CHANGES:
+  TEZ-2669. Propagation of errors from plugins to the AM for error reporting.
   TEZ-2978. Add an option to allow the SplitGrouper to generate node local only groups.
   TEZ-2129. Task and Attempt views should contain links to the logs
   TEZ-3025. InputInitializer creation should use the dag ugi.

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-api/src/main/java/org/apache/tez/serviceplugins/api/ContainerLauncher.java
----------------------------------------------------------------------
diff --git a/tez-api/src/main/java/org/apache/tez/serviceplugins/api/ContainerLauncher.java b/tez-api/src/main/java/org/apache/tez/serviceplugins/api/ContainerLauncher.java
index 5a77b69..8792fd7 100644
--- a/tez-api/src/main/java/org/apache/tez/serviceplugins/api/ContainerLauncher.java
+++ b/tez-api/src/main/java/org/apache/tez/serviceplugins/api/ContainerLauncher.java
@@ -74,16 +74,22 @@ public abstract class ContainerLauncher implements ServicePluginLifecycle {
   }
 
   /**
-   * A request to launch the specified container
+   * Get the {@link ContainerLauncherContext} associated with this instance of the container
+   * launcher, which is used to communicate with the rest of the system
    *
    * @param launchRequest the actual launch request
+   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
+   *                               This will cause the app to shutdown.
    */
-  public abstract void launchContainer(ContainerLaunchRequest launchRequest);
+  public abstract void launchContainer(ContainerLaunchRequest launchRequest) throws
+      ServicePluginException;
 
   /**
    * A request to stop a specific container
    *
    * @param stopRequest the actual stop request
+   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
+   *                               This will cause the app to shutdown.
    */
-  public abstract void stopContainer(ContainerStopRequest stopRequest);
+  public abstract void stopContainer(ContainerStopRequest stopRequest) throws ServicePluginException;
 }

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-api/src/main/java/org/apache/tez/serviceplugins/api/ContainerLauncherContext.java
----------------------------------------------------------------------
diff --git a/tez-api/src/main/java/org/apache/tez/serviceplugins/api/ContainerLauncherContext.java b/tez-api/src/main/java/org/apache/tez/serviceplugins/api/ContainerLauncherContext.java
index dcd9e80..70a3498 100644
--- a/tez-api/src/main/java/org/apache/tez/serviceplugins/api/ContainerLauncherContext.java
+++ b/tez-api/src/main/java/org/apache/tez/serviceplugins/api/ContainerLauncherContext.java
@@ -99,12 +99,13 @@ public interface ContainerLauncherContext {
   ApplicationAttemptId getApplicationAttemptId();
 
   /**
-   * Get meta info from the specified TaskCommunicator. This assumes that the launched has been
+   * Get meta info from the specified TaskCommunicator. This assumes that the launcher has been
    * setup
    * along with a compatible TaskCommunicator, and the launcher knows how to read this meta-info
    *
    * @param taskCommName the name of the task communicator
    * @return meta info for the requested task communicator
+   *
    */
   Object getTaskCommunicatorMetaInfo(String taskCommName);
 }

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-api/src/main/java/org/apache/tez/serviceplugins/api/ServicePluginException.java
----------------------------------------------------------------------
diff --git a/tez-api/src/main/java/org/apache/tez/serviceplugins/api/ServicePluginException.java b/tez-api/src/main/java/org/apache/tez/serviceplugins/api/ServicePluginException.java
new file mode 100644
index 0000000..737329a
--- /dev/null
+++ b/tez-api/src/main/java/org/apache/tez/serviceplugins/api/ServicePluginException.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tez.serviceplugins.api;
+
+/**
+ * Indicates an error from pluggable Tez Services.
+ */
+public class ServicePluginException extends Exception {
+
+  public ServicePluginException() {
+  }
+
+  public ServicePluginException(String message) {
+    super(message);
+  }
+
+  public ServicePluginException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  public ServicePluginException(Throwable cause) {
+    super(cause);
+  }
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-api/src/main/java/org/apache/tez/serviceplugins/api/TaskScheduler.java
----------------------------------------------------------------------
diff --git a/tez-api/src/main/java/org/apache/tez/serviceplugins/api/TaskScheduler.java b/tez-api/src/main/java/org/apache/tez/serviceplugins/api/TaskScheduler.java
index de76029..5875bd2 100644
--- a/tez-api/src/main/java/org/apache/tez/serviceplugins/api/TaskScheduler.java
+++ b/tez-api/src/main/java/org/apache/tez/serviceplugins/api/TaskScheduler.java
@@ -101,38 +101,48 @@ public abstract class TaskScheduler implements ServicePluginLifecycle {
    * Get the currently available resources from this source
    *
    * @return the resources available at the time of invocation
+   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
+   *                               This will cause the app to shutdown.
    */
-  public abstract Resource getAvailableResources();
+  public abstract Resource getAvailableResources() throws ServicePluginException;
 
   /**
    * Get the total available resources from this source
    *
    * @return the total available resources from the source
+   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
+   *                               This will cause the app to shutdown.
    */
-  public abstract Resource getTotalResources();
+  public abstract Resource getTotalResources() throws ServicePluginException;
 
   /**
    * Get the number of nodes available from the source
    *
    * @return the number of nodes
+   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
+   *                               This will cause the app to shutdown.
    */
-  public abstract int getClusterNodeCount();
+  public abstract int getClusterNodeCount() throws ServicePluginException;
 
   /**
    * Indication to a source that a node has been blacklisted, and should not be used for subsequent
    * allocations.
    *
    * @param nodeId te nodeId to be blacklisted
+   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
+   *                               This will cause the app to shutdown.
    */
-  public abstract void blacklistNode(NodeId nodeId);
+  public abstract void blacklistNode(NodeId nodeId) throws ServicePluginException;
 
   /**
    * Indication to a source that a node has been un-blacklisted, and can be used from subsequent
    * allocations
    *
    * @param nodeId the nodeId to be unblacklisted
+   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
+   *                               This will cause the app to shutdown.
    */
-  public abstract void unblacklistNode(NodeId nodeId);
+  public abstract void unblacklistNode(NodeId nodeId) throws ServicePluginException;
 
   /**
    * A request to the source to allocate resources for a requesting task, with location information
@@ -150,10 +160,12 @@ public abstract class TaskScheduler implements ServicePluginLifecycle {
    * @param clientCookie       a cookie associated with this request. This should be returned back
    *                           via the {@link TaskSchedulerContext#taskAllocated(Object, Object,
    *                           Container)} method when a task is assigned to a resource
+   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
+   *                               This will cause the app to shutdown.
    */
   public abstract void allocateTask(Object task, Resource capability,
                                     String[] hosts, String[] racks, Priority priority,
-                                    Object containerSignature, Object clientCookie);
+                                    Object containerSignature, Object clientCookie) throws ServicePluginException;
 
   /**
    * A request to the source to allocate resources for a requesting task, based on a previously used
@@ -171,11 +183,13 @@ public abstract class TaskScheduler implements ServicePluginLifecycle {
    * @param clientCookie       a cookie associated with this request. This should be returned back
    *                           via the {@link TaskSchedulerContext#taskAllocated(Object, Object,
    *                           Container)} method when a task is assigned to a resource
+   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
+   *                               This will cause the app to shutdown.
    */
   public abstract void allocateTask(Object task, Resource capability,
                                     ContainerId containerId, Priority priority,
                                     Object containerSignature,
-                                    Object clientCookie);
+                                    Object clientCookie) throws ServicePluginException;
 
   /**
    * A request to deallocate a task. This is typically a result of a task completing - with success
@@ -190,38 +204,48 @@ public abstract class TaskScheduler implements ServicePluginLifecycle {
    * @param endReason     the reason for the task failure
    * @param diagnostics   additional diagnostics information which may be relevant
    * @return true if the task was associated with a container, false if the task was not associated
+   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
+   *                               This will cause the app to shutdown.
    * with a container
    */
   public abstract boolean deallocateTask(Object task, boolean taskSucceeded,
                                          TaskAttemptEndReason endReason,
-                                         @Nullable String diagnostics);
+                                         @Nullable String diagnostics) throws ServicePluginException;
 
   /**
    * A request to de-allocate a previously allocated container.
    *
    * @param containerId the containerId to de-allocate
    * @return the task which was previously associated with this container, null otherwise
+   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
+   *                               This will cause the app to shutdown.
    */
-  public abstract Object deallocateContainer(ContainerId containerId);
+  public abstract Object deallocateContainer(ContainerId containerId) throws ServicePluginException;
 
   /**
    * Inform the scheduler that it should unregister. This is primarily valid for schedulers which
    * require registration (YARN a.t.m)
+   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
+   *                               This will cause the app to shutdown.
    */
-  public abstract void setShouldUnregister();
+  public abstract void setShouldUnregister() throws ServicePluginException;
 
   /**
    * Checks with the scheduler whether it has unregistered.
    *
    * @return true if the scheduler has unregistered. False otherwise.
+   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
+   *                               This will cause the app to shutdown.
    */
-  public abstract boolean hasUnregistered();
+  public abstract boolean hasUnregistered() throws ServicePluginException;
 
   /**
    * Indicates to the scheduler that the currently running dag has completed.
    * This can be used to reset dag specific statistics, potentially release resources and prepare
    * for a new DAG.
+   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
+   *                               This will cause the app to shutdown.
    */
-  public abstract void dagComplete();
+  public abstract void dagComplete() throws ServicePluginException;
 
 }

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/main/java/org/apache/tez/Utils.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/Utils.java b/tez-dag/src/main/java/org/apache/tez/Utils.java
new file mode 100644
index 0000000..959b536
--- /dev/null
+++ b/tez-dag/src/main/java/org/apache/tez/Utils.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tez;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.tez.dag.app.AppContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@InterfaceAudience.Private
+/**
+ * Utility class within the tez-dag module
+ */
+public class Utils {
+
+  private static final Logger LOG = LoggerFactory.getLogger(Utils.class);
+
+  public static String getContainerLauncherIdentifierString(int launcherIndex, AppContext appContext) {
+    String name;
+    try {
+      name = appContext.getContainerLauncherName(launcherIndex);
+    } catch (Exception e) {
+      LOG.error("Unable to get launcher name for index: " + launcherIndex +
+          ", falling back to reporting the index");
+      return "[" + String.valueOf(launcherIndex) + "]";
+    }
+    return "[" + launcherIndex + ":" + name + "]";
+  }
+
+  public static String getTaskCommIdentifierString(int taskCommIndex, AppContext appContext) {
+    String name;
+    try {
+      name = appContext.getTaskCommunicatorName(taskCommIndex);
+    } catch (Exception e) {
+      LOG.error("Unable to get taskcomm name for index: " + taskCommIndex +
+          ", falling back to reporting the index");
+      return "[" + String.valueOf(taskCommIndex) + "]";
+    }
+    return "[" + taskCommIndex + ":" + name + "]";
+  }
+
+  public static String getTaskSchedulerIdentifierString(int schedulerIndex, AppContext appContext) {
+    String name;
+    try {
+      name = appContext.getTaskSchedulerName(schedulerIndex);
+    } catch (Exception e) {
+      LOG.error("Unable to get scheduler name for index: " + schedulerIndex +
+          ", falling back to reporting the index");
+      return "[" + String.valueOf(schedulerIndex) + "]";
+    }
+    return "[" + schedulerIndex + ":" + name + "]";
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/main/java/org/apache/tez/dag/api/TaskCommunicator.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/api/TaskCommunicator.java b/tez-dag/src/main/java/org/apache/tez/dag/api/TaskCommunicator.java
index 38742de..1b6ad07 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/api/TaskCommunicator.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/api/TaskCommunicator.java
@@ -24,6 +24,7 @@ import org.apache.hadoop.yarn.api.records.LocalResource;
 import org.apache.tez.common.ServicePluginLifecycle;
 import org.apache.tez.dag.api.event.VertexStateUpdate;
 import org.apache.tez.serviceplugins.api.ContainerEndReason;
+import org.apache.tez.serviceplugins.api.ServicePluginException;
 import org.apache.tez.serviceplugins.api.TaskAttemptEndReason;
 import org.apache.tez.dag.records.TezTaskAttemptID;
 import org.apache.tez.runtime.api.impl.TaskSpec;
@@ -107,8 +108,11 @@ public abstract class TaskCommunicator implements ServicePluginLifecycle {
    * @param containerId the associated containerId
    * @param hostname    the hostname on which the container runs
    * @param port        the port for the service which is running the container
+   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
+   *                               This will cause the app to shutdown.
    */
-  public abstract void registerRunningContainer(ContainerId containerId, String hostname, int port);
+  public abstract void registerRunningContainer(ContainerId containerId, String hostname,
+                                                int port) throws ServicePluginException;
 
   /**
    * Register the end of a container. This can be caused by preemption, the container completing
@@ -117,9 +121,12 @@ public abstract class TaskCommunicator implements ServicePluginLifecycle {
    * @param containerId the associated containerId
    * @param endReason   the end reason for the container completing
    * @param diagnostics diagnostics associated with the container end
+   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
+   *                               This will cause the app to shutdown.
    */
   public abstract void registerContainerEnd(ContainerId containerId, ContainerEndReason endReason,
-                                            @Nullable String diagnostics);
+                                            @Nullable String diagnostics) throws
+      ServicePluginException;
 
   /**
    * Register a task attempt to execute on a container
@@ -133,11 +140,14 @@ public abstract class TaskCommunicator implements ServicePluginLifecycle {
    * @param credentialsChanged  whether the credentials are different from the original credentials
    *                            associated with this container
    * @param priority            the priority of the task being executed
+   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
+   *                               This will cause the app to shutdown.
    */
   public abstract void registerRunningTaskAttempt(ContainerId containerId, TaskSpec taskSpec,
                                                   Map<String, LocalResource> additionalResources,
                                                   Credentials credentials,
-                                                  boolean credentialsChanged, int priority);
+                                                  boolean credentialsChanged, int priority) throws
+      ServicePluginException;
 
   /**
    * Register the completion of a task. This may be a result of preemption, the container dying,
@@ -146,17 +156,22 @@ public abstract class TaskCommunicator implements ServicePluginLifecycle {
    * @param taskAttemptID the task attempt which has completed / needs to be completed
    * @param endReason     the endReason for the task attempt.
    * @param diagnostics   diagnostics associated with the task end
+   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
+   *                               This will cause the app to shutdown.
    */
   public abstract void unregisterRunningTaskAttempt(TezTaskAttemptID taskAttemptID,
                                                     TaskAttemptEndReason endReason,
-                                                    @Nullable String diagnostics);
+                                                    @Nullable String diagnostics) throws
+      ServicePluginException;
 
   /**
    * Return the address, if any, that the service listens on
    *
    * @return the address
+   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
+   *                               This will cause the app to shutdown.
    */
-  public abstract InetSocketAddress getAddress();
+  public abstract InetSocketAddress getAddress() throws ServicePluginException;
 
   /**
    * Receive notifications on vertex state changes.
@@ -175,9 +190,10 @@ public abstract class TaskCommunicator implements ServicePluginLifecycle {
    * @param stateUpdate an event indicating the name of the vertex, and it's updated state.
    *                    Additional information may be available for specific events, Look at the
    *                    type hierarchy for {@link org.apache.tez.dag.api.event.VertexStateUpdate}
-   * @throws Exception
+   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
+   *                               This will cause the app to shutdown.
    */
-  public abstract void onVertexStateUpdated(VertexStateUpdate stateUpdate) throws Exception;
+  public abstract void onVertexStateUpdated(VertexStateUpdate stateUpdate) throws ServicePluginException;
 
   /**
    * Indicates the current running dag is complete. The TaskCommunicatorContext can be used to
@@ -187,9 +203,10 @@ public abstract class TaskCommunicator implements ServicePluginLifecycle {
    * the next dag being submitted.
    *
    * @param dagIdentifier the unique numerical identifier for the DAG in the specified execution context.
-   *
+   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
+   *                               This will cause the app to shutdown.
    */
-  public abstract void dagComplete(int dagIdentifier);
+  public abstract void dagComplete(int dagIdentifier) throws ServicePluginException;
 
   /**
    * Share meta-information such as host:port information where the Task Communicator may be
@@ -197,6 +214,8 @@ public abstract class TaskCommunicator implements ServicePluginLifecycle {
    * Primarily for use by compatible launchers to learn this information.
    *
    * @return meta info for the task communicator
+   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
+   *                               This will cause the app to shutdown.
    */
-  public abstract Object getMetaInfo();
+  public abstract Object getMetaInfo() throws ServicePluginException;
 }

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/main/java/org/apache/tez/dag/app/ContainerLauncherContextImpl.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/ContainerLauncherContextImpl.java b/tez-dag/src/main/java/org/apache/tez/dag/app/ContainerLauncherContextImpl.java
index a2e0dd6..9434256 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/ContainerLauncherContextImpl.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/ContainerLauncherContextImpl.java
@@ -19,6 +19,8 @@ import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
 import org.apache.hadoop.yarn.api.records.ContainerId;
 import org.apache.tez.common.TezUtilsInternal;
 import org.apache.tez.dag.api.UserPayload;
+import org.apache.tez.dag.app.dag.event.DAGAppMasterEventType;
+import org.apache.tez.dag.app.dag.event.DAGAppMasterEventUserServiceFatalError;
 import org.apache.tez.serviceplugins.api.ContainerLauncherContext;
 import org.apache.tez.serviceplugins.api.TaskAttemptEndReason;
 import org.apache.tez.dag.app.rm.container.AMContainerEvent;
@@ -29,10 +31,13 @@ import org.apache.tez.dag.app.rm.container.AMContainerEventStopFailed;
 import org.apache.tez.dag.app.rm.container.AMContainerEventType;
 import org.apache.tez.dag.history.DAGHistoryEvent;
 import org.apache.tez.dag.history.events.ContainerLaunchedEvent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 @SuppressWarnings("unchecked")
 public class ContainerLauncherContextImpl implements ContainerLauncherContext {
 
+  private static final Logger LOG = LoggerFactory.getLogger(ContainerLauncherContextImpl.class);
   private final AppContext context;
   private final TaskCommunicatorManagerInterface tal;
   private final UserPayload initialUserPayload;
@@ -101,7 +106,18 @@ public class ContainerLauncherContextImpl implements ContainerLauncherContext {
   @Override
   public Object getTaskCommunicatorMetaInfo(String taskCommName) {
     int taskCommId = context.getTaskCommunicatorIdentifier(taskCommName);
-    return tal.getTaskCommunicator(taskCommId).getMetaInfo();
+    try {
+      return tal.getTaskCommunicator(taskCommId).getMetaInfo();
+    } catch (Exception e) {
+      String msg = "Error in retrieving meta-info from TaskCommunicator"
+          + ", communicatorName=" + context.getTaskCommunicatorName(taskCommId);
+      LOG.error(msg, e);
+      context.getEventHandler().handle(
+          new DAGAppMasterEventUserServiceFatalError(
+              DAGAppMasterEventType.TASK_COMMUNICATOR_SERVICE_FATAL_ERROR,
+              msg, e));
+    }
+    return null;
   }
 
 }

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/main/java/org/apache/tez/dag/app/DAGAppMaster.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/DAGAppMaster.java b/tez-dag/src/main/java/org/apache/tez/dag/app/DAGAppMaster.java
index c0b86a5..609a018 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/DAGAppMaster.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/DAGAppMaster.java
@@ -63,6 +63,7 @@ import com.google.common.collect.Lists;
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.GnuParser;
 import org.apache.commons.cli.Options;
+import org.apache.commons.lang.exception.ExceptionUtils;
 import org.apache.tez.client.CallerContext;
 import org.apache.tez.common.TezUtils;
 import org.apache.tez.dag.api.NamedEntityDescriptor;
@@ -72,6 +73,8 @@ import org.apache.tez.dag.api.records.DAGProtos.AMPluginDescriptorProto;
 import org.apache.tez.dag.api.records.DAGProtos.ConfigurationProto;
 import org.apache.tez.dag.api.records.DAGProtos.TezNamedEntityDescriptorProto;
 import org.apache.tez.dag.app.dag.event.DAGAppMasterEventDagCleanup;
+import org.apache.tez.dag.app.dag.event.DAGAppMasterEventUserServiceFatalError;
+import org.apache.tez.dag.app.dag.event.DAGEventInternalError;
 import org.apache.tez.dag.history.events.DAGRecoveredEvent;
 import org.apache.tez.dag.records.TezTaskAttemptID;
 import org.apache.tez.dag.records.TezTaskID;
@@ -151,10 +154,6 @@ import org.apache.tez.dag.app.dag.event.VertexEvent;
 import org.apache.tez.dag.app.dag.event.VertexEventType;
 import org.apache.tez.dag.app.dag.impl.DAGImpl;
 import org.apache.tez.dag.app.launcher.ContainerLauncherManager;
-import org.apache.tez.dag.app.dag.impl.TaskAttemptImpl;
-import org.apache.tez.dag.app.dag.impl.TaskImpl;
-import org.apache.tez.dag.app.dag.impl.VertexImpl;
-import org.apache.tez.dag.app.launcher.LocalContainerLauncher;
 import org.apache.tez.dag.app.rm.AMSchedulerEventType;
 import org.apache.tez.dag.app.rm.ContainerLauncherEventType;
 import org.apache.tez.dag.app.rm.TaskSchedulerManager;
@@ -671,8 +670,34 @@ public class DAGAppMaster extends AbstractService {
     return taskSchedulerManager;
   }
 
+  private void handleInternalError(String errDiagnosticsPrefix, String errDiagDagEvent) {
+    state = DAGAppMasterState.ERROR;
+    if (currentDAG != null) {
+      _updateLoggers(currentDAG, "_post");
+      String errDiagnostics = errDiagnosticsPrefix + ". Aborting dag: " + currentDAG.getID();
+      LOG.info(errDiagnostics);
+      // Inform the current DAG about the error
+      sendEvent(new DAGEventInternalError(currentDAG.getID(), errDiagDagEvent));
+    } else {
+      LOG.info(errDiagnosticsPrefix + ". AppMaster will exit as no dag is active");
+      // This could be problematic if the scheduler generated the error,
+      // since un-registration may not be possible.
+      // For now - try setting this flag, but call the shutdownHandler irrespective of
+      // how the flag is handled by user code.
+      try {
+        this.taskSchedulerManager.setShouldUnregisterFlag();
+      } catch (Exception e) {
+        // Ignore exception for now
+        LOG.error("Error when trying to set unregister flag for TaskScheduler", e);
+      } finally {
+        shutdownHandler.shutdown();
+      }
+    }
+  }
+
   @VisibleForTesting
   protected synchronized void handle(DAGAppMasterEvent event) {
+    String errDiagnostics;
     switch (event.getType()) {
     case SCHEDULING_SERVICE_ERROR:
       // Scheduling error - probably an issue with the communication with the RM
@@ -683,22 +708,30 @@ public class DAGAppMaster extends AbstractService {
       DAGAppMasterEventSchedulingServiceError schedulingServiceErrorEvent =
           (DAGAppMasterEventSchedulingServiceError) event;
       state = DAGAppMasterState.ERROR;
-      LOG.info("Error in the TaskScheduler. Shutting down.",
-          schedulingServiceErrorEvent.getThrowable());
+      errDiagnostics = "Error in the TaskScheduler. Shutting down. ";
+      addDiagnostic(errDiagnostics
+          + "Error=" + ExceptionUtils.getStackTrace(schedulingServiceErrorEvent.getThrowable()));
+      LOG.error(errDiagnostics, schedulingServiceErrorEvent.getThrowable());
       shutdownHandler.shutdown();
       break;
+    case TASK_COMMUNICATOR_SERVICE_FATAL_ERROR:
+    case CONTAINER_LAUNCHER_SERVICE_FATAL_ERROR:
+    case TASK_SCHEDULER_SERVICE_FATAL_ERROR:
+      // A fatal error from the pluggable services. The AM cannot continue operation, and should
+      // be shutdown. The AM should not be restarted for recovery.
+      DAGAppMasterEventUserServiceFatalError usfe = (DAGAppMasterEventUserServiceFatalError) event;
+      Throwable error = usfe.getError();
+      errDiagnostics = "Service Error: " + usfe.getDiagnosticInfo()
+          + ", eventType=" + event.getType()
+          + ", exception=" + ExceptionUtils.getStackTrace(usfe.getError());
+      LOG.error(errDiagnostics, error);
+      addDiagnostic(errDiagnostics);
+
+      handleInternalError("Service error: " + event.getType(), errDiagnostics);
+      break;
     case INTERNAL_ERROR:
-      state = DAGAppMasterState.ERROR;
-      if(currentDAG != null) {
-        _updateLoggers(currentDAG, "_post");
-        // notify dag to finish which will send the DAG_FINISHED event
-        LOG.info("Internal Error. Notifying dags to finish.");
-        sendEvent(new DAGEvent(currentDAG.getID(), DAGEventType.INTERNAL_ERROR));
-      } else {
-        LOG.info("Internal Error. Finishing directly as no dag is active.");
-        this.taskSchedulerManager.setShouldUnregisterFlag();
-        shutdownHandler.shutdown();
-      }
+      handleInternalError("DAGAppMaster Internal Error occurred",
+          "DAGAppMaster Internal Error occurred");
       break;
     case DAG_FINISHED:
       DAGAppMasterEventDAGFinished finishEvt =
@@ -756,6 +789,7 @@ public class DAGAppMaster extends AbstractService {
           LOG.error("Received a DAG Finished Event with state="
               + finishEvt.getDAGState()
               + ". Error. Shutting down.");
+          addDiagnostic("DAG completed with an ERROR state. Shutting down AM");
           state = DAGAppMasterState.ERROR;
           this.taskSchedulerManager.setShouldUnregisterFlag();
           shutdownHandler.shutdown();

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorContextImpl.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorContextImpl.java b/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorContextImpl.java
index 6ae6dad..2b7234c 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorContextImpl.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorContextImpl.java
@@ -205,11 +205,7 @@ public class TaskCommunicatorContextImpl implements TaskCommunicatorContext, Ver
 
   @Override
   public void onStateUpdated(VertexStateUpdate event) {
-    try {
-      taskCommunicatorManager.vertexStateUpdateNotificationReceived(event, taskCommunicatorIndex);
-    } catch (Exception e) {
-      throw new TezUncheckedException(e);
-    }
+    taskCommunicatorManager.vertexStateUpdateNotificationReceived(event, taskCommunicatorIndex);
   }
 
   private DAG getDag() {

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorManager.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorManager.java b/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorManager.java
index 92bf3c4..64a964b 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorManager.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorManager.java
@@ -30,9 +30,14 @@ import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
 
 import org.apache.commons.collections4.ListUtils;
+import org.apache.hadoop.yarn.event.Event;
+import org.apache.tez.Utils;
 import org.apache.tez.dag.api.NamedEntityDescriptor;
+import org.apache.tez.dag.api.TaskCommunicator;
 import org.apache.tez.dag.api.TezConstants;
 import org.apache.tez.dag.api.UserPayload;
+import org.apache.tez.dag.app.dag.event.DAGAppMasterEventType;
+import org.apache.tez.dag.app.dag.event.DAGAppMasterEventUserServiceFatalError;
 import org.apache.tez.dag.app.dag.event.TaskAttemptEventType;
 import org.apache.tez.serviceplugins.api.ContainerEndReason;
 import org.apache.tez.dag.app.dag.event.TaskAttemptEventStatusUpdate;
@@ -48,7 +53,6 @@ import org.apache.hadoop.service.AbstractService;
 import org.apache.hadoop.yarn.api.records.NodeId;
 import org.apache.tez.common.ReflectionUtils;
 import org.apache.tez.common.TezUtilsInternal;
-import org.apache.tez.dag.api.TaskCommunicator;
 import org.apache.tez.dag.api.TaskCommunicatorContext;
 import org.apache.tez.serviceplugins.api.TaskAttemptEndReason;
 import org.apache.tez.dag.api.TaskHeartbeatResponse;
@@ -81,7 +85,7 @@ public class TaskCommunicatorManager extends AbstractService implements
       .getLogger(TaskCommunicatorManager.class);
 
   private final AppContext context;
-  private final TaskCommunicator[] taskCommunicators;
+  private final TaskCommunicatorWrapper[] taskCommunicators;
   private final TaskCommunicatorContext[] taskCommunicatorContexts;
   protected final ServicePluginLifecycleAbstractService []taskCommunicatorServiceWrappers;
 
@@ -106,6 +110,24 @@ public class TaskCommunicatorManager extends AbstractService implements
   private static final ContainerInfo NULL_CONTAINER_INFO = new ContainerInfo(null);
 
 
+  @VisibleForTesting
+  @InterfaceAudience.Private
+  /**
+   * Only for testing.
+   */
+  public TaskCommunicatorManager(TaskCommunicator taskCommunicator, AppContext appContext,
+                                 TaskHeartbeatHandler thh, ContainerHeartbeatHandler chh) {
+    super(TaskCommunicatorManager.class.getName());
+    this.context = appContext;
+    this.taskHeartbeatHandler = thh;
+    this.containerHeartbeatHandler = chh;
+    taskCommunicators =
+        new TaskCommunicatorWrapper[]{new TaskCommunicatorWrapper(taskCommunicator)};
+    taskCommunicatorContexts = new TaskCommunicatorContext[]{taskCommunicator.getContext()};
+    taskCommunicatorServiceWrappers = new ServicePluginLifecycleAbstractService[]{
+        new ServicePluginLifecycleAbstractService(taskCommunicator)};
+  }
+
   public TaskCommunicatorManager(AppContext context,
                                  TaskHeartbeatHandler thh, ContainerHeartbeatHandler chh,
                                  List<NamedEntityDescriptor> taskCommunicatorDescriptors) throws TezException {
@@ -116,14 +138,15 @@ public class TaskCommunicatorManager extends AbstractService implements
     Preconditions.checkArgument(
         taskCommunicatorDescriptors != null && !taskCommunicatorDescriptors.isEmpty(),
         "TaskCommunicators must be specified");
-    this.taskCommunicators = new TaskCommunicator[taskCommunicatorDescriptors.size()];
+    this.taskCommunicators = new TaskCommunicatorWrapper[taskCommunicatorDescriptors.size()];
     this.taskCommunicatorContexts = new TaskCommunicatorContext[taskCommunicatorDescriptors.size()];
     this.taskCommunicatorServiceWrappers = new ServicePluginLifecycleAbstractService[taskCommunicatorDescriptors.size()];
     for (int i = 0 ; i < taskCommunicatorDescriptors.size() ; i++) {
       UserPayload userPayload = taskCommunicatorDescriptors.get(i).getUserPayload();
       taskCommunicatorContexts[i] = new TaskCommunicatorContextImpl(context, this, userPayload, i);
-      taskCommunicators[i] = createTaskCommunicator(taskCommunicatorDescriptors.get(i), i);
-      taskCommunicatorServiceWrappers[i] = new ServicePluginLifecycleAbstractService(taskCommunicators[i]);
+      taskCommunicators[i] = new TaskCommunicatorWrapper(createTaskCommunicator(taskCommunicatorDescriptors.get(i), i));
+      taskCommunicatorServiceWrappers[i] =
+          new ServicePluginLifecycleAbstractService(taskCommunicators[i].getTaskCommunicator());
     }
     // TODO TEZ-2118 Start using taskCommunicator indices properly
   }
@@ -269,11 +292,11 @@ public class TaskCommunicatorManager extends AbstractService implements
       }
       if (taskAttemptEvent != null) {
         taskAttemptEvent.setReadErrorReported(readErrorReported);
-        context.getEventHandler().handle(taskAttemptEvent);
+        sendEvent(taskAttemptEvent);
       }
       // route taGeneratedEvents to TaskAttempt
       if (!taGeneratedEvents.isEmpty()) {
-        context.getEventHandler().handle(new TaskAttemptEventTezEventUpdate(taskAttemptID, taGeneratedEvents));
+        sendEvent(new TaskAttemptEventTezEventUpdate(taskAttemptID, taGeneratedEvents));
       }
       // route events to TaskAttempt
       Preconditions.checkArgument(taFinishedEvents.size() <= 1, "Multiple TaskAttemptFinishedEvent");
@@ -300,14 +323,14 @@ public class TaskCommunicatorManager extends AbstractService implements
                 sourceMeta.getEventGenerator());
           }
           TaskAttemptFailedEvent taskFailedEvent =(TaskAttemptFailedEvent) e.getEvent();
-          context.getEventHandler().handle(
+          sendEvent(
                new TaskAttemptEventAttemptFailed(sourceMeta.getTaskAttemptID(),
                    TaskAttemptEventType.TA_FAILED,
                   "Error: " + taskFailedEvent.getDiagnostics(),
                     errCause));
           break;
         case TASK_ATTEMPT_COMPLETED_EVENT:
-          context.getEventHandler().handle(
+          sendEvent(
               new TaskAttemptEvent(sourceMeta.getTaskAttemptID(), TaskAttemptEventType.TA_DONE));
           break;
         default:
@@ -317,7 +340,7 @@ public class TaskCommunicatorManager extends AbstractService implements
       }
       if (!eventsForVertex.isEmpty()) {
         TezVertexID vertexId = taskAttemptID.getTaskID().getVertexID();
-        context.getEventHandler().handle(
+        sendEvent(
             new VertexEventRouteEvent(vertexId, Collections.unmodifiableList(eventsForVertex)));
       }
       taskHeartbeatHandler.pinged(taskAttemptID);
@@ -339,8 +362,7 @@ public class TaskCommunicatorManager extends AbstractService implements
   }
 
   public void taskStartedRemotely(TezTaskAttemptID taskAttemptID, ContainerId containerId) {
-    context.getEventHandler()
-        .handle(new TaskAttemptEventStartedRemotely(taskAttemptID, containerId, null));
+    sendEvent(new TaskAttemptEventStartedRemotely(taskAttemptID, containerId, null));
     pingContainerHeartbeatHandler(containerId);
   }
 
@@ -351,7 +373,7 @@ public class TaskCommunicatorManager extends AbstractService implements
     // TODO TEZ-2003 (post) TEZ-2671 Maybe consider un-registering here itself, since the task is not active anymore,
     // instead of waiting for the unregister to flow through the Container.
     // Fix along the same lines as TEZ-2124 by introducing an explict context.
-    context.getEventHandler().handle(new TaskAttemptEventAttemptKilled(taskAttemptId,
+    sendEvent(new TaskAttemptEventAttemptKilled(taskAttemptId,
         diagnostics, TezUtilsInternal.fromTaskAttemptEndReason(
         taskAttemptEndReason)));
   }
@@ -363,14 +385,25 @@ public class TaskCommunicatorManager extends AbstractService implements
     // TODO TEZ-2003 (post) TEZ-2671 Maybe consider un-registering here itself, since the task is not active anymore,
     // instead of waiting for the unregister to flow through the Container.
     // Fix along the same lines as TEZ-2124 by introducing an explict context.
-    context.getEventHandler().handle(new TaskAttemptEventAttemptFailed(taskAttemptId,
+    sendEvent(new TaskAttemptEventAttemptFailed(taskAttemptId,
         TaskAttemptEventType.TA_FAILED, diagnostics, TezUtilsInternal.fromTaskAttemptEndReason(
         taskAttemptEndReason)));
   }
 
-  public void vertexStateUpdateNotificationReceived(VertexStateUpdate event, int taskCommIndex) throws
-      Exception {
-    taskCommunicators[taskCommIndex].onVertexStateUpdated(event);
+  public void vertexStateUpdateNotificationReceived(VertexStateUpdate event, int taskCommIndex) {
+    try {
+      taskCommunicators[taskCommIndex].onVertexStateUpdated(event);
+    } catch (Exception e) {
+      String msg = "Error in TaskCommunicator when handling vertex state update notification"
+          + ", communicator=" + Utils.getTaskCommIdentifierString(taskCommIndex, context)
+          + ", vertexName=" + event.getVertexName()
+          + ", vertexState=" + event.getVertexState();
+      LOG.error(msg, e);
+      sendEvent(
+          new DAGAppMasterEventUserServiceFatalError(
+              DAGAppMasterEventType.TASK_COMMUNICATOR_SERVICE_FATAL_ERROR,
+              msg, e));
+    }
   }
 
 
@@ -410,9 +443,19 @@ public class TaskCommunicatorManager extends AbstractService implements
 
     // Inform all communicators of the dagCompletion.
     for (int i = 0 ; i < taskCommunicators.length ; i++) {
-      ((TaskCommunicatorContextImpl)taskCommunicatorContexts[i]).dagCompleteStart(dag);
-      taskCommunicators[i].dagComplete(dag.getID().getId());
-      ((TaskCommunicatorContextImpl)taskCommunicatorContexts[i]).dagCompleteEnd();
+      try {
+        ((TaskCommunicatorContextImpl) taskCommunicatorContexts[i]).dagCompleteStart(dag);
+        taskCommunicators[i].dagComplete(dag.getID().getId());
+        ((TaskCommunicatorContextImpl) taskCommunicatorContexts[i]).dagCompleteEnd();
+      } catch (Exception e) {
+        String msg = "Error in TaskCommunicator when notifying for DAG completion"
+            + ", communicator=" + Utils.getTaskCommIdentifierString(i, context);
+        LOG.error(msg, e);
+        sendEvent(
+            new DAGAppMasterEventUserServiceFatalError(
+                DAGAppMasterEventType.TASK_COMMUNICATOR_SERVICE_FATAL_ERROR,
+                msg, e));
+      }
     }
 
   }
@@ -434,8 +477,20 @@ public class TaskCommunicatorManager extends AbstractService implements
           "Multiple registrations for containerId: " + containerId);
     }
     NodeId nodeId = context.getAllContainers().get(containerId).getContainer().getNodeId();
-    taskCommunicators[taskCommId].registerRunningContainer(containerId, nodeId.getHost(),
-        nodeId.getPort());
+    try {
+      taskCommunicators[taskCommId].registerRunningContainer(containerId, nodeId.getHost(),
+          nodeId.getPort());
+    } catch (Exception e) {
+      String msg = "Error in TaskCommunicator when registering running Container"
+          + ", communicator=" + Utils.getTaskCommIdentifierString(taskCommId, context)
+          + ", containerId=" + containerId
+          + ", nodeId=" + nodeId;
+      LOG.error(msg, e);
+      sendEvent(
+          new DAGAppMasterEventUserServiceFatalError(
+              DAGAppMasterEventType.TASK_COMMUNICATOR_SERVICE_FATAL_ERROR,
+              msg, e));
+    }
   }
 
   @Override
@@ -447,7 +502,18 @@ public class TaskCommunicatorManager extends AbstractService implements
     if (containerInfo.taskAttemptId != null) {
       registeredAttempts.remove(containerInfo.taskAttemptId);
     }
-    taskCommunicators[taskCommId].registerContainerEnd(containerId, endReason, diagnostics);
+    try {
+      taskCommunicators[taskCommId].registerContainerEnd(containerId, endReason, diagnostics);
+    } catch (Exception e) {
+      String msg = "Error in TaskCommunicator when unregistering Container"
+          + ", communicator=" + Utils.getTaskCommIdentifierString(taskCommId, context)
+          + ", containerId=" + containerId;
+      LOG.error(msg, e);
+      sendEvent(
+          new DAGAppMasterEventUserServiceFatalError(
+              DAGAppMasterEventType.TASK_COMMUNICATOR_SERVICE_FATAL_ERROR,
+              msg, e));
+    }
   }
 
   @Override
@@ -475,9 +541,21 @@ public class TaskCommunicatorManager extends AbstractService implements
           + amContainerTask.getTask().getTaskAttemptID() + " to container: " + containerId
           + " when already assigned to: " + containerIdFromMap);
     }
-    taskCommunicators[taskCommId].registerRunningTaskAttempt(containerId, amContainerTask.getTask(),
-        amContainerTask.getAdditionalResources(), amContainerTask.getCredentials(),
-        amContainerTask.haveCredentialsChanged(), amContainerTask.getPriority());
+    try {
+      taskCommunicators[taskCommId].registerRunningTaskAttempt(containerId, amContainerTask.getTask(),
+          amContainerTask.getAdditionalResources(), amContainerTask.getCredentials(),
+          amContainerTask.haveCredentialsChanged(), amContainerTask.getPriority());
+    } catch (Exception e) {
+      String msg = "Error in TaskCommunicator when registering Task Attempt"
+          + ", communicator=" + Utils.getTaskCommIdentifierString(taskCommId, context)
+          + ", containerId=" + containerId
+          + ", taskId=" + amContainerTask.getTask().getTaskAttemptID();
+      LOG.error(msg, e);
+      sendEvent(
+          new DAGAppMasterEventUserServiceFatalError(
+              DAGAppMasterEventType.TASK_COMMUNICATOR_SERVICE_FATAL_ERROR,
+              msg, e));
+    }
   }
 
   @Override
@@ -495,11 +573,23 @@ public class TaskCommunicatorManager extends AbstractService implements
     }
     // Explicitly putting in a new entry so that synchronization is not required on the existing element in the map.
     registeredContainers.put(containerId, NULL_CONTAINER_INFO);
-    taskCommunicators[taskCommId].unregisterRunningTaskAttempt(attemptId, endReason, diagnostics);
+    try {
+      taskCommunicators[taskCommId].unregisterRunningTaskAttempt(attemptId, endReason, diagnostics);
+    } catch (Exception e) {
+      String msg = "Error in TaskCommunicator when unregistering Task Attempt"
+          + ", communicator=" + Utils.getTaskCommIdentifierString(taskCommId, context)
+          + ", containerId=" + containerId
+          + ", taskId=" + attemptId;
+      LOG.error(msg, e);
+      sendEvent(
+          new DAGAppMasterEventUserServiceFatalError(
+              DAGAppMasterEventType.TASK_COMMUNICATOR_SERVICE_FATAL_ERROR,
+              msg, e));
+    }
   }
 
   @Override
-  public TaskCommunicator getTaskCommunicator(int taskCommIndex) {
+  public TaskCommunicatorWrapper getTaskCommunicator(int taskCommIndex) {
     return taskCommunicators[taskCommIndex];
   }
 
@@ -516,4 +606,9 @@ public class TaskCommunicatorManager extends AbstractService implements
           + ", ContainerId not known for this attempt");
     }
   }
+
+  @SuppressWarnings("unchecked")
+  private void sendEvent(Event<?> event) {
+    context.getEventHandler().handle(event);
+  }
 }

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorManagerInterface.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorManagerInterface.java b/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorManagerInterface.java
index 8d060a2..e07b1a0 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorManagerInterface.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorManagerInterface.java
@@ -22,7 +22,6 @@ import org.apache.hadoop.yarn.api.records.ContainerId;
 import org.apache.tez.serviceplugins.api.ContainerEndReason;
 import org.apache.tez.serviceplugins.api.TaskAttemptEndReason;
 import org.apache.tez.dag.app.dag.DAG;
-import org.apache.tez.dag.api.TaskCommunicator;
 import org.apache.tez.dag.app.rm.container.AMContainerTask;
 import org.apache.tez.dag.records.TezTaskAttemptID;
 /**
@@ -42,5 +41,5 @@ public interface TaskCommunicatorManagerInterface {
 
   void dagSubmitted();
 
-  TaskCommunicator getTaskCommunicator(int taskCommIndex);
+  TaskCommunicatorWrapper getTaskCommunicator(int taskCommIndex);
 }

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorWrapper.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorWrapper.java b/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorWrapper.java
new file mode 100644
index 0000000..4f9780e
--- /dev/null
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorWrapper.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tez.dag.app;
+
+import javax.annotation.Nullable;
+import java.net.InetSocketAddress;
+import java.util.Map;
+
+import org.apache.hadoop.security.Credentials;
+import org.apache.hadoop.yarn.api.records.ContainerId;
+import org.apache.hadoop.yarn.api.records.LocalResource;
+import org.apache.tez.dag.api.TaskCommunicator;
+import org.apache.tez.dag.api.event.VertexStateUpdate;
+import org.apache.tez.dag.records.TezTaskAttemptID;
+import org.apache.tez.runtime.api.impl.TaskSpec;
+import org.apache.tez.serviceplugins.api.ContainerEndReason;
+import org.apache.tez.serviceplugins.api.TaskAttemptEndReason;
+
+public class TaskCommunicatorWrapper {
+
+  private final TaskCommunicator real;
+
+  public TaskCommunicatorWrapper(TaskCommunicator real) {
+    this.real = real;
+  }
+
+
+  public void registerRunningContainer(ContainerId containerId, String hostname, int port) throws
+      Exception {
+    real.registerRunningContainer(containerId, hostname, port);
+  }
+
+  public void registerContainerEnd(ContainerId containerId, ContainerEndReason endReason,
+                                   @Nullable String diagnostics) throws Exception {
+    real.registerContainerEnd(containerId, endReason, diagnostics);
+
+  }
+
+  public void registerRunningTaskAttempt(ContainerId containerId, TaskSpec taskSpec,
+                                         Map<String, LocalResource> additionalResources,
+                                         Credentials credentials, boolean credentialsChanged,
+                                         int priority) throws Exception {
+    real.registerRunningTaskAttempt(containerId, taskSpec, additionalResources, credentials, credentialsChanged, priority);
+  }
+
+  public void unregisterRunningTaskAttempt(TezTaskAttemptID taskAttemptID,
+                                           TaskAttemptEndReason endReason,
+                                           @Nullable String diagnostics) throws Exception {
+    real.unregisterRunningTaskAttempt(taskAttemptID, endReason, diagnostics);
+  }
+
+  public InetSocketAddress getAddress() throws Exception {
+    return real.getAddress();
+  }
+
+  public void onVertexStateUpdated(VertexStateUpdate stateUpdate) throws Exception {
+    real.onVertexStateUpdated(stateUpdate);
+  }
+
+  public void dagComplete(int dagIdentifier) throws Exception {
+    real.dagComplete(dagIdentifier);
+  }
+
+  public Object getMetaInfo() throws Exception {
+    return real.getMetaInfo();
+  }
+
+  public TaskCommunicator getTaskCommunicator() {
+    return real;
+  }
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/main/java/org/apache/tez/dag/app/TezTaskCommunicatorImpl.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/TezTaskCommunicatorImpl.java b/tez-dag/src/main/java/org/apache/tez/dag/app/TezTaskCommunicatorImpl.java
index 78e95bd..d071e0d 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/TezTaskCommunicatorImpl.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/TezTaskCommunicatorImpl.java
@@ -273,7 +273,7 @@ public class TezTaskCommunicatorImpl extends TaskCommunicator {
   }
 
   @Override
-  public void onVertexStateUpdated(VertexStateUpdate stateUpdate) throws Exception {
+  public void onVertexStateUpdated(VertexStateUpdate stateUpdate) {
     // Empty. Not registering, or expecting any updates.
   }
 

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/main/java/org/apache/tez/dag/app/dag/StateChangeNotifier.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/StateChangeNotifier.java b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/StateChangeNotifier.java
index 990bdea..bd04fd8 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/StateChangeNotifier.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/StateChangeNotifier.java
@@ -34,10 +34,12 @@ import com.google.common.collect.ListMultimap;
 import com.google.common.collect.Multimaps;
 import com.google.common.collect.SetMultimap;
 
+import org.apache.commons.lang.exception.ExceptionUtils;
 import org.apache.hadoop.classification.InterfaceAudience;
 import org.apache.tez.dag.api.TezUncheckedException;
 import org.apache.tez.dag.api.event.VertexStateUpdate;
 import org.apache.tez.dag.app.dag.event.DAGEvent;
+import org.apache.tez.dag.app.dag.event.DAGEventInternalError;
 import org.apache.tez.dag.app.dag.event.DAGEventType;
 import org.apache.tez.dag.records.TezTaskID;
 import org.apache.tez.dag.records.TezVertexID;
@@ -110,7 +112,10 @@ public class StateChangeNotifier {
           } catch (Exception e) {
             // TODO send user code exception - TEZ-2332
             LOG.error("Error in state update notification for " + event, e);
-            dag.getEventHandler().handle(new DAGEvent(dag.getID(), DAGEventType.INTERNAL_ERROR));
+            dag.getEventHandler().handle(
+                new DAGEventInternalError(dag.getID(),
+                    "Internal Error in State Update Notification: "
+                        + ExceptionUtils.getStackTrace(e)));
             return;
           }
         }

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/main/java/org/apache/tez/dag/app/dag/event/DAGAppMasterEventType.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/event/DAGAppMasterEventType.java b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/event/DAGAppMasterEventType.java
index 5a102a5..9cf2414 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/event/DAGAppMasterEventType.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/event/DAGAppMasterEventType.java
@@ -22,6 +22,9 @@ public enum DAGAppMasterEventType {
   INTERNAL_ERROR,
   AM_REBOOT,
   DAG_FINISHED,
+  TASK_COMMUNICATOR_SERVICE_FATAL_ERROR,
+  CONTAINER_LAUNCHER_SERVICE_FATAL_ERROR,
+  TASK_SCHEDULER_SERVICE_FATAL_ERROR,
   SCHEDULING_SERVICE_ERROR,
   NEW_DAG_SUBMITTED, // Indicates a new dag being submitted, to notify sub-components
   DAG_CLEANUP

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/main/java/org/apache/tez/dag/app/dag/event/DAGAppMasterEventUserServiceFatalError.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/event/DAGAppMasterEventUserServiceFatalError.java b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/event/DAGAppMasterEventUserServiceFatalError.java
new file mode 100644
index 0000000..7bc3bd8
--- /dev/null
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/event/DAGAppMasterEventUserServiceFatalError.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tez.dag.app.dag.event;
+
+import java.util.EnumSet;
+
+import com.google.common.base.Preconditions;
+
+public class DAGAppMasterEventUserServiceFatalError extends DAGAppMasterEvent implements DiagnosableEvent {
+
+  private final Throwable error;
+  private final String diagnostics;
+
+  public DAGAppMasterEventUserServiceFatalError(DAGAppMasterEventType type,
+                                                String diagnostics, Throwable t) {
+    super(type);
+    Preconditions.checkArgument(
+        EnumSet.of(DAGAppMasterEventType.TASK_SCHEDULER_SERVICE_FATAL_ERROR,
+            DAGAppMasterEventType.CONTAINER_LAUNCHER_SERVICE_FATAL_ERROR,
+            DAGAppMasterEventType.TASK_COMMUNICATOR_SERVICE_FATAL_ERROR).contains(type),
+        "Event created with incorrect type: " + type);
+    this.error = t;
+    this.diagnostics = diagnostics;
+  }
+
+  public Throwable getError() {
+    return error;
+  }
+
+  @Override
+  public String getDiagnosticInfo() {
+    return diagnostics;
+  }
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/main/java/org/apache/tez/dag/app/dag/event/DAGEventInternalError.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/event/DAGEventInternalError.java b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/event/DAGEventInternalError.java
new file mode 100644
index 0000000..724ecbe
--- /dev/null
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/event/DAGEventInternalError.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tez.dag.app.dag.event;
+
+import org.apache.tez.dag.records.TezDAGID;
+
+public class DAGEventInternalError extends DAGEvent implements DiagnosableEvent {
+
+  private final String diagnostics;
+
+  public DAGEventInternalError(TezDAGID dagId, String diagnostics) {
+    super(dagId, DAGEventType.INTERNAL_ERROR);
+    this.diagnostics = diagnostics;
+  }
+
+  @Override
+  public String getDiagnosticInfo() {
+    return diagnostics;
+  }
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/DAGImpl.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/DAGImpl.java b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/DAGImpl.java
index 60f933f..41017ea 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/DAGImpl.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/DAGImpl.java
@@ -43,6 +43,8 @@ import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.exception.ExceptionUtils;
 import org.apache.tez.common.TezUtilsInternal;
 import org.apache.tez.common.counters.LimitExceededException;
+import org.apache.tez.dag.app.dag.event.DAGEventInternalError;
+import org.apache.tez.dag.app.dag.event.DiagnosableEvent;
 import org.apache.tez.state.OnStateChangedCallback;
 import org.apache.tez.state.StateMachineTez;
 import org.slf4j.Logger;
@@ -2252,13 +2254,21 @@ public class DAGImpl implements org.apache.tez.dag.app.dag.DAG,
   private static class InternalErrorTransition implements
       SingleArcTransition<DAGImpl, DAGEvent> {
     @Override
-    public void transition(DAGImpl job, DAGEvent event) {
-      LOG.info(job.getID() + " terminating due to internal error");
+    public void transition(DAGImpl dag, DAGEvent event) {
+      String diagnostics = null;
+      if (event instanceof DiagnosableEvent) {
+        DiagnosableEvent errEvent = (DiagnosableEvent) event;
+        diagnostics = errEvent.getDiagnosticInfo();
+        dag.addDiagnostic(diagnostics);
+      }
+
+      LOG.info(dag.getID() + " terminating due to internal error. "
+          + (diagnostics == null? "" : " Error=" + diagnostics));
       // terminate all vertices
-      job.enactKill(DAGTerminationCause.INTERNAL_ERROR, VertexTerminationCause.INTERNAL_ERROR);
-      job.setFinishTime();
-      job.cancelCommits();
-      job.finished(DAGState.ERROR);
+      dag.enactKill(DAGTerminationCause.INTERNAL_ERROR, VertexTerminationCause.INTERNAL_ERROR);
+      dag.setFinishTime();
+      dag.cancelCommits();
+      dag.finished(DAGState.ERROR);
     }
   }
 

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/VertexManager.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/VertexManager.java b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/VertexManager.java
index 379e316..388d3c7 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/VertexManager.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/VertexManager.java
@@ -33,6 +33,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
 
 import javax.annotation.Nullable;
 
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.apache.tez.dag.app.dag.event.DAGEventInternalError;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.apache.hadoop.security.UserGroupInformation;
@@ -56,8 +58,6 @@ import org.apache.tez.dag.app.AppContext;
 import org.apache.tez.dag.app.dag.StateChangeNotifier;
 import org.apache.tez.dag.app.dag.Vertex;
 import org.apache.tez.dag.app.dag.event.CallableEvent;
-import org.apache.tez.dag.app.dag.event.DAGEvent;
-import org.apache.tez.dag.app.dag.event.DAGEventType;
 import org.apache.tez.dag.app.dag.event.VertexEventInputDataInformation;
 import org.apache.tez.dag.app.dag.event.VertexEventManagerUserCodeError;
 import org.apache.tez.dag.app.dag.impl.AMUserCodeException.Source;
@@ -530,7 +530,9 @@ public class VertexManager {
       // state change must be triggered via an event transition
       LOG.error("Error after vertex manager callback " + managedVertex.getLogIdentifier(), e);
       appContext.getEventHandler().handle(
-          (new DAGEvent(managedVertex.getVertexId().getDAGId(), DAGEventType.INTERNAL_ERROR)));
+          (new DAGEventInternalError(managedVertex.getVertexId().getDAGId(),
+              "Error in VertexManager for vertex: " + managedVertex.getLogIdentifier()
+              + ", error=" + ExceptionUtils.getStackTrace(e))));
     }
   }
   

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/main/java/org/apache/tez/dag/app/launcher/ContainerLauncherManager.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/launcher/ContainerLauncherManager.java b/tez-dag/src/main/java/org/apache/tez/dag/app/launcher/ContainerLauncherManager.java
index 9e56f44..98237c1 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/launcher/ContainerLauncherManager.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/launcher/ContainerLauncherManager.java
@@ -22,13 +22,17 @@ import com.google.common.base.Preconditions;
 
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.service.AbstractService;
+import org.apache.hadoop.yarn.event.Event;
 import org.apache.hadoop.yarn.event.EventHandler;
+import org.apache.tez.Utils;
 import org.apache.tez.common.ReflectionUtils;
 import org.apache.tez.dag.api.NamedEntityDescriptor;
 import org.apache.tez.dag.api.TezConstants;
 import org.apache.tez.dag.api.TezException;
 import org.apache.tez.dag.api.UserPayload;
 import org.apache.tez.dag.app.ServicePluginLifecycleAbstractService;
+import org.apache.tez.dag.app.dag.event.DAGAppMasterEventType;
+import org.apache.tez.dag.app.dag.event.DAGAppMasterEventUserServiceFatalError;
 import org.apache.tez.serviceplugins.api.ContainerLaunchRequest;
 import org.apache.tez.serviceplugins.api.ContainerLauncher;
 import org.apache.tez.serviceplugins.api.ContainerLauncherContext;
@@ -49,7 +53,7 @@ public class ContainerLauncherManager extends AbstractService
   static final Logger LOG = LoggerFactory.getLogger(TezContainerLauncherImpl.class);
 
   @VisibleForTesting
-  final ContainerLauncher containerLaunchers[];
+  final ContainerLauncherWrapper containerLaunchers[];
   @VisibleForTesting
   final ContainerLauncherContext containerLauncherContexts[];
   protected final ServicePluginLifecycleAbstractService[] containerLauncherServiceWrappers;
@@ -59,7 +63,7 @@ public class ContainerLauncherManager extends AbstractService
   public ContainerLauncherManager(ContainerLauncher containerLauncher, AppContext context) {
     super(ContainerLauncherManager.class.getName());
     this.appContext = context;
-    containerLaunchers = new ContainerLauncher[] {containerLauncher};
+    containerLaunchers = new ContainerLauncherWrapper[] {new ContainerLauncherWrapper(containerLauncher)};
     containerLauncherContexts = new ContainerLauncherContext[] {containerLauncher.getContext()};
     containerLauncherServiceWrappers = new ServicePluginLifecycleAbstractService[]{
         new ServicePluginLifecycleAbstractService<>(containerLauncher)};
@@ -78,7 +82,7 @@ public class ContainerLauncherManager extends AbstractService
         containerLauncherDescriptors != null && !containerLauncherDescriptors.isEmpty(),
         "ContainerLauncherDescriptors must be specified");
     containerLauncherContexts = new ContainerLauncherContext[containerLauncherDescriptors.size()];
-    containerLaunchers = new ContainerLauncher[containerLauncherDescriptors.size()];
+    containerLaunchers = new ContainerLauncherWrapper[containerLauncherDescriptors.size()];
     containerLauncherServiceWrappers = new ServicePluginLifecycleAbstractService[containerLauncherDescriptors.size()];
 
 
@@ -87,9 +91,9 @@ public class ContainerLauncherManager extends AbstractService
       ContainerLauncherContext containerLauncherContext =
           new ContainerLauncherContextImpl(context, taskCommunicatorManagerInterface, userPayload);
       containerLauncherContexts[i] = containerLauncherContext;
-      containerLaunchers[i] = createContainerLauncher(containerLauncherDescriptors.get(i), context,
-          containerLauncherContext, taskCommunicatorManagerInterface, workingDirectory, i, isPureLocalMode);
-      containerLauncherServiceWrappers[i] = new ServicePluginLifecycleAbstractService<>(containerLaunchers[i]);
+      containerLaunchers[i] = new ContainerLauncherWrapper(createContainerLauncher(containerLauncherDescriptors.get(i), context,
+          containerLauncherContext, taskCommunicatorManagerInterface, workingDirectory, i, isPureLocalMode));
+      containerLauncherServiceWrappers[i] = new ServicePluginLifecycleAbstractService<>(containerLaunchers[i].getContainerLauncher());
     }
   }
 
@@ -197,14 +201,43 @@ public class ContainerLauncherManager extends AbstractService
                 launchEvent.getContainerToken(), launchEvent.getContainerLaunchContext(),
                 launchEvent.getContainer(), schedulerName,
                 taskCommName);
-        containerLaunchers[launcherId].launchContainer(launchRequest);
+        try {
+          containerLaunchers[launcherId].launchContainer(launchRequest);
+        } catch (Exception e) {
+          String msg = "Error when launching container"
+              + ", containerLauncher=" + Utils.getContainerLauncherIdentifierString(launcherId, appContext)
+              + ", scheduler=" + Utils.getTaskSchedulerIdentifierString(event.getSchedulerId(), appContext)
+              + ", taskCommunicator=" + Utils.getTaskCommIdentifierString(event.getTaskCommId(), appContext);
+          LOG.error(msg, e);
+          sendEvent(
+              new DAGAppMasterEventUserServiceFatalError(
+                  DAGAppMasterEventType.CONTAINER_LAUNCHER_SERVICE_FATAL_ERROR,
+                  msg, e));
+        }
         break;
       case CONTAINER_STOP_REQUEST:
         ContainerStopRequest stopRequest =
             new ContainerStopRequest(event.getNodeId(), event.getContainerId(),
                 event.getContainerToken(), schedulerName, taskCommName);
-        containerLaunchers[launcherId].stopContainer(stopRequest);
+        try {
+          containerLaunchers[launcherId].stopContainer(stopRequest);
+        } catch (Exception e) {
+          String msg = "Error when stopping container"
+              + ", containerLauncher=" + Utils.getContainerLauncherIdentifierString(launcherId, appContext)
+              + ", scheduler=" + Utils.getTaskSchedulerIdentifierString(event.getSchedulerId(), appContext)
+              + ", taskCommunicator=" + Utils.getTaskCommIdentifierString(event.getTaskCommId(), appContext);
+          LOG.error(msg, e);
+          sendEvent(
+              new DAGAppMasterEventUserServiceFatalError(
+                  DAGAppMasterEventType.CONTAINER_LAUNCHER_SERVICE_FATAL_ERROR,
+                  msg, e));
+        }
         break;
     }
   }
+
+  @SuppressWarnings("unchecked")
+  private void sendEvent(Event<?> event) {
+    appContext.getEventHandler().handle(event);
+  }
 }

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/main/java/org/apache/tez/dag/app/launcher/ContainerLauncherWrapper.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/launcher/ContainerLauncherWrapper.java b/tez-dag/src/main/java/org/apache/tez/dag/app/launcher/ContainerLauncherWrapper.java
new file mode 100644
index 0000000..08e287e
--- /dev/null
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/launcher/ContainerLauncherWrapper.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tez.dag.app.launcher;
+
+import org.apache.tez.serviceplugins.api.ContainerLaunchRequest;
+import org.apache.tez.serviceplugins.api.ContainerLauncher;
+import org.apache.tez.serviceplugins.api.ContainerStopRequest;
+
+public class ContainerLauncherWrapper {
+
+  private final ContainerLauncher real;
+
+  public ContainerLauncherWrapper(ContainerLauncher containerLauncher) {
+    this.real = containerLauncher;
+  }
+
+  public void launchContainer(ContainerLaunchRequest launchRequest) throws Exception {
+    real.launchContainer(launchRequest);
+  }
+
+  public void stopContainer(ContainerStopRequest stopRequest) throws Exception {
+    real.stopContainer(stopRequest);
+  }
+
+  public ContainerLauncher getContainerLauncher() {
+    return real;
+  }
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/main/java/org/apache/tez/dag/app/launcher/LocalContainerLauncher.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/launcher/LocalContainerLauncher.java b/tez-dag/src/main/java/org/apache/tez/dag/app/launcher/LocalContainerLauncher.java
index c4ab6e3..b737fda 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/launcher/LocalContainerLauncher.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/launcher/LocalContainerLauncher.java
@@ -228,7 +228,7 @@ public class LocalContainerLauncher extends ContainerLauncher {
         tezChild =
             createTezChild(context.getAMConf(), event.getContainerId(), tokenIdentifier,
                 context.getApplicationAttemptId().getAttemptId(), context.getLocalDirs(),
-                ((TezTaskCommunicatorImpl)tal.getTaskCommunicator(taskCommId)).getUmbilical(),
+                ((TezTaskCommunicatorImpl)tal.getTaskCommunicator(taskCommId).getTaskCommunicator()).getUmbilical(),
                 TezCommonUtils.parseCredentialsBytes(event.getContainerLaunchContext().getTokens().array()));
       } catch (InterruptedException e) {
         handleLaunchFailed(e, event.getContainerId());


[04/50] [abbrv] tez git commit: TEZ-2972. Avoid task rescheduling when a node turns unhealthy (jlowe)

Posted by sr...@apache.org.
TEZ-2972. Avoid task rescheduling when a node turns unhealthy (jlowe)


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

Branch: refs/heads/TEZ-2980
Commit: 4ed7d1abafa9aab7636c1febcb1a63ea63fde9c8
Parents: c34c54f
Author: Jason Lowe <jl...@apache.org>
Authored: Fri Dec 18 21:01:36 2015 +0000
Committer: Jason Lowe <jl...@apache.org>
Committed: Fri Dec 18 21:01:36 2015 +0000

----------------------------------------------------------------------
 CHANGES.txt                                     |  2 +
 .../apache/tez/dag/api/TezConfiguration.java    | 13 ++++++
 .../apache/tez/dag/app/rm/node/AMNodeImpl.java  | 16 ++++---
 .../tez/dag/app/rm/node/AMNodeTracker.java      | 10 ++++-
 .../dag/app/rm/node/PerSourceNodeTracker.java   |  8 +++-
 .../tez/dag/app/rm/node/TestAMNodeTracker.java  | 47 ++++++++++++++++++++
 6 files changed, 86 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/4ed7d1ab/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 0ad2203..a3b0fa6 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -8,6 +8,7 @@ INCOMPATIBLE CHANGES
   TEZ-2948. Stop using dagName in the dagComplete notification to TaskCommunicators.
   TEZ-2949. Allow duplicate dag names within session for Tez.
   TEZ-604. Revert temporary changes made in TEZ-603 to kill the provided tez session, if running a MapReduce job.
+  TEZ-2972. Avoid task rescheduling when a node turns unhealthy
 
 ALL CHANGES:
   TEZ-3011. Link Vertex Name in Dag Tasks/Task Attempts to Vertex
@@ -90,6 +91,7 @@ ALL CHANGES:
   TEZ-2866. Tez UI: Newly added columns wont be displayed by default in tables
   TEZ-2887. Tez build failure due to missing dependency in pom files.
   TEZ-1692. Reduce code duplication between TezMapredSplitsGrouper and TezMapreduceSplitsGrouper.
+  TEZ-2972. Avoid task rescheduling when a node turns unhealthy
 
 
 Release 0.8.1-alpha: 2015-10-12

http://git-wip-us.apache.org/repos/asf/tez/blob/4ed7d1ab/tez-api/src/main/java/org/apache/tez/dag/api/TezConfiguration.java
----------------------------------------------------------------------
diff --git a/tez-api/src/main/java/org/apache/tez/dag/api/TezConfiguration.java b/tez-api/src/main/java/org/apache/tez/dag/api/TezConfiguration.java
index fabc256..b707857 100644
--- a/tez-api/src/main/java/org/apache/tez/dag/api/TezConfiguration.java
+++ b/tez-api/src/main/java/org/apache/tez/dag/api/TezConfiguration.java
@@ -569,6 +569,19 @@ public class TezConfiguration extends Configuration {
       + "node-blacklisting.ignore-threshold-node-percent";
   public static final int TEZ_AM_NODE_BLACKLISTING_IGNORE_THRESHOLD_DEFAULT = 33;
 
+  /**
+   * Boolean value. Enable task rescheduling for node updates.
+   * When enabled the task scheduler will reschedule task attempts that
+   * are associated with an unhealthy node to avoid potential data transfer
+   * errors from downstream tasks.
+   */
+  @ConfigurationScope(Scope.AM)
+  @ConfigurationProperty(type="boolean")
+  public static final String TEZ_AM_NODE_UNHEALTHY_RESCHEDULE_TASKS =
+      TEZ_AM_PREFIX + "node-unhealthy-reschedule-tasks";
+  public static final boolean
+    TEZ_AM_NODE_UNHEALTHY_RESCHEDULE_TASKS_DEFAULT = false;
+
   /** Int value. Number of threads to handle client RPC requests. Expert level setting.*/
   @ConfigurationScope(Scope.AM)
   @ConfigurationProperty(type="integer")

http://git-wip-us.apache.org/repos/asf/tez/blob/4ed7d1ab/tez-dag/src/main/java/org/apache/tez/dag/app/rm/node/AMNodeImpl.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/rm/node/AMNodeImpl.java b/tez-dag/src/main/java/org/apache/tez/dag/app/rm/node/AMNodeImpl.java
index 18d5978..bcc38c6 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/rm/node/AMNodeImpl.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/rm/node/AMNodeImpl.java
@@ -59,6 +59,7 @@ public class AMNodeImpl implements AMNode {
   private final int maxTaskFailuresPerNode;
   private boolean blacklistingEnabled;
   private boolean ignoreBlacklisting = false;
+  private boolean nodeUpdatesRescheduleEnabled;
   private Set<TezTaskAttemptID> failedAttemptIds = Sets.newHashSet();
 
   @SuppressWarnings("rawtypes")
@@ -175,7 +176,7 @@ public class AMNodeImpl implements AMNode {
   @SuppressWarnings("rawtypes")
   public AMNodeImpl(NodeId nodeId, int schedulerId, int maxTaskFailuresPerNode,
       EventHandler eventHandler, boolean blacklistingEnabled,
-      AppContext appContext) {
+      boolean rescheduleOnUnhealthyNode, AppContext appContext) {
     ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
     this.readLock = rwLock.readLock();
     this.writeLock = rwLock.writeLock();
@@ -184,6 +185,7 @@ public class AMNodeImpl implements AMNode {
     this.appContext = appContext;
     this.eventHandler = eventHandler;
     this.blacklistingEnabled = blacklistingEnabled;
+    this.nodeUpdatesRescheduleEnabled = rescheduleOnUnhealthyNode;
     this.maxTaskFailuresPerNode = maxTaskFailuresPerNode;
     this.stateMachine = stateMachineFactory.make(this);
     // TODO Handle the case where a node is created due to the RM reporting it's
@@ -323,12 +325,14 @@ public class AMNodeImpl implements AMNode {
       SingleArcTransition<AMNodeImpl, AMNodeEvent> {
     @Override
     public void transition(AMNodeImpl node, AMNodeEvent nEvent) {
-      for (ContainerId c : node.containers) {
-        node.sendEvent(new AMContainerEventNodeFailed(c, "Node failed"));
+      if (node.nodeUpdatesRescheduleEnabled) {
+        for (ContainerId c : node.containers) {
+          node.sendEvent(new AMContainerEventNodeFailed(c, "Node failed"));
+        }
+        // Resetting counters.
+        node.numFailedTAs = 0;
+        node.numSuccessfulTAs = 0;
       }
-      // Resetting counters.
-      node.numFailedTAs = 0;
-      node.numSuccessfulTAs = 0;
     }
   }
 

http://git-wip-us.apache.org/repos/asf/tez/blob/4ed7d1ab/tez-dag/src/main/java/org/apache/tez/dag/app/rm/node/AMNodeTracker.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/rm/node/AMNodeTracker.java b/tez-dag/src/main/java/org/apache/tez/dag/app/rm/node/AMNodeTracker.java
index 1aa8472..fdc8a4c 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/rm/node/AMNodeTracker.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/rm/node/AMNodeTracker.java
@@ -50,6 +50,7 @@ public class AMNodeTracker extends AbstractService implements
   private int maxTaskFailuresPerNode;
   private boolean nodeBlacklistingEnabled;
   private int blacklistDisablePercent;
+  private boolean nodeUpdatesRescheduleEnabled;
 
   @SuppressWarnings("rawtypes")
   public AMNodeTracker(EventHandler eventHandler, AppContext appContext) {
@@ -70,10 +71,14 @@ public class AMNodeTracker extends AbstractService implements
     this.blacklistDisablePercent = conf.getInt(
           TezConfiguration.TEZ_AM_NODE_BLACKLISTING_IGNORE_THRESHOLD,
           TezConfiguration.TEZ_AM_NODE_BLACKLISTING_IGNORE_THRESHOLD_DEFAULT);
+    this.nodeUpdatesRescheduleEnabled = conf.getBoolean(
+          TezConfiguration.TEZ_AM_NODE_UNHEALTHY_RESCHEDULE_TASKS,
+          TezConfiguration.TEZ_AM_NODE_UNHEALTHY_RESCHEDULE_TASKS_DEFAULT);
 
     LOG.info("blacklistDisablePercent is " + blacklistDisablePercent +
         ", blacklistingEnabled: " + nodeBlacklistingEnabled +
-        ", maxTaskFailuresPerNode: " + maxTaskFailuresPerNode);
+        ", maxTaskFailuresPerNode: " + maxTaskFailuresPerNode +
+        ", nodeUpdatesRescheduleEnabled: " + nodeUpdatesRescheduleEnabled);
 
     if (blacklistDisablePercent < -1 || blacklistDisablePercent > 100) {
       throw new TezUncheckedException("Invalid blacklistDisablePercent: "
@@ -143,7 +148,8 @@ public class AMNodeTracker extends AbstractService implements
     if (nodeTracker == null) {
       nodeTracker =
           new PerSourceNodeTracker(schedulerId, eventHandler, appContext, maxTaskFailuresPerNode,
-              nodeBlacklistingEnabled, blacklistDisablePercent);
+              nodeBlacklistingEnabled, blacklistDisablePercent,
+              nodeUpdatesRescheduleEnabled);
       PerSourceNodeTracker old = perSourceNodeTrackers.putIfAbsent(schedulerId, nodeTracker);
       nodeTracker = old != null ? old : nodeTracker;
     }

http://git-wip-us.apache.org/repos/asf/tez/blob/4ed7d1ab/tez-dag/src/main/java/org/apache/tez/dag/app/rm/node/PerSourceNodeTracker.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/rm/node/PerSourceNodeTracker.java b/tez-dag/src/main/java/org/apache/tez/dag/app/rm/node/PerSourceNodeTracker.java
index b1c81af..72c3230 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/rm/node/PerSourceNodeTracker.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/rm/node/PerSourceNodeTracker.java
@@ -42,6 +42,7 @@ public class PerSourceNodeTracker {
   private final int maxTaskFailuresPerNode;
   private final boolean nodeBlacklistingEnabled;
   private final int blacklistDisablePercent;
+  private final boolean nodeUpdatesRescheduleEnabled;
 
   private int numClusterNodes;
   float currentIgnoreBlacklistingCountThreshold = 0;
@@ -50,7 +51,8 @@ public class PerSourceNodeTracker {
   @SuppressWarnings("rawtypes")
   public PerSourceNodeTracker(int sourceId, EventHandler eventHandler, AppContext appContext,
                               int maxTaskFailuresPerNode, boolean nodeBlacklistingEnabled,
-                              int blacklistDisablePercent) {
+                              int blacklistDisablePercent,
+                              boolean nodeUpdatesRescheduleEnabled) {
     this.sourceId = sourceId;
     this.nodeMap = new ConcurrentHashMap<>();
     this.blacklistMap = new ConcurrentHashMap<>();
@@ -60,13 +62,15 @@ public class PerSourceNodeTracker {
     this.maxTaskFailuresPerNode = maxTaskFailuresPerNode;
     this.nodeBlacklistingEnabled = nodeBlacklistingEnabled;
     this.blacklistDisablePercent = blacklistDisablePercent;
+    this.nodeUpdatesRescheduleEnabled = nodeUpdatesRescheduleEnabled;
   }
 
 
 
   public void nodeSeen(NodeId nodeId) {
     if (nodeMap.putIfAbsent(nodeId, new AMNodeImpl(nodeId, sourceId, maxTaskFailuresPerNode,
-        eventHandler, nodeBlacklistingEnabled, appContext)) == null) {
+        eventHandler, nodeBlacklistingEnabled, nodeUpdatesRescheduleEnabled,
+        appContext)) == null) {
       LOG.info("Adding new node {} to nodeTracker {}", nodeId, sourceId);
     }
   }

http://git-wip-us.apache.org/repos/asf/tez/blob/4ed7d1ab/tez-dag/src/test/java/org/apache/tez/dag/app/rm/node/TestAMNodeTracker.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/rm/node/TestAMNodeTracker.java b/tez-dag/src/test/java/org/apache/tez/dag/app/rm/node/TestAMNodeTracker.java
index 143fcbf..25d1784 100644
--- a/tez-dag/src/test/java/org/apache/tez/dag/app/rm/node/TestAMNodeTracker.java
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/rm/node/TestAMNodeTracker.java
@@ -326,6 +326,53 @@ public class TestAMNodeTracker {
     }
   }
 
+  @Test(timeout=10000)
+  public void testNodeUnhealthyRescheduleTasksEnabled() throws Exception {
+    _testNodeUnhealthyRescheduleTasks(true);
+  }
+
+  @Test(timeout=10000)
+  public void testNodeUnhealthyRescheduleTasksDisabled() throws Exception {
+    _testNodeUnhealthyRescheduleTasks(false);
+  }
+
+  private void _testNodeUnhealthyRescheduleTasks(boolean rescheduleTasks) {
+    AppContext appContext = mock(AppContext.class);
+    Configuration conf = new Configuration(false);
+    conf.setBoolean(TezConfiguration.TEZ_AM_NODE_UNHEALTHY_RESCHEDULE_TASKS,
+        rescheduleTasks);
+    TestEventHandler handler = new TestEventHandler();
+    AMNodeTracker amNodeTracker = new AMNodeTracker(handler, appContext);
+    doReturn(amNodeTracker).when(appContext).getNodeTracker();
+    amNodeTracker.init(conf);
+    amNodeTracker.start();
+
+    // add a node
+    amNodeTracker.handle(new AMNodeEventNodeCountUpdated(1, 0));
+    NodeId nodeId = NodeId.newInstance("host1", 1234);
+    amNodeTracker.nodeSeen(nodeId, 0);
+    AMNodeImpl node = (AMNodeImpl) amNodeTracker.get(nodeId, 0);
+
+    // simulate task starting on node
+    ContainerId cid = mock(ContainerId.class);
+    amNodeTracker.handle(new AMNodeEventContainerAllocated(nodeId, 0, cid));
+
+    // mark node unhealthy
+    NodeReport nodeReport = generateNodeReport(nodeId, NodeState.UNHEALTHY);
+    amNodeTracker.handle(new AMNodeEventStateChanged(nodeReport, 0));
+    assertEquals(AMNodeState.UNHEALTHY, node.getState());
+
+    // check for task rescheduling events
+    if (rescheduleTasks) {
+      assertEquals(1, handler.events.size());
+      assertEquals(AMContainerEventType.C_NODE_FAILED, handler.events.get(0).getType());
+    } else {
+      assertEquals(0, handler.events.size());
+    }
+
+    amNodeTracker.stop();
+  }
+
   private void _testSingleNodeNotBlacklisted(AMNodeTracker amNodeTracker,
                                              TestEventHandler handler, int schedulerId) {
     amNodeTracker.handle(new AMNodeEventNodeCountUpdated(1, schedulerId));


[11/50] [abbrv] tez git commit: TEZ-2978. Add an option to allow the SplitGrouper to generate node local only groups. (sseth)

Posted by sr...@apache.org.
TEZ-2978. Add an option to allow the SplitGrouper to generate node local
only groups. (sseth)


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

Branch: refs/heads/TEZ-2980
Commit: 0c085771b8c501d4fa492ab7c9dc57a1abcae52b
Parents: 85637c6
Author: Siddharth Seth <ss...@apache.org>
Authored: Tue Jan 12 15:16:31 2016 -0800
Committer: Siddharth Seth <ss...@apache.org>
Committed: Tue Jan 12 15:16:31 2016 -0800

----------------------------------------------------------------------
 CHANGES.txt                                     |   1 +
 .../tez/mapreduce/grouper/TezSplitGrouper.java  |  33 +++-
 .../hadoop/mapred/split/TestGroupedSplits.java  | 192 ++++++++++++++-----
 3 files changed, 180 insertions(+), 46 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/0c085771/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index ea2b1d5..6cdc037 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -11,6 +11,7 @@ INCOMPATIBLE CHANGES
   TEZ-2972. Avoid task rescheduling when a node turns unhealthy
 
 ALL CHANGES:
+  TEZ-2978. Add an option to allow the SplitGrouper to generate node local only groups.
   TEZ-2129. Task and Attempt views should contain links to the logs
   TEZ-3025. InputInitializer creation should use the dag ugi.
   TEZ-3017. HistoryACLManager does not have a close method for cleanup

http://git-wip-us.apache.org/repos/asf/tez/blob/0c085771/tez-mapreduce/src/main/java/org/apache/tez/mapreduce/grouper/TezSplitGrouper.java
----------------------------------------------------------------------
diff --git a/tez-mapreduce/src/main/java/org/apache/tez/mapreduce/grouper/TezSplitGrouper.java b/tez-mapreduce/src/main/java/org/apache/tez/mapreduce/grouper/TezSplitGrouper.java
index 163a2a3..9435e68 100644
--- a/tez-mapreduce/src/main/java/org/apache/tez/mapreduce/grouper/TezSplitGrouper.java
+++ b/tez-mapreduce/src/main/java/org/apache/tez/mapreduce/grouper/TezSplitGrouper.java
@@ -94,6 +94,13 @@ public abstract class TezSplitGrouper {
   public static final String TEZ_GROUPING_REPEATABLE = "tez.grouping.repeatable";
   public static final boolean TEZ_GROUPING_REPEATABLE_DEFAULT = true;
 
+  /**
+   * Generate node local splits only. This prevents fallback to rack locality etc, and overrides
+   * the target size for small splits.
+   */
+  public static final String TEZ_GROUPING_NODE_LOCAL_ONLY = "tez.grouping.node.local.only";
+  public static final boolean TEZ_GROUPING_NODE_LOCAL_ONLY_DEFAULT = false;
+
 
   static class LocationHolder {
     List<SplitContainer> splits;
@@ -302,6 +309,9 @@ public abstract class TezSplitGrouper {
     boolean groupByCount = conf.getBoolean(
         TEZ_GROUPING_SPLIT_BY_COUNT,
         TEZ_GROUPING_SPLIT_BY_COUNT_DEFAULT);
+    boolean nodeLocalOnly = conf.getBoolean(
+        TEZ_GROUPING_NODE_LOCAL_ONLY,
+        TEZ_GROUPING_NODE_LOCAL_ONLY_DEFAULT);
     if (!(groupByLength || groupByCount)) {
       throw new TezUncheckedException(
           "None of the grouping parameters are true: "
@@ -315,7 +325,9 @@ public abstract class TezSplitGrouper {
         " numSplitsInGroup: " + numSplitsInGroup +
         " totalLength: " + totalLength +
         " numOriginalSplits: " + originalSplits.size() +
-        " . Grouping by length: " + groupByLength + " count: " + groupByCount);
+        " . Grouping by length: " + groupByLength +
+        " count: " + groupByCount +
+        " nodeLocalOnly: " + nodeLocalOnly);
 
     // go through locations and group splits
     int splitsProcessed = 0;
@@ -332,7 +344,6 @@ public abstract class TezSplitGrouper {
         groupLocationSet.clear();
         String location = entry.getKey();
         LocationHolder holder = entry.getValue();
-        // KKK rename to splitContainer
         SplitContainer splitContainer = holder.getUnprocessedHeadSplit();
         if (splitContainer == null) {
           // all splits on node processed
@@ -402,7 +413,18 @@ public abstract class TezSplitGrouper {
       }
 
       if (!doingRackLocal && numFullGroupsCreated < 1) {
-        // no node could create a node-local group. go rack-local
+        // no node could create a regular node-local group.
+
+        // Allow small groups if that is configured.
+        if (nodeLocalOnly && !allowSmallGroups) {
+          LOG.info(
+              "Allowing small groups early after attempting to create full groups at iteration: {}, groupsCreatedSoFar={}",
+              iterations, groupedSplits.size());
+          allowSmallGroups = true;
+          continue;
+        }
+
+        // else go rack-local
         doingRackLocal = true;
         // re-create locations
         int numRemainingSplits = originalSplits.size() - splitsProcessed;
@@ -601,6 +623,11 @@ public abstract class TezSplitGrouper {
       return this;
     }
 
+    public TezMRSplitsGrouperConfigBuilder setNodeLocalGroupsOnly(boolean nodeLocalGroupsOnly) {
+      this.conf.setBoolean(TEZ_GROUPING_NODE_LOCAL_ONLY, nodeLocalGroupsOnly);
+      return this;
+    }
+
     /**
      * upper and lower bounds for the splits
      */

http://git-wip-us.apache.org/repos/asf/tez/blob/0c085771/tez-mapreduce/src/test/java/org/apache/hadoop/mapred/split/TestGroupedSplits.java
----------------------------------------------------------------------
diff --git a/tez-mapreduce/src/test/java/org/apache/hadoop/mapred/split/TestGroupedSplits.java b/tez-mapreduce/src/test/java/org/apache/hadoop/mapred/split/TestGroupedSplits.java
index 140a09d..fba72a3 100644
--- a/tez-mapreduce/src/test/java/org/apache/hadoop/mapred/split/TestGroupedSplits.java
+++ b/tez-mapreduce/src/test/java/org/apache/hadoop/mapred/split/TestGroupedSplits.java
@@ -28,10 +28,13 @@ import java.io.OutputStreamWriter;
 import java.io.Writer;
 import java.util.ArrayList;
 import java.util.BitSet;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Random;
 import java.util.Set;
 
+import org.apache.commons.lang.mutable.MutableInt;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.tez.mapreduce.grouper.TezSplitGrouper;
 import org.slf4j.Logger;
@@ -57,6 +60,9 @@ import org.junit.Test;
 
 import com.google.common.collect.Sets;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.*;
 
 public class TestGroupedSplits {
@@ -118,9 +124,9 @@ public class TestGroupedSplits {
 
       // we should have a single split as the length is comfortably smaller than
       // the block size
-      Assert.assertEquals("We got more than one splits!", 1, splits.length);
+      assertEquals("We got more than one splits!", 1, splits.length);
       InputSplit split = splits[0];
-      Assert.assertEquals("It should be TezGroupedSplit",
+      assertEquals("It should be TezGroupedSplit",
         TezGroupedSplit.class, split.getClass());
 
       // check the split
@@ -137,7 +143,7 @@ public class TestGroupedSplits {
             LOG.warn("conflict with " + v +
                      " at position "+reader.getPos());
           }
-          Assert.assertFalse("Key in multiple partitions.", bits.get(v));
+          assertFalse("Key in multiple partitions.", bits.get(v));
           bits.set(v);
           count++;
         }
@@ -145,7 +151,7 @@ public class TestGroupedSplits {
       } finally {
         reader.close();
       }
-      Assert.assertEquals("Some keys in no partition.", length, bits.cardinality());
+      assertEquals("Some keys in no partition.", length, bits.cardinality());
     }
   }
 
@@ -260,14 +266,14 @@ public class TestGroupedSplits {
       if (j==1) {
         // j==1 covers single split corner case
         // and does not do grouping
-        Assert.assertEquals("compressed splits == " + j, j, splits.length);
+        assertEquals("compressed splits == " + j, j, splits.length);
       }
       List<Text> results = new ArrayList<Text>();
       for (int i=0; i<splits.length; ++i) { 
         List<Text> read = readSplit(format, splits[i], job);
         results.addAll(read);
       }
-      Assert.assertEquals("splits length", 11, results.size());
+      assertEquals("splits length", 11, results.size());
   
       final String[] firstList =
         {"the quick", "brown", "fox jumped", "over", " the lazy", " dog"};
@@ -293,7 +299,7 @@ public class TestGroupedSplits {
 
   private static int testResults(List<Text> results, String[] first, int start) {
     for (int i = 0; i < first.length; i++) {
-      Assert.assertEquals("splits["+i+"]", first[i], results.get(start+i).toString());
+      assertEquals("splits["+i+"]", first[i], results.get(start+i).toString());
     }
     return first.length+start;
   }  
@@ -324,17 +330,17 @@ public class TestGroupedSplits {
     // desired splits not set. We end up choosing min/max split size based on 
     // total data and num original splits. In this case, min size will be hit
     InputSplit[] splits = format.getSplits(job, 0);
-    Assert.assertEquals(25, splits.length);
+    assertEquals(25, splits.length);
     
     // split too big. override with max
     format.setDesiredNumberOfSplits(1);
     splits = format.getSplits(job, 0);
-    Assert.assertEquals(4, splits.length);
+    assertEquals(4, splits.length);
     
     // splits too small. override with min
     format.setDesiredNumberOfSplits(1000);
     splits = format.getSplits(job, 0);
-    Assert.assertEquals(25, splits.length);
+    assertEquals(25, splits.length);
     
   }
   
@@ -398,7 +404,7 @@ public class TestGroupedSplits {
     // the remainig 3 splits (1 from each node) will be grouped at rack level (default-rack)
     // all of them will maintain ordering
     InputSplit[] groupedSplits = grouper.getGroupedSplits(conf, origSplits, 4, "InputFormat");
-    Assert.assertEquals(4, groupedSplits.length);
+    assertEquals(4, groupedSplits.length);
     for (int i=0; i<4; ++i) {
       TezGroupedSplit split = (TezGroupedSplit)groupedSplits[i];
       List<InputSplit> innerSplits = split.getGroupedSplits();
@@ -406,12 +412,12 @@ public class TestGroupedSplits {
       // splits in group maintain original order
       for (InputSplit innerSplit : innerSplits) {
         int splitPos = ((TestInputSplit) innerSplit).getPosition();
-        Assert.assertTrue(pos < splitPos);
+        assertTrue(pos < splitPos);
         pos = splitPos;
       }
       // last one is rack split
       if (i==3) {
-        Assert.assertTrue(split.getRack() != null);
+        assertTrue(split.getRack() != null);
       }
     }
   }
@@ -456,24 +462,25 @@ public class TestGroupedSplits {
     // all of them will maintain ordering
     InputSplit[] groupedSplits1 = grouper.getGroupedSplits(conf, origSplits, 4, "InputFormat");
     InputSplit[] groupedSplits2 = grouper.getGroupedSplits(conf, origSplits, 4, "InputFormat");
-    Assert.assertEquals(4, groupedSplits1.length);
-    Assert.assertEquals(4, groupedSplits2.length);
+    // KKK Start looking here.
+    assertEquals(4, groupedSplits1.length);
+    assertEquals(4, groupedSplits2.length);
     // check both split groups are the same. this depends on maintaining split order tested above
     for (int i=0; i<4; ++i) {
       TezGroupedSplit gSplit1 = ((TezGroupedSplit) groupedSplits1[i]);
       List<InputSplit> testSplits1 = gSplit1.getGroupedSplits();
       TezGroupedSplit gSplit2 = ((TezGroupedSplit) groupedSplits2[i]);
       List<InputSplit> testSplits2 = gSplit2.getGroupedSplits();
-      Assert.assertEquals(testSplits1.size(), testSplits2.size());
+      assertEquals(testSplits1.size(), testSplits2.size());
       for (int j=0; j<testSplits1.size(); j++) {
         TestInputSplit split1 = (TestInputSplit) testSplits1.get(j);
         TestInputSplit split2 = (TestInputSplit) testSplits2.get(j);
-        Assert.assertEquals(split1.position, split2.position);
+        assertEquals(split1.position, split2.position);
       }
       if (i==3) {
         // check for rack split creation. Ensures repeatability holds for rack splits also
-        Assert.assertTrue(gSplit1.getRack() != null);
-        Assert.assertTrue(gSplit2.getRack() != null);
+        assertTrue(gSplit1.getRack() != null);
+        assertTrue(gSplit2.getRack() != null);
       }
     }
   }
@@ -502,12 +509,12 @@ public class TestGroupedSplits {
     
     format.setDesiredNumberOfSplits(1);
     InputSplit[] splits = format.getSplits(job, 1);
-    Assert.assertEquals(1, splits.length);
+    assertEquals(1, splits.length);
     TezGroupedSplit split = (TezGroupedSplit) splits[0];
     // all 3 splits are present
-    Assert.assertEquals(numSplits, split.wrappedSplits.size());
+    assertEquals(numSplits, split.wrappedSplits.size());
     Set<InputSplit> splitSet = Sets.newHashSet(split.wrappedSplits);
-    Assert.assertEquals(numSplits, splitSet.size());
+    assertEquals(numSplits, splitSet.size());
   }
   
   @SuppressWarnings({ "rawtypes", "unchecked" })
@@ -540,10 +547,10 @@ public class TestGroupedSplits {
     
     format.setDesiredNumberOfSplits(1);
     InputSplit[] splits = format.getSplits(job, 1);
-    Assert.assertEquals(1, splits.length);
+    assertEquals(1, splits.length);
     TezGroupedSplit split = (TezGroupedSplit) splits[0];
     // all 3 splits are present
-    Assert.assertEquals(numSplits, split.wrappedSplits.size());
+    assertEquals(numSplits, split.wrappedSplits.size());
     ByteArrayOutputStream bOut = new ByteArrayOutputStream();
     split.write(new DataOutputStream(bOut));
   }
@@ -589,17 +596,17 @@ public class TestGroupedSplits {
 
     format.setDesiredNumberOfSplits(numSplits);
     InputSplit[] splits = format.getSplits(job, 1);
-    Assert.assertEquals(numSplits, splits.length);
+    assertEquals(numSplits, splits.length);
     for (int i = 0 ; i < numSplits ; i++) {
       TezGroupedSplit split = (TezGroupedSplit) splits[i];
       // all 3 splits are present
-      Assert.assertEquals(1, split.wrappedSplits.size());
+      assertEquals(1, split.wrappedSplits.size());
       if (i==3) {
-        Assert.assertEquals(1, split.getLocations().length);
-        Assert.assertEquals(validLocation, split.getLocations()[0]);
+        assertEquals(1, split.getLocations().length);
+        assertEquals(validLocation, split.getLocations()[0]);
       } else if (i==4) {
-        Assert.assertEquals(1, split.getLocations().length);
-        Assert.assertTrue(split.getLocations()[0].equals(validLocation) || split.getLocations()[0].equals(validLocation2));
+        assertEquals(1, split.getLocations().length);
+        assertTrue(split.getLocations()[0].equals(validLocation) || split.getLocations()[0].equals(validLocation2));
       } else {
         Assert.assertNull(split.getLocations());
       }
@@ -662,16 +669,16 @@ public class TestGroupedSplits {
 
     InputSplit[] splits = format.getSplits(job, 1);
     // due to the min = 12Mb
-    Assert.assertEquals(2, splits.length);
+    assertEquals(2, splits.length);
 
     for (InputSplit group : splits) {
       TezGroupedSplit split = (TezGroupedSplit) group;
       if (split.wrappedSplits.size() == 2) {
         // split1+split2
-        Assert.assertEquals(split.getLength(), 2 * 1000 * 1000l);
+        assertEquals(split.getLength(), 2 * 1000 * 1000l);
       } else {
         // split3
-        Assert.assertEquals(split.getLength(), 2 * 1000 * 1000l + 1);
+        assertEquals(split.getLength(), 2 * 1000 * 1000l + 1);
       }
     }
   }
@@ -708,14 +715,14 @@ public class TestGroupedSplits {
         "MockInputForamt", null, locationProvider);
 
     // Sanity. 1 group, with 3 splits.
-    Assert.assertEquals(1, groupedSplits.length);
-    Assert.assertTrue(groupedSplits[0] instanceof  TezGroupedSplit);
+    assertEquals(1, groupedSplits.length);
+    assertTrue(groupedSplits[0] instanceof  TezGroupedSplit);
     TezGroupedSplit groupedSplit = (TezGroupedSplit)groupedSplits[0];
-    Assert.assertEquals(3, groupedSplit.getGroupedSplits().size());
+    assertEquals(3, groupedSplit.getGroupedSplits().size());
 
     // Verify that the split ends up being grouped to the custom location.
-    Assert.assertEquals(1, groupedSplit.getLocations().length);
-    Assert.assertEquals("customLocation", groupedSplit.getLocations()[0]);
+    assertEquals(1, groupedSplit.getLocations().length);
+    assertEquals("customLocation", groupedSplit.getLocations()[0]);
   }
 
   // Original splits returned.
@@ -749,15 +756,114 @@ public class TestGroupedSplits {
         "MockInputForamt", null, locationProvider);
 
     // Sanity. 3 group, with 1 split each
-    Assert.assertEquals(3, groupedSplits.length);
+    assertEquals(3, groupedSplits.length);
     for (int i = 0 ; i < 3 ; i++) {
-      Assert.assertTrue(groupedSplits[i] instanceof  TezGroupedSplit);
+      assertTrue(groupedSplits[i] instanceof  TezGroupedSplit);
       TezGroupedSplit groupedSplit = (TezGroupedSplit)groupedSplits[i];
-      Assert.assertEquals(1, groupedSplit.getGroupedSplits().size());
+      assertEquals(1, groupedSplit.getGroupedSplits().size());
 
       // Verify the splits have their final location set to customLocation
-      Assert.assertEquals(1, groupedSplit.getLocations().length);
-      Assert.assertEquals("customLocation", groupedSplit.getLocations()[0]);
+      assertEquals(1, groupedSplit.getLocations().length);
+      assertEquals("customLocation", groupedSplit.getLocations()[0]);
+    }
+  }
+
+  @Test(timeout = 5000)
+  public void testForceNodeLocalSplits() throws IOException {
+    int numLocations = 7;
+    long splitLen = 100L;
+    String[] locations = new String[numLocations];
+    for (int i = 0; i < numLocations; i++) {
+      locations[i] = "node" + i;
+    }
+
+    // Generate 24 splits (6 per node) spread evenly across node0-node3.
+    // Generate 1 split each on the remaining 3 nodes (4-6)
+    int numSplits = 27;
+    InputSplit[] rawSplits = new InputSplit[numSplits];
+    for (int i = 0; i < 27; i++) {
+      String splitLoc[] = new String[1];
+      if (i < 24) {
+        splitLoc[0] = locations[i % 4];
+      } else {
+        splitLoc[0] = locations[4 + i % 24];
+      }
+      rawSplits[i] = new TestInputSplit(splitLen, splitLoc, i);
+    }
+
+    TezMapredSplitsGrouper grouper = new TezMapredSplitsGrouper();
+    JobConf confDisallowSmallEarly = new JobConf(defaultConf);
+    confDisallowSmallEarly = (JobConf) TezSplitGrouper.newConfigBuilder(confDisallowSmallEarly)
+        .setGroupingSplitSize(splitLen * 3, splitLen * 3)
+        .setGroupingRackSplitSizeReduction(1)
+        .setNodeLocalGroupsOnly(false)
+        .build();
+
+    JobConf confSmallEarly = new JobConf(defaultConf);
+    confSmallEarly = (JobConf) TezSplitGrouper.newConfigBuilder(confSmallEarly)
+        .setGroupingSplitSize(splitLen * 3, splitLen * 3)
+        .setGroupingRackSplitSizeReduction(1)
+        .setNodeLocalGroupsOnly(true)
+        .build();
+
+    // Without early grouping -> 4 * 2 node local, 1 merged - 9 total
+    // With early grouping -> 4 * 2 node local (first 4 nodes), 3 smaller node local (4-6) -> 11 total
+
+    // Requesting 9 based purely on size.
+    InputSplit[] groupedSplitsDisallowSmallEarly =
+        grouper.getGroupedSplits(confDisallowSmallEarly, rawSplits, 9, "InputFormat");
+    assertEquals(9, groupedSplitsDisallowSmallEarly.length);
+    // Verify the actual splits as well.
+    Map<String, MutableInt> matchedLocations = new HashMap<>();
+    verifySplitsFortestAllowSmallSplitsEarly(groupedSplitsDisallowSmallEarly);
+    TezGroupedSplit group = (TezGroupedSplit) groupedSplitsDisallowSmallEarly[8];
+    assertEquals(3, group.getLocations().length);
+    assertEquals(3, group.getGroupedSplits().size());
+    Set<String> exp = Sets.newHashSet(locations[4], locations[5], locations[6]);
+    for (int i = 0; i < 3; i++) {
+      LOG.info(group.getLocations()[i]);
+      exp.remove(group.getLocations()[i]);
+    }
+    assertEquals(0, exp.size());
+
+    InputSplit[] groupedSplitsSmallEarly =
+        grouper.getGroupedSplits(confSmallEarly, rawSplits, 9, "InputFormat");
+    assertEquals(11, groupedSplitsSmallEarly.length);
+    // The first 8 are the larger groups.
+    verifySplitsFortestAllowSmallSplitsEarly(groupedSplitsSmallEarly);
+    exp = Sets.newHashSet(locations[4], locations[5], locations[6]);
+    for (int i = 8; i < 11; i++) {
+      group = (TezGroupedSplit) groupedSplitsSmallEarly[i];
+      assertEquals(1, group.getLocations().length);
+      assertEquals(1, group.getGroupedSplits().size());
+      String matchedLoc = group.getLocations()[0];
+      assertTrue(exp.contains(matchedLoc));
+      exp.remove(matchedLoc);
+    }
+    assertEquals(0, exp.size());
+  }
+
+  private void verifySplitsFortestAllowSmallSplitsEarly(InputSplit[] groupedSplits) throws
+      IOException {
+    Map<String, MutableInt> matchedLocations = new HashMap<>();
+    for (int i = 0; i < 8; i++) {
+      TezGroupedSplit group = (TezGroupedSplit) groupedSplits[i];
+      assertEquals(1, group.getLocations().length);
+      assertEquals(3, group.getGroupedSplits().size());
+      String matchedLoc = group.getLocations()[0];
+      MutableInt count = matchedLocations.get(matchedLoc);
+      if (count == null) {
+        count = new MutableInt(0);
+        matchedLocations.put(matchedLoc, count);
+      }
+      count.increment();
+    }
+    for (Map.Entry<String, MutableInt> entry : matchedLocations.entrySet()) {
+      String loc = entry.getKey();
+      int nodeId = Character.getNumericValue(loc.charAt(loc.length() - 1));
+      assertTrue(nodeId < 4);
+      assertTrue(loc.startsWith("node") && loc.length() == 5);
+      assertEquals(2, entry.getValue().getValue());
     }
   }
 


[17/50] [abbrv] tez git commit: TEZ-3032. DAG start time getting logged using system time instead of recorded time in startTime field. (hitesh)

Posted by sr...@apache.org.
TEZ-3032. DAG start time getting logged using system time instead of recorded time in startTime field. (hitesh)


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

Branch: refs/heads/TEZ-2980
Commit: 37e70146e9c6162c048af2388f732a701654cda9
Parents: b656157
Author: Hitesh Shah <hi...@apache.org>
Authored: Thu Jan 14 13:49:17 2016 -0800
Committer: Hitesh Shah <hi...@apache.org>
Committed: Thu Jan 14 13:49:17 2016 -0800

----------------------------------------------------------------------
 CHANGES.txt                                                        | 2 ++
 tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/DAGImpl.java | 2 +-
 2 files changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/37e70146/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index ec3e84b..ca668a0 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -18,6 +18,7 @@ INCOMPATIBLE CHANGES
   TEZ-2972. Avoid task rescheduling when a node turns unhealthy
 
 ALL CHANGES:
+  TEZ-3032. DAG start time getting logged using system time instead of recorded time in startTime field.
   TEZ-2669. Propagation of errors from plugins to the AM for error reporting.
   TEZ-2978. Add an option to allow the SplitGrouper to generate node local only groups.
   TEZ-2129. Task and Attempt views should contain links to the logs
@@ -312,6 +313,7 @@ INCOMPATIBLE CHANGES
   TEZ-2949. Allow duplicate dag names within session for Tez.
 
 ALL CHANGES
+  TEZ-3032. DAG start time getting logged using system time instead of recorded time in startTime field.
   TEZ-2129. Task and Attempt views should contain links to the logs
   TEZ-3025. InputInitializer creation should use the dag ugi.
   TEZ-3017. HistoryACLManager does not have a close method for cleanup

http://git-wip-us.apache.org/repos/asf/tez/blob/37e70146/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/DAGImpl.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/DAGImpl.java b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/DAGImpl.java
index 41017ea..139fd51 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/DAGImpl.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/DAGImpl.java
@@ -1222,7 +1222,7 @@ public class DAGImpl implements org.apache.tez.dag.app.dag.DAG,
     if (recoveryData == null
         || recoveryData.getDAGStartedEvent() == null) {
       DAGStartedEvent startEvt = new DAGStartedEvent(this.dagId,
-          clock.getTime(), this.userName, this.dagName);
+          this.startTime, this.userName, this.dagName);
       this.appContext.getHistoryHandler().handle(
           new DAGHistoryEvent(dagId, startEvt));
     }


[13/50] [abbrv] tez git commit: TEZ-2669. Propagation of errors from plugins to the AM for error reporting. Contributed by Hitesh Shah and Siddharth Seth.

Posted by sr...@apache.org.
http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/main/java/org/apache/tez/dag/app/rm/TaskSchedulerManager.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/rm/TaskSchedulerManager.java b/tez-dag/src/main/java/org/apache/tez/dag/app/rm/TaskSchedulerManager.java
index f688b57..e4612b6 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/rm/TaskSchedulerManager.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/rm/TaskSchedulerManager.java
@@ -32,9 +32,12 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.util.concurrent.ThreadFactoryBuilder;
 
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.tez.Utils;
 import org.apache.tez.dag.api.NamedEntityDescriptor;
 import org.apache.tez.dag.api.TezConstants;
 import org.apache.tez.dag.app.ServicePluginLifecycleAbstractService;
+import org.apache.tez.dag.app.dag.event.DAGAppMasterEventUserServiceFatalError;
 import org.apache.tez.serviceplugins.api.TaskScheduler;
 import org.apache.tez.serviceplugins.api.TaskSchedulerContext;
 import org.apache.tez.serviceplugins.api.TaskSchedulerContext.AppFinalStatus;
@@ -112,7 +115,7 @@ public class TaskSchedulerManager extends AbstractService implements
       new AtomicBoolean(false);
   private final WebUIService webUI;
   private final NamedEntityDescriptor[] taskSchedulerDescriptors;
-  protected final TaskScheduler[]taskSchedulers;
+  protected final TaskSchedulerWrapper[] taskSchedulers;
   protected final ServicePluginLifecycleAbstractService []taskSchedulerServiceWrappers;
 
   // Single executor service shared by all Schedulers for context callbacks
@@ -134,6 +137,29 @@ public class TaskSchedulerManager extends AbstractService implements
   // Not tracking container / task to schedulerId. Instead relying on everything flowing through
   // the system and being propagated back via events.
 
+  @VisibleForTesting
+  @InterfaceAudience.Private
+  /**
+   * For Testing only
+   */
+  public TaskSchedulerManager(TaskScheduler taskScheduler, AppContext appContext,
+                              ContainerSignatureMatcher containerSignatureMatcher,
+                              DAGClientServer clientService, ExecutorService appCallbackExecutor) {
+    super(TaskSchedulerManager.class.getName());
+    this.appContext = appContext;
+    this.containerSignatureMatcher = containerSignatureMatcher;
+    this.clientService = clientService;
+    this.eventHandler = appContext.getEventHandler();
+    this.appCallbackExecutor = appCallbackExecutor;
+    this.taskSchedulers = new TaskSchedulerWrapper[]{new TaskSchedulerWrapper(taskScheduler)};
+    this.taskSchedulerServiceWrappers = new ServicePluginLifecycleAbstractService[]{
+        new ServicePluginLifecycleAbstractService<>(taskScheduler)};
+    this.taskSchedulerDescriptors = null;
+    this.webUI = null;
+    this.historyUrl = null;
+    this.isPureLocalMode = false;
+  }
+
   /**
    *
    * @param appContext
@@ -169,7 +195,7 @@ public class TaskSchedulerManager extends AbstractService implements
 
     this.taskSchedulerDescriptors = schedulerDescriptors.toArray(new NamedEntityDescriptor[schedulerDescriptors.size()]);
 
-    taskSchedulers = new TaskScheduler[this.taskSchedulerDescriptors.length];
+    taskSchedulers = new TaskSchedulerWrapper[this.taskSchedulerDescriptors.length];
     taskSchedulerServiceWrappers = new ServicePluginLifecycleAbstractService[this.taskSchedulerDescriptors.length];
   }
 
@@ -187,11 +213,33 @@ public class TaskSchedulerManager extends AbstractService implements
   }
   
   public Resource getAvailableResources(int schedulerId) {
-    return taskSchedulers[schedulerId].getAvailableResources();
+    try {
+      return taskSchedulers[schedulerId].getAvailableResources();
+    } catch (Exception e) {
+      String msg = "Error in TaskScheduler while getting available resources"
+          + ", schedule=" + Utils.getTaskSchedulerIdentifierString(schedulerId, appContext);
+      LOG.error(msg, e);
+      sendEvent(
+          new DAGAppMasterEventUserServiceFatalError(
+              DAGAppMasterEventType.TASK_SCHEDULER_SERVICE_FATAL_ERROR,
+              msg, e));
+      throw new RuntimeException(e);
+    }
   }
 
   public Resource getTotalResources(int schedulerId) {
-    return taskSchedulers[schedulerId].getTotalResources();
+    try {
+      return taskSchedulers[schedulerId].getTotalResources();
+    } catch (Exception e) {
+      String msg = "Error in TaskScheduler while getting total resources"
+          + ", scheduler=" + Utils.getTaskSchedulerIdentifierString(schedulerId, appContext);
+      LOG.error(msg, e);
+      sendEvent(
+          new DAGAppMasterEventUserServiceFatalError(
+              DAGAppMasterEventType.TASK_SCHEDULER_SERVICE_FATAL_ERROR,
+              msg, e));
+      throw new RuntimeException(e);
+    }
   }
 
   private ExecutorService createAppCallbackExecutorService() {
@@ -265,11 +313,27 @@ public class TaskSchedulerManager extends AbstractService implements
   }
 
   private void handleNodeBlacklistUpdate(AMSchedulerEventNodeBlacklistUpdate event) {
-    if (event.getType() == AMSchedulerEventType.S_NODE_BLACKLISTED) {
-      taskSchedulers[event.getSchedulerId()].blacklistNode(event.getNodeId());
-    } else if (event.getType() == AMSchedulerEventType.S_NODE_UNBLACKLISTED) {
-      taskSchedulers[event.getSchedulerId()].unblacklistNode(event.getNodeId());
-    } else {
+    boolean invalidEventType = false;
+    try {
+      if (event.getType() == AMSchedulerEventType.S_NODE_BLACKLISTED) {
+        taskSchedulers[event.getSchedulerId()].blacklistNode(event.getNodeId());
+      } else if (event.getType() == AMSchedulerEventType.S_NODE_UNBLACKLISTED) {
+        taskSchedulers[event.getSchedulerId()].unblacklistNode(event.getNodeId());
+      } else {
+        invalidEventType = true;
+      }
+    } catch (Exception e) {
+      String msg = "Error in TaskScheduler for handling node blacklisting"
+          + ", eventType=" + event.getType()
+          + ", scheduler=" + Utils.getTaskSchedulerIdentifierString(event.getSchedulerId(), appContext);
+      LOG.error(msg, e);
+      sendEvent(
+          new DAGAppMasterEventUserServiceFatalError(
+              DAGAppMasterEventType.TASK_SCHEDULER_SERVICE_FATAL_ERROR,
+              msg, e));
+      return;
+    }
+    if (invalidEventType) {
       throw new TezUncheckedException("Invalid event type: " + event.getType());
     }
   }
@@ -280,7 +344,20 @@ public class TaskSchedulerManager extends AbstractService implements
     // TODO what happens to the task that was connected to this container?
     // current assumption is that it will eventually call handleTaStopRequest
     //TaskAttempt taskAttempt = (TaskAttempt)
-    taskSchedulers[event.getSchedulerId()].deallocateContainer(containerId);
+    try {
+      taskSchedulers[event.getSchedulerId()].deallocateContainer(containerId);
+    } catch (Exception e) {
+      String msg = "Error in TaskScheduler for handling Container De-allocation"
+          + ", eventType=" + event.getType()
+          + ", scheduler=" + Utils.getTaskSchedulerIdentifierString(event.getSchedulerId(), appContext)
+          + ", containerId=" + containerId;
+      LOG.error(msg, e);
+      sendEvent(
+          new DAGAppMasterEventUserServiceFatalError(
+              DAGAppMasterEventType.TASK_SCHEDULER_SERVICE_FATAL_ERROR,
+              msg, e));
+      return;
+    }
     // TODO does this container need to be stopped via C_STOP_REQUEST
     sendEvent(new AMContainerEventStopRequest(containerId));
   }
@@ -288,8 +365,22 @@ public class TaskSchedulerManager extends AbstractService implements
   private void handleTAUnsuccessfulEnd(AMSchedulerEventTAEnded event) {
     TaskAttempt attempt = event.getAttempt();
     // Propagate state and failure cause (if any) when informing the scheduler about the de-allocation.
-    boolean wasContainerAllocated = taskSchedulers[event.getSchedulerId()]
-        .deallocateTask(attempt, false, event.getTaskAttemptEndReason(), event.getDiagnostics());
+    boolean wasContainerAllocated = false;
+    try {
+      wasContainerAllocated = taskSchedulers[event.getSchedulerId()]
+          .deallocateTask(attempt, false, event.getTaskAttemptEndReason(), event.getDiagnostics());
+    } catch (Exception e) {
+      String msg = "Error in TaskScheduler for handling Task De-allocation"
+          + ", eventType=" + event.getType()
+          + ", scheduler=" + Utils.getTaskSchedulerIdentifierString(event.getSchedulerId(), appContext)
+          + ", taskAttemptId=" + attempt.getID();
+      LOG.error(msg, e);
+      sendEvent(
+          new DAGAppMasterEventUserServiceFatalError(
+              DAGAppMasterEventType.TASK_SCHEDULER_SERVICE_FATAL_ERROR,
+              msg, e));
+      return;
+    }
     // use stored value of container id in case the scheduler has removed this
     // assignment because the task has been deallocated earlier.
     // retroactive case
@@ -333,8 +424,24 @@ public class TaskSchedulerManager extends AbstractService implements
           event.getAttemptID()));
     }
 
-    boolean wasContainerAllocated = taskSchedulers[event.getSchedulerId()].deallocateTask(attempt,
+    boolean wasContainerAllocated = false;
+
+    try {
+      wasContainerAllocated = taskSchedulers[event.getSchedulerId()].deallocateTask(attempt,
         true, null, event.getDiagnostics());
+    } catch (Exception e) {
+      String msg = "Error in TaskScheduler for handling Task De-allocation"
+          + ", eventType=" + event.getType()
+          + ", scheduler=" + Utils.getTaskSchedulerIdentifierString(event.getSchedulerId(), appContext)
+          + ", taskAttemptId=" + attempt.getID();
+      LOG.error(msg, e);
+      sendEvent(
+          new DAGAppMasterEventUserServiceFatalError(
+              DAGAppMasterEventType.TASK_SCHEDULER_SERVICE_FATAL_ERROR,
+              msg, e));
+      return;
+    }
+
     if (!wasContainerAllocated) {
       LOG.error("De-allocated successful task: " + attempt.getID()
           + ", but TaskScheduler reported no container assigned to task");
@@ -359,12 +466,24 @@ public class TaskSchedulerManager extends AbstractService implements
         TaskAttempt affinityAttempt = vertex.getTask(taskIndex).getSuccessfulAttempt();
         if (affinityAttempt != null) {
           Preconditions.checkNotNull(affinityAttempt.getAssignedContainerID(), affinityAttempt.getID());
-          taskSchedulers[event.getSchedulerId()].allocateTask(taskAttempt,
-              event.getCapability(),
-              affinityAttempt.getAssignedContainerID(),
-              Priority.newInstance(event.getPriority()),
-              event.getContainerContext(),
-              event);
+          try {
+            taskSchedulers[event.getSchedulerId()].allocateTask(taskAttempt,
+                event.getCapability(),
+                affinityAttempt.getAssignedContainerID(),
+                Priority.newInstance(event.getPriority()),
+                event.getContainerContext(),
+                event);
+          } catch (Exception e) {
+            String msg = "Error in TaskScheduler for handling Task Allocation"
+                + ", eventType=" + event.getType()
+                + ", scheduler=" + Utils.getTaskSchedulerIdentifierString(event.getSchedulerId(), appContext)
+                + ", taskAttemptId=" + taskAttempt.getID();
+            LOG.error(msg, e);
+            sendEvent(
+                new DAGAppMasterEventUserServiceFatalError(
+                    DAGAppMasterEventType.TASK_SCHEDULER_SERVICE_FATAL_ERROR,
+                    msg, e));
+          }
           return;
         }
         LOG.info("No attempt for task affinity to " + taskAffinity + " for attempt "
@@ -379,21 +498,33 @@ public class TaskSchedulerManager extends AbstractService implements
       }
     }
 
-    taskSchedulers[event.getSchedulerId()].allocateTask(taskAttempt,
-        event.getCapability(),
-        hosts,
-        racks,
-        Priority.newInstance(event.getPriority()),
-        event.getContainerContext(),
-        event);
+    try {
+      taskSchedulers[event.getSchedulerId()].allocateTask(taskAttempt,
+          event.getCapability(),
+          hosts,
+          racks,
+          Priority.newInstance(event.getPriority()),
+          event.getContainerContext(),
+          event);
+    } catch (Exception e) {
+      String msg = "Error in TaskScheduler for handling Task Allocation"
+          + ", eventType=" + event.getType()
+          + ", scheduler=" + Utils.getTaskSchedulerIdentifierString(event.getSchedulerId(), appContext)
+          + ", taskAttemptId=" + taskAttempt.getID();
+      LOG.error(msg, e);
+      sendEvent(
+          new DAGAppMasterEventUserServiceFatalError(
+              DAGAppMasterEventType.TASK_SCHEDULER_SERVICE_FATAL_ERROR,
+              msg, e));
+    }
   }
 
   @VisibleForTesting
   TaskScheduler createTaskScheduler(String host, int port, String trackingUrl,
-                                                   AppContext appContext,
-                                                   NamedEntityDescriptor taskSchedulerDescriptor,
-                                                   long customAppIdIdentifier,
-                                                   int schedulerId) throws TezException {
+                                    AppContext appContext,
+                                    NamedEntityDescriptor taskSchedulerDescriptor,
+                                    long customAppIdIdentifier,
+                                    int schedulerId) throws TezException {
     TaskSchedulerContext rawContext =
         new TaskSchedulerContextImpl(this, appContext, schedulerId, trackingUrl,
             customAppIdIdentifier, host, port, taskSchedulerDescriptor.getUserPayload());
@@ -452,9 +583,10 @@ public class TaskSchedulerManager extends AbstractService implements
       } else {
         customAppIdIdentifier = SCHEDULER_APP_ID_BASE + (j++ * SCHEDULER_APP_ID_INCREMENT);
       }
-      taskSchedulers[i] = createTaskScheduler(host, port,
-          trackingUrl, appContext, taskSchedulerDescriptors[i], customAppIdIdentifier, i);
-      taskSchedulerServiceWrappers[i] = new ServicePluginLifecycleAbstractService<>(taskSchedulers[i]);
+      taskSchedulers[i] = new TaskSchedulerWrapper(createTaskScheduler(host, port,
+          trackingUrl, appContext, taskSchedulerDescriptors[i], customAppIdIdentifier, i));
+      taskSchedulerServiceWrappers[i] =
+          new ServicePluginLifecycleAbstractService<>(taskSchedulers[i].getTaskScheduler());
     }
   }
 
@@ -521,7 +653,13 @@ public class TaskSchedulerManager extends AbstractService implements
 
   public void initiateStop() {
     for (int i = 0 ; i < taskSchedulers.length ; i++) {
-      taskSchedulers[i].initiateStop();
+      try {
+        taskSchedulers[i].getTaskScheduler().initiateStop();
+      } catch (Exception e) {
+        // Ignore for now as scheduler stop invoked on shutdown
+        LOG.error("Failed to do a clean initiateStop for Scheduler: "
+            + Utils.getTaskSchedulerIdentifierString(i, appContext), e);
+      }
     }
   }
 
@@ -686,7 +824,19 @@ public class TaskSchedulerManager extends AbstractService implements
     // Doubles as a mechanism to update node counts periodically. Hence schedulerId required.
 
     // TODO Handle this in TEZ-2124. Need a way to know which scheduler is calling in.
-    int nodeCount = taskSchedulers[0].getClusterNodeCount();
+    int nodeCount = 0;
+    try {
+      nodeCount = taskSchedulers[0].getClusterNodeCount();
+    } catch (Exception e) {
+      String msg = "Error in TaskScheduler while getting node count"
+          + ", scheduler=" + Utils.getTaskSchedulerIdentifierString(schedulerId, appContext);
+      LOG.error(msg, e);
+      sendEvent(
+          new DAGAppMasterEventUserServiceFatalError(
+              DAGAppMasterEventType.TASK_SCHEDULER_SERVICE_FATAL_ERROR,
+              msg, e));
+      throw new RuntimeException(e);
+    }
     if (nodeCount != cachedNodeCount) {
       cachedNodeCount = nodeCount;
       sendEvent(new AMNodeEventNodeCountUpdated(cachedNodeCount, schedulerId));
@@ -701,7 +851,17 @@ public class TaskSchedulerManager extends AbstractService implements
 
   public void dagCompleted() {
     for (int i = 0 ; i < taskSchedulers.length ; i++) {
-      taskSchedulers[i].dagComplete();
+      try {
+        taskSchedulers[i].dagComplete();
+      } catch (Exception e) {
+        String msg = "Error in TaskScheduler when notified for Dag Completion"
+            + ", scheduler=" + Utils.getTaskSchedulerIdentifierString(i, appContext);
+        LOG.error(msg, e);
+        sendEvent(
+            new DAGAppMasterEventUserServiceFatalError(
+                DAGAppMasterEventType.TASK_SCHEDULER_SERVICE_FATAL_ERROR,
+                msg, e));
+      }
     }
   }
 
@@ -714,7 +874,18 @@ public class TaskSchedulerManager extends AbstractService implements
     // TODO Why is this making a call back into the scheduler, when the call is originating from there.
     // An AMContainer instance should already exist if an attempt is being made to preempt it
     AMContainer amContainer = appContext.getAllContainers().get(containerId);
-    taskSchedulers[amContainer.getTaskSchedulerIdentifier()].deallocateContainer(containerId);
+    try {
+      taskSchedulers[amContainer.getTaskSchedulerIdentifier()].deallocateContainer(containerId);
+    } catch (Exception e) {
+      String msg = "Error in TaskScheduler when preempting container"
+          + ", scheduler=" + Utils.getTaskSchedulerIdentifierString(amContainer.getTaskSchedulerIdentifier(), appContext)
+          + ", containerId=" + containerId;
+      LOG.error(msg, e);
+      sendEvent(
+          new DAGAppMasterEventUserServiceFatalError(
+              DAGAppMasterEventType.TASK_SCHEDULER_SERVICE_FATAL_ERROR,
+              msg, e));
+    }
     // Inform the Containers about completion.
     sendEvent(new AMContainerEventCompleted(containerId, ContainerExitStatus.INVALID,
         "Container preempted internally", TaskAttemptTerminationCause.INTERNAL_PREEMPTION));
@@ -725,7 +896,17 @@ public class TaskSchedulerManager extends AbstractService implements
     this.shouldUnregisterFlag.set(true);
     for (int i = 0 ; i < taskSchedulers.length ; i++) {
       if (this.taskSchedulers[i] != null) {
-        this.taskSchedulers[i].setShouldUnregister();
+        try {
+          this.taskSchedulers[i].setShouldUnregister();
+        } catch (Exception e) {
+          String msg = "Error in TaskScheduler when setting Unregister Flag"
+              + ", scheduler=" + Utils.getTaskSchedulerIdentifierString(i, appContext);
+          LOG.error(msg, e);
+          sendEvent(
+              new DAGAppMasterEventUserServiceFatalError(
+                  DAGAppMasterEventType.TASK_SCHEDULER_SERVICE_FATAL_ERROR,
+                  msg, e));
+        }
       }
     }
   }
@@ -737,7 +918,19 @@ public class TaskSchedulerManager extends AbstractService implements
   public boolean hasUnregistered() {
     boolean result = true;
     for (int i = 0 ; i < taskSchedulers.length ; i++) {
-      result = result & this.taskSchedulers[i].hasUnregistered();
+      // Explicitly not catching any exceptions around this API
+      // No clear route to recover. Better to crash.
+      try {
+        result = result & this.taskSchedulers[i].hasUnregistered();
+      } catch (Exception e) {
+        String msg = "Error in TaskScheduler when checking if a scheduler has unregistered"
+            + ", scheduler=" + Utils.getTaskSchedulerIdentifierString(i, appContext);
+        LOG.error(msg, e);
+        sendEvent(
+            new DAGAppMasterEventUserServiceFatalError(
+                DAGAppMasterEventType.TASK_SCHEDULER_SERVICE_FATAL_ERROR,
+                msg, e));
+      }
       if (result == false) {
         return result;
       }

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/main/java/org/apache/tez/dag/app/rm/TaskSchedulerWrapper.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/rm/TaskSchedulerWrapper.java b/tez-dag/src/main/java/org/apache/tez/dag/app/rm/TaskSchedulerWrapper.java
new file mode 100644
index 0000000..43cf045
--- /dev/null
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/rm/TaskSchedulerWrapper.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tez.dag.app.rm;
+
+import javax.annotation.Nullable;
+
+import org.apache.hadoop.yarn.api.records.ContainerId;
+import org.apache.hadoop.yarn.api.records.NodeId;
+import org.apache.hadoop.yarn.api.records.Priority;
+import org.apache.hadoop.yarn.api.records.Resource;
+import org.apache.tez.serviceplugins.api.TaskAttemptEndReason;
+import org.apache.tez.serviceplugins.api.TaskScheduler;
+
+public class TaskSchedulerWrapper {
+
+  private final TaskScheduler real;
+
+  public TaskSchedulerWrapper(TaskScheduler real) {
+    this.real = real;
+  }
+
+  public Resource getAvailableResources() throws Exception {
+    return real.getAvailableResources();
+  }
+
+  public Resource getTotalResources() throws Exception {
+    return real.getTotalResources();
+  }
+
+  public int getClusterNodeCount() throws Exception {
+    return real.getClusterNodeCount();
+  }
+
+  public void blacklistNode(NodeId nodeId) throws Exception {
+    real.blacklistNode(nodeId);
+  }
+
+  public void unblacklistNode(NodeId nodeId) throws Exception {
+    real.unblacklistNode(nodeId);
+  }
+
+  public void allocateTask(Object task, Resource capability, String[] hosts, String[] racks,
+                           Priority priority, Object containerSignature, Object clientCookie) throws
+      Exception {
+    real.allocateTask(task, capability, hosts, racks, priority, containerSignature, clientCookie);
+  }
+
+  public void allocateTask(Object task, Resource capability, ContainerId containerId,
+                           Priority priority, Object containerSignature, Object clientCookie) throws
+      Exception {
+    real.allocateTask(task, capability, containerId, priority, containerSignature, clientCookie);
+  }
+
+  public boolean deallocateTask(Object task, boolean taskSucceeded, TaskAttemptEndReason endReason,
+                                @Nullable String diagnostics) throws Exception {
+    return real.deallocateTask(task, taskSucceeded, endReason, diagnostics);
+  }
+
+  public Object deallocateContainer(ContainerId containerId) throws Exception {
+    return real.deallocateContainer(containerId);
+  }
+
+  public void setShouldUnregister() throws Exception {
+    real.setShouldUnregister();
+  }
+
+  public boolean hasUnregistered() throws Exception {
+    return real.hasUnregistered();
+  }
+
+  public void dagComplete() throws Exception {
+    real.dagComplete();
+  }
+
+  public TaskScheduler getTaskScheduler() {
+    return real;
+  }
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/main/java/org/apache/tez/dag/app/rm/container/AMContainerImpl.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/rm/container/AMContainerImpl.java b/tez-dag/src/main/java/org/apache/tez/dag/app/rm/container/AMContainerImpl.java
index d37d106..e4302aa 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/rm/container/AMContainerImpl.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/rm/container/AMContainerImpl.java
@@ -18,6 +18,7 @@
 
 package org.apache.tez.dag.app.rm.container;
 
+import java.net.InetSocketAddress;
 import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.LinkedList;
@@ -27,7 +28,10 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
 
+import org.apache.tez.Utils;
 import org.apache.tez.common.TezUtilsInternal;
+import org.apache.tez.dag.app.dag.event.DAGAppMasterEventType;
+import org.apache.tez.dag.app.dag.event.DAGAppMasterEventUserServiceFatalError;
 import org.apache.tez.serviceplugins.api.ContainerEndReason;
 import org.apache.tez.common.ContainerSignatureMatcher;
 import org.apache.tez.serviceplugins.api.TaskAttemptEndReason;
@@ -461,6 +465,29 @@ public class AMContainerImpl implements AMContainer {
         dagId = container.appContext.getCurrentDAG().getID();
         dagLocalResources = container.appContext.getCurrentDAG().getLocalResources();
       }
+
+      // TODO TEZ-2625 This should ideally be handled inside of user code. Will change once
+      // CLC construction moves into user code. For now, generating a user code error here
+      InetSocketAddress cAddress = null;
+      try {
+        cAddress =
+            container.taskCommunicatorManagerInterface.getTaskCommunicator(container.taskCommId).getAddress();
+      } catch (Exception e) {
+        String msg = "Error in TaskCommunicator when getting address"
+            + ", communicator=" + Utils.getTaskCommIdentifierString(container.taskCommId, container.appContext)
+            + ", containerId=" + container.containerId;
+        LOG.error(msg, e);
+        container.sendEvent(
+            new DAGAppMasterEventUserServiceFatalError(
+                DAGAppMasterEventType.TASK_COMMUNICATOR_SERVICE_FATAL_ERROR,
+                msg, e));
+        // We have not registered with any of the listeners etc yet. Send out a deallocateContainer
+        // message and return. The AM will shutdown shortly.
+        container.inError = true;
+        container.deAllocate();
+        return;
+      }
+
       ContainerLaunchContext clc = AMContainerHelpers.createContainerLaunchContext(
           dagId, dagLocalResources,
           container.appContext.getApplicationACLs(),
@@ -468,7 +495,8 @@ public class AMContainerImpl implements AMContainer {
           containerContext.getLocalResources(),
           containerContext.getEnvironment(),
           containerContext.getJavaOpts(),
-          container.taskCommunicatorManagerInterface.getTaskCommunicator(container.taskCommId).getAddress(), containerContext.getCredentials(),
+          cAddress,
+          containerContext.getCredentials(),
           container.appContext, container.container.getResource(),
           container.appContext.getAMConf());
 

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/test/java/org/apache/tez/dag/app/MockDAGAppMaster.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/MockDAGAppMaster.java b/tez-dag/src/test/java/org/apache/tez/dag/app/MockDAGAppMaster.java
index b322e05..08f81fb 100644
--- a/tez-dag/src/test/java/org/apache/tez/dag/app/MockDAGAppMaster.java
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/MockDAGAppMaster.java
@@ -193,7 +193,7 @@ public class MockDAGAppMaster extends DAGAppMaster {
     @Override
     public void start() throws Exception {
       taskCommunicatorManager = (TaskCommunicatorManager) getTaskCommunicatorManager();
-      taskCommunicator = (TezTaskCommunicatorImpl) taskCommunicatorManager.getTaskCommunicator(0);
+      taskCommunicator = (TezTaskCommunicatorImpl) taskCommunicatorManager.getTaskCommunicator(0).getTaskCommunicator();
       eventHandlingThread = new Thread(this);
       eventHandlingThread.start();
       ExecutorService rawExecutor = Executors.newFixedThreadPool(handlerConcurrency,

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/test/java/org/apache/tez/dag/app/PluginWrapperTestHelpers.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/PluginWrapperTestHelpers.java b/tez-dag/src/test/java/org/apache/tez/dag/app/PluginWrapperTestHelpers.java
new file mode 100644
index 0000000..fb6faa1
--- /dev/null
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/PluginWrapperTestHelpers.java
@@ -0,0 +1,149 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tez.dag.app;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Set;
+
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class PluginWrapperTestHelpers {
+
+  private static final Logger LOG = LoggerFactory.getLogger(PluginWrapperTestHelpers.class);
+
+  public static void testDelegation(Class<?> delegateClass, Class<?> rawClass,
+                                    Set<String> skipMethods) throws Exception {
+    TrackingAnswer answer = new TrackingAnswer();
+    Object mock = mock(rawClass, answer);
+    Constructor ctor = delegateClass.getConstructor(rawClass);
+    Object wrapper = ctor.newInstance(mock);
+
+    // Run through all the methods on the wrapper, and invoke the methods. Constructs
+    // arguments and return types for each of them.
+    Method[] methods = delegateClass.getMethods();
+    for (Method method : methods) {
+      if (method.getDeclaringClass().equals(delegateClass) &&
+          !skipMethods.contains(method.getName())) {
+
+        assertTrue(method.getExceptionTypes().length == 1);
+        assertEquals(Exception.class, method.getExceptionTypes()[0]);
+
+        LOG.info("Checking method [{}] with parameterTypes [{}]", method.getName(), Arrays.toString(method.getParameterTypes()));
+
+        Object[] params = constructMethodArgs(method);
+        Object result = method.invoke(wrapper, params);
+
+        // Validate the correct arguments are forwarded, and the real instance is invoked.
+        assertEquals(method.getName(), answer.lastMethodName);
+        assertArrayEquals(params, answer.lastArgs);
+
+        // Validate the results.
+        // Handle auto-boxing
+        if (answer.compareAsPrimitive) {
+          assertEquals(answer.lastRetValue, result);
+        } else {
+          assertTrue("Expected: " + System.identityHashCode(answer.lastRetValue) + ", actual=" +
+              System.identityHashCode(result), answer.lastRetValue == result);
+        }
+      }
+    }
+
+
+  }
+
+  public static Object[] constructMethodArgs(Method method) throws IllegalAccessException,
+      InstantiationException {
+    Class<?>[] paramTypes = method.getParameterTypes();
+    Object[] params = new Object[paramTypes.length];
+    for (int i = 0; i < paramTypes.length; i++) {
+      params[i] = constructSingleArg(paramTypes[i]);
+    }
+    return params;
+  }
+
+  private static Object constructSingleArg(Class<?> clazz) {
+    if (clazz.isPrimitive() || clazz.equals(String.class)) {
+      return getValueForPrimitiveOrString(clazz);
+    } else if (clazz.isEnum()) {
+      if (clazz.getEnumConstants().length == 0) {
+        return null;
+      } else {
+        return clazz.getEnumConstants()[0];
+      }
+    } else if (clazz.isArray() &&
+        (clazz.getComponentType().isPrimitive() || clazz.getComponentType().equals(String.class))) {
+      // Cannot mock. For now using null. Also does not handle deeply nested arrays.
+      return null;
+    } else {
+      return mock(clazz);
+    }
+  }
+
+  private static Object getValueForPrimitiveOrString(Class<?> clazz) {
+    if (clazz.equals(String.class)) {
+      return "teststring";
+    } else if (clazz.equals(byte.class)) {
+      return 'b';
+    } else if (clazz.equals(short.class)) {
+      return 2;
+    } else if (clazz.equals(int.class)) {
+      return 224;
+    } else if (clazz.equals(long.class)) {
+      return 445l;
+    } else if (clazz.equals(float.class)) {
+      return 2.24f;
+    } else if (clazz.equals(double.class)) {
+      return 4.57d;
+    } else if (clazz.equals(boolean.class)) {
+      return true;
+    } else if (clazz.equals(char.class)) {
+      return 'c';
+    } else if (clazz.equals(void.class)) {
+      return null;
+    } else {
+      throw new RuntimeException("Unrecognized type: " + clazz.getName());
+    }
+  }
+
+  public static class TrackingAnswer implements Answer {
+
+    public String lastMethodName;
+    public Object[] lastArgs;
+    public Object lastRetValue;
+    boolean compareAsPrimitive;
+
+    @Override
+    public Object answer(InvocationOnMock invocation) throws Throwable {
+      lastArgs = invocation.getArguments();
+      lastMethodName = invocation.getMethod().getName();
+      Class<?> retType = invocation.getMethod().getReturnType();
+      lastRetValue = constructSingleArg(retType);
+      compareAsPrimitive = retType.isPrimitive() || retType.isEnum() || retType.equals(String.class);
+
+      return lastRetValue;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorManager.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorManager.java b/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorManager.java
index d1fd4f3..d76a5b3 100644
--- a/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorManager.java
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorManager.java
@@ -21,12 +21,15 @@ import static org.junit.Assert.fail;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import java.io.IOException;
+import java.lang.reflect.Method;
 import java.net.InetSocketAddress;
 import java.nio.ByteBuffer;
 import java.util.HashSet;
@@ -42,6 +45,8 @@ import org.apache.hadoop.security.Credentials;
 import org.apache.hadoop.yarn.api.records.ContainerId;
 import org.apache.hadoop.yarn.api.records.LocalResource;
 import org.apache.hadoop.yarn.api.records.NodeId;
+import org.apache.hadoop.yarn.event.Event;
+import org.apache.hadoop.yarn.event.EventHandler;
 import org.apache.tez.common.TezUtils;
 import org.apache.tez.dag.api.NamedEntityDescriptor;
 import org.apache.tez.dag.api.TaskCommunicator;
@@ -50,6 +55,9 @@ import org.apache.tez.dag.api.TezConstants;
 import org.apache.tez.dag.api.TezException;
 import org.apache.tez.dag.api.UserPayload;
 import org.apache.tez.dag.api.event.VertexStateUpdate;
+import org.apache.tez.dag.app.dag.DAG;
+import org.apache.tez.dag.app.dag.event.DAGAppMasterEventType;
+import org.apache.tez.dag.app.dag.event.DAGAppMasterEventUserServiceFatalError;
 import org.apache.tez.dag.records.TezTaskAttemptID;
 import org.apache.tez.runtime.api.impl.TaskSpec;
 import org.apache.tez.serviceplugins.api.ContainerEndReason;
@@ -57,6 +65,9 @@ import org.apache.tez.serviceplugins.api.TaskAttemptEndReason;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
 
 public class TestTaskCommunicatorManager {
 
@@ -215,8 +226,90 @@ public class TestTaskCommunicatorManager {
 
     } finally {
       tcm.stop();
-      verify(tcm.getTaskCommunicator(0)).shutdown();
-      verify(tcm.getTaskCommunicator(1)).shutdown();
+      verify(tcm.getTaskCommunicator(0).getTaskCommunicator()).shutdown();
+      verify(tcm.getTaskCommunicator(1).getTaskCommunicator()).shutdown();
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  @Test(timeout = 5000)
+  public void testTaskCommunicatorUserError() {
+    TaskCommunicatorContextImpl taskCommContext = mock(TaskCommunicatorContextImpl.class);
+    TaskCommunicator taskCommunicator = mock(TaskCommunicator.class, new ExceptionAnswer());
+    doReturn(taskCommContext).when(taskCommunicator).getContext();
+
+    EventHandler eventHandler = mock(EventHandler.class);
+    AppContext appContext = mock(AppContext.class, RETURNS_DEEP_STUBS);
+
+    when(appContext.getEventHandler()).thenReturn(eventHandler);
+    doReturn("testTaskCommunicator").when(appContext).getTaskCommunicatorName(0);
+    String expectedId = "[0:testTaskCommunicator]";
+
+    Configuration conf = new Configuration(false);
+
+    TaskCommunicatorManager taskCommunicatorManager =
+        new TaskCommunicatorManager(taskCommunicator, appContext, mock(TaskHeartbeatHandler.class),
+            mock(ContainerHeartbeatHandler.class));
+    try {
+      taskCommunicatorManager.init(conf);
+      taskCommunicatorManager.start();
+
+      // Invoking a couple of random methods.
+
+      DAG mockDag = mock(DAG.class, RETURNS_DEEP_STUBS);
+      when(mockDag.getID().getId()).thenReturn(1);
+
+      taskCommunicatorManager.dagComplete(mockDag);
+      ArgumentCaptor<Event> argumentCaptor = ArgumentCaptor.forClass(Event.class);
+      verify(eventHandler, times(1)).handle(argumentCaptor.capture());
+
+      Event rawEvent = argumentCaptor.getValue();
+      assertTrue(rawEvent instanceof DAGAppMasterEventUserServiceFatalError);
+      DAGAppMasterEventUserServiceFatalError event =
+          (DAGAppMasterEventUserServiceFatalError) rawEvent;
+
+      assertEquals(DAGAppMasterEventType.TASK_COMMUNICATOR_SERVICE_FATAL_ERROR, event.getType());
+      assertTrue(event.getError().getMessage().contains("TestException_" + "dagComplete"));
+      assertTrue(event.getDiagnosticInfo().contains("DAG completion"));
+      assertTrue(event.getDiagnosticInfo().contains(expectedId));
+
+
+      when(appContext.getAllContainers().get(any(ContainerId.class)).getContainer().getNodeId())
+          .thenReturn(mock(NodeId.class));
+
+      taskCommunicatorManager.registerRunningContainer(mock(ContainerId.class), 0);
+      argumentCaptor = ArgumentCaptor.forClass(Event.class);
+      verify(eventHandler, times(2)).handle(argumentCaptor.capture());
+
+      rawEvent = argumentCaptor.getAllValues().get(1);
+      assertTrue(rawEvent instanceof DAGAppMasterEventUserServiceFatalError);
+      event = (DAGAppMasterEventUserServiceFatalError) rawEvent;
+
+      assertEquals(DAGAppMasterEventType.TASK_COMMUNICATOR_SERVICE_FATAL_ERROR, event.getType());
+      assertTrue(
+          event.getError().getMessage().contains("TestException_" + "registerRunningContainer"));
+      assertTrue(event.getDiagnosticInfo().contains("registering running Container"));
+      assertTrue(event.getDiagnosticInfo().contains(expectedId));
+
+
+    } finally {
+      taskCommunicatorManager.stop();
+    }
+
+  }
+
+  private static class ExceptionAnswer implements Answer {
+
+    @Override
+    public Object answer(InvocationOnMock invocation) throws Throwable {
+      Method method = invocation.getMethod();
+      if (method.getDeclaringClass().equals(TaskCommunicator.class) &&
+          !method.getName().equals("getContext") && !method.getName().equals("initialize") &&
+          !method.getName().equals("start") && !method.getName().equals("shutdown")) {
+        throw new RuntimeException("TestException_" + method.getName());
+      } else {
+        return invocation.callRealMethod();
+      }
     }
   }
 
@@ -353,7 +446,7 @@ public class TestTaskCommunicatorManager {
     }
 
     @Override
-    public void onVertexStateUpdated(VertexStateUpdate stateUpdate) throws Exception {
+    public void onVertexStateUpdated(VertexStateUpdate stateUpdate) {
 
     }
 

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorManager1.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorManager1.java b/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorManager1.java
index 3f80928..2921a22 100644
--- a/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorManager1.java
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorManager1.java
@@ -169,7 +169,8 @@ public class TestTaskCommunicatorManager1 {
   @Test(timeout = 5000)
   public void testGetTask() throws IOException {
 
-    TezTaskCommunicatorImpl taskCommunicator = (TezTaskCommunicatorImpl)taskAttemptListener.getTaskCommunicator(0);
+    TezTaskCommunicatorImpl taskCommunicator =
+        (TezTaskCommunicatorImpl) taskAttemptListener.getTaskCommunicator(0).getTaskCommunicator();
     TezTaskUmbilicalProtocol tezUmbilical = taskCommunicator.getUmbilical();
 
     ContainerId containerId1 = createContainerId(appId, 1);
@@ -216,7 +217,8 @@ public class TestTaskCommunicatorManager1 {
 
   @Test(timeout = 5000)
   public void testGetTaskMultiplePulls() throws IOException {
-    TezTaskCommunicatorImpl taskCommunicator = (TezTaskCommunicatorImpl)taskAttemptListener.getTaskCommunicator(0);
+    TezTaskCommunicatorImpl taskCommunicator =
+        (TezTaskCommunicatorImpl) taskAttemptListener.getTaskCommunicator(0).getTaskCommunicator();
     TezTaskUmbilicalProtocol tezUmbilical = taskCommunicator.getUmbilical();
 
     ContainerId containerId1 = createContainerId(appId, 1);

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorWrapper.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorWrapper.java b/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorWrapper.java
new file mode 100644
index 0000000..212bca4
--- /dev/null
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorWrapper.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tez.dag.app;
+
+import com.google.common.collect.Sets;
+import org.apache.tez.dag.api.TaskCommunicator;
+import org.junit.Test;
+
+public class TestTaskCommunicatorWrapper {
+
+  @Test(timeout = 5000)
+  public void testDelegation() throws Exception {
+    PluginWrapperTestHelpers.testDelegation(TaskCommunicatorWrapper.class, TaskCommunicator.class,
+        Sets.newHashSet("getTaskCommunicator"));
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/test/java/org/apache/tez/dag/app/dag/impl/TestTaskAttempt.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/dag/impl/TestTaskAttempt.java b/tez-dag/src/test/java/org/apache/tez/dag/app/dag/impl/TestTaskAttempt.java
index 6dd578f..4772492 100644
--- a/tez-dag/src/test/java/org/apache/tez/dag/app/dag/impl/TestTaskAttempt.java
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/dag/impl/TestTaskAttempt.java
@@ -69,6 +69,7 @@ import org.apache.tez.dag.app.ClusterInfo;
 import org.apache.tez.dag.app.ContainerContext;
 import org.apache.tez.dag.app.ContainerHeartbeatHandler;
 import org.apache.tez.dag.app.TaskCommunicatorManagerInterface;
+import org.apache.tez.dag.app.TaskCommunicatorWrapper;
 import org.apache.tez.dag.app.TaskHeartbeatHandler;
 import org.apache.tez.dag.app.dag.Task;
 import org.apache.tez.dag.app.dag.TaskAttemptStateInternal;
@@ -108,6 +109,7 @@ import org.apache.tez.runtime.api.events.TaskStatusUpdateEvent;
 import org.apache.tez.runtime.api.impl.EventMetaData;
 import org.apache.tez.runtime.api.impl.TaskSpec;
 import org.apache.tez.runtime.api.impl.TezEvent;
+import org.apache.tez.serviceplugins.api.ServicePluginException;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -1469,7 +1471,7 @@ public class TestTaskAttempt {
 
   @SuppressWarnings("deprecation")
   @Test(timeout = 5000)
-  public void testKilledInNew() {
+  public void testKilledInNew() throws ServicePluginException {
     ApplicationId appId = ApplicationId.newInstance(1, 2);
     ApplicationAttemptId appAttemptId = ApplicationAttemptId.newInstance(
         appId, 0);
@@ -1609,11 +1611,12 @@ public class TestTaskAttempt {
         new Credentials(), new HashMap<String, String>(), "");
   }
 
-  private TaskCommunicatorManagerInterface createMockTaskAttemptListener() {
+  private TaskCommunicatorManagerInterface createMockTaskAttemptListener() throws
+      ServicePluginException {
     TaskCommunicatorManagerInterface taListener = mock(TaskCommunicatorManagerInterface.class);
     TaskCommunicator taskComm = mock(TaskCommunicator.class);
     doReturn(new InetSocketAddress("localhost", 0)).when(taskComm).getAddress();
-    doReturn(taskComm).when(taListener).getTaskCommunicator(0);
+    doReturn(new TaskCommunicatorWrapper(taskComm)).when(taListener).getTaskCommunicator(0);
     return taListener;
   }
 }

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/test/java/org/apache/tez/dag/app/launcher/TestContainerLauncherManager.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/launcher/TestContainerLauncherManager.java b/tez-dag/src/test/java/org/apache/tez/dag/app/launcher/TestContainerLauncherManager.java
index a8af808..1f75afb 100644
--- a/tez-dag/src/test/java/org/apache/tez/dag/app/launcher/TestContainerLauncherManager.java
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/launcher/TestContainerLauncherManager.java
@@ -19,8 +19,13 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
 import java.io.IOException;
@@ -35,20 +40,27 @@ import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.yarn.api.records.Container;
+import org.apache.hadoop.yarn.api.records.ContainerId;
 import org.apache.hadoop.yarn.api.records.ContainerLaunchContext;
+import org.apache.hadoop.yarn.api.records.NodeId;
+import org.apache.hadoop.yarn.event.Event;
+import org.apache.hadoop.yarn.event.EventHandler;
 import org.apache.tez.common.TezUtils;
 import org.apache.tez.dag.api.NamedEntityDescriptor;
 import org.apache.tez.dag.api.TezConstants;
 import org.apache.tez.dag.api.TezException;
-import org.apache.tez.dag.api.TezReflectionException;
 import org.apache.tez.dag.api.UserPayload;
 import org.apache.tez.dag.app.AppContext;
 import org.apache.tez.dag.app.TaskCommunicatorManagerInterface;
+import org.apache.tez.dag.app.dag.event.DAGAppMasterEventType;
+import org.apache.tez.dag.app.dag.event.DAGAppMasterEventUserServiceFatalError;
 import org.apache.tez.dag.app.rm.ContainerLauncherLaunchRequestEvent;
+import org.apache.tez.dag.app.rm.ContainerLauncherStopRequestEvent;
 import org.apache.tez.serviceplugins.api.ContainerLaunchRequest;
 import org.apache.tez.serviceplugins.api.ContainerLauncher;
 import org.apache.tez.serviceplugins.api.ContainerLauncherContext;
 import org.apache.tez.serviceplugins.api.ContainerStopRequest;
+import org.apache.tez.serviceplugins.api.ServicePluginException;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -58,7 +70,7 @@ public class TestContainerLauncherManager {
 
   @Before
   @After
-  public void reset() {
+  public void resetTest() {
     ContainerLaucherRouterForMultipleLauncherTest.reset();
   }
 
@@ -230,6 +242,73 @@ public class TestContainerLauncherManager {
     }
   }
 
+  @SuppressWarnings("unchecked")
+  @Test(timeout = 5000)
+  public void testContainerLauncherUserError() throws ServicePluginException {
+
+    ContainerLauncher containerLauncher = mock(ContainerLauncher.class);
+
+    EventHandler eventHandler = mock(EventHandler.class);
+    AppContext appContext = mock(AppContext.class);
+    doReturn(eventHandler).when(appContext).getEventHandler();
+    doReturn("testlauncher").when(appContext).getContainerLauncherName(0);
+
+    Configuration conf = new Configuration(false);
+
+    ContainerLauncherManager containerLauncherManager =
+        new ContainerLauncherManager(containerLauncher, appContext);
+    try {
+      containerLauncherManager.init(conf);
+      containerLauncherManager.start();
+
+      // launch container
+      doThrow(new RuntimeException("testexception")).when(containerLauncher)
+          .launchContainer(any(ContainerLaunchRequest.class));
+      ContainerLaunchContext clc1 = mock(ContainerLaunchContext.class);
+      Container container1 = mock(Container.class);
+      ContainerLauncherLaunchRequestEvent launchRequestEvent =
+          new ContainerLauncherLaunchRequestEvent(clc1, container1, 0, 0, 0);
+
+
+      containerLauncherManager.handle(launchRequestEvent);
+
+      ArgumentCaptor<Event> argumentCaptor = ArgumentCaptor.forClass(Event.class);
+      verify(eventHandler, times(1)).handle(argumentCaptor.capture());
+
+      Event rawEvent = argumentCaptor.getValue();
+      assertTrue(rawEvent instanceof DAGAppMasterEventUserServiceFatalError);
+      DAGAppMasterEventUserServiceFatalError event =
+          (DAGAppMasterEventUserServiceFatalError) rawEvent;
+      assertEquals(DAGAppMasterEventType.CONTAINER_LAUNCHER_SERVICE_FATAL_ERROR, event.getType());
+      assertTrue(event.getError().getMessage().contains("testexception"));
+      assertTrue(event.getDiagnosticInfo().contains("launching container"));
+      assertTrue(event.getDiagnosticInfo().contains("[0:testlauncher]"));
+
+      reset(eventHandler);
+      // stop container
+
+      doThrow(new RuntimeException("teststopexception")).when(containerLauncher)
+          .stopContainer(any(ContainerStopRequest.class));
+      ContainerId containerId2 = mock(ContainerId.class);
+      NodeId nodeId2 = mock(NodeId.class);
+      ContainerLauncherStopRequestEvent stopRequestEvent =
+          new ContainerLauncherStopRequestEvent(containerId2, nodeId2, null, 0, 0, 0);
+
+      argumentCaptor = ArgumentCaptor.forClass(Event.class);
+
+      containerLauncherManager.handle(stopRequestEvent);
+      verify(eventHandler, times(1)).handle(argumentCaptor.capture());
+      rawEvent = argumentCaptor.getValue();
+      assertTrue(rawEvent instanceof DAGAppMasterEventUserServiceFatalError);
+      event = (DAGAppMasterEventUserServiceFatalError) rawEvent;
+      assertTrue(event.getError().getMessage().contains("teststopexception"));
+      assertTrue(event.getDiagnosticInfo().contains("stopping container"));
+      assertTrue(event.getDiagnosticInfo().contains("[0:testlauncher]"));
+    } finally {
+      containerLauncherManager.stop();
+    }
+  }
+
   private static class ContainerLaucherRouterForMultipleLauncherTest
       extends ContainerLauncherManager {
 

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/test/java/org/apache/tez/dag/app/launcher/TestContainerLauncherWrapper.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/launcher/TestContainerLauncherWrapper.java b/tez-dag/src/test/java/org/apache/tez/dag/app/launcher/TestContainerLauncherWrapper.java
new file mode 100644
index 0000000..d786bf9
--- /dev/null
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/launcher/TestContainerLauncherWrapper.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tez.dag.app.launcher;
+
+import com.google.common.collect.Sets;
+import org.apache.tez.dag.app.PluginWrapperTestHelpers;
+import org.apache.tez.serviceplugins.api.ContainerLauncher;
+import org.junit.Test;
+
+public class TestContainerLauncherWrapper {
+
+  @Test(timeout = 5000)
+  public void testDelegation() throws Exception {
+    PluginWrapperTestHelpers.testDelegation(ContainerLauncherWrapper.class, ContainerLauncher.class,
+        Sets.newHashSet("getContainerLauncher"));
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestContainerReuse.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestContainerReuse.java b/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestContainerReuse.java
index 0e90681..78dc8fd 100644
--- a/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestContainerReuse.java
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestContainerReuse.java
@@ -1407,8 +1407,12 @@ public class TestContainerReuse {
   private void verifyDeAllocateTask(TaskScheduler taskScheduler, Object ta, boolean taskSucceeded,
                                     TaskAttemptEndReason endReason, String diagContains) {
     ArgumentCaptor<String> argumentCaptor = ArgumentCaptor.forClass(String.class);
-    verify(taskScheduler)
-        .deallocateTask(eq(ta), eq(taskSucceeded), eq(endReason), argumentCaptor.capture());
+    try {
+      verify(taskScheduler)
+          .deallocateTask(eq(ta), eq(taskSucceeded), eq(endReason), argumentCaptor.capture());
+    } catch (Exception e) {
+      throw new RuntimeException(e);
+    }
     assertEquals(1, argumentCaptor.getAllValues().size());
     if (diagContains == null) {
       assertNull(argumentCaptor.getValue());

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestTaskSchedulerHelpers.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestTaskSchedulerHelpers.java b/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestTaskSchedulerHelpers.java
index 8b489ea..b54d024 100644
--- a/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestTaskSchedulerHelpers.java
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestTaskSchedulerHelpers.java
@@ -157,13 +157,15 @@ class TestTaskSchedulerHelpers {
           new TaskSchedulerContextImplWrapper(taskSchedulerContext,
               new CountingExecutorService(appCallbackExecutor));
       TaskSchedulerContextDrainable drainable = new TaskSchedulerContextDrainable(wrapper);
-      taskSchedulers[0] =
-          new TaskSchedulerWithDrainableContext(drainable, amrmClientAsync);
-      taskSchedulerServiceWrappers[0] = new ServicePluginLifecycleAbstractService(taskSchedulers[0]);
+
+      taskSchedulers[0] = new TaskSchedulerWrapper(
+          new TaskSchedulerWithDrainableContext(drainable, amrmClientAsync));
+      taskSchedulerServiceWrappers[0] =
+          new ServicePluginLifecycleAbstractService(taskSchedulers[0].getTaskScheduler());
     }
 
     public TaskScheduler getSpyTaskScheduler() {
-      return taskSchedulers[0];
+      return taskSchedulers[0].getTaskScheduler();
     }
 
     @Override
@@ -172,7 +174,9 @@ class TestTaskSchedulerHelpers {
       // Init the service so that reuse configuration is picked up.
       ((AbstractService)taskSchedulerServiceWrappers[0]).init(getConfig());
       ((AbstractService)taskSchedulerServiceWrappers[0]).start();
-      taskSchedulers[0] = spy(taskSchedulers[0]);
+      // For some reason, the spy needs to be setup after sertvice startup.
+      taskSchedulers[0] = new TaskSchedulerWrapper(spy(taskSchedulers[0].getTaskScheduler()));
+
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestTaskSchedulerManager.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestTaskSchedulerManager.java b/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestTaskSchedulerManager.java
index 8e4e4f0..c649870 100644
--- a/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestTaskSchedulerManager.java
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestTaskSchedulerManager.java
@@ -34,6 +34,7 @@ import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import java.io.IOException;
+import java.lang.reflect.Method;
 import java.net.InetSocketAddress;
 import java.nio.ByteBuffer;
 import java.util.HashMap;
@@ -41,6 +42,7 @@ import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
+import java.util.concurrent.Executors;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -60,6 +62,7 @@ import org.apache.hadoop.yarn.event.EventHandler;
 import org.apache.tez.common.ContainerSignatureMatcher;
 import org.apache.tez.common.TezUtils;
 import org.apache.tez.dag.api.NamedEntityDescriptor;
+import org.apache.tez.dag.api.TaskCommunicator;
 import org.apache.tez.dag.api.TaskLocationHint;
 import org.apache.tez.dag.api.TezConfiguration;
 import org.apache.tez.dag.api.TezConstants;
@@ -68,8 +71,13 @@ import org.apache.tez.dag.api.UserPayload;
 import org.apache.tez.dag.api.client.DAGClientServer;
 import org.apache.tez.dag.app.AppContext;
 import org.apache.tez.dag.app.ContainerContext;
+import org.apache.tez.dag.app.ContainerHeartbeatHandler;
 import org.apache.tez.dag.app.ServicePluginLifecycleAbstractService;
+import org.apache.tez.dag.app.TaskCommunicatorManager;
+import org.apache.tez.dag.app.TaskHeartbeatHandler;
 import org.apache.tez.dag.app.dag.TaskAttempt;
+import org.apache.tez.dag.app.dag.event.DAGAppMasterEventType;
+import org.apache.tez.dag.app.dag.event.DAGAppMasterEventUserServiceFatalError;
 import org.apache.tez.dag.app.dag.impl.TaskAttemptImpl;
 import org.apache.tez.dag.app.dag.impl.TaskImpl;
 import org.apache.tez.dag.app.dag.impl.VertexImpl;
@@ -86,6 +94,7 @@ import org.apache.tez.dag.records.TezTaskAttemptID;
 import org.apache.tez.dag.records.TezTaskID;
 import org.apache.tez.dag.records.TezVertexID;
 import org.apache.tez.runtime.api.impl.TaskSpec;
+import org.apache.tez.serviceplugins.api.ServicePluginException;
 import org.apache.tez.serviceplugins.api.TaskAttemptEndReason;
 import org.apache.tez.serviceplugins.api.TaskScheduler;
 import org.apache.tez.serviceplugins.api.TaskSchedulerContext;
@@ -94,6 +103,9 @@ import org.junit.Before;
 import org.junit.Test;
 
 import com.google.common.collect.Lists;
+import org.mockito.ArgumentCaptor;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
 
 @SuppressWarnings("rawtypes")
 public class TestTaskSchedulerManager {
@@ -121,8 +133,9 @@ public class TestTaskSchedulerManager {
     @Override
     protected void instantiateSchedulers(String host, int port, String trackingUrl,
                                          AppContext appContext) {
-      taskSchedulers[0] = mockTaskScheduler;
-      taskSchedulerServiceWrappers[0] = new ServicePluginLifecycleAbstractService<>(taskSchedulers[0]);
+      taskSchedulers[0] = new TaskSchedulerWrapper(mockTaskScheduler);
+      taskSchedulerServiceWrappers[0] =
+          new ServicePluginLifecycleAbstractService<>(taskSchedulers[0].getTaskScheduler());
     }
     
     @Override
@@ -272,7 +285,7 @@ public class TestTaskSchedulerManager {
   }
   
   @Test (timeout = 5000)
-  public void testContainerInternalPreempted() throws IOException {
+  public void testContainerInternalPreempted() throws IOException, ServicePluginException {
     Configuration conf = new Configuration(false);
     schedulerHandler.init(conf);
     schedulerHandler.start();
@@ -533,6 +546,93 @@ public class TestTaskSchedulerManager {
         eq(launchRequest2));
   }
 
+  @SuppressWarnings("unchecked")
+  @Test(timeout = 5000)
+  public void testTaskSchedulerUserError() {
+    TaskScheduler taskScheduler = mock(TaskScheduler.class, new ExceptionAnswer());
+
+    EventHandler eventHandler = mock(EventHandler.class);
+    AppContext appContext = mock(AppContext.class, RETURNS_DEEP_STUBS);
+
+    when(appContext.getEventHandler()).thenReturn(eventHandler);
+    doReturn("testTaskScheduler").when(appContext).getTaskSchedulerName(0);
+    String expectedId = "[0:testTaskScheduler]";
+
+    Configuration conf = new Configuration(false);
+
+    InetSocketAddress address = new InetSocketAddress(15222);
+    DAGClientServer mockClientService = mock(DAGClientServer.class);
+    doReturn(address).when(mockClientService).getBindAddress();
+    TaskSchedulerManager taskSchedulerManager =
+        new TaskSchedulerManager(taskScheduler, appContext, mock(ContainerSignatureMatcher.class),
+            mockClientService,
+            Executors.newFixedThreadPool(1)) {
+          @Override
+          protected void instantiateSchedulers(String host, int port, String trackingUrl,
+                                               AppContext appContext) throws TezException {
+            // Stubbed out since these are setup up front in the constructor used for testing
+          }
+        };
+
+    try {
+      taskSchedulerManager.init(conf);
+      taskSchedulerManager.start();
+
+      // Invoking a couple of random methods
+
+      AMSchedulerEventTALaunchRequest launchRequest =
+          new AMSchedulerEventTALaunchRequest(mock(TezTaskAttemptID.class), mock(Resource.class),
+              mock(TaskSpec.class), mock(TaskAttempt.class), mock(TaskLocationHint.class), 0,
+              mock(ContainerContext.class), 0, 0, 0);
+      taskSchedulerManager.handleEvent(launchRequest);
+
+      ArgumentCaptor<Event> argumentCaptor = ArgumentCaptor.forClass(Event.class);
+
+      verify(eventHandler, times(1)).handle(argumentCaptor.capture());
+
+      Event rawEvent = argumentCaptor.getValue();
+      assertTrue(rawEvent instanceof DAGAppMasterEventUserServiceFatalError);
+      DAGAppMasterEventUserServiceFatalError event =
+          (DAGAppMasterEventUserServiceFatalError) rawEvent;
+
+      assertEquals(DAGAppMasterEventType.TASK_SCHEDULER_SERVICE_FATAL_ERROR, event.getType());
+      assertTrue(event.getError().getMessage().contains("TestException_" + "allocateTask"));
+      assertTrue(event.getDiagnosticInfo().contains("Task Allocation"));
+      assertTrue(event.getDiagnosticInfo().contains(expectedId));
+
+
+      taskSchedulerManager.dagCompleted();
+      argumentCaptor = ArgumentCaptor.forClass(Event.class);
+      verify(eventHandler, times(2)).handle(argumentCaptor.capture());
+
+      rawEvent = argumentCaptor.getAllValues().get(1);
+      assertTrue(rawEvent instanceof DAGAppMasterEventUserServiceFatalError);
+      event = (DAGAppMasterEventUserServiceFatalError) rawEvent;
+
+      assertEquals(DAGAppMasterEventType.TASK_SCHEDULER_SERVICE_FATAL_ERROR, event.getType());
+      assertTrue(event.getError().getMessage().contains("TestException_" + "dagComplete"));
+      assertTrue(event.getDiagnosticInfo().contains("Dag Completion"));
+      assertTrue(event.getDiagnosticInfo().contains(expectedId));
+
+    } finally {
+      taskSchedulerManager.stop();
+    }
+  }
+
+  private static class ExceptionAnswer implements Answer {
+    @Override
+    public Object answer(InvocationOnMock invocation) throws Throwable {
+      Method method = invocation.getMethod();
+      if (method.getDeclaringClass().equals(TaskScheduler.class) &&
+          !method.getName().equals("getContext") && !method.getName().equals("initialize") &&
+          !method.getName().equals("start") && !method.getName().equals("shutdown")) {
+        throw new RuntimeException("TestException_" + method.getName());
+      } else {
+        return invocation.callRealMethod();
+      }
+    }
+  }
+
   public static class TSEHForMultipleSchedulersTest extends TaskSchedulerManager {
 
     private final TaskScheduler yarnTaskScheduler;

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestTaskSchedulerWrapper.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestTaskSchedulerWrapper.java b/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestTaskSchedulerWrapper.java
new file mode 100644
index 0000000..cd8a496
--- /dev/null
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestTaskSchedulerWrapper.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tez.dag.app.rm;
+
+import com.google.common.collect.Sets;
+import org.apache.tez.dag.app.PluginWrapperTestHelpers;
+import org.apache.tez.serviceplugins.api.TaskScheduler;
+import org.junit.Test;
+
+public class TestTaskSchedulerWrapper {
+
+  @Test(timeout = 5000)
+  public void testDelegation() throws Exception {
+    PluginWrapperTestHelpers.testDelegation(TaskSchedulerWrapper.class, TaskScheduler.class,
+        Sets.newHashSet("getTaskScheduler"));
+  }
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/test/java/org/apache/tez/dag/app/rm/container/TestAMContainer.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/rm/container/TestAMContainer.java b/tez-dag/src/test/java/org/apache/tez/dag/app/rm/container/TestAMContainer.java
index cc88f0d..8b8b6d7 100644
--- a/tez-dag/src/test/java/org/apache/tez/dag/app/rm/container/TestAMContainer.java
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/rm/container/TestAMContainer.java
@@ -63,7 +63,9 @@ import org.apache.hadoop.yarn.event.EventHandler;
 import org.apache.hadoop.yarn.util.SystemClock;
 import org.apache.tez.common.security.JobTokenIdentifier;
 import org.apache.tez.common.security.TokenCache;
+import org.apache.tez.dag.app.TaskCommunicatorWrapper;
 import org.apache.tez.serviceplugins.api.ContainerEndReason;
+import org.apache.tez.serviceplugins.api.ServicePluginException;
 import org.apache.tez.serviceplugins.api.TaskAttemptEndReason;
 import org.apache.tez.dag.api.TaskCommunicator;
 import org.apache.tez.dag.app.AppContext;
@@ -1228,8 +1230,12 @@ public class TestAMContainer {
 
       tal = mock(TaskCommunicatorManagerInterface.class);
       TaskCommunicator taskComm = mock(TaskCommunicator.class);
-      doReturn(new InetSocketAddress("localhost", 0)).when(taskComm).getAddress();
-      doReturn(taskComm).when(tal).getTaskCommunicator(0);
+      try {
+        doReturn(new InetSocketAddress("localhost", 0)).when(taskComm).getAddress();
+      } catch (ServicePluginException e) {
+        throw new RuntimeException(e);
+      }
+      doReturn(new TaskCommunicatorWrapper(taskComm)).when(tal).getTaskCommunicator(0);
 
       dagID = TezDAGID.getInstance(applicationID, 1);
       vertexID = TezVertexID.getInstance(dagID, 1);

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-dag/src/test/java/org/apache/tez/dag/app/rm/container/TestAMContainerMap.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/rm/container/TestAMContainerMap.java b/tez-dag/src/test/java/org/apache/tez/dag/app/rm/container/TestAMContainerMap.java
index 31d756c..e21dda1 100644
--- a/tez-dag/src/test/java/org/apache/tez/dag/app/rm/container/TestAMContainerMap.java
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/rm/container/TestAMContainerMap.java
@@ -35,6 +35,7 @@ import org.apache.tez.dag.api.TaskCommunicator;
 import org.apache.tez.dag.app.AppContext;
 import org.apache.tez.dag.app.ContainerHeartbeatHandler;
 import org.apache.tez.dag.app.TaskCommunicatorManagerInterface;
+import org.apache.tez.serviceplugins.api.ServicePluginException;
 
 public class TestAMContainerMap {
 
@@ -42,7 +43,7 @@ public class TestAMContainerMap {
     return mock(ContainerHeartbeatHandler.class);
   }
 
-  private TaskCommunicatorManagerInterface mockTaskAttemptListener() {
+  private TaskCommunicatorManagerInterface mockTaskAttemptListener() throws ServicePluginException {
     TaskCommunicatorManagerInterface tal = mock(TaskCommunicatorManagerInterface.class);
     TaskCommunicator taskComm = mock(TaskCommunicator.class);
     doReturn(new InetSocketAddress("localhost", 21000)).when(taskComm).getAddress();

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-examples/src/main/java/org/apache/tez/examples/JoinValidate.java
----------------------------------------------------------------------
diff --git a/tez-examples/src/main/java/org/apache/tez/examples/JoinValidate.java b/tez-examples/src/main/java/org/apache/tez/examples/JoinValidate.java
index 186bacd..f9358bf 100644
--- a/tez-examples/src/main/java/org/apache/tez/examples/JoinValidate.java
+++ b/tez-examples/src/main/java/org/apache/tez/examples/JoinValidate.java
@@ -21,6 +21,7 @@ package org.apache.tez.examples;
 import java.io.IOException;
 import java.util.Set;
 
+import com.google.common.annotations.VisibleForTesting;
 import org.apache.tez.dag.api.Vertex.VertexExecutionContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -134,7 +135,8 @@ public class JoinValidate extends TezExampleBase {
     return 0;
   }
 
-  private DAG createDag(TezConfiguration tezConf, Path lhs, Path rhs, int numPartitions)
+  @VisibleForTesting
+  DAG createDag(TezConfiguration tezConf, Path lhs, Path rhs, int numPartitions)
       throws IOException {
     DAG dag = DAG.create(getDagName());
     if (getDefaultExecutionContext() != null) {

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-ext-service-tests/src/test/java/org/apache/tez/dag/app/launcher/TezTestServiceContainerLauncherWithErrors.java
----------------------------------------------------------------------
diff --git a/tez-ext-service-tests/src/test/java/org/apache/tez/dag/app/launcher/TezTestServiceContainerLauncherWithErrors.java b/tez-ext-service-tests/src/test/java/org/apache/tez/dag/app/launcher/TezTestServiceContainerLauncherWithErrors.java
new file mode 100644
index 0000000..d489cca
--- /dev/null
+++ b/tez-ext-service-tests/src/test/java/org/apache/tez/dag/app/launcher/TezTestServiceContainerLauncherWithErrors.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tez.dag.app.launcher;
+
+import org.apache.tez.serviceplugins.api.ContainerLaunchRequest;
+import org.apache.tez.serviceplugins.api.ContainerLauncher;
+import org.apache.tez.serviceplugins.api.ContainerLauncherContext;
+import org.apache.tez.serviceplugins.api.ContainerStopRequest;
+
+public class TezTestServiceContainerLauncherWithErrors extends ContainerLauncher {
+  public TezTestServiceContainerLauncherWithErrors(
+      ContainerLauncherContext containerLauncherContext) {
+    super(containerLauncherContext);
+  }
+
+  @Override
+  public void launchContainer(ContainerLaunchRequest launchRequest) {
+    throw new RuntimeException("Simulated Error");
+  }
+
+  @Override
+  public void stopContainer(ContainerStopRequest stopRequest) {
+    throw new RuntimeException("Simulated Error");
+  }
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-ext-service-tests/src/test/java/org/apache/tez/dag/app/rm/TezTestServiceTaskSchedulerServiceWithErrors.java
----------------------------------------------------------------------
diff --git a/tez-ext-service-tests/src/test/java/org/apache/tez/dag/app/rm/TezTestServiceTaskSchedulerServiceWithErrors.java b/tez-ext-service-tests/src/test/java/org/apache/tez/dag/app/rm/TezTestServiceTaskSchedulerServiceWithErrors.java
new file mode 100644
index 0000000..1705eac
--- /dev/null
+++ b/tez-ext-service-tests/src/test/java/org/apache/tez/dag/app/rm/TezTestServiceTaskSchedulerServiceWithErrors.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tez.dag.app.rm;
+
+import javax.annotation.Nullable;
+
+import org.apache.hadoop.yarn.api.records.ContainerId;
+import org.apache.hadoop.yarn.api.records.NodeId;
+import org.apache.hadoop.yarn.api.records.Priority;
+import org.apache.hadoop.yarn.api.records.Resource;
+import org.apache.tez.serviceplugins.api.TaskAttemptEndReason;
+import org.apache.tez.serviceplugins.api.TaskScheduler;
+import org.apache.tez.serviceplugins.api.TaskSchedulerContext;
+
+public class TezTestServiceTaskSchedulerServiceWithErrors extends TaskScheduler {
+  public TezTestServiceTaskSchedulerServiceWithErrors(
+      TaskSchedulerContext taskSchedulerContext) {
+    super(taskSchedulerContext);
+  }
+
+  @Override
+  public Resource getAvailableResources() {
+    return Resource.newInstance(2048, 2);
+  }
+
+  @Override
+  public Resource getTotalResources() {
+    return Resource.newInstance(2048, 2);
+  }
+
+  @Override
+  public int getClusterNodeCount() {
+    return 1;
+  }
+
+  @Override
+  public void blacklistNode(NodeId nodeId) {
+    throw new RuntimeException("Simulated Error");
+  }
+
+  @Override
+  public void unblacklistNode(NodeId nodeId) {
+    throw new RuntimeException("Simulated Error");
+  }
+
+  @Override
+  public void allocateTask(Object task, Resource capability, String[] hosts, String[] racks,
+                           Priority priority, Object containerSignature, Object clientCookie) {
+    throw new RuntimeException("Simulated Error");
+  }
+
+  @Override
+  public void allocateTask(Object task, Resource capability, ContainerId containerId,
+                           Priority priority, Object containerSignature, Object clientCookie) {
+    throw new RuntimeException("Simulated Error");
+  }
+
+  @Override
+  public boolean deallocateTask(Object task, boolean taskSucceeded, TaskAttemptEndReason endReason,
+                                @Nullable String diagnostics) {
+    throw new RuntimeException("Simulated Error");
+  }
+
+  @Override
+  public Object deallocateContainer(ContainerId containerId) {
+    throw new RuntimeException("Simulated Error");
+  }
+
+  @Override
+  public void setShouldUnregister() {
+  }
+
+  @Override
+  public boolean hasUnregistered() {
+    return false;
+  }
+
+  @Override
+  public void dagComplete() {
+  }
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-ext-service-tests/src/test/java/org/apache/tez/dag/app/taskcomm/TezTestServiceTaskCommunicatorWithErrors.java
----------------------------------------------------------------------
diff --git a/tez-ext-service-tests/src/test/java/org/apache/tez/dag/app/taskcomm/TezTestServiceTaskCommunicatorWithErrors.java b/tez-ext-service-tests/src/test/java/org/apache/tez/dag/app/taskcomm/TezTestServiceTaskCommunicatorWithErrors.java
new file mode 100644
index 0000000..0a3d8d4
--- /dev/null
+++ b/tez-ext-service-tests/src/test/java/org/apache/tez/dag/app/taskcomm/TezTestServiceTaskCommunicatorWithErrors.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tez.dag.app.taskcomm;
+
+import javax.annotation.Nullable;
+import java.net.InetSocketAddress;
+import java.util.Map;
+
+import org.apache.hadoop.net.NetUtils;
+import org.apache.hadoop.security.Credentials;
+import org.apache.hadoop.yarn.api.records.ContainerId;
+import org.apache.hadoop.yarn.api.records.LocalResource;
+import org.apache.tez.dag.api.TaskCommunicator;
+import org.apache.tez.dag.api.TaskCommunicatorContext;
+import org.apache.tez.dag.api.event.VertexStateUpdate;
+import org.apache.tez.dag.records.TezTaskAttemptID;
+import org.apache.tez.runtime.api.impl.TaskSpec;
+import org.apache.tez.serviceplugins.api.ContainerEndReason;
+import org.apache.tez.serviceplugins.api.TaskAttemptEndReason;
+
+public class TezTestServiceTaskCommunicatorWithErrors extends TaskCommunicator {
+  public TezTestServiceTaskCommunicatorWithErrors(
+      TaskCommunicatorContext taskCommunicatorContext) {
+    super(taskCommunicatorContext);
+  }
+
+  @Override
+  public void registerRunningContainer(ContainerId containerId, String hostname, int port) {
+    throw new RuntimeException("Simulated Error");
+  }
+
+  @Override
+  public void registerContainerEnd(ContainerId containerId, ContainerEndReason endReason,
+                                   @Nullable String diagnostics) {
+    throw new RuntimeException("Simulated Error");
+  }
+
+  @Override
+  public void registerRunningTaskAttempt(ContainerId containerId, TaskSpec taskSpec,
+                                         Map<String, LocalResource> additionalResources,
+                                         Credentials credentials, boolean credentialsChanged,
+                                         int priority) {
+    throw new RuntimeException("Simulated Error");
+  }
+
+  @Override
+  public void unregisterRunningTaskAttempt(TezTaskAttemptID taskAttemptID,
+                                           TaskAttemptEndReason endReason,
+                                           @Nullable String diagnostics) {
+    throw new RuntimeException("Simulated Error");
+  }
+
+  @Override
+  public InetSocketAddress getAddress() {
+    return NetUtils.createSocketAddrForHost("localhost", 0);
+  }
+
+  @Override
+  public void onVertexStateUpdated(VertexStateUpdate stateUpdate) {
+    throw new RuntimeException("Simulated Error");
+  }
+
+  @Override
+  public void dagComplete(int dagIdentifier) {
+  }
+
+  @Override
+  public Object getMetaInfo() {
+    throw new RuntimeException("Simulated Error");
+  }
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/1d765431/tez-ext-service-tests/src/test/java/org/apache/tez/examples/JoinValidateConfigured.java
----------------------------------------------------------------------
diff --git a/tez-ext-service-tests/src/test/java/org/apache/tez/examples/JoinValidateConfigured.java b/tez-ext-service-tests/src/test/java/org/apache/tez/examples/JoinValidateConfigured.java
index f31476f..64b9063 100644
--- a/tez-ext-service-tests/src/test/java/org/apache/tez/examples/JoinValidateConfigured.java
+++ b/tez-ext-service-tests/src/test/java/org/apache/tez/examples/JoinValidateConfigured.java
@@ -15,6 +15,11 @@
 package org.apache.tez.examples;
 
 
+import java.io.IOException;
+
+import org.apache.hadoop.fs.Path;
+import org.apache.tez.dag.api.DAG;
+import org.apache.tez.dag.api.TezConfiguration;
 import org.apache.tez.dag.api.Vertex.VertexExecutionContext;
 
 public class JoinValidateConfigured extends JoinValidate {
@@ -60,4 +65,9 @@ public class JoinValidateConfigured extends JoinValidate {
   protected String getDagName() {
     return "JoinValidate_" + dagNameSuffix;
   }
+
+  public DAG createDag(TezConfiguration tezConf, Path lhs, Path rhs, int numPartitions)
+      throws IOException {
+    return super.createDag(tezConf, lhs, rhs, numPartitions);
+  }
 }


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

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


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

Branch: refs/heads/TEZ-2980
Commit: 7a9f38bcef3cb3139f36fd13f150a27cefd0ecab
Parents: 31baf3c
Author: Siddharth Seth <ss...@apache.org>
Authored: Mon Jan 4 13:34:19 2016 -0800
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Wed Jan 20 22:30:06 2016 +0530

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


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


[06/50] [abbrv] tez git commit: TEZ-2914. Ability to limit vertex concurrency (bikas)

Posted by sr...@apache.org.
TEZ-2914. Ability to limit vertex concurrency (bikas)


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

Branch: refs/heads/TEZ-2980
Commit: 34eb75d709bbe6e0417f9b4023f4fa1cec81bd8b
Parents: 12bd908
Author: Bikas Saha <bi...@apache.org>
Authored: Fri Dec 25 19:39:04 2015 -0800
Committer: Bikas Saha <bi...@apache.org>
Committed: Fri Dec 25 19:39:04 2015 -0800

----------------------------------------------------------------------
 CHANGES.txt                                     |   1 +
 .../apache/tez/dag/api/TezConfiguration.java    |  12 +-
 .../apache/tez/dag/app/dag/DAGScheduler.java    |  68 +++++++++-
 .../java/org/apache/tez/dag/app/dag/Vertex.java |   2 +-
 .../app/dag/event/DAGEventSchedulerUpdate.java  |   3 +-
 .../DAGEventSchedulerUpdateTAAssigned.java      |  36 ------
 .../apache/tez/dag/app/dag/impl/DAGImpl.java    |  17 +--
 .../app/dag/impl/DAGSchedulerNaturalOrder.java  |  15 +--
 .../DAGSchedulerNaturalOrderControlled.java     |  15 +--
 .../apache/tez/dag/app/dag/impl/TaskImpl.java   |  43 ++-----
 .../apache/tez/dag/app/dag/impl/VertexImpl.java |   6 +
 .../tez/dag/app/rm/TaskSchedulerManager.java    |   2 -
 .../apache/tez/dag/app/MockDAGAppMaster.java    |  13 +-
 .../tez/dag/app/TestMockDAGAppMaster.java       |  50 ++++++++
 .../tez/dag/app/dag/impl/TestDAGImpl.java       |   4 -
 .../tez/dag/app/dag/impl/TestDAGScheduler.java  | 127 ++++++++++++++++++-
 .../TestDAGSchedulerNaturalOrderControlled.java |  38 +++---
 .../dag/app/rm/TestTaskSchedulerManager.java    |   6 +-
 18 files changed, 306 insertions(+), 152 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/34eb75d7/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index a3b0fa6..25cfd86 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -11,6 +11,7 @@ INCOMPATIBLE CHANGES
   TEZ-2972. Avoid task rescheduling when a node turns unhealthy
 
 ALL CHANGES:
+  TEZ-2914. Ability to limit vertex concurrency
   TEZ-3011. Link Vertex Name in Dag Tasks/Task Attempts to Vertex
   TEZ-3006. Remove unused import in TestHistoryParser.
   TEZ-2910. Set caller context for tracing ( integrate with HDFS-9184 ).

http://git-wip-us.apache.org/repos/asf/tez/blob/34eb75d7/tez-api/src/main/java/org/apache/tez/dag/api/TezConfiguration.java
----------------------------------------------------------------------
diff --git a/tez-api/src/main/java/org/apache/tez/dag/api/TezConfiguration.java b/tez-api/src/main/java/org/apache/tez/dag/api/TezConfiguration.java
index b707857..9f7777f 100644
--- a/tez-api/src/main/java/org/apache/tez/dag/api/TezConfiguration.java
+++ b/tez-api/src/main/java/org/apache/tez/dag/api/TezConfiguration.java
@@ -537,7 +537,17 @@ public class TezConfiguration extends Configuration {
   public static final String TEZ_AM_MAX_APP_ATTEMPTS = TEZ_AM_PREFIX +
       "max.app.attempts";
   public static final int TEZ_AM_MAX_APP_ATTEMPTS_DEFAULT = 2;
-  
+
+  /**
+   * Int value. The maximum number of attempts that can run concurrently for a given vertex.
+   * Setting <=0 implies no limit
+   */
+  @ConfigurationScope(Scope.VERTEX)
+  @ConfigurationProperty(type="integer")
+  public static final String TEZ_AM_VERTEX_MAX_TASK_CONCURRENCY =
+      TEZ_AM_PREFIX + "vertex.max-task-concurrency";
+  public static final int TEZ_AM_VERTEX_MAX_TASK_CONCURRENCY_DEFAULT = -1;
+
   /**
    * Int value. The maximum number of attempts that can fail for a particular task before the task is failed. 
    * This does not count killed attempts. Task failure results in DAG failure.

http://git-wip-us.apache.org/repos/asf/tez/blob/34eb75d7/tez-dag/src/main/java/org/apache/tez/dag/app/dag/DAGScheduler.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/DAGScheduler.java b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/DAGScheduler.java
index 2d3b006..87a6261 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/DAGScheduler.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/DAGScheduler.java
@@ -18,16 +18,70 @@
 
 package org.apache.tez.dag.app.dag;
 
+import java.util.Map;
+import java.util.Queue;
+
 import org.apache.tez.dag.app.dag.event.DAGEventSchedulerUpdate;
-import org.apache.tez.dag.app.dag.event.DAGEventSchedulerUpdateTAAssigned;
+import org.apache.tez.dag.records.TezVertexID;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
 
-public interface DAGScheduler {
+public abstract class DAGScheduler {
+  private static class VertexInfo {
+    int concurrencyLimit;
+    int concurrency;
+    Queue<DAGEventSchedulerUpdate> pendingAttempts = Lists.newLinkedList();
+    
+    VertexInfo(int limit) {
+      this.concurrencyLimit = limit;
+    }
+  }
   
-  public void vertexCompleted(Vertex vertex);
+  Map<TezVertexID, VertexInfo> vertexInfo = null;
   
-  public void scheduleTask(DAGEventSchedulerUpdate event);
+  public void addVertexConcurrencyLimit(TezVertexID vId, int concurrency) {
+    if (vertexInfo == null) {
+      vertexInfo = Maps.newHashMap();
+    }
+    if (concurrency > 0) {
+      vertexInfo.put(vId, new VertexInfo(concurrency));
+    }
+  }
   
-  public void taskScheduled(DAGEventSchedulerUpdateTAAssigned event);
-
-  public void taskSucceeded(DAGEventSchedulerUpdate event);
+  public void scheduleTask(DAGEventSchedulerUpdate event) {
+    VertexInfo vInfo = null;
+    if (vertexInfo != null) {
+      vInfo = vertexInfo.get(event.getAttempt().getID().getTaskID().getVertexID());
+    }
+    scheduleTaskWithLimit(event, vInfo);
+  }
+  
+  private void scheduleTaskWithLimit(DAGEventSchedulerUpdate event, VertexInfo vInfo) {
+    if (vInfo != null) {
+      if (vInfo.concurrency >= vInfo.concurrencyLimit) {
+        vInfo.pendingAttempts.add(event);
+        return; // already at max concurrency
+      }
+      vInfo.concurrency++;
+    }
+    scheduleTaskEx(event);
+  }
+  
+  public void taskCompleted(DAGEventSchedulerUpdate event) {
+    taskCompletedEx(event);
+    if (vertexInfo != null) {
+      VertexInfo vInfo = vertexInfo.get(event.getAttempt().getID().getTaskID().getVertexID());
+      if (vInfo != null) {
+        vInfo.concurrency--;
+        if (!vInfo.pendingAttempts.isEmpty()) {
+          scheduleTaskWithLimit(vInfo.pendingAttempts.poll(), vInfo);
+        }
+      }
+    }
+  }
+  
+  public abstract void scheduleTaskEx(DAGEventSchedulerUpdate event);
+  
+  public abstract void taskCompletedEx(DAGEventSchedulerUpdate event);
 }

http://git-wip-us.apache.org/repos/asf/tez/blob/34eb75d7/tez-dag/src/main/java/org/apache/tez/dag/app/dag/Vertex.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/Vertex.java b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/Vertex.java
index 9fc73a2..54f2ffa 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/Vertex.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/Vertex.java
@@ -85,7 +85,7 @@ public interface Vertex extends Comparable<Vertex> {
    */
   TezCounters getCachedCounters();
 
-
+  int getMaxTaskConcurrency();
   Map<TezTaskID, Task> getTasks();
   Task getTask(TezTaskID taskID);
   Task getTask(int taskIndex);

http://git-wip-us.apache.org/repos/asf/tez/blob/34eb75d7/tez-dag/src/main/java/org/apache/tez/dag/app/dag/event/DAGEventSchedulerUpdate.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/event/DAGEventSchedulerUpdate.java b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/event/DAGEventSchedulerUpdate.java
index a436a8c..eda02b5 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/event/DAGEventSchedulerUpdate.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/event/DAGEventSchedulerUpdate.java
@@ -24,8 +24,7 @@ public class DAGEventSchedulerUpdate extends DAGEvent {
   
   public enum UpdateType {
     TA_SCHEDULE,
-    TA_SCHEDULED,
-    TA_SUCCEEDED
+    TA_COMPLETED
   }
   
   private final TaskAttempt attempt;

http://git-wip-us.apache.org/repos/asf/tez/blob/34eb75d7/tez-dag/src/main/java/org/apache/tez/dag/app/dag/event/DAGEventSchedulerUpdateTAAssigned.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/event/DAGEventSchedulerUpdateTAAssigned.java b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/event/DAGEventSchedulerUpdateTAAssigned.java
deleted file mode 100644
index 8e27843..0000000
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/event/DAGEventSchedulerUpdateTAAssigned.java
+++ /dev/null
@@ -1,36 +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.
-*/
-
-package org.apache.tez.dag.app.dag.event;
-
-import org.apache.hadoop.yarn.api.records.Container;
-import org.apache.tez.dag.app.dag.TaskAttempt;
-
-public class DAGEventSchedulerUpdateTAAssigned extends DAGEventSchedulerUpdate {
-  
-  final Container container;
-
-  public DAGEventSchedulerUpdateTAAssigned(TaskAttempt attempt, Container container) {
-    super(DAGEventSchedulerUpdate.UpdateType.TA_SCHEDULED, attempt);
-    this.container = container;
-  }
-
-  public Container getContainer() {
-    return container;
-  }
-}

http://git-wip-us.apache.org/repos/asf/tez/blob/34eb75d7/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/DAGImpl.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/DAGImpl.java b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/DAGImpl.java
index 3d47450..60f933f 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/DAGImpl.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/DAGImpl.java
@@ -104,7 +104,6 @@ import org.apache.tez.dag.app.dag.event.DAGEventCounterUpdate;
 import org.apache.tez.dag.app.dag.event.DAGEventDiagnosticsUpdate;
 import org.apache.tez.dag.app.dag.event.DAGEventRecoverEvent;
 import org.apache.tez.dag.app.dag.event.DAGEventSchedulerUpdate;
-import org.apache.tez.dag.app.dag.event.DAGEventSchedulerUpdateTAAssigned;
 import org.apache.tez.dag.app.dag.event.DAGEventStartDag;
 import org.apache.tez.dag.app.dag.event.DAGEventType;
 import org.apache.tez.dag.app.dag.event.DAGEventVertexCompleted;
@@ -1592,6 +1591,9 @@ public class DAGImpl implements org.apache.tez.dag.app.dag.DAG,
     LOG.info("Using DAG Scheduler: " + dagSchedulerClassName);
     dag.dagScheduler = ReflectionUtils.createClazzInstance(dagSchedulerClassName, new Class<?>[] {
         DAG.class, EventHandler.class}, new Object[] {dag, dag.eventHandler});
+    for (Vertex v : dag.vertices.values()) {
+      dag.dagScheduler.addVertexConcurrencyLimit(v.getVertexId(), v.getMaxTaskConcurrency());
+    }
   }
 
   private static VertexImpl createVertex(DAGImpl dag, String vertexName, int vId) {
@@ -1903,10 +1905,6 @@ public class DAGImpl implements org.apache.tez.dag.app.dag.DAG,
       Vertex vertex = job.vertices.get(vertexEvent.getVertexId());
       job.numCompletedVertices++;
       if (vertexEvent.getVertexState() == VertexState.SUCCEEDED) {
-        if (!job.reRunningVertices.contains(vertex.getVertexId())) {
-          // vertex succeeded for the first time
-          job.dagScheduler.vertexCompleted(vertex);
-        }
         forceTransitionToKillWait = !(job.vertexSucceeded(vertex));
       }
       else if (vertexEvent.getVertexState() == VertexState.FAILED) {
@@ -2146,13 +2144,8 @@ public class DAGImpl implements org.apache.tez.dag.app.dag.DAG,
         case TA_SCHEDULE:
           dag.dagScheduler.scheduleTask(sEvent);
           break;
-        case TA_SCHEDULED:
-          DAGEventSchedulerUpdateTAAssigned taEvent =
-                                (DAGEventSchedulerUpdateTAAssigned) sEvent;
-          dag.dagScheduler.taskScheduled(taEvent);
-          break;
-        case TA_SUCCEEDED:
-          dag.dagScheduler.taskSucceeded(sEvent);
+        case TA_COMPLETED:
+          dag.dagScheduler.taskCompleted(sEvent);
           break;
         default:
           throw new TezUncheckedException("Unknown DAGEventSchedulerUpdate:"

http://git-wip-us.apache.org/repos/asf/tez/blob/34eb75d7/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/DAGSchedulerNaturalOrder.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/DAGSchedulerNaturalOrder.java b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/DAGSchedulerNaturalOrder.java
index 8d42227..4246ad0 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/DAGSchedulerNaturalOrder.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/DAGSchedulerNaturalOrder.java
@@ -26,11 +26,10 @@ import org.apache.tez.dag.app.dag.DAGScheduler;
 import org.apache.tez.dag.app.dag.TaskAttempt;
 import org.apache.tez.dag.app.dag.Vertex;
 import org.apache.tez.dag.app.dag.event.DAGEventSchedulerUpdate;
-import org.apache.tez.dag.app.dag.event.DAGEventSchedulerUpdateTAAssigned;
 import org.apache.tez.dag.app.dag.event.TaskAttemptEventSchedule;
 
 @SuppressWarnings("rawtypes")
-public class DAGSchedulerNaturalOrder implements DAGScheduler {
+public class DAGSchedulerNaturalOrder extends DAGScheduler {
   
   private static final Logger LOG = 
                             LoggerFactory.getLogger(DAGSchedulerNaturalOrder.class);
@@ -44,11 +43,7 @@ public class DAGSchedulerNaturalOrder implements DAGScheduler {
   }
   
   @Override
-  public void vertexCompleted(Vertex vertex) {
-  }
-
-  @Override
-  public void scheduleTask(DAGEventSchedulerUpdate event) {
+  public void scheduleTaskEx(DAGEventSchedulerUpdate event) {
     TaskAttempt attempt = event.getAttempt();
     Vertex vertex = dag.getVertex(attempt.getVertexID());
     int vertexDistanceFromRoot = vertex.getDistanceFromRoot();
@@ -69,11 +64,7 @@ public class DAGSchedulerNaturalOrder implements DAGScheduler {
   }
   
   @Override
-  public void taskScheduled(DAGEventSchedulerUpdateTAAssigned event) {
-  }
-
-  @Override
-  public void taskSucceeded(DAGEventSchedulerUpdate event) {
+  public void taskCompletedEx(DAGEventSchedulerUpdate event) {
   }
   
   @SuppressWarnings("unchecked")

http://git-wip-us.apache.org/repos/asf/tez/blob/34eb75d7/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/DAGSchedulerNaturalOrderControlled.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/DAGSchedulerNaturalOrderControlled.java b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/DAGSchedulerNaturalOrderControlled.java
index 2469a2f..0802dce 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/DAGSchedulerNaturalOrderControlled.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/DAGSchedulerNaturalOrderControlled.java
@@ -36,7 +36,6 @@ import org.apache.tez.dag.app.dag.DAGScheduler;
 import org.apache.tez.dag.app.dag.TaskAttempt;
 import org.apache.tez.dag.app.dag.Vertex;
 import org.apache.tez.dag.app.dag.event.DAGEventSchedulerUpdate;
-import org.apache.tez.dag.app.dag.event.DAGEventSchedulerUpdateTAAssigned;
 import org.apache.tez.dag.app.dag.event.TaskAttemptEventSchedule;
 import org.apache.tez.dag.records.TezTaskAttemptID;
 
@@ -50,7 +49,7 @@ import org.apache.tez.dag.records.TezTaskAttemptID;
  * - generic slow start mechanism across all vertices - independent of the type of edges.
  */
 @SuppressWarnings("rawtypes")
-public class DAGSchedulerNaturalOrderControlled implements DAGScheduler {
+public class DAGSchedulerNaturalOrderControlled extends DAGScheduler {
 
   private static final Logger LOG =
       LoggerFactory.getLogger(DAGSchedulerNaturalOrderControlled.class);
@@ -72,13 +71,9 @@ public class DAGSchedulerNaturalOrderControlled implements DAGScheduler {
     this.handler = dispatcher;
   }
 
-  @Override
-  public void vertexCompleted(Vertex vertex) {
-  }
-
   // TODO Does ordering matter - it currently depends on the order returned by vertex.getOutput*
   @Override
-  public void scheduleTask(DAGEventSchedulerUpdate event) {
+  public void scheduleTaskEx(DAGEventSchedulerUpdate event) {
     TaskAttempt attempt = event.getAttempt();
     Vertex vertex = dag.getVertex(attempt.getVertexID());
     int vertexDistanceFromRoot = vertex.getDistanceFromRoot();
@@ -241,11 +236,7 @@ public class DAGSchedulerNaturalOrderControlled implements DAGScheduler {
   }
 
   @Override
-  public void taskScheduled(DAGEventSchedulerUpdateTAAssigned event) {
-  }
-
-  @Override
-  public void taskSucceeded(DAGEventSchedulerUpdate event) {
+  public void taskCompletedEx(DAGEventSchedulerUpdate event) {
   }
 
   @SuppressWarnings("unchecked")

http://git-wip-us.apache.org/repos/asf/tez/blob/34eb75d7/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/TaskImpl.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/TaskImpl.java b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/TaskImpl.java
index 0f76a63..c00d674 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/TaskImpl.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/TaskImpl.java
@@ -825,40 +825,17 @@ public class TaskImpl implements Task, EventHandler<TaskEvent> {
   private void handleTaskAttemptCompletion(TezTaskAttemptID attemptId,
       TaskAttemptStateInternal attemptState) {
     this.sendTaskAttemptCompletionEvent(attemptId, attemptState);
-  }
-
-  // TODO: Recovery
-  /*
-  private static TaskFinishedEvent createTaskFinishedEvent(TaskImpl task, TaskStateInternal taskState) {
-    TaskFinishedEvent tfe =
-      new TaskFinishedEvent(task.taskId,
-        task.successfulAttempt,
-        task.getFinishTime(task.successfulAttempt),
-        task.taskId.getTaskType(),
-        taskState.toString(),
-        task.getCounters());
-    return tfe;
-  }
-
-  private static TaskFailedEvent createTaskFailedEvent(TaskImpl task, List<String> diag, TaskStateInternal taskState, TezTaskAttemptID taId) {
-    StringBuilder errorSb = new StringBuilder();
-    if (diag != null) {
-      for (String d : diag) {
-        errorSb.append(", ").append(d);
-      }
+    if (getInternalState() != TaskStateInternal.SUCCEEDED) {
+      sendDAGSchedulerFinishedEvent(attemptId); // not a retro active action
     }
-    TaskFailedEvent taskFailedEvent = new TaskFailedEvent(
-        TypeConverter.fromYarn(task.taskId),
-     // Hack since getFinishTime needs isFinished to be true and that doesn't happen till after the transition.
-        task.getFinishTime(taId),
-        TypeConverter.fromYarn(task.getType()),
-        errorSb.toString(),
-        taskState.toString(),
-        taId == null ? null : TypeConverter.fromYarn(taId));
-    return taskFailedEvent;
   }
-  */
 
+  private void sendDAGSchedulerFinishedEvent(TezTaskAttemptID taId) {
+    // send notification to DAG scheduler
+    eventHandler.handle(new DAGEventSchedulerUpdate(
+        DAGEventSchedulerUpdate.UpdateType.TA_COMPLETED, attempts.get(taId)));
+  }
+  
   private static void unSucceed(TaskImpl task) {
     task.commitAttempt = null;
     task.successfulAttempt = null;
@@ -1105,10 +1082,6 @@ public class TaskImpl implements Task, EventHandler<TaskEvent> {
               .getID(), diagnostics, errCause));
         }
       }
-      // send notification to DAG scheduler
-      task.eventHandler.handle(new DAGEventSchedulerUpdate(
-          DAGEventSchedulerUpdate.UpdateType.TA_SUCCEEDED, task.attempts
-              .get(task.successfulAttempt)));
       return task.finished(TaskStateInternal.SUCCEEDED);
     }
   }

http://git-wip-us.apache.org/repos/asf/tez/blob/34eb75d7/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/VertexImpl.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/VertexImpl.java b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/VertexImpl.java
index 93baa0a..065974e 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/VertexImpl.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/dag/impl/VertexImpl.java
@@ -1184,6 +1184,12 @@ public class VertexImpl implements org.apache.tez.dag.app.dag.Vertex, EventHandl
       readLock.unlock();
     }
   }
+  
+  @Override
+  public int getMaxTaskConcurrency() {
+    return vertexConf.getInt(TezConfiguration.TEZ_AM_VERTEX_MAX_TASK_CONCURRENCY, 
+        TezConfiguration.TEZ_AM_VERTEX_MAX_TASK_CONCURRENCY_DEFAULT);
+  }
 
   public VertexStats getVertexStats() {
 

http://git-wip-us.apache.org/repos/asf/tez/blob/34eb75d7/tez-dag/src/main/java/org/apache/tez/dag/app/rm/TaskSchedulerManager.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/rm/TaskSchedulerManager.java b/tez-dag/src/main/java/org/apache/tez/dag/app/rm/TaskSchedulerManager.java
index dbf8e38..f688b57 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/rm/TaskSchedulerManager.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/rm/TaskSchedulerManager.java
@@ -69,7 +69,6 @@ import org.apache.tez.dag.app.dag.Vertex;
 import org.apache.tez.dag.app.dag.event.DAGAppMasterEvent;
 import org.apache.tez.dag.app.dag.event.DAGAppMasterEventSchedulingServiceError;
 import org.apache.tez.dag.app.dag.event.DAGAppMasterEventType;
-import org.apache.tez.dag.app.dag.event.DAGEventSchedulerUpdateTAAssigned;
 import org.apache.tez.dag.app.rm.container.AMContainer;
 import org.apache.tez.dag.app.rm.container.AMContainerEventAssignTA;
 import org.apache.tez.dag.app.rm.container.AMContainerEventCompleted;
@@ -569,7 +568,6 @@ public class TaskSchedulerManager extends AbstractService implements
       sendEvent(new AMContainerEventLaunchRequest(containerId, taskAttempt.getVertexID(),
           event.getContainerContext(), event.getLauncherId(), event.getTaskCommId()));
     }
-    sendEvent(new DAGEventSchedulerUpdateTAAssigned(taskAttempt, container));
     sendEvent(new AMContainerEventAssignTA(containerId, taskAttempt.getID(),
         event.getRemoteTaskSpec(), event.getContainerContext().getLocalResources(), event
             .getContainerContext().getCredentials(), event.getPriority()));

http://git-wip-us.apache.org/repos/asf/tez/blob/34eb75d7/tez-dag/src/test/java/org/apache/tez/dag/app/MockDAGAppMaster.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/MockDAGAppMaster.java b/tez-dag/src/test/java/org/apache/tez/dag/app/MockDAGAppMaster.java
index bc7fa98..b322e05 100644
--- a/tez-dag/src/test/java/org/apache/tez/dag/app/MockDAGAppMaster.java
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/MockDAGAppMaster.java
@@ -83,7 +83,6 @@ import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.common.util.concurrent.MoreExecutors;
 import com.google.common.util.concurrent.ThreadFactoryBuilder;
 
-@SuppressWarnings("unchecked")
 public class MockDAGAppMaster extends DAGAppMaster {
   
   private static final Logger LOG = LoggerFactory.getLogger(MockDAGAppMaster.class);
@@ -95,6 +94,7 @@ public class MockDAGAppMaster extends DAGAppMaster {
   EventsDelegate eventsDelegate;
   CountersDelegate countersDelegate;
   StatisticsDelegate statsDelegate;
+  ContainerDelegate containerDelegate;
   long launcherSleepTime = 1;
   boolean doSleep = true;
   int handlerConcurrency = 1;
@@ -115,6 +115,11 @@ public class MockDAGAppMaster extends DAGAppMaster {
   public static interface EventsDelegate {
     public void getEvents(TaskSpec taskSpec, List<TezEvent> events, long time);
   }
+  
+  public static interface ContainerDelegate {
+    public void stop(ContainerStopRequest event);
+    public void launch(ContainerLaunchRequest event);
+  }
 
   // mock container launcher does not launch real tasks.
   // Upon, launch of a container is simulates the container asking for tasks
@@ -268,6 +273,9 @@ public class MockDAGAppMaster extends DAGAppMaster {
     void stop(ContainerStopRequest event) {
       // remove from simulated container list
       containers.remove(event.getContainerId());
+      if (containerDelegate != null) {
+        containerDelegate.stop(event);
+      }
       getContext().containerStopRequested(event.getContainerId());
     }
 
@@ -277,6 +285,9 @@ public class MockDAGAppMaster extends DAGAppMaster {
           event.getContainerLaunchContext());
       containers.put(event.getContainerId(), cData);
       containersToProcess.add(cData);
+      if (containerDelegate != null) {
+        containerDelegate.launch(event);
+      }
       getContext().containerLaunched(event.getContainerId());
     }
     

http://git-wip-us.apache.org/repos/asf/tez/blob/34eb75d7/tez-dag/src/test/java/org/apache/tez/dag/app/TestMockDAGAppMaster.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/TestMockDAGAppMaster.java b/tez-dag/src/test/java/org/apache/tez/dag/app/TestMockDAGAppMaster.java
index b0bc571..d5ee67d 100644
--- a/tez-dag/src/test/java/org/apache/tez/dag/app/TestMockDAGAppMaster.java
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/TestMockDAGAppMaster.java
@@ -28,6 +28,7 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.SystemUtils;
@@ -73,6 +74,7 @@ import org.apache.tez.dag.api.client.VertexStatus;
 import org.apache.tez.dag.api.client.VertexStatus.State;
 import org.apache.tez.dag.api.oldrecords.TaskAttemptState;
 import org.apache.tez.dag.app.MockDAGAppMaster.CountersDelegate;
+import org.apache.tez.dag.app.MockDAGAppMaster.ContainerDelegate;
 import org.apache.tez.dag.app.MockDAGAppMaster.EventsDelegate;
 import org.apache.tez.dag.app.MockDAGAppMaster.MockContainerLauncher;
 import org.apache.tez.dag.app.MockDAGAppMaster.MockContainerLauncher.ContainerData;
@@ -100,6 +102,8 @@ import org.apache.tez.runtime.api.impl.TaskSpec;
 import org.apache.tez.runtime.api.impl.TaskStatistics;
 import org.apache.tez.runtime.api.impl.TezEvent;
 import org.apache.tez.runtime.api.impl.EventMetaData.EventProducerConsumerType;
+import org.apache.tez.serviceplugins.api.ContainerLaunchRequest;
+import org.apache.tez.serviceplugins.api.ContainerStopRequest;
 import org.junit.Assert;
 import org.junit.Ignore;
 import org.junit.Test;
@@ -406,6 +410,52 @@ public class TestMockDAGAppMaster {
 
     tezClient.stop();
   }
+  
+  @Test (timeout = 100000)
+  public void testConcurrencyLimit() throws Exception {
+    // the test relies on local mode behavior of launching a new container per task.
+    // so task concurrency == container concurrency
+    TezConfiguration tezconf = new TezConfiguration(defaultConf);
+    
+    final int concurrencyLimit = 5;
+    MockTezClient tezClient = new MockTezClient("testMockAM", tezconf, true, null, null, null,
+        null, false, false, concurrencyLimit*4, 1000);
+
+    tezClient.start();
+    
+    MockDAGAppMaster mockApp = tezClient.getLocalClient().getMockApp();
+    MockContainerLauncher mockLauncher = mockApp.getContainerLauncher();
+    mockLauncher.startScheduling(false);
+    
+    final AtomicInteger concurrency = new AtomicInteger(0);
+    final AtomicBoolean exceededConcurrency = new AtomicBoolean(false);
+    mockApp.containerDelegate = new ContainerDelegate() {
+      @Override
+      public void stop(ContainerStopRequest event) {
+        concurrency.decrementAndGet();
+      }
+      @Override
+      public void launch(ContainerLaunchRequest event) {
+        int maxConc = concurrency.incrementAndGet();
+        if (maxConc > concurrencyLimit) {
+          exceededConcurrency.set(true);
+        }
+        System.out.println("Launched: " + maxConc);
+      }
+    };
+    DAG dag = DAG.create("testConcurrencyLimit");
+    Vertex vA = Vertex.create("A", ProcessorDescriptor.create("Proc.class"), 20).setConf(
+        TezConfiguration.TEZ_AM_VERTEX_MAX_TASK_CONCURRENCY, String.valueOf(concurrencyLimit));
+    dag.addVertex(vA);
+
+    mockLauncher.startScheduling(true);
+    DAGClient dagClient = tezClient.submitDAG(dag);
+    dagClient.waitForCompletion();
+    Assert.assertEquals(DAGStatus.State.SUCCEEDED, dagClient.getDAGStatus(null).getState());
+    Assert.assertFalse(exceededConcurrency.get());
+    tezClient.stop();
+  }
+
 
   @Test (timeout = 10000)
   public void testBasicCounters() throws Exception {

http://git-wip-us.apache.org/repos/asf/tez/blob/34eb75d7/tez-dag/src/test/java/org/apache/tez/dag/app/dag/impl/TestDAGImpl.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/dag/impl/TestDAGImpl.java b/tez-dag/src/test/java/org/apache/tez/dag/app/dag/impl/TestDAGImpl.java
index 1809230..2158368 100644
--- a/tez-dag/src/test/java/org/apache/tez/dag/app/dag/impl/TestDAGImpl.java
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/dag/impl/TestDAGImpl.java
@@ -1617,7 +1617,6 @@ public class TestDAGImpl {
     Assert.assertEquals(VertexState.SUCCEEDED, v.getState());
     Assert.assertEquals(1, dag.getSuccessfulVertices());
     Assert.assertEquals(1, dag.numCompletedVertices);
-    verify(dag.dagScheduler, times(1)).vertexCompleted(v);
     
     dispatcher.getEventHandler().handle(
         new VertexEventTaskReschedule(TezTaskID.getInstance(vId, 0)));
@@ -1634,9 +1633,6 @@ public class TestDAGImpl {
     Assert.assertEquals(1, dag.getSuccessfulVertices());
     Assert.assertEquals(1, dag.numCompletedVertices);
     
-    // re-completion is not notified again
-    verify(dag.dagScheduler, times(1)).vertexCompleted(v);
-
   }
 
   @SuppressWarnings("unchecked")

http://git-wip-us.apache.org/repos/asf/tez/blob/34eb75d7/tez-dag/src/test/java/org/apache/tez/dag/app/dag/impl/TestDAGScheduler.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/dag/impl/TestDAGScheduler.java b/tez-dag/src/test/java/org/apache/tez/dag/app/dag/impl/TestDAGScheduler.java
index 913f5fa..a28f367 100644
--- a/tez-dag/src/test/java/org/apache/tez/dag/app/dag/impl/TestDAGScheduler.java
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/dag/impl/TestDAGScheduler.java
@@ -25,27 +25,34 @@ import org.apache.tez.dag.app.dag.TaskAttempt;
 import org.apache.tez.dag.app.dag.Vertex;
 import org.apache.tez.dag.app.dag.event.DAGEventSchedulerUpdate;
 import org.apache.tez.dag.app.dag.event.TaskAttemptEventSchedule;
+import org.apache.tez.dag.records.TezTaskAttemptID;
+import org.apache.tez.dag.records.TezTaskID;
 import org.apache.tez.dag.records.TezVertexID;
 import org.junit.Assert;
 import org.junit.Test;
 
+import com.google.common.collect.Lists;
+
 import static org.mockito.Mockito.*;
 
+import java.util.List;
+
 public class TestDAGScheduler {
 
   class MockEventHandler implements EventHandler<TaskAttemptEventSchedule> {
     TaskAttemptEventSchedule event;
+    List<TaskAttemptEventSchedule> events = Lists.newLinkedList();
     @Override
     public void handle(TaskAttemptEventSchedule event) {
       this.event = event;
+      this.events.add(event);
     }
-    
   }
   
-  MockEventHandler mockEventHandler = new MockEventHandler();
   
   @Test(timeout=5000)
   public void testDAGSchedulerNaturalOrder() {
+    MockEventHandler mockEventHandler = new MockEventHandler();
     DAG mockDag = mock(DAG.class);
     Vertex mockVertex = mock(Vertex.class);
     TaskAttempt mockAttempt = mock(TaskAttempt.class);
@@ -58,15 +65,125 @@ public class TestDAGScheduler {
     
     DAGScheduler scheduler = new DAGSchedulerNaturalOrder(mockDag,
         mockEventHandler);
-    scheduler.scheduleTask(event);
+    scheduler.scheduleTaskEx(event);
     Assert.assertEquals(1, mockEventHandler.event.getPriorityHighLimit());
     Assert.assertEquals(3, mockEventHandler.event.getPriorityLowLimit());
-    scheduler.scheduleTask(event);
+    scheduler.scheduleTaskEx(event);
     Assert.assertEquals(4, mockEventHandler.event.getPriorityHighLimit());
     Assert.assertEquals(6, mockEventHandler.event.getPriorityLowLimit());
-    scheduler.scheduleTask(event);
+    scheduler.scheduleTaskEx(event);
     Assert.assertEquals(7, mockEventHandler.event.getPriorityHighLimit());
     Assert.assertEquals(9, mockEventHandler.event.getPriorityLowLimit());
   }
   
+  @Test(timeout=5000)
+  public void testConcurrencyLimit() {
+    MockEventHandler mockEventHandler = new MockEventHandler();
+    DAG mockDag = mock(DAG.class);
+    TezVertexID vId0 = TezVertexID.fromString("vertex_1436907267600_195589_1_00");
+    TezVertexID vId1 = TezVertexID.fromString("vertex_1436907267600_195589_1_01");
+    TezTaskID tId0 = TezTaskID.getInstance(vId0, 0);
+    TezTaskID tId1 = TezTaskID.getInstance(vId1, 0);
+    
+    TaskAttempt mockAttempt;
+
+    Vertex mockVertex = mock(Vertex.class);
+    when(mockDag.getVertex((TezVertexID) any())).thenReturn(mockVertex);
+    when(mockVertex.getDistanceFromRoot()).thenReturn(0);
+    
+    DAGScheduler scheduler = new DAGSchedulerNaturalOrder(mockDag,
+        mockEventHandler);
+    scheduler.addVertexConcurrencyLimit(vId0, 0); // not effective
+    
+    // schedule beyond limit and it gets scheduled
+    mockAttempt = mock(TaskAttempt.class);
+    when(mockAttempt.getID()).thenReturn(TezTaskAttemptID.getInstance(tId0, 0));
+    scheduler.scheduleTask(new DAGEventSchedulerUpdate(
+        DAGEventSchedulerUpdate.UpdateType.TA_SCHEDULE, mockAttempt));
+    Assert.assertEquals(1, mockEventHandler.events.size());
+    mockAttempt = mock(TaskAttempt.class);
+    when(mockAttempt.getID()).thenReturn(TezTaskAttemptID.getInstance(tId0, 1));
+    scheduler.scheduleTask(new DAGEventSchedulerUpdate(
+        DAGEventSchedulerUpdate.UpdateType.TA_SCHEDULE, mockAttempt));
+    Assert.assertEquals(2, mockEventHandler.events.size());
+    mockAttempt = mock(TaskAttempt.class);
+    when(mockAttempt.getID()).thenReturn(TezTaskAttemptID.getInstance(tId0, 2));
+    scheduler.scheduleTask(new DAGEventSchedulerUpdate(
+        DAGEventSchedulerUpdate.UpdateType.TA_SCHEDULE, mockAttempt));
+    Assert.assertEquals(3, mockEventHandler.events.size());
+    
+    mockEventHandler.events.clear();
+    List<TaskAttempt> mockAttempts = Lists.newArrayList();
+    int completed = 0;
+    int requested = 0;
+    int scheduled = 0;
+    scheduler.addVertexConcurrencyLimit(vId1, 2); // effective    
+    
+    // schedule beyond limit and it gets buffered
+    mockAttempt = mock(TaskAttempt.class);
+    mockAttempts.add(mockAttempt);
+    when(mockAttempt.getID()).thenReturn(TezTaskAttemptID.getInstance(tId1, requested++));
+    scheduler.scheduleTask(new DAGEventSchedulerUpdate(
+        DAGEventSchedulerUpdate.UpdateType.TA_SCHEDULE, mockAttempt));
+    Assert.assertEquals(scheduled+1, mockEventHandler.events.size()); // scheduled
+    Assert.assertEquals(mockAttempts.get(scheduled).getID(),
+        mockEventHandler.events.get(scheduled).getTaskAttemptID()); // matches order
+    scheduled++;
+    
+    mockAttempt = mock(TaskAttempt.class);
+    mockAttempts.add(mockAttempt);
+    when(mockAttempt.getID()).thenReturn(TezTaskAttemptID.getInstance(tId1, requested++));
+    scheduler.scheduleTask(new DAGEventSchedulerUpdate(
+        DAGEventSchedulerUpdate.UpdateType.TA_SCHEDULE, mockAttempt));
+    Assert.assertEquals(scheduled+1, mockEventHandler.events.size()); // scheduled
+    Assert.assertEquals(mockAttempts.get(scheduled).getID(),
+        mockEventHandler.events.get(scheduled).getTaskAttemptID()); // matches order
+    scheduled++;
+    
+    mockAttempt = mock(TaskAttempt.class);
+    mockAttempts.add(mockAttempt);
+    when(mockAttempt.getID()).thenReturn(TezTaskAttemptID.getInstance(tId1, requested++));
+    scheduler.scheduleTask(new DAGEventSchedulerUpdate(
+        DAGEventSchedulerUpdate.UpdateType.TA_SCHEDULE, mockAttempt));
+    Assert.assertEquals(scheduled, mockEventHandler.events.size()); // buffered
+
+    mockAttempt = mock(TaskAttempt.class);
+    mockAttempts.add(mockAttempt);
+    when(mockAttempt.getID()).thenReturn(TezTaskAttemptID.getInstance(tId1, requested++));
+    scheduler.scheduleTask(new DAGEventSchedulerUpdate(
+        DAGEventSchedulerUpdate.UpdateType.TA_SCHEDULE, mockAttempt));
+    Assert.assertEquals(scheduled, mockEventHandler.events.size()); // buffered
+
+    scheduler.taskCompleted(new DAGEventSchedulerUpdate(
+        DAGEventSchedulerUpdate.UpdateType.TA_COMPLETED, mockAttempts.get(completed++)));
+    Assert.assertEquals(scheduled+1, mockEventHandler.events.size()); // scheduled
+    Assert.assertEquals(mockAttempts.get(scheduled).getID(),
+        mockEventHandler.events.get(scheduled).getTaskAttemptID()); // matches order
+    scheduled++;
+
+    scheduler.taskCompleted(new DAGEventSchedulerUpdate(
+        DAGEventSchedulerUpdate.UpdateType.TA_COMPLETED, mockAttempts.get(completed++)));
+    Assert.assertEquals(scheduled+1, mockEventHandler.events.size()); // scheduled
+    Assert.assertEquals(mockAttempts.get(scheduled).getID(),
+        mockEventHandler.events.get(scheduled).getTaskAttemptID()); // matches order
+    scheduled++;
+
+    scheduler.taskCompleted(new DAGEventSchedulerUpdate(
+        DAGEventSchedulerUpdate.UpdateType.TA_COMPLETED, mockAttempts.get(completed++)));
+    Assert.assertEquals(scheduled, mockEventHandler.events.size()); // no extra scheduling
+
+    mockAttempt = mock(TaskAttempt.class);
+    mockAttempts.add(mockAttempt);
+    when(mockAttempt.getID()).thenReturn(TezTaskAttemptID.getInstance(tId1, requested++));
+    scheduler.scheduleTask(new DAGEventSchedulerUpdate(
+        DAGEventSchedulerUpdate.UpdateType.TA_SCHEDULE, mockAttempt));
+    Assert.assertEquals(scheduled+1, mockEventHandler.events.size()); // scheduled
+    Assert.assertEquals(mockAttempts.get(scheduled).getID(),
+        mockEventHandler.events.get(scheduled).getTaskAttemptID()); // matches order
+    scheduled++;
+
+  }
+  
+  
+  
 }

http://git-wip-us.apache.org/repos/asf/tez/blob/34eb75d7/tez-dag/src/test/java/org/apache/tez/dag/app/dag/impl/TestDAGSchedulerNaturalOrderControlled.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/dag/impl/TestDAGSchedulerNaturalOrderControlled.java b/tez-dag/src/test/java/org/apache/tez/dag/app/dag/impl/TestDAGSchedulerNaturalOrderControlled.java
index bc86761..63137c7 100644
--- a/tez-dag/src/test/java/org/apache/tez/dag/app/dag/impl/TestDAGSchedulerNaturalOrderControlled.java
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/dag/impl/TestDAGSchedulerNaturalOrderControlled.java
@@ -63,35 +63,35 @@ public class TestDAGSchedulerNaturalOrderControlled {
 
     // Schedule all tasks belonging to v0
     for (int i = 0; i < vertices[0].getTotalTasks(); i++) {
-      dagScheduler.scheduleTask(createScheduleRequest(vertices[0].getVertexId(), i, 0));
+      dagScheduler.scheduleTaskEx(createScheduleRequest(vertices[0].getVertexId(), i, 0));
     }
     verify(eventHandler, times(vertices[0].getTotalTasks())).handle(any(Event.class));
     reset(eventHandler);
 
     // Schedule 3 tasks belonging to v2
     for (int i = 0; i < 3; i++) {
-      dagScheduler.scheduleTask(createScheduleRequest(vertices[2].getVertexId(), i, 0));
+      dagScheduler.scheduleTaskEx(createScheduleRequest(vertices[2].getVertexId(), i, 0));
     }
     verify(eventHandler, times(3)).handle(any(Event.class));
     reset(eventHandler);
 
     // Schedule 3 tasks belonging to v3
     for (int i = 0; i < 3; i++) {
-      dagScheduler.scheduleTask(createScheduleRequest(vertices[3].getVertexId(), i, 0));
+      dagScheduler.scheduleTaskEx(createScheduleRequest(vertices[3].getVertexId(), i, 0));
     }
     verify(eventHandler, times(3)).handle(any(Event.class));
     reset(eventHandler);
 
     // Schedule remaining tasks belonging to v2
     for (int i = 3; i < vertices[2].getTotalTasks(); i++) {
-      dagScheduler.scheduleTask(createScheduleRequest(vertices[2].getVertexId(), i, 0));
+      dagScheduler.scheduleTaskEx(createScheduleRequest(vertices[2].getVertexId(), i, 0));
     }
     verify(eventHandler, times(vertices[2].getTotalTasks() - 3)).handle(any(Event.class));
     reset(eventHandler);
 
     // Schedule remaining tasks belonging to v3
     for (int i = 3; i < vertices[3].getTotalTasks(); i++) {
-      dagScheduler.scheduleTask(createScheduleRequest(vertices[3].getVertexId(), i, 0));
+      dagScheduler.scheduleTaskEx(createScheduleRequest(vertices[3].getVertexId(), i, 0));
     }
     verify(eventHandler, times(vertices[3].getTotalTasks() - 3)).handle(any(Event.class));
     reset(eventHandler);
@@ -99,7 +99,7 @@ public class TestDAGSchedulerNaturalOrderControlled {
 
     // Schedule all tasks belonging to v4
     for (int i = 0; i < vertices[4].getTotalTasks(); i++) {
-      dagScheduler.scheduleTask(createScheduleRequest(vertices[4].getVertexId(), i, 0));
+      dagScheduler.scheduleTaskEx(createScheduleRequest(vertices[4].getVertexId(), i, 0));
     }
     verify(eventHandler, times(vertices[4].getTotalTasks())).handle(any(Event.class));
     reset(eventHandler);
@@ -122,7 +122,7 @@ public class TestDAGSchedulerNaturalOrderControlled {
 
     // Schedule all tasks belonging to v0
     for (int i = 0; i < vertices[0].getTotalTasks(); i++) {
-      dagScheduler.scheduleTask(createScheduleRequest(vertices[0].getVertexId(), i, 0));
+      dagScheduler.scheduleTaskEx(createScheduleRequest(vertices[0].getVertexId(), i, 0));
     }
     verify(eventHandler, times(vertices[0].getTotalTasks())).handle(any(Event.class));
     reset(eventHandler);
@@ -130,14 +130,14 @@ public class TestDAGSchedulerNaturalOrderControlled {
     // v2 behaving as if configured with slow-start.
     // Schedule all tasks belonging to v3.
     for (int i = 0; i < vertices[3].getTotalTasks(); i++) {
-      dagScheduler.scheduleTask(createScheduleRequest(vertices[3].getVertexId(), i, 0));
+      dagScheduler.scheduleTaskEx(createScheduleRequest(vertices[3].getVertexId(), i, 0));
     }
     verify(eventHandler, times(vertices[3].getTotalTasks())).handle(any(Event.class));
     reset(eventHandler);
 
     // Scheduling all tasks belonging to v4. None should get scheduled.
     for (int i = 0; i < vertices[4].getTotalTasks(); i++) {
-      dagScheduler.scheduleTask(createScheduleRequest(vertices[4].getVertexId(), i, 0));
+      dagScheduler.scheduleTaskEx(createScheduleRequest(vertices[4].getVertexId(), i, 0));
     }
     verify(eventHandler, never()).handle(any(Event.class));
     reset(eventHandler);
@@ -145,14 +145,14 @@ public class TestDAGSchedulerNaturalOrderControlled {
     // v2 now starts scheduling ...
     // Schedule 3 tasks for v2 initially.
     for (int i = 0; i < 3; i++) {
-      dagScheduler.scheduleTask(createScheduleRequest(vertices[2].getVertexId(), i, 0));
+      dagScheduler.scheduleTaskEx(createScheduleRequest(vertices[2].getVertexId(), i, 0));
     }
     verify(eventHandler, times(3)).handle(any(Event.class));
     reset(eventHandler);
 
     // Schedule remaining tasks belonging to v2
     for (int i = 3; i < vertices[2].getTotalTasks(); i++) {
-      dagScheduler.scheduleTask(createScheduleRequest(vertices[2].getVertexId(), i, 0));
+      dagScheduler.scheduleTaskEx(createScheduleRequest(vertices[2].getVertexId(), i, 0));
     }
     ArgumentCaptor<Event> args = ArgumentCaptor.forClass(Event.class);
     // All of v2 and v3 should be sent out.
@@ -190,7 +190,7 @@ public class TestDAGSchedulerNaturalOrderControlled {
 
     // Schedule all tasks belonging to v0
     for (int i = 0; i < vertices[0].getTotalTasks(); i++) {
-      dagScheduler.scheduleTask(createScheduleRequest(vertices[0].getVertexId(), i, 0));
+      dagScheduler.scheduleTaskEx(createScheduleRequest(vertices[0].getVertexId(), i, 0));
     }
     verify(eventHandler, times(vertices[0].getTotalTasks())).handle(any(Event.class));
     reset(eventHandler);
@@ -200,14 +200,14 @@ public class TestDAGSchedulerNaturalOrderControlled {
     // v2 will change parallelism
     // Schedule all tasks belonging to v3
     for (int i = 0; i < vertices[3].getTotalTasks(); i++) {
-      dagScheduler.scheduleTask(createScheduleRequest(vertices[3].getVertexId(), i, 0));
+      dagScheduler.scheduleTaskEx(createScheduleRequest(vertices[3].getVertexId(), i, 0));
     }
     verify(eventHandler, times(vertices[3].getTotalTasks())).handle(any(Event.class));
     reset(eventHandler);
 
     // Schedule all tasks belonging to v4
     for (int i = 0; i < vertices[4].getTotalTasks(); i++) {
-      dagScheduler.scheduleTask(createScheduleRequest(vertices[4].getVertexId(), i, 0));
+      dagScheduler.scheduleTaskEx(createScheduleRequest(vertices[4].getVertexId(), i, 0));
     }
     verify(eventHandler, never()).handle(any(Event.class));
     reset(eventHandler);
@@ -218,7 +218,7 @@ public class TestDAGSchedulerNaturalOrderControlled {
 
     // Schedule all tasks belonging to v2
     for (int i = 0; i < vertices[2].getTotalTasks(); i++) {
-      dagScheduler.scheduleTask(createScheduleRequest(vertices[2].getVertexId(), i, 0));
+      dagScheduler.scheduleTaskEx(createScheduleRequest(vertices[2].getVertexId(), i, 0));
     }
     verify(eventHandler, times(vertices[2].getTotalTasks() + vertices[4].getTotalTasks()))
         .handle(any(Event.class));
@@ -241,7 +241,7 @@ public class TestDAGSchedulerNaturalOrderControlled {
 
     // Schedule all but 1 task belonging to v0
     for (int i = 0; i < vertices[0].getTotalTasks() - 1; i++) {
-      dagScheduler.scheduleTask(createScheduleRequest(vertices[0].getVertexId(), i, 0));
+      dagScheduler.scheduleTaskEx(createScheduleRequest(vertices[0].getVertexId(), i, 0));
     }
     verify(eventHandler, times(vertices[0].getTotalTasks() - 1)).handle(any(Event.class));
     reset(eventHandler);
@@ -249,7 +249,7 @@ public class TestDAGSchedulerNaturalOrderControlled {
 
     // Schedule all tasks belonging to v2
     for (int i = 0; i < vertices[2].getTotalTasks(); i++) {
-      dagScheduler.scheduleTask(createScheduleRequest(vertices[2].getVertexId(), i, 0));
+      dagScheduler.scheduleTaskEx(createScheduleRequest(vertices[2].getVertexId(), i, 0));
     }
     // Nothing should be scheduled
     verify(eventHandler, never()).handle(any(Event.class));
@@ -257,14 +257,14 @@ public class TestDAGSchedulerNaturalOrderControlled {
 
     // Schedule an extra attempt for all but 1 task belonging to v0
     for (int i = 0; i < vertices[0].getTotalTasks() - 1; i++) {
-      dagScheduler.scheduleTask(createScheduleRequest(vertices[0].getVertexId(), i, 1));
+      dagScheduler.scheduleTaskEx(createScheduleRequest(vertices[0].getVertexId(), i, 1));
     }
     // Only v0 requests should have gone out
     verify(eventHandler, times(vertices[0].getTotalTasks() - 1)).handle(any(Event.class));
     reset(eventHandler);
 
     // Schedule last task of v0, with attempt 1
-    dagScheduler.scheduleTask(
+    dagScheduler.scheduleTaskEx(
         createScheduleRequest(vertices[0].getVertexId(), vertices[0].getTotalTasks() - 1, 1));
     // One v0 request and all of v2 should have gone out
     verify(eventHandler, times(1 + vertices[2].getTotalTasks())).handle(any(Event.class));

http://git-wip-us.apache.org/repos/asf/tez/blob/34eb75d7/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestTaskSchedulerManager.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestTaskSchedulerManager.java b/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestTaskSchedulerManager.java
index 4db51b9..8e4e4f0 100644
--- a/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestTaskSchedulerManager.java
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestTaskSchedulerManager.java
@@ -191,10 +191,10 @@ public class TestTaskSchedulerManager {
         new AMSchedulerEventTALaunchRequest(mockAttemptId, resource, null, mockTaskAttempt, locHint,
             priority, containerContext, 0, 0, 0);
     schedulerHandler.taskAllocated(0, mockTaskAttempt, lr, container);
-    assertEquals(2, mockEventHandler.events.size());
-    assertTrue(mockEventHandler.events.get(1) instanceof AMContainerEventAssignTA);
+    assertEquals(1, mockEventHandler.events.size());
+    assertTrue(mockEventHandler.events.get(0) instanceof AMContainerEventAssignTA);
     AMContainerEventAssignTA assignEvent =
-        (AMContainerEventAssignTA) mockEventHandler.events.get(1);
+        (AMContainerEventAssignTA) mockEventHandler.events.get(0);
     assertEquals(priority, assignEvent.getPriority());
     assertEquals(mockAttemptId, assignEvent.getTaskAttemptId());
   }


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

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


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

Branch: refs/heads/TEZ-2980
Commit: fca31c5894c7aef9cd81555f2f1e658059d62e36
Parents: 8408a75
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Tue Jan 19 12:50:29 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Wed Jan 20 22:30:07 2016 +0530

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


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

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


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

Posted by sr...@apache.org.
http://git-wip-us.apache.org/repos/asf/tez/blob/b272c1a3/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/b272c1a3/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);
+});


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

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


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

Branch: refs/heads/TEZ-2980
Commit: 62deacbddae841a6c9419819c7d758fde9a6f589
Parents: dd0e36d
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Wed Jan 20 20:55:06 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Wed Jan 20 22:30:08 2016 +0530

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


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

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

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

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

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

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

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

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

http://git-wip-us.apache.org/repos/asf/tez/blob/62deacbd/tez-ui2/src/main/webapp/app/mixins/auto-counter-column.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/mixins/auto-counter-column.js b/tez-ui2/src/main/webapp/app/mixins/auto-counter-column.js
new file mode 100644
index 0000000..7820e4a
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/mixins/auto-counter-column.js
@@ -0,0 +1,69 @@
+/*global more*/
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+var MoreObject = more.Object;
+
+export default Ember.Mixin.create({
+  columnSelectorMessage: "<span class='per-io'>Per-IO counter</span> selection wouldn't persist.",
+
+  getCounterColumns: function () {
+    var columns = [],
+        records = this.get("model"),
+        counterHash = {};
+
+    this._super().forEach(function (column) {
+      var groupHash =
+          counterHash[column.counterGroupName] =
+          counterHash[column.counterGroupName] || {};
+      groupHash[column.counterName] = column.counterName;
+    });
+
+    if(records) {
+      records.forEach(function (record) {
+        let counterGroups = Ember.get(record, 'counterGroups');
+
+        if(counterGroups) {
+          counterGroups.forEach(function (group) {
+            var groupHash =
+                counterHash[group.counterGroupName] =
+                counterHash[group.counterGroupName] || {};
+
+            group.counters.forEach(function (counter) {
+              groupHash[counter.counterName] = counter.counterName;
+            });
+          });
+        }
+      });
+    }
+
+    MoreObject.forEach(counterHash, function (groupName, counters) {
+      MoreObject.forEach(counters, function (counterName) {
+        columns.push({
+          counterName: counterName,
+          counterGroupName: groupName
+        });
+      });
+    });
+
+    return columns;
+  }
+});

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

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

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

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

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

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

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

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

http://git-wip-us.apache.org/repos/asf/tez/blob/62deacbd/tez-ui2/src/main/webapp/tests/unit/mixins/auto-counter-column-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/mixins/auto-counter-column-test.js b/tez-ui2/src/main/webapp/tests/unit/mixins/auto-counter-column-test.js
new file mode 100644
index 0000000..191eb67
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/mixins/auto-counter-column-test.js
@@ -0,0 +1,64 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import AutoCounterColumnMixin from '../../../mixins/auto-counter-column';
+import { module, test } from 'qunit';
+
+module('Unit | Mixin | auto counter column');
+
+test('Basic creation test', function(assert) {
+  let AutoCounterColumnObject = Ember.Object.extend(AutoCounterColumnMixin);
+  let subject = AutoCounterColumnObject.create();
+
+  assert.ok(subject);
+  assert.ok(subject.columnSelectorMessage);
+  assert.ok(subject.getCounterColumns);
+});
+
+test('getCounterColumns test', function(assert) {
+  let TestParent = Ember.Object.extend({
+    getCounterColumns: function () { return []; }
+  });
+
+  let AutoCounterColumnObject = TestParent.extend(AutoCounterColumnMixin);
+  let subject = AutoCounterColumnObject.create({
+    model: [{
+      counterGroups: [{
+        counterGroupName: "gp1",
+        counters: [{counterName: "c11"}, {counterName: "c12"}]
+      }]
+    }, {
+      counterGroups: [{
+        counterGroupName: "gp2",
+        counters: [{counterName: "c21"}, {counterName: "c22"}]
+      }]
+    }]
+  });
+
+  let columns = subject.getCounterColumns();
+  assert.equal(columns.length, 4);
+  assert.equal(columns[0].counterGroupName, "gp1");
+  assert.equal(columns[0].counterName, "c11");
+  assert.equal(columns[1].counterGroupName, "gp1");
+  assert.equal(columns[1].counterName, "c12");
+  assert.equal(columns[2].counterGroupName, "gp2");
+  assert.equal(columns[2].counterName, "c21");
+  assert.equal(columns[3].counterGroupName, "gp2");
+  assert.equal(columns[3].counterName, "c22");
+});

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


[42/50] [abbrv] 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/b272c1a3
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/b272c1a3
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/b272c1a3

Branch: refs/heads/TEZ-2980
Commit: b272c1a37b52167af5560b8bda432ac6e144ac43
Parents: 3888786
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Fri Jan 15 17:29:30 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Wed Jan 20 22:30:07 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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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/b272c1a3/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);
+});


[05/50] [abbrv] tez git commit: TEZ-2972. addendum for findbugs. (Jason Lowe via bikas)

Posted by sr...@apache.org.
TEZ-2972. addendum for findbugs. (Jason Lowe via bikas)


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

Branch: refs/heads/TEZ-2980
Commit: 12bd908f4b5b95d993635b051646a04e76c90db6
Parents: 4ed7d1a
Author: Bikas Saha <bi...@apache.org>
Authored: Fri Dec 25 16:54:09 2015 -0800
Committer: Bikas Saha <bi...@apache.org>
Committed: Fri Dec 25 16:54:09 2015 -0800

----------------------------------------------------------------------
 tez-dag/findbugs-exclude.xml | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/12bd908f/tez-dag/findbugs-exclude.xml
----------------------------------------------------------------------
diff --git a/tez-dag/findbugs-exclude.xml b/tez-dag/findbugs-exclude.xml
index 43046d9..f106c8b 100644
--- a/tez-dag/findbugs-exclude.xml
+++ b/tez-dag/findbugs-exclude.xml
@@ -19,6 +19,7 @@
       <Field name="blacklistDisablePercent" />
       <Field name="maxTaskFailuresPerNode" />
       <Field name="nodeBlacklistingEnabled" />
+      <Field name="nodeUpdatesRescheduleEnabled" />
     </Or>
     <Bug pattern="IS2_INCONSISTENT_SYNC" />
   </Match>


[03/50] [abbrv] tez git commit: TEZ-3011. Link Vertex Name in Dag Tasks/Task Attempts to Vertex (jeagles)

Posted by sr...@apache.org.
TEZ-3011. Link Vertex Name in Dag Tasks/Task Attempts to Vertex (jeagles)


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

Branch: refs/heads/TEZ-2980
Commit: c34c54f70214560ed20cbb885da90230346b9e47
Parents: 6486435
Author: Jonathan Eagles <je...@yahoo-inc.com>
Authored: Fri Dec 18 01:44:26 2015 -0600
Committer: Jonathan Eagles <je...@yahoo-inc.com>
Committed: Fri Dec 18 01:45:36 2015 -0600

----------------------------------------------------------------------
 CHANGES.txt                                                 | 2 ++
 .../app/scripts/controllers/dag-task-attempts-controller.js | 9 +++++++--
 tez-ui/src/main/webapp/app/scripts/controllers/dag_tasks.js | 9 +++++++--
 3 files changed, 16 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/c34c54f7/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 17142ce..0ad2203 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -10,6 +10,7 @@ INCOMPATIBLE CHANGES
   TEZ-604. Revert temporary changes made in TEZ-603 to kill the provided tez session, if running a MapReduce job.
 
 ALL CHANGES:
+  TEZ-3011. Link Vertex Name in Dag Tasks/Task Attempts to Vertex
   TEZ-3006. Remove unused import in TestHistoryParser.
   TEZ-2910. Set caller context for tracing ( integrate with HDFS-9184 ).
   TEZ-2976. Recovery fails when InputDescriptor is changed during input initialization.
@@ -296,6 +297,7 @@ INCOMPATIBLE CHANGES
   TEZ-2949. Allow duplicate dag names within session for Tez.
 
 ALL CHANGES
+  TEZ-3011. Link Vertex Name in Dag Tasks/Task Attempts to Vertex
   TEZ-2538. ADDITIONAL_SPILL_COUNT wrongly populated for DefaultSorter with multiple partitions.
   TEZ-3006. Remove unused import in TestHistoryParser.
   TEZ-2979. FlakyTest: org.apache.tez.history.TestHistoryParser.

http://git-wip-us.apache.org/repos/asf/tez/blob/c34c54f7/tez-ui/src/main/webapp/app/scripts/controllers/dag-task-attempts-controller.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/controllers/dag-task-attempts-controller.js b/tez-ui/src/main/webapp/app/scripts/controllers/dag-task-attempts-controller.js
index db5b1fd..7a7af91 100644
--- a/tez-ui/src/main/webapp/app/scripts/controllers/dag-task-attempts-controller.js
+++ b/tez-ui/src/main/webapp/app/scripts/controllers/dag-task-attempts-controller.js
@@ -161,10 +161,15 @@ App.DagTaskAttemptsController = App.TablePageController.extend({
       {
         id: 'vertexName',
         headerCellName: 'Vertex Name',
+        templateName: 'components/basic-table/linked-cell',
         contentPath: 'vertexID',
         getCellContent: function(row) {
-          var vertexId = row.get('vertexID');
-          return vertexIdToNameMap[vertexId] || vertexId;
+          var vertexId = row.get('vertexID') || '';
+          return {
+            linkTo: 'vertex',
+            displayText: vertexIdToNameMap[vertexId] || vertexId,
+            entityId: vertexId
+          };
         },
         getSearchValue: function (row) {
           var vertexId = row.get('vertexID');

http://git-wip-us.apache.org/repos/asf/tez/blob/c34c54f7/tez-ui/src/main/webapp/app/scripts/controllers/dag_tasks.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/controllers/dag_tasks.js b/tez-ui/src/main/webapp/app/scripts/controllers/dag_tasks.js
index 8ab20e3..2413a24 100644
--- a/tez-ui/src/main/webapp/app/scripts/controllers/dag_tasks.js
+++ b/tez-ui/src/main/webapp/app/scripts/controllers/dag_tasks.js
@@ -126,10 +126,15 @@ App.DagTasksController = App.TablePageController.extend({
       {
         id: 'vertexName',
         headerCellName: 'Vertex Name',
+        templateName: 'components/basic-table/linked-cell',
         contentPath: 'vertexID',
         getCellContent: function(row) {
-          var vertexId = row.get('vertexID');
-          return vertexIdToNameMap[vertexId] || vertexId;
+          var vertexId = row.get('vertexID') || '';
+          return {
+            linkTo: 'vertex',
+            displayText: vertexIdToNameMap[vertexId] || vertexId,
+            entityId: vertexId
+          };
         },
         getSearchValue: function(row) {
           var vertexId = row.get('vertexID');


[45/50] [abbrv] tez git commit: TEZ-3039. Tez UI 2: Create all sub-pages for DAG (sree)

Posted by sr...@apache.org.
TEZ-3039. Tez UI 2: Create all sub-pages for DAG (sree)


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

Branch: refs/heads/TEZ-2980
Commit: 7a8d82691779e1dfbc26266b6a51967c7d26bf40
Parents: a94aeb2
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Mon Jan 18 21:25:54 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Wed Jan 20 22:30:07 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |  1 +
 tez-ui2/src/main/webapp/app/adapters/attempt.js | 22 ++++++
 tez-ui2/src/main/webapp/app/adapters/task.js    | 22 ++++++
 .../src/main/webapp/app/adapters/timeline.js    | 77 +++++++++++++++++++-
 tez-ui2/src/main/webapp/app/adapters/vertex.js  | 22 ++++++
 .../main/webapp/app/controllers/dag/attempts.js | 61 +++++++++++++++-
 .../main/webapp/app/controllers/dag/tasks.js    | 49 ++++++++++++-
 .../main/webapp/app/controllers/dag/vertices.js | 61 +++++++++++++++-
 tez-ui2/src/main/webapp/app/controllers/dags.js |  2 +-
 .../main/webapp/app/controllers/table-page.js   | 15 +++-
 tez-ui2/src/main/webapp/app/models/attempt.js   | 71 ++++++++++++++++++
 tez-ui2/src/main/webapp/app/models/dag.js       |  2 +
 tez-ui2/src/main/webapp/app/models/task.js      | 62 ++++++++++++++++
 tez-ui2/src/main/webapp/app/models/vertex.js    | 61 ++++++++++++++++
 .../src/main/webapp/app/routes/dag/attempts.js  |  8 +-
 tez-ui2/src/main/webapp/app/routes/dag/tasks.js |  8 +-
 .../src/main/webapp/app/routes/dag/vertices.js  |  8 +-
 .../src/main/webapp/app/serializers/attempt.js  | 30 ++++++++
 tez-ui2/src/main/webapp/app/serializers/dag.js  | 21 +++++-
 tez-ui2/src/main/webapp/app/serializers/task.js | 26 +++++++
 .../src/main/webapp/app/serializers/timeline.js | 13 ++++
 .../src/main/webapp/app/serializers/vertex.js   | 44 +++++++++++
 .../main/webapp/app/templates/dag/attempts.hbs  | 16 +++-
 .../src/main/webapp/app/templates/dag/tasks.hbs | 16 +++-
 .../main/webapp/app/templates/dag/vertices.hbs  | 16 +++-
 .../src/main/webapp/config/default-app-conf.js  |  3 +-
 .../webapp/tests/unit/adapters/attempt-test.js  | 30 ++++++++
 .../webapp/tests/unit/adapters/task-test.js     | 29 ++++++++
 .../webapp/tests/unit/adapters/timeline-test.js | 53 ++++++++++++++
 .../webapp/tests/unit/adapters/vertex-test.js   | 30 ++++++++
 .../tests/unit/controllers/dag/attempts-test.js |  1 +
 .../tests/unit/controllers/dag/tasks-test.js    |  1 +
 .../tests/unit/controllers/dag/vertices-test.js |  1 +
 .../webapp/tests/unit/models/attempt-test.js    | 63 ++++++++++++++++
 .../main/webapp/tests/unit/models/task-test.js  | 55 ++++++++++++++
 .../webapp/tests/unit/models/vertex-test.js     | 48 ++++++++++++
 .../tests/unit/routes/dag/attempts-test.js      |  1 +
 .../webapp/tests/unit/routes/dag/tasks-test.js  |  1 +
 .../tests/unit/routes/dag/vertices-test.js      |  1 +
 .../tests/unit/serializers/attempt-test.js      | 31 ++++++++
 .../webapp/tests/unit/serializers/dag-test.js   | 22 ++++++
 .../webapp/tests/unit/serializers/task-test.js  | 31 ++++++++
 .../tests/unit/serializers/timeline-test.js     |  1 +
 .../tests/unit/serializers/vertex-test.js       | 49 +++++++++++++
 44 files changed, 1163 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index 925dc7f..372369a 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -14,3 +14,4 @@ ALL CHANGES:
   TEZ-3027. Tez UI 2: Add header and footer elements
   TEZ-2986. Tez UI 2: Implement All DAGs page
   TEZ-3038. Tez UI 2: Create DAG details page
+  TEZ-3039. Tez UI 2: Create all sub-pages for DAG

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/app/adapters/attempt.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/attempt.js b/tez-ui2/src/main/webapp/app/adapters/attempt.js
new file mode 100644
index 0000000..b47e05f
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/adapters/attempt.js
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import TimelineAdapter from './timeline';
+
+export default TimelineAdapter.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/app/adapters/task.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/task.js b/tez-ui2/src/main/webapp/app/adapters/task.js
new file mode 100644
index 0000000..b47e05f
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/adapters/task.js
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import TimelineAdapter from './timeline';
+
+export default TimelineAdapter.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/app/adapters/timeline.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/timeline.js b/tez-ui2/src/main/webapp/app/adapters/timeline.js
index 454cbc9..6e06c7b 100644
--- a/tez-ui2/src/main/webapp/app/adapters/timeline.js
+++ b/tez-ui2/src/main/webapp/app/adapters/timeline.js
@@ -1,3 +1,5 @@
+/*global more*/
+
 /**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -18,8 +20,81 @@
 
 import AbstractAdapter from './abstract';
 
+var MoreObject = more.Object;
+
 export default AbstractAdapter.extend({
   serverName: "timeline",
 
-  // Any timeline specific adapter changes must be added here
+  filters: {
+    dagID: 'TEZ_DAG_ID',
+    vertexID: 'TEZ_VERTEX_ID',
+    taskID: 'TEZ_TASK_ID',
+    attemptID: 'TEZ_TASK_ATTEMPT_ID',
+    hiveQueryID: 'HIVE_QUERY_ID',
+    appID: 'applicationId'
+  },
+
+  stringifyFilters: function (filters) {
+    var filterStrs = [];
+
+    MoreObject.forEach(filters, function (key, value) {
+      filterStrs.push(`${key}:${value}`);
+    });
+
+    return filterStrs.join(",");
+  },
+
+  normalizeQuery: function(query) {
+    var primaryFilter = null, // Primary must have just one single filter
+        secondaryFilters = {},
+        normalQuery = {},
+        filterStr;
+
+    MoreObject.forEach(query, function (key, value) {
+      var filter = this.get(`filters.${key}`);
+
+      if(filter) {
+        if(!primaryFilter) {
+          primaryFilter = {};
+          primaryFilter[filter] = value;
+        }
+        else {
+          secondaryFilters[filter] = value;
+        }
+      }
+      else {
+        normalQuery[key] = value;
+      }
+    }, this);
+
+    // primaryFilter
+    if(primaryFilter) {
+      filterStr = this.stringifyFilters(primaryFilter);
+    }
+    if(filterStr) {
+      normalQuery.primaryFilter = filterStr;
+    }
+
+    // secondaryFilters
+    filterStr = this.stringifyFilters(secondaryFilters);
+    if(filterStr) {
+      normalQuery.secondaryFilter = filterStr;
+    }
+
+    // Limit
+    normalQuery.limit = normalQuery.limit || this.get("env.app.rowLoadLimit");
+
+    return normalQuery;
+  },
+
+  query: function (store, type, query/*, recordArray*/) {
+    var queryParams = query.params,
+        url = this.buildURL(type.modelName, null, null, 'query', queryParams, query.urlParams);
+
+    if(query) {
+      queryParams = this.normalizeQuery(queryParams);
+    }
+
+    return this._loaderAjax(url, queryParams, query.nameSpace);
+  }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/app/adapters/vertex.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/vertex.js b/tez-ui2/src/main/webapp/app/adapters/vertex.js
new file mode 100644
index 0000000..b47e05f
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/adapters/vertex.js
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import TimelineAdapter from './timeline';
+
+export default TimelineAdapter.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js b/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
index d5efc50..1ffc00c 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/attempts.js
@@ -16,11 +16,66 @@
  * limitations under the License.
  */
 
-import PageController from '../page';
+import TablePageController from '../table-page';
+import ColumnDefinition from 'em-table/utils/column-definition';
 
-export default PageController.extend({
+export default TablePageController.extend({
   breadcrumbs: [{
     text: "All Attempts",
     routeName: "dag.attempts",
-  }]
+  }],
+
+  columns: ColumnDefinition.make([{
+    id: 'index',
+    headerTitle: 'Attempt No',
+    contentPath: 'index'
+  },{
+    id: 'taskIndex',
+    headerTitle: 'Task Index',
+    contentPath: 'taskIndex'
+  },{
+    id: 'vertexName',
+    headerTitle: 'Vertex Index',
+    contentPath: 'vertexName'
+  },{
+    id: 'status',
+    headerTitle: 'Status',
+    contentPath: 'status',
+    cellComponentName: 'em-table-status-cell'
+  },{
+    id: 'progress',
+    headerTitle: 'Progress',
+    contentPath: 'progress',
+    cellComponentName: 'em-table-progress-cell',
+    observePath: true
+  },{
+    id: 'startTime',
+    headerTitle: 'Start Time',
+    contentPath: 'startTime',
+    cellDefinition: {
+      type: 'date'
+    }
+  },{
+    id: 'endTime',
+    headerTitle: 'End Time',
+    contentPath: 'endTime',
+    cellDefinition: {
+      type: 'date'
+    }
+  },{
+    id: 'duration',
+    headerTitle: 'Duration',
+    contentPath: 'duration',
+    cellDefinition: {
+      type: 'duration'
+    }
+  },{
+    id: 'containerID',
+    headerTitle: 'Container',
+    contentPath: 'containerID'
+  },{
+    id: 'nodeID',
+    headerTitle: 'Node',
+    contentPath: 'nodeID'
+  }])
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js b/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
index e83df5d..7c91deb 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/tasks.js
@@ -16,11 +16,54 @@
  * limitations under the License.
  */
 
-import PageController from '../page';
+import TablePageController from '../table-page';
+import ColumnDefinition from 'em-table/utils/column-definition';
 
-export default PageController.extend({
+export default TablePageController.extend({
   breadcrumbs: [{
     text: "All Tasks",
     routeName: "dag.tasks",
-  }]
+  }],
+
+  columns: ColumnDefinition.make([{
+    id: 'index',
+    headerTitle: 'Task Index',
+    contentPath: 'index'
+  },{
+    id: 'vertexName',
+    headerTitle: 'Vertex Name',
+    contentPath: 'vertexName'
+  },{
+    id: 'status',
+    headerTitle: 'Status',
+    contentPath: 'status',
+    cellComponentName: 'em-table-status-cell'
+  },{
+    id: 'progress',
+    headerTitle: 'Progress',
+    contentPath: 'progress',
+    cellComponentName: 'em-table-progress-cell',
+    observePath: true
+  },{
+    id: 'startTime',
+    headerTitle: 'Start Time',
+    contentPath: 'startTime',
+    cellDefinition: {
+      type: 'date'
+    }
+  },{
+    id: 'endTime',
+    headerTitle: 'End Time',
+    contentPath: 'endTime',
+    cellDefinition: {
+      type: 'date'
+    }
+  },{
+    id: 'duration',
+    headerTitle: 'Duration',
+    contentPath: 'duration',
+    cellDefinition: {
+      type: 'duration'
+    }
+  }])
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js b/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
index e001652..7bdc229 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dag/vertices.js
@@ -16,11 +16,66 @@
  * limitations under the License.
  */
 
-import PageController from '../page';
+import TablePageController from '../table-page';
+import ColumnDefinition from 'em-table/utils/column-definition';
 
-export default PageController.extend({
+export default TablePageController.extend({
   breadcrumbs: [{
     text: "All Vertices",
     routeName: "dag.vertices",
-  }]
+  }],
+
+  columns: ColumnDefinition.make([{
+    id: 'name',
+    headerTitle: 'Vertex Name',
+    contentPath: 'name',
+  },{
+    id: 'entityID',
+    headerTitle: 'Vertex Id',
+    contentPath: 'entityID'
+  },{
+    id: 'status',
+    headerTitle: 'Status',
+    contentPath: 'status',
+    cellComponentName: 'em-table-status-cell'
+  },{
+    id: 'progress',
+    headerTitle: 'Progress',
+    contentPath: 'progress',
+    cellComponentName: 'em-table-progress-cell',
+    observePath: true
+  },{
+    id: 'startTime',
+    headerTitle: 'Start Time',
+    contentPath: 'startTime',
+    cellDefinition: {
+      type: 'date'
+    }
+  },{
+    id: 'endTime',
+    headerTitle: 'End Time',
+    contentPath: 'endTime',
+    cellDefinition: {
+      type: 'date'
+    }
+  },{
+    id: 'duration',
+    headerTitle: 'Duration',
+    contentPath: 'duration',
+    cellDefinition: {
+      type: 'duration'
+    }
+  },{
+    id: 'firstTaskStartTime',
+    headerTitle: 'First Task Start Time',
+    contentPath: 'firstTaskStartTime',
+    cellDefinition: {
+     type: 'date'
+    }
+  },{
+    id: 'processorClassName',
+    headerTitle: 'Processor Class',
+    contentPath: 'processorClassName',
+  }])
+
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/app/controllers/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dags.js b/tez-ui2/src/main/webapp/app/controllers/dags.js
index 354f4f8..8d7e73e 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dags.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dags.js
@@ -24,7 +24,7 @@ export default TablePageController.extend({
   breadcrumbs: [],
 
   columns: ColumnDefinition.make([{
-    id: 'dagName',
+    id: 'name',
     headerTitle: 'Dag Name',
     contentPath: 'name',
     cellComponentName: 'em-table-linked-cell',

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/app/controllers/table-page.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/table-page.js b/tez-ui2/src/main/webapp/app/controllers/table-page.js
index 14219d9..1f2fe57 100644
--- a/tez-ui2/src/main/webapp/app/controllers/table-page.js
+++ b/tez-ui2/src/main/webapp/app/controllers/table-page.js
@@ -16,7 +16,10 @@
  * limitations under the License.
  */
 
+import Ember from 'ember';
+
 import PageController from './page';
+import TableDefinition from 'em-table/utils/table-definition';
 
 export default PageController.extend({
   queryParams: ["rowCount", "searchText", "sortColumnId", "sortOrder", "pageNo"],
@@ -26,6 +29,16 @@ export default PageController.extend({
   sortOrder: "",
   pageNo: 1,
 
+  definition: Ember.computed(function () {
+    return TableDefinition.create({
+      rowCount: this.get("rowCount"),
+      searchText: this.get("searchText"),
+      sortColumnId: this.get("sortColumnId"),
+      sortOrder: this.get("sortOrder"),
+      pageNo: this.get("pageNo")
+    });
+  }),
+
   actions: {
     searchChanged: function (searchText) {
       this.set("searchText", searchText);
@@ -41,7 +54,7 @@ export default PageController.extend({
       this.set("rowCount", rowCount);
     },
     pageChanged: function (pageNum) {
-      this.set("pageNum", pageNum);
+      this.set("pageNo", pageNum);
     },
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/app/models/attempt.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/attempt.js b/tez-ui2/src/main/webapp/app/models/attempt.js
new file mode 100644
index 0000000..eb99169
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/models/attempt.js
@@ -0,0 +1,71 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import DS from 'ember-data';
+
+import TimelineModel from './timeline';
+/*
+  Inherited properties
+
+  entityID - String
+  appID - Computed from entityID
+
+  status - String
+  progress - Computed from status
+
+  startTime - Number
+  endTime - Number
+  duration - Computed from start & end times
+
+  counterGroups - Array
+  counterHash - Computed from counterGroups
+*/
+
+export default TimelineModel.extend({
+  needs: {
+    dag: {
+      type: "dag",
+      idKey: "dagID",
+      silent: true
+    }
+  },
+
+  index: Ember.computed("entityID", function () {
+    var idParts = this.get("entityID").split("_");
+    return idParts[Math.max(idParts.length - 1, 1)];
+  }),
+
+  taskID: DS.attr('string'),
+  taskIndex: Ember.computed("taskID", function () {
+    var idParts = this.get("taskID").split("_");
+    return idParts.slice(Math.max(idParts.length - 2, 1)).join("_");
+  }),
+
+  vertexID: DS.attr('string'),
+  vertexName: Ember.computed("vertexID", "dag", function () {
+    var vertexID = this.get("vertexID");
+    return this.get(`dag.vertexIdNameMap.${vertexID}`);
+  }),
+
+  dagID: DS.attr('string'),
+  dag: DS.attr('object'), // Auto-loaded by need
+
+  containerID: DS.attr('string'),
+  nodeID: DS.attr('string'),
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/app/models/dag.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/dag.js b/tez-ui2/src/main/webapp/app/models/dag.js
index 4e9ff7c..2efb65f 100644
--- a/tez-ui2/src/main/webapp/app/models/dag.js
+++ b/tez-ui2/src/main/webapp/app/models/dag.js
@@ -48,4 +48,6 @@ export default TimelineModel.extend({
   queue: Ember.computed("app", function () {
     return this.get("app.queue");
   }),
+
+  vertexIdNameMap: DS.attr("object"),
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/app/models/task.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/task.js b/tez-ui2/src/main/webapp/app/models/task.js
new file mode 100644
index 0000000..2ded910
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/models/task.js
@@ -0,0 +1,62 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import DS from 'ember-data';
+
+import TimelineModel from './timeline';
+/*
+  Inherited properties
+
+  entityID - String
+  appID - Computed from entityID
+
+  status - String
+  progress - Computed from status
+
+  startTime - Number
+  endTime - Number
+  duration - Computed from start & end times
+
+  counterGroups - Array
+  counterHash - Computed from counterGroups
+*/
+
+export default TimelineModel.extend({
+  needs: {
+    dag: {
+      type: "dag",
+      idKey: "dagID",
+      silent: true
+    }
+  },
+
+  index: Ember.computed("entityID", function () {
+    var idParts = this.get("entityID").split("_");
+    return idParts.slice(Math.max(idParts.length - 2, 1)).join("_");
+  }),
+
+  vertexID: DS.attr('string'),
+  vertexName: Ember.computed("vertexID", "dag", function () {
+    var vertexID = this.get("vertexID");
+    return this.get(`dag.vertexIdNameMap.${vertexID}`);
+  }),
+
+  dagID: DS.attr('string'),
+  dag: DS.attr('object'), // Auto-loaded by need
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/app/models/vertex.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/vertex.js b/tez-ui2/src/main/webapp/app/models/vertex.js
new file mode 100644
index 0000000..dcdb0f2
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/models/vertex.js
@@ -0,0 +1,61 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import DS from 'ember-data';
+
+import TimelineModel from './timeline';
+/*
+  Inherited properties
+
+  entityID - String
+  appID - Computed from entityID
+
+  status - String
+  progress - Computed from status
+
+  startTime - Number
+  endTime - Number
+  duration - Computed from start & end times
+
+  counterGroups - Array
+  counterHash - Computed from counterGroups
+*/
+
+export default TimelineModel.extend({
+  name: DS.attr('string'),
+
+  firstTaskStartTime: DS.attr('number'),
+
+  numTasks: DS.attr('number'),
+  failedTasks: DS.attr('number'),
+  sucessfulTasks: DS.attr('number'),
+  killedTasks: DS.attr('number'),
+
+  runningTasks: Ember.computed("status", function () {
+    return this.get("status") === 'SUCCEEDED' ? 0 : null;
+  }),
+  pendingTasks: Ember.computed("status", function () {
+    return this.get("status") === 'SUCCEEDED' ? 0 : null;
+  }),
+
+  failedTaskAttempts: DS.attr('number'),
+  killedTaskAttempts: DS.attr('number'),
+
+  processorClassName: DS.attr('string'),
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/app/routes/dag/attempts.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/dag/attempts.js b/tez-ui2/src/main/webapp/app/routes/dag/attempts.js
index 5de1cab..3a05867 100644
--- a/tez-ui2/src/main/webapp/app/routes/dag/attempts.js
+++ b/tez-ui2/src/main/webapp/app/routes/dag/attempts.js
@@ -20,10 +20,16 @@ import Ember from 'ember';
 import AbstractRoute from '../abstract';
 
 export default AbstractRoute.extend({
-  title: "DAG Details",
+  title: "All Attempts",
 
   setupController: function (controller, model) {
     this._super(controller, model);
     Ember.run.later(this, "startCrumbBubble");
   },
+
+  load: function (/*value, query*/) {
+    return this.get("loader").query('attempt', {
+      dagID: this.modelFor("dag").id
+    });
+  }
 });

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

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

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/app/serializers/attempt.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/attempt.js b/tez-ui2/src/main/webapp/app/serializers/attempt.js
new file mode 100644
index 0000000..d7e2a7d
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/serializers/attempt.js
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import TimelineSerializer from './timeline';
+
+export default TimelineSerializer.extend({
+  maps: {
+    taskID: 'primaryfilters.TEZ_TASK_ID.0',
+    vertexID: 'primaryfilters.TEZ_VERTEX_ID.0',
+    dagID: 'primaryfilters.TEZ_DAG_ID.0',
+
+    containerID: 'otherinfo.containerId',
+    nodeID: 'otherinfo.nodeId',
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/app/serializers/dag.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/dag.js b/tez-ui2/src/main/webapp/app/serializers/dag.js
index 35c53ba..00113e4 100644
--- a/tez-ui2/src/main/webapp/app/serializers/dag.js
+++ b/tez-ui2/src/main/webapp/app/serializers/dag.js
@@ -1,3 +1,4 @@
+/*global more*/
 /**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -20,6 +21,8 @@ import Ember from 'ember';
 
 import TimelineSerializer from './timeline';
 
+var MoreObject = more.Object;
+
 function getStatus(source) {
   var status = Ember.get(source, 'otherinfo.status') || Ember.get(source, 'primaryfilters.status.0'),
       event = source.events;
@@ -86,9 +89,21 @@ function getContainerLogs(source) {
   return containerLogs;
 }
 
+function getIdNameMap(source) {
+  var nameIdMap = Ember.get(source, 'otherinfo.vertexNameIdMapping'),
+      idNameMap = {};
+
+  if(nameIdMap) {
+    MoreObject.forEach(nameIdMap, function (name, id) {
+      idNameMap[id] = name;
+    });
+  }
+
+  return idNameMap;
+}
+
 export default TimelineSerializer.extend({
   maps: {
-    entityID: 'entity',
     name: 'primaryfilters.dagName.0',
 
     user: 'primaryfilters.user.0',
@@ -101,11 +116,11 @@ export default TimelineSerializer.extend({
     endTime: getEndTime,
     // duration
 
-    appID: 'otherinfo.applicationId',
+    // appID
     domain: 'domain',
     // queue
     containerLogs: getContainerLogs,
 
-    counterGroups: 'otherinfo.counters.counterGroups'
+    vertexIdNameMap: getIdNameMap
   }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/app/serializers/task.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/task.js b/tez-ui2/src/main/webapp/app/serializers/task.js
new file mode 100644
index 0000000..7918e89
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/serializers/task.js
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import TimelineSerializer from './timeline';
+
+export default TimelineSerializer.extend({
+  maps: {
+    vertexID: 'primaryfilters.TEZ_VERTEX_ID.0',
+    dagID: 'primaryfilters.TEZ_DAG_ID.0',
+  }
+});

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

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/app/serializers/vertex.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/vertex.js b/tez-ui2/src/main/webapp/app/serializers/vertex.js
new file mode 100644
index 0000000..88ee5d3
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/serializers/vertex.js
@@ -0,0 +1,44 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import TimelineSerializer from './timeline';
+
+function getProcessorClass(source) {
+  var name = Ember.get(source, 'otherinfo.processorClassName') || "";
+  return name.substr(name.lastIndexOf('.') + 1);
+}
+
+export default TimelineSerializer.extend({
+  maps: {
+    name: 'otherinfo.vertexName',
+
+    firstTaskStartTime: 'otherinfo.stats.firstTaskStartTime',
+
+    numTasks: 'otherinfo.numTasks',
+    failedTasks: 'otherinfo.numFailedTasks',
+    sucessfulTasks: 'otherinfo.numSucceededTasks',
+    killedTasks: 'otherinfo.numKilledTasks',
+
+    failedTaskAttempts: 'otherinfo.numFailedTaskAttempts',
+    killedTaskAttempts: 'otherinfo.numKilledTaskAttempts',
+
+    processorClassName: getProcessorClass,
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/app/templates/dag/attempts.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/attempts.hbs b/tez-ui2/src/main/webapp/app/templates/dag/attempts.hbs
index 63840f5..932db09 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag/attempts.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag/attempts.hbs
@@ -16,4 +16,18 @@
  * limitations under the License.
 }}
 
-Attempts
\ No newline at end of file
+{{#if loaded}}
+  {{em-table
+    columns=columns
+    rows=model
+
+    definition=definition
+
+    searchAction="searchChanged"
+    sortAction="sortChanged"
+    rowAction="rowsChanged"
+    pageAction="pageChanged"
+  }}
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/app/templates/dag/tasks.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/tasks.hbs b/tez-ui2/src/main/webapp/app/templates/dag/tasks.hbs
index daee5b5..932db09 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag/tasks.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag/tasks.hbs
@@ -16,4 +16,18 @@
  * limitations under the License.
 }}
 
-Tasks
\ No newline at end of file
+{{#if loaded}}
+  {{em-table
+    columns=columns
+    rows=model
+
+    definition=definition
+
+    searchAction="searchChanged"
+    sortAction="sortChanged"
+    rowAction="rowsChanged"
+    pageAction="pageChanged"
+  }}
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/app/templates/dag/vertices.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/vertices.hbs b/tez-ui2/src/main/webapp/app/templates/dag/vertices.hbs
index 7f0bd85..932db09 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag/vertices.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag/vertices.hbs
@@ -16,4 +16,18 @@
  * limitations under the License.
 }}
 
-Vertices
\ No newline at end of file
+{{#if loaded}}
+  {{em-table
+    columns=columns
+    rows=model
+
+    definition=definition
+
+    searchAction="searchChanged"
+    sortAction="sortChanged"
+    rowAction="rowsChanged"
+    pageAction="pageChanged"
+  }}
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/config/default-app-conf.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/config/default-app-conf.js b/tez-ui2/src/main/webapp/config/default-app-conf.js
index e3d9076..feea181 100644
--- a/tez-ui2/src/main/webapp/config/default-app-conf.js
+++ b/tez-ui2/src/main/webapp/config/default-app-conf.js
@@ -19,6 +19,7 @@
 module.exports = { // Tez App configurations
   buildVersion: "",
   isStandalone: true, // Must be set false while running in wrapped mode
+  rowLoadLimit: 9007199254740991,
   hosts: {
     timeline: 'localhost:8188',
     rm: 'localhost:8088',
@@ -39,7 +40,7 @@ module.exports = { // Tez App configurations
       dag: 'TEZ_DAG_ID',
       vertex: 'TEZ_VERTEX_ID',
       task: 'TEZ_TASK_ID',
-      taskAttempt: 'TEZ_TASK_ATTEMPT_ID',
+      attempt: 'TEZ_TASK_ATTEMPT_ID',
 
       hiveQuery: 'HIVE_QUERY_ID',
 

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/tests/unit/adapters/attempt-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/attempt-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/attempt-test.js
new file mode 100644
index 0000000..584c46e
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/adapters/attempt-test.js
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('adapter:attempt', 'Unit | Adapter | attempt', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let adapter = this.subject();
+
+  assert.ok(adapter);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/tests/unit/adapters/task-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/task-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/task-test.js
new file mode 100644
index 0000000..ca39e56
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/adapters/task-test.js
@@ -0,0 +1,29 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('adapter:task', 'Unit | Adapter | task', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let adapter = this.subject();
+  assert.ok(adapter);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/tests/unit/adapters/timeline-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/timeline-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/timeline-test.js
index 9b1a8de..7b0e978 100644
--- a/tez-ui2/src/main/webapp/tests/unit/adapters/timeline-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/adapters/timeline-test.js
@@ -27,5 +27,58 @@ test('Basic creation test', function(assert) {
   let adapter = this.subject();
 
   assert.ok(adapter);
+  assert.ok(adapter.filters);
+  assert.ok(adapter.stringifyFilters);
+  assert.ok(adapter.normalizeQuery);
+  assert.ok(adapter.query);
+
   assert.equal(adapter.serverName, "timeline");
 });
+
+test('stringifyFilters test', function(assert) {
+  let adapter = this.subject();
+
+  assert.equal(adapter.stringifyFilters({a: 1, b: 2}), "a:1,b:2");
+  assert.throws(function () {
+    adapter.stringifyFilters();
+  });
+});
+
+test('normalizeQuery test', function(assert) {
+  let adapter = this.subject(),
+      normalQuery;
+
+  adapter.set("filters", {
+    a: "A_ID",
+    b: "B_ID",
+  });
+
+  normalQuery = adapter.normalizeQuery({a: 1, b: 2, c: 3, d: 4});
+
+  assert.deepEqual(normalQuery.primaryFilter, "A_ID:1");
+  assert.deepEqual(normalQuery.secondaryFilter, "B_ID:2");
+  assert.deepEqual(normalQuery.c, 3);
+  assert.deepEqual(normalQuery.d, 4);
+});
+
+test('query test', function(assert) {
+  let adapter = this.subject(),
+      normalQuery = {},
+      testStore = {},
+      testType = "ts",
+      testQuery = {};
+
+  assert.expect(1 + 1);
+
+  adapter.normalizeQuery = function (params) {
+    assert.equal(params, testQuery);
+    return normalQuery;
+  };
+  adapter._loaderAjax = function (url, queryParams) {
+    assert.equal(queryParams, normalQuery);
+  };
+
+  adapter.query(testStore, testType, {
+    params: testQuery
+  });
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/tests/unit/adapters/vertex-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/vertex-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/vertex-test.js
new file mode 100644
index 0000000..191f781
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/adapters/vertex-test.js
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('adapter:vertex', 'Unit | Adapter | vertex', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let adapter = this.subject();
+
+  assert.ok(adapter);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js
index 1908e69..11bb0fa 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/attempts-test.js
@@ -32,4 +32,5 @@ test('Basic creation test', function(assert) {
 
   assert.ok(controller);
   assert.ok(controller.breadcrumbs);
+  assert.ok(controller.columns);
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js
index 9d22331..073e3d3 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/tasks-test.js
@@ -32,4 +32,5 @@ test('Basic creation test', function(assert) {
 
   assert.ok(controller);
   assert.ok(controller.breadcrumbs);
+  assert.ok(controller.columns);
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
index ca6d3d9..fc75935 100644
--- a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/vertices-test.js
@@ -32,4 +32,5 @@ test('Basic creation test', function(assert) {
 
   assert.ok(controller);
   assert.ok(controller.breadcrumbs);
+  assert.ok(controller.columns);
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/tests/unit/models/attempt-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/attempt-test.js b/tez-ui2/src/main/webapp/tests/unit/models/attempt-test.js
new file mode 100644
index 0000000..7d0a78e
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/models/attempt-test.js
@@ -0,0 +1,63 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleForModel, test } from 'ember-qunit';
+
+moduleForModel('attempt', 'Unit | Model | attempt', {
+  // Specify the other units that are required for this test.
+  needs: []
+});
+
+test('Basic creation test', function(assert) {
+  let model = this.subject();
+
+  assert.ok(model);
+  assert.ok(model.index);
+  assert.ok(model.taskIndex);
+  assert.ok(model.vertexName);
+});
+
+test('index test', function(assert) {
+  let model = this.subject({
+    entityID: "1_2_3"
+  });
+
+  assert.equal(model.get("index"), "3");
+});
+
+test('taskIndex test', function(assert) {
+  let model = this.subject({
+        taskID: "1_2_3",
+      });
+
+  assert.equal(model.get("taskIndex"), "2_3");
+});
+
+test('vertexName test', function(assert) {
+  let testVertexName = "Test Vertex",
+      model = this.subject({
+        vertexID: "1_2",
+        dag: {
+          vertexIdNameMap: {
+            "1_2": testVertexName
+          }
+        }
+      });
+
+  assert.equal(model.get("vertexName"), testVertexName);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/tests/unit/models/task-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/task-test.js b/tez-ui2/src/main/webapp/tests/unit/models/task-test.js
new file mode 100644
index 0000000..3d59df6
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/models/task-test.js
@@ -0,0 +1,55 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleForModel, test } from 'ember-qunit';
+
+moduleForModel('task', 'Unit | Model | task', {
+  // Specify the other units that are required for this test.
+  needs: []
+});
+
+test('Basic creation test', function(assert) {
+  let model = this.subject();
+
+  assert.ok(model);
+  assert.ok(model.needs);
+  assert.ok(model.index);
+  assert.ok(model.vertexName);
+});
+
+test('index test', function(assert) {
+  let model = this.subject({
+        entityID: "1_2_3",
+      });
+
+  assert.equal(model.get("index"), "2_3");
+});
+
+test('vertexName test', function(assert) {
+  let testVertexName = "Test Vertex",
+      model = this.subject({
+        vertexID: "1_2",
+        dag: {
+          vertexIdNameMap: {
+            "1_2": testVertexName
+          }
+        }
+      });
+
+  assert.equal(model.get("vertexName"), testVertexName);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/tests/unit/models/vertex-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/vertex-test.js b/tez-ui2/src/main/webapp/tests/unit/models/vertex-test.js
new file mode 100644
index 0000000..bea4317
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/models/vertex-test.js
@@ -0,0 +1,48 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleForModel, test } from 'ember-qunit';
+
+moduleForModel('vertex', 'Unit | Model | vertex', {
+  // Specify the other units that are required for this test.
+  needs: []
+});
+
+test('Basic creation test', function(assert) {
+  let model = this.subject();
+
+  assert.ok(model);
+  assert.ok(model.runningTasks);
+  assert.ok(model.pendingTasks);
+});
+
+test('runningTasks test', function(assert) {
+  let model = this.subject();
+
+  assert.equal(model.get("runningTasks"), null);
+  model.set("status", "SUCCEEDED");
+  assert.equal(model.get("runningTasks"), 0);
+});
+
+test('pendingTasks test', function(assert) {
+  let model = this.subject();
+
+  assert.equal(model.get("pendingTasks"), null);
+  model.set("status", "SUCCEEDED");
+  assert.equal(model.get("pendingTasks"), 0);
+});

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

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

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

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/tests/unit/serializers/attempt-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/serializers/attempt-test.js b/tez-ui2/src/main/webapp/tests/unit/serializers/attempt-test.js
new file mode 100644
index 0000000..452b8af
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/serializers/attempt-test.js
@@ -0,0 +1,31 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('serializer:attempt', 'Unit | Serializer | attempt', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:attempt']
+});
+
+// Replace this with your real tests.
+test('Basic creation test', function(assert) {
+  let serializer = this.subject();
+
+  assert.ok(serializer);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/tests/unit/serializers/dag-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/serializers/dag-test.js b/tez-ui2/src/main/webapp/tests/unit/serializers/dag-test.js
index 7dd635c..eb39508 100644
--- a/tez-ui2/src/main/webapp/tests/unit/serializers/dag-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/serializers/dag-test.js
@@ -31,6 +31,7 @@ test('Basic creation test', function(assert) {
   assert.ok(serializer.maps.startTime);
   assert.ok(serializer.maps.endTime);
   assert.ok(serializer.maps.containerLogs);
+  assert.ok(serializer.maps.vertexIdNameMap);
 });
 
 test('atsStatus test', function(assert) {
@@ -107,3 +108,24 @@ test('containerLogs test', function(assert) {
     otherinfo: {inProgressLogsURL_1: "foo", inProgressLogsURL_2: "bar"},
   }), [{text: "1", href: "http://foo"}, {text: "2", href: "http://bar"}], "2 logs");
 });
+
+test('vertexIdNameMap test', function(assert) {
+  let serializer = this.subject(),
+      mapper = serializer.maps.vertexIdNameMap;
+
+  let nameIdMap = {
+    otherinfo: {
+      vertexNameIdMapping: {
+        name1: "ID1",
+        name2: "ID2",
+        name3: "ID3",
+      }
+    }
+  };
+
+  assert.deepEqual(mapper(nameIdMap), {
+    ID1: "name1",
+    ID2: "name2",
+    ID3: "name3",
+  });
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/tests/unit/serializers/task-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/serializers/task-test.js b/tez-ui2/src/main/webapp/tests/unit/serializers/task-test.js
new file mode 100644
index 0000000..fc79ae9
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/serializers/task-test.js
@@ -0,0 +1,31 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('serializer:task', 'Unit | Serializer | task', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:task']
+});
+
+test('Basic creation test', function(assert) {
+  let serializer = this.subject();
+
+  assert.ok(serializer);
+  assert.ok(serializer.maps);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/tests/unit/serializers/timeline-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/serializers/timeline-test.js b/tez-ui2/src/main/webapp/tests/unit/serializers/timeline-test.js
index 53f0b06..3c267ad 100644
--- a/tez-ui2/src/main/webapp/tests/unit/serializers/timeline-test.js
+++ b/tez-ui2/src/main/webapp/tests/unit/serializers/timeline-test.js
@@ -28,6 +28,7 @@ test('Basic creation test', function(assert) {
 
   assert.ok(serializer);
   assert.ok(serializer.extractArrayPayload);
+  assert.ok(serializer.maps);
 });
 
 test('extractArrayPayload test', function(assert) {

http://git-wip-us.apache.org/repos/asf/tez/blob/7a8d8269/tez-ui2/src/main/webapp/tests/unit/serializers/vertex-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/serializers/vertex-test.js b/tez-ui2/src/main/webapp/tests/unit/serializers/vertex-test.js
new file mode 100644
index 0000000..7dfb5da
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/serializers/vertex-test.js
@@ -0,0 +1,49 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('serializer:vertex', 'Unit | Serializer | vertex', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:vertex']
+});
+
+test('Basic creation test', function(assert) {
+  let serializer = this.subject();
+
+  assert.ok(serializer);
+  assert.ok(serializer.maps);
+  assert.ok(serializer.maps.processorClassName);
+});
+
+test('processorClassName test', function(assert) {
+  let serializer = this.subject(),
+      processorClassName = serializer.maps.processorClassName;
+
+  assert.equal(processorClassName({}), "");
+  assert.equal(processorClassName({
+    otherinfo: {
+      processorClassName: "foo"
+    }
+  }), "foo");
+  assert.equal(processorClassName({
+    otherinfo: {
+      processorClassName: "a.b.foo"
+    }
+  }), "foo");
+});


[39/50] [abbrv] tez git commit: TEZ-3045. Tez UI 2: Create application details page with DAGs tab (sree)

Posted by sr...@apache.org.
TEZ-3045. Tez UI 2: Create application details page with DAGs tab (sree)


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

Branch: refs/heads/TEZ-2980
Commit: 8408a75c23ee50dcecc53c82872974eec7e78980
Parents: da115b9
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Tue Jan 19 03:12:39 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Wed Jan 20 22:30:07 2016 +0530

----------------------------------------------------------------------
 TEZ-2980-CHANGES.txt                            |   1 +
 tez-ui2/src/main/webapp/app/adapters/app.js     |  22 ++++
 tez-ui2/src/main/webapp/app/controllers/app.js  |  41 ++++++
 .../src/main/webapp/app/controllers/app/dags.js |  98 +++++++++++++++
 .../main/webapp/app/controllers/app/index.js    |  22 ++++
 tez-ui2/src/main/webapp/app/controllers/dags.js |  10 +-
 tez-ui2/src/main/webapp/app/models/ahs-app.js   |  14 ++-
 tez-ui2/src/main/webapp/app/models/app.js       |  52 ++++++++
 tez-ui2/src/main/webapp/app/router.js           |   4 +-
 tez-ui2/src/main/webapp/app/routes/app.js       |  13 +-
 tez-ui2/src/main/webapp/app/routes/app/dags.js  |  35 ++++++
 tez-ui2/src/main/webapp/app/routes/app/index.js |  33 +++++
 .../src/main/webapp/app/serializers/ahs-app.js  |   6 +-
 tez-ui2/src/main/webapp/app/serializers/app.js  |  30 +++++
 .../main/webapp/app/styles/details-page.less    |   4 +
 tez-ui2/src/main/webapp/app/templates/app.hbs   |   3 +-
 .../src/main/webapp/app/templates/app/dags.hbs  |  33 +++++
 .../src/main/webapp/app/templates/app/index.hbs | 126 +++++++++++++++++++
 .../src/main/webapp/app/templates/dag/index.hbs |   4 +-
 .../src/main/webapp/config/default-app-conf.js  |   2 +-
 .../main/webapp/tests/unit/adapters/app-test.js |  30 +++++
 .../webapp/tests/unit/controllers/app-test.js   |  36 ++++++
 .../tests/unit/controllers/app/dags-test.js     |  36 ++++++
 .../tests/unit/controllers/app/index-test.js    |  34 +++++
 .../main/webapp/tests/unit/models/app-test.js   |  40 ++++++
 .../webapp/tests/unit/routes/app/dags-test.js   |  45 +++++++
 .../webapp/tests/unit/routes/app/index-test.js  |  45 +++++++
 .../webapp/tests/unit/serializers/app-test.js   |  31 +++++
 28 files changed, 833 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/8408a75c/TEZ-2980-CHANGES.txt
----------------------------------------------------------------------
diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt
index 354816e..366396f 100644
--- a/TEZ-2980-CHANGES.txt
+++ b/TEZ-2980-CHANGES.txt
@@ -17,3 +17,4 @@ ALL CHANGES:
   TEZ-3039. Tez UI 2: Create all sub-pages for DAG
   TEZ-3040. Tez UI 2: Create Vertex details page & sub tables
   TEZ-3041. Tez UI 2: Create Task & Attempt details page with sub tables
+  TEZ-3045. Tez UI 2: Create application details page with DAGs tab

http://git-wip-us.apache.org/repos/asf/tez/blob/8408a75c/tez-ui2/src/main/webapp/app/adapters/app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/app.js b/tez-ui2/src/main/webapp/app/adapters/app.js
new file mode 100644
index 0000000..b47e05f
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/adapters/app.js
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import TimelineAdapter from './timeline';
+
+export default TimelineAdapter.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/8408a75c/tez-ui2/src/main/webapp/app/controllers/app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/app.js b/tez-ui2/src/main/webapp/app/controllers/app.js
new file mode 100644
index 0000000..95159c5
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/app.js
@@ -0,0 +1,41 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import AbstractController from './abstract';
+
+export default AbstractController.extend({
+  breadcrumbs: Ember.computed("model.appID", "model.app.name", function () {
+    var name = this.get("model.app.name") || this.get("model.appID");
+
+    return [{
+      text: `Application [ ${name} ]`,
+      routeName: "app.index",
+      model: this.get("model.entityID")
+    }];
+  }),
+
+  tabs: [{
+    text: "Application Details",
+    routeName: "app.index"
+  }, {
+    text: "DAGs",
+    routeName: "app.dags"
+  }]
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/8408a75c/tez-ui2/src/main/webapp/app/controllers/app/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/app/dags.js b/tez-ui2/src/main/webapp/app/controllers/app/dags.js
new file mode 100644
index 0000000..bcb4db8
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/app/dags.js
@@ -0,0 +1,98 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import TablePageController from '../table-page';
+import ColumnDefinition from 'em-table/utils/column-definition';
+
+export default TablePageController.extend({
+  breadcrumbs: [{
+    text: "DAGs",
+    routeName: "app.dags",
+  }],
+
+  columns: ColumnDefinition.make([{
+    id: 'name',
+    headerTitle: 'Dag Name',
+    contentPath: 'name',
+    cellComponentName: 'em-table-linked-cell',
+    getCellContent: function (row) {
+      return {
+        routeName: "dag",
+        model: row.get("entityID"),
+        text: row.get("name")
+      };
+    }
+  },{
+    id: 'entityID',
+    headerTitle: 'Id',
+    contentPath: 'entityID'
+  },{
+    id: 'user',
+    headerTitle: 'Submitter',
+    contentPath: 'user'
+  },{
+    id: 'status',
+    headerTitle: 'Status',
+    contentPath: 'status',
+    cellComponentName: 'em-table-status-cell'
+  },{
+    id: 'progress',
+    headerTitle: 'Progress',
+    contentPath: 'progress',
+    cellComponentName: 'em-table-progress-cell',
+    observePath: true
+  },{
+    id: 'startTime',
+    headerTitle: 'Start Time',
+    contentPath: 'startTime',
+    cellDefinition: {
+      type: 'date'
+    }
+  },{
+    id: 'endTime',
+    headerTitle: 'End Time',
+    contentPath: 'endTime',
+    cellDefinition: {
+      type: 'date'
+    }
+  },{
+    id: 'duration',
+    headerTitle: 'Duration',
+    contentPath: 'duration',
+    cellDefinition: {
+      type: 'duration'
+    }
+  },{
+    id: 'queue',
+    headerTitle: 'Queue',
+    contentPath: 'queue'
+  },{
+    id: 'contextID',
+    headerTitle: 'Context ID',
+    contentPath: 'contextID'
+  },{
+    id: 'logs',
+    headerTitle: 'Logs',
+    contentPath: 'containerLogs',
+    cellComponentName: "em-table-linked-cell",
+    cellDefinition: {
+      target: "_blank"
+    }
+  }]),
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/8408a75c/tez-ui2/src/main/webapp/app/controllers/app/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/app/index.js b/tez-ui2/src/main/webapp/app/controllers/app/index.js
new file mode 100644
index 0000000..9745328
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/controllers/app/index.js
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import PageController from '../page';
+
+export default PageController.extend({
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/8408a75c/tez-ui2/src/main/webapp/app/controllers/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/controllers/dags.js b/tez-ui2/src/main/webapp/app/controllers/dags.js
index 8d7e73e..fced7d8 100644
--- a/tez-ui2/src/main/webapp/app/controllers/dags.js
+++ b/tez-ui2/src/main/webapp/app/controllers/dags.js
@@ -78,7 +78,15 @@ export default TablePageController.extend({
   },{
     id: 'appID',
     headerTitle: 'Application Id',
-    contentPath: 'appID'
+    contentPath: 'appID',
+    cellComponentName: 'em-table-linked-cell',
+    getCellContent: function (row) {
+      return {
+        routeName: "app",
+        model: row.get("appID"),
+        text: row.get("appID")
+      };
+    }
   },{
     id: 'queue',
     headerTitle: 'Queue',

http://git-wip-us.apache.org/repos/asf/tez/blob/8408a75c/tez-ui2/src/main/webapp/app/models/ahs-app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/ahs-app.js b/tez-ui2/src/main/webapp/app/models/ahs-app.js
index 8f4a153..ce087eb31 100644
--- a/tez-ui2/src/main/webapp/app/models/ahs-app.js
+++ b/tez-ui2/src/main/webapp/app/models/ahs-app.js
@@ -16,10 +16,14 @@
  * limitations under the License.
  */
 
+import Ember from 'ember';
+
 import DS from 'ember-data';
 import AbstractModel from './abstract';
 
 export default AbstractModel.extend({
+  entityID: DS.attr('string'),
+
   attemptID: DS.attr('string'),
 
   name: DS.attr('string'),
@@ -30,10 +34,12 @@ export default AbstractModel.extend({
   status: DS.attr('string'),
   finalStatus: DS.attr('string'),
 
-  startedTime: DS.attr('number'),
-  elapsedTime: DS.attr('number'),
-  finishedTime: DS.attr('number'),
-  submittedTime: DS.attr('number'),
+  startTime: DS.attr('number'),
+  endTime: DS.attr('number'),
+  duration: Ember.computed("startTime", "endTime", function () {
+    var duration = this.get("endTime") - this.get("startTime");
+    return duration > 0 ? duration : null;
+  }),
 
   diagnostics: DS.attr('string'),
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8408a75c/tez-ui2/src/main/webapp/app/models/app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/models/app.js b/tez-ui2/src/main/webapp/app/models/app.js
new file mode 100644
index 0000000..42fa1c5
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/models/app.js
@@ -0,0 +1,52 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import DS from 'ember-data';
+
+import TimelineModel from './timeline';
+/*
+  Inherited properties
+
+  entityID - String
+  appID - Computed from entityID
+
+  status - String
+  progress - Computed from status
+
+  startTime - Number
+  endTime - Number
+  duration - Computed from start & end times
+
+  counterGroups - Array
+  counterHash - Computed from counterGroups
+*/
+
+export default TimelineModel.extend({
+  appID: Ember.computed("entityID", function () {
+    return this.get("entityID").substr(4);
+  }),
+
+  domain: DS.attr("string"),
+
+  user: DS.attr("string"),
+
+  buildTime: DS.attr("string"),
+  tezRevision: DS.attr("string"),
+  tezVersion: DS.attr("string"),
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/8408a75c/tez-ui2/src/main/webapp/app/router.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/router.js b/tez-ui2/src/main/webapp/app/router.js
index e907cc7..d619e42 100644
--- a/tez-ui2/src/main/webapp/app/router.js
+++ b/tez-ui2/src/main/webapp/app/router.js
@@ -38,7 +38,9 @@ Router.map(function() {
     this.route('attempts');
   });
   this.route('attempt', {path: '/attempt/:attempt_id'}, function () {});
-  this.route('app', {path: '/app/:app_id'}, function () {});
+  this.route('app', {path: '/app/:app_id'}, function () {
+    this.route('dags');
+  });
 });
 
 export default Router;

http://git-wip-us.apache.org/repos/asf/tez/blob/8408a75c/tez-ui2/src/main/webapp/app/routes/app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/app.js b/tez-ui2/src/main/webapp/app/routes/app.js
index 8719170..2bbf14a 100644
--- a/tez-ui2/src/main/webapp/app/routes/app.js
+++ b/tez-ui2/src/main/webapp/app/routes/app.js
@@ -16,7 +16,16 @@
  * limitations under the License.
  */
 
-import Ember from 'ember';
+import AbstractRoute from './abstract';
 
-export default Ember.Route.extend({
+export default AbstractRoute.extend({
+  title: "Application",
+
+  loaderQueryParams: {
+    id: "app_id"
+  },
+
+  model: function (params) {
+    return this.get("loader").queryRecord('app', "tez_" + this.queryFromParams(params).id);
+  }
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/8408a75c/tez-ui2/src/main/webapp/app/routes/app/dags.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/app/dags.js b/tez-ui2/src/main/webapp/app/routes/app/dags.js
new file mode 100644
index 0000000..8c695b3
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/app/dags.js
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  title: "DAGs",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (/*value, query*/) {
+    return this.get("loader").query('dag', {
+      appID: (this.modelFor("app").id || "").substr(4)
+    });
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/8408a75c/tez-ui2/src/main/webapp/app/routes/app/index.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/routes/app/index.js b/tez-ui2/src/main/webapp/app/routes/app/index.js
new file mode 100644
index 0000000..b6768fa
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/routes/app/index.js
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  title: "Application Details",
+
+  setupController: function (controller, model) {
+    this._super(controller, model);
+    Ember.run.later(this, "startCrumbBubble");
+  },
+
+  load: function (/*value, query*/) {
+    return this.get("loader").queryRecord('app', this.modelFor("app").id);
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/8408a75c/tez-ui2/src/main/webapp/app/serializers/ahs-app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/ahs-app.js b/tez-ui2/src/main/webapp/app/serializers/ahs-app.js
index 10825b2..0c35d54 100644
--- a/tez-ui2/src/main/webapp/app/serializers/ahs-app.js
+++ b/tez-ui2/src/main/webapp/app/serializers/ahs-app.js
@@ -41,10 +41,8 @@ export default LoaderSerializer.extend({
     status: 'appState',
     finalStatus: 'finalAppStatus',
 
-    startedTime: 'startedTime',
-    elapsedTime: 'elapsedTime',
-    finishedTime: 'finishedTime',
-    submittedTime: 'submittedTime',
+    startTime: 'startedTime',
+    endTime: 'finishedTime',
 
     diagnostics: 'otherinfo.diagnostics',
   }

http://git-wip-us.apache.org/repos/asf/tez/blob/8408a75c/tez-ui2/src/main/webapp/app/serializers/app.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/app.js b/tez-ui2/src/main/webapp/app/serializers/app.js
new file mode 100644
index 0000000..86d8fa0
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/serializers/app.js
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import TimelineSerializer from './timeline';
+
+export default TimelineSerializer.extend({
+  maps: {
+    domain: 'domain',
+    user: 'otherinfo.user',
+
+    buildTime: 'otherinfo.tezVersion.buildTime',
+    tezRevision: 'otherinfo.tezVersion.revision',
+    tezVersion: 'otherinfo.tezVersion.version',
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/8408a75c/tez-ui2/src/main/webapp/app/styles/details-page.less
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/styles/details-page.less b/tez-ui2/src/main/webapp/app/styles/details-page.less
index 8c85d1f..4f65018 100644
--- a/tez-ui2/src/main/webapp/app/styles/details-page.less
+++ b/tez-ui2/src/main/webapp/app/styles/details-page.less
@@ -17,6 +17,10 @@
  */
 
 .detail-list {
+  display: inline-block;
+
+  margin: 0 10px 10px 0;
+
   table-layout: fixed;
   white-space: nowrap;
 

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

http://git-wip-us.apache.org/repos/asf/tez/blob/8408a75c/tez-ui2/src/main/webapp/app/templates/app/dags.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/app/dags.hbs b/tez-ui2/src/main/webapp/app/templates/app/dags.hbs
new file mode 100644
index 0000000..cdb28aa
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/app/dags.hbs
@@ -0,0 +1,33 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+}}
+
+{{#if loaded}}
+  {{em-table
+  columns=columns
+  rows=model
+
+  definition=definition
+
+  searchAction="searchChanged"
+  sortAction="sortChanged"
+  rowAction="rowsChanged"
+  pageAction="pageChanged"
+  }}
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/8408a75c/tez-ui2/src/main/webapp/app/templates/app/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/app/index.hbs b/tez-ui2/src/main/webapp/app/templates/app/index.hbs
new file mode 100644
index 0000000..916051b
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/templates/app/index.hbs
@@ -0,0 +1,126 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+}}
+
+{{#if loaded}}
+  {{#if model.app}}
+    <table class='detail-list'>
+      <thead>
+      <tr>
+        <th colspan=2>YARN App Details</th>
+      </tr>
+      </thead>
+      <tbody>
+      <tr>
+        <td>Status</td>
+        <td>{{em-table-status-cell content=model.app.status}}</td>
+      </tr>
+      <tr>
+        <td>Final Status</td>
+        <td>{{em-table-status-cell content=model.app.finalStatus}}</td>
+      </tr>
+      <tr>
+        <td>Start Time</td>
+        <td>{{txt model.app.startTime type="date"}}</td>
+      </tr>
+      <tr>
+        <td>End Time</td>
+        <td>{{txt model.app.endTime type="date"}}</td>
+      </tr>
+      <tr>
+        <td>Duration</td>
+        <td>{{txt model.app.duration type="duration"}}</td>
+      </tr>
+      </tbody>
+    </table>
+    <table class='detail-list'>
+      <thead>
+      <tr>
+        <th colspan=2>YARN App Description</th>
+      </tr>
+      </thead>
+      <tbody>
+      <tr>
+        <td>Application ID</td>
+        <td>{{model.app.entityID}}</td>
+      </tr>
+      <tr>
+        <td>Application Name</td>
+        <td>{{model.app.name}}</td>
+      </tr>
+      <tr>
+        <td>Queue</td>
+        <td>{{model.app.queue}}</td>
+      </tr>
+      <tr>
+        <td>Application Type</td>
+        <td>{{model.app.type}}</td>
+      </tr>
+      <tr>
+        <td>User</td>
+        <td>{{model.app.user}}</td>
+      </tr>
+      </tbody>
+    </table>
+    <br/>
+  {{/if}}
+  <table class='detail-list'>
+    <thead>
+      <tr>
+        <th colspan=2>Tez Details</th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>Application ID</td>
+        <td>{{model.appID}}</td>
+      </tr>
+      <tr>
+        <td>Domain</td>
+        <td>{{model.domain}}</td>
+      </tr>
+      <tr>
+        <td>User</td>
+        <td>{{model.user}}</td>
+      </tr>
+    </tbody>
+  </table>
+
+  <table class='detail-list'>
+    <thead>
+      <tr>
+        <th colspan=2>Version Details</th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>Build Version</td>
+        <td>{{model.tezVersion}}</td>
+      </tr>
+      <tr>
+        <td>Build Revision</td>
+        <td>{{model.tezRevision}}</td>
+      </tr>
+      <tr>
+        <td>Build Time</td>
+        <td>{{model.buildTime}}</td>
+      </tr>
+    </tbody>
+  </table>
+{{else}}
+  {{partial "partials/loading-anim"}}
+{{/if}}

http://git-wip-us.apache.org/repos/asf/tez/blob/8408a75c/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/templates/dag/index.hbs b/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
index 1bd3c21..fdb0a91 100644
--- a/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
+++ b/tez-ui2/src/main/webapp/app/templates/dag/index.hbs
@@ -47,9 +47,7 @@
       </tr>
       <tr>
         <td>Status</td>
-        <td>
-          {{em-table-status-cell content=model.status}}
-        </td>
+        <td>{{em-table-status-cell content=model.status}}</td>
       </tr>
       <tr>
         <td>Start Time</td>

http://git-wip-us.apache.org/repos/asf/tez/blob/8408a75c/tez-ui2/src/main/webapp/config/default-app-conf.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/config/default-app-conf.js b/tez-ui2/src/main/webapp/config/default-app-conf.js
index feea181..400290a 100644
--- a/tez-ui2/src/main/webapp/config/default-app-conf.js
+++ b/tez-ui2/src/main/webapp/config/default-app-conf.js
@@ -44,7 +44,7 @@ module.exports = { // Tez App configurations
 
       hiveQuery: 'HIVE_QUERY_ID',
 
-      tezApp: 'TEZ_APPLICATION'
+      app: 'TEZ_APPLICATION'
     }
   },
   hrefs: {

http://git-wip-us.apache.org/repos/asf/tez/blob/8408a75c/tez-ui2/src/main/webapp/tests/unit/adapters/app-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/app-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/app-test.js
new file mode 100644
index 0000000..dd2db50
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/adapters/app-test.js
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('adapter:app', 'Unit | Adapter | dag', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let adapter = this.subject();
+
+  assert.ok(adapter);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/8408a75c/tez-ui2/src/main/webapp/tests/unit/controllers/app-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/app-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/app-test.js
new file mode 100644
index 0000000..304321e
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/app-test.js
@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:dag', 'Unit | Controller | dag', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+  assert.ok(controller.tabs);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/8408a75c/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js
new file mode 100644
index 0000000..10ba8a3
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/app/dags-test.js
@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:app/dags', 'Unit | Controller | vertex/attempts', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+  assert.ok(controller.breadcrumbs);
+  assert.ok(controller.columns);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/8408a75c/tez-ui2/src/main/webapp/tests/unit/controllers/app/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/app/index-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/app/index-test.js
new file mode 100644
index 0000000..c2004ba
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/controllers/app/index-test.js
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:app/index', 'Unit | Controller | vertex/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let controller = this.subject({
+    send: Ember.K
+  });
+
+  assert.ok(controller);
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/8408a75c/tez-ui2/src/main/webapp/tests/unit/models/app-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/models/app-test.js b/tez-ui2/src/main/webapp/tests/unit/models/app-test.js
new file mode 100644
index 0000000..e0fb7f0
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/models/app-test.js
@@ -0,0 +1,40 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleForModel, test } from 'ember-qunit';
+
+moduleForModel('app', 'Unit | Model | task', {
+  // Specify the other units that are required for this test.
+  needs: []
+});
+
+test('Basic creation test', function(assert) {
+  let model = this.subject();
+
+  assert.ok(model);
+  assert.ok(model.needs);
+  assert.ok(model.appID);
+});
+
+test('appID test', function(assert) {
+  let model = this.subject({
+        entityID: "tez_1_2_3",
+      });
+
+  assert.equal(model.get("appID"), "1_2_3");
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/8408a75c/tez-ui2/src/main/webapp/tests/unit/routes/app/dags-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/app/dags-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/app/dags-test.js
new file mode 100644
index 0000000..05c1436
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/app/dags-test.js
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:app/dags', 'Unit | Route | vertex/attempts', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+  assert.ok(route.load);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/8408a75c/tez-ui2/src/main/webapp/tests/unit/routes/app/index-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/app/index-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/app/index-test.js
new file mode 100644
index 0000000..83697f4
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/routes/app/index-test.js
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:app/index', 'Unit | Route | vertex/index', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('Basic creation test', function(assert) {
+  let route = this.subject();
+
+  assert.ok(route);
+  assert.ok(route.title);
+  assert.ok(route.setupController);
+  assert.ok(route.load);
+});
+
+test('setupController test', function(assert) {
+  assert.expect(1);
+
+  let route = this.subject({
+    startCrumbBubble: function () {
+      assert.ok(true);
+    }
+  });
+
+  route.setupController({}, {});
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/8408a75c/tez-ui2/src/main/webapp/tests/unit/serializers/app-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/serializers/app-test.js b/tez-ui2/src/main/webapp/tests/unit/serializers/app-test.js
new file mode 100644
index 0000000..fc79ae9
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/serializers/app-test.js
@@ -0,0 +1,31 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('serializer:task', 'Unit | Serializer | task', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:task']
+});
+
+test('Basic creation test', function(assert) {
+  let serializer = this.subject();
+
+  assert.ok(serializer);
+  assert.ok(serializer.maps);
+});


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

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


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

Branch: refs/heads/TEZ-2980
Commit: e673284f1e1df78597e49d5d296b65699dbce4be
Parents: f1d1084
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Mon Jan 4 03:25:04 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Wed Jan 20 22:26:20 2016 +0530

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


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

http://git-wip-us.apache.org/repos/asf/tez/blob/e673284f/tez-ui2/src/main/webapp/app/adapters/abstract.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/abstract.js b/tez-ui2/src/main/webapp/app/adapters/abstract.js
deleted file mode 100644
index aca0faf..0000000
--- a/tez-ui2/src/main/webapp/app/adapters/abstract.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/*global more*/
-
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import Ember from 'ember';
-import DS from 'ember-data';
-
-var MoreString = more.String;
-
-export default DS.RESTAdapter.extend({
-  ajax: function(url, method, hash) {
-    return this._super(url, method, Ember.$.extend(hash || {}, {
-      crossDomain: true,
-      xhrFields: {
-        withCredentials: true
-      }
-    }));
-  },
-  buildURL: function(type, id, record) {
-    var url = this._super(type, undefined, record);
-    return MoreString.fmt(url, record);
-  },
-  findQuery: function(store, type, query) {
-    var record = query.metadata;
-    delete query.metadata;
-
-    return this.ajax(this.buildURL(
-        Ember.String.pluralize(type.typeKey),
-        record.id,
-        Ember.Object.create(record)
-      ),
-      'GET',
-      {
-        data: query
-      }
-    );
-  }
-});

http://git-wip-us.apache.org/repos/asf/tez/blob/e673284f/tez-ui2/src/main/webapp/app/adapters/loader.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/loader.js b/tez-ui2/src/main/webapp/app/adapters/loader.js
new file mode 100644
index 0000000..d4b502c
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/adapters/loader.js
@@ -0,0 +1,58 @@
+/*global more*/
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import DS from 'ember-data';
+
+var MoreString = more.String;
+
+export default DS.RESTAdapter.extend({
+  _isLoader: true,
+
+  buildURL: function(modelName, id, snapshot, requestType, query, params) {
+    var url = this._super(modelName, id, snapshot, null, query);
+    return params ? MoreString.fmt(url, params) : url;
+  },
+
+  _loaderAjax: function (url, queryParams, nameSpace) {
+    if (this.sortQueryParams && queryParams) {
+      queryParams = this.sortQueryParams(queryParams);
+    }
+
+    // Inject nameSpace
+    return this.ajax(url, 'GET', { data: queryParams }).then(function (data) {
+      return {
+        nameSpace: nameSpace,
+        data: data
+      };
+    });
+  },
+
+  queryRecord: function(store, type, query) {
+    var queryParams = query.params,
+        url = this.buildURL(type.modelName, query.id, null, null, queryParams, query.urlParams);
+    return this._loaderAjax(url, queryParams, query.nameSpace);
+  },
+
+  query: function (store, type, query/*, recordArray*/) {
+    var queryParams = query.params,
+        url = this.buildURL(type.modelName, null, null, 'query', queryParams, query.urlParams);
+    return this._loaderAjax(url, queryParams, query.nameSpace);
+  }
+
+});

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

http://git-wip-us.apache.org/repos/asf/tez/blob/e673284f/tez-ui2/src/main/webapp/app/initializers/loader.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/initializers/loader.js b/tez-ui2/src/main/webapp/app/initializers/loader.js
new file mode 100644
index 0000000..2956d2c
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/initializers/loader.js
@@ -0,0 +1,27 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export function initialize(application) {
+  application.inject('route', 'loader', 'service:loader');
+  application.inject('entity', 'loader', 'service:loader');
+}
+
+export default {
+  name: 'loader',
+  initialize
+};

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

http://git-wip-us.apache.org/repos/asf/tez/blob/e673284f/tez-ui2/src/main/webapp/app/serializers/loader.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/serializers/loader.js b/tez-ui2/src/main/webapp/app/serializers/loader.js
new file mode 100644
index 0000000..9c97886
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/serializers/loader.js
@@ -0,0 +1,81 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import DS from 'ember-data';
+
+// TODO - Move to more js
+function mapObject(hash, map) {
+  var mappedObject = Ember.Object.create();
+  for (var key in map) {
+    mappedObject.set(key, Ember.get(hash, map[key]));
+  }
+  return mappedObject;
+}
+
+export default DS.JSONSerializer.extend({
+  _isLoader: true,
+
+  maps: null,
+
+  extractId: function (modelClass, resourceHash) {
+    var id = this._super(modelClass, resourceHash.data),
+        nameSpace = resourceHash.nameSpace;
+
+    if(nameSpace) {
+      return nameSpace + ":" + id;
+    }
+    return id;
+  },
+  extractAttributes: function (modelClass, resourceHash) {
+    var maps = this.get('maps'),
+        data = resourceHash.data;
+    return this._super(modelClass, maps ? mapObject(data, maps) : data);
+  },
+  extractRelationships: function (modelClass, resourceHash) {
+    return this._super(modelClass, resourceHash.data);
+  },
+
+  extractSinglePayload: function (payload) {
+    return payload;
+  },
+  extractArrayPayload: function (payload) {
+    return payload;
+  },
+
+  normalizeSingleResponse: function (store, primaryModelClass, payload, id, requestType) {
+    payload.data = this.extractSinglePayload(payload.data);
+    return this._super(store, primaryModelClass, payload, id, requestType);
+  },
+
+  normalizeArrayResponse: function (store, primaryModelClass, payload, id, requestType) {
+    var nameSpace = payload.nameSpace;
+
+    // convert into a _normalizeResponse friendly format
+    payload = this.extractArrayPayload(payload.data);
+    Ember.assert("Loader expects an array in return for a query", Array.isArray(payload));
+    payload = payload.map(function (item) {
+      return {
+        nameSpace: nameSpace,
+        data: item
+      };
+    });
+
+    return this._super(store, primaryModelClass, payload, id, requestType);
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/e673284f/tez-ui2/src/main/webapp/app/services/loader.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/services/loader.js b/tez-ui2/src/main/webapp/app/services/loader.js
new file mode 100644
index 0000000..054a6b5
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/services/loader.js
@@ -0,0 +1,145 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Service.extend({
+
+  nameSpace: '',
+  store: Ember.inject.service('store'),
+  cache: null,
+
+  _setOptions: function (options) {
+    var nameSpace = options.nameSpace;
+    if(nameSpace) {
+      // We need to validate only if nameSpace is passed. Else it would be stored in the global space
+      Ember.assert(`Invalid nameSpace. Please pass a string instead of ${Ember.inspect(nameSpace)}`, typeof nameSpace === 'string');
+      this.set("nameSpace", nameSpace);
+    }
+  },
+
+  init: function (options) {
+    this._super();
+    this._setOptions(options || {});
+    this.set("cache", Ember.Object.create());
+  },
+
+  checkRequisite: function (type) {
+    var store = this.get("store"),
+        adapter = store.adapterFor(type),
+        serializer = store.serializerFor(type);
+
+    Ember.assert(
+      `No loader adapter found for type ${type}. Either extend loader and create a custom adapter or extend ApplicationAdapter from loader.`,
+      adapter && adapter._isLoader
+    );
+    Ember.assert(
+      `No loader serializer found for type ${type}. Either extend loader and create a custom serializer or extend ApplicationSerializer from loader.`,
+      serializer && serializer._isLoader
+    );
+  },
+
+  lookup: function (type, name) {
+    name = Ember.String.dasherize(name);
+    return this.get("container").lookup(type + ":" + name);
+  },
+
+  entityFor: function (entityName) {
+    var entity = this.lookup("entitie", entityName);
+    if(!entity) {
+      entity = this.lookup("entitie", "entity");
+    }
+    entity.name = entityName;
+    return entity;
+  },
+
+  getCacheKey: function (type, query, id) {
+    var parts = [type];
+
+    if(id) {
+      parts.push(id);
+    }
+    if(query) {
+      parts.push(JSON.stringify(query));
+    }
+
+    return parts.join(":");
+  },
+
+  queryRecord: function(type, id, query, urlParams, options) {
+    var entity = this.entityFor(type),
+        cache = this.get("cache"),
+        cacheKey = this.getCacheKey(type, query, id),
+        that = this,
+        record;
+
+    this.checkRequisite(type);
+
+    options = options || {};
+    if(!options.reload) {
+      record = cache.get(cacheKey);
+      if(record) {
+        return record;
+      }
+    }
+
+    record = this.get('store').queryRecord(type, {
+      id: id,
+      nameSpace: this.get('nameSpace'),
+      params: query,
+      urlParams: urlParams
+    }).then(function (record) {
+      return entity.loadRelations(that, record);
+    });
+
+    cache.set(cacheKey, record);
+    return record;
+  },
+  query: function(type, query, urlParams, options) {
+    var entity = this.entityFor(type),
+        cache = this.get("cache"),
+        cacheKey = this.getCacheKey(type, query),
+        that = this,
+        records;
+
+    this.checkRequisite(type);
+
+    options = options || {};
+    if(!options.reload) {
+      records = cache.get(cacheKey);
+      if(records) {
+        return records;
+      }
+    }
+
+    records = this.get('store').query(type, {
+      nameSpace: this.get('nameSpace'),
+      params: query,
+      urlParams: urlParams
+    }).then(function (records) {
+      return Ember.RSVP.all(records.map(function (record) {
+        return entity.loadRelations(that, record);
+      })).then(function () {
+       return records;
+      });
+    });
+
+    cache.set(cacheKey, records);
+    return records;
+  }
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/e673284f/tez-ui2/src/main/webapp/tests/unit/adapters/abstract-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/adapters/abstract-test.js b/tez-ui2/src/main/webapp/tests/unit/adapters/abstract-test.js
deleted file mode 100644
index 00be0ac..0000000
--- a/tez-ui2/src/main/webapp/tests/unit/adapters/abstract-test.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import { moduleFor, test } from 'ember-qunit';
-
-moduleFor('adapter:abstract', 'Unit | Adapter | abstract', {
-  // Specify the other units that are required for this test.
-  // needs: ['serializer:foo']
-});
-
-test('Basic creation', function(assert) {
-  let adapter = this.subject();
-
-  assert.ok(adapter);
-});
-
-test('buildURL test', function(assert) {
-  let adapter = this.subject();
-
-  assert.equal(adapter.buildURL("{x}/{y}/type", null, {
-    x: "x_x",
-    y: "y_y"
-  }), "/x_x/y_y/types");
-});

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

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

http://git-wip-us.apache.org/repos/asf/tez/blob/e673284f/tez-ui2/src/main/webapp/tests/unit/initializers/loader-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/initializers/loader-test.js b/tez-ui2/src/main/webapp/tests/unit/initializers/loader-test.js
new file mode 100644
index 0000000..cc32e92
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/initializers/loader-test.js
@@ -0,0 +1,40 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+import LoaderInitializer from '../../../initializers/loader';
+import { module, test } from 'qunit';
+
+let application;
+
+module('Unit | Initializer | loader', {
+  beforeEach() {
+    Ember.run(function() {
+      application = Ember.Application.create();
+      application.deferReadiness();
+    });
+  }
+});
+
+// Replace this with your real tests.
+test('it works', function(assert) {
+  LoaderInitializer.initialize(application);
+
+  // you would normally confirm the results of the initializer here
+  assert.ok(true);
+});

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

http://git-wip-us.apache.org/repos/asf/tez/blob/e673284f/tez-ui2/src/main/webapp/tests/unit/serializers/loader-test.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/tests/unit/serializers/loader-test.js b/tez-ui2/src/main/webapp/tests/unit/serializers/loader-test.js
new file mode 100644
index 0000000..5add84a
--- /dev/null
+++ b/tez-ui2/src/main/webapp/tests/unit/serializers/loader-test.js
@@ -0,0 +1,193 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('serializer:loader', 'Unit | Serializer | loader', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:loader']
+});
+
+test('Basic creation test', function(assert) {
+  let serializer = this.subject();
+
+  assert.ok(serializer);
+  assert.ok(serializer._isLoader);
+
+  assert.ok(serializer.extractId);
+  assert.ok(serializer.extractAttributes);
+  assert.ok(serializer.extractRelationships);
+
+  assert.ok(serializer.extractSinglePayload);
+  assert.ok(serializer.extractArrayPayload);
+
+  assert.ok(serializer.normalizeSingleResponse);
+  assert.ok(serializer.normalizeArrayResponse);
+});
+
+test('extractId test', function(assert) {
+  let serializer = this.subject(),
+    modelClass = {},
+    resourceHash = {
+      nameSpace: "ns",
+      data: {
+        id: 1,
+        entityID: 3
+      }
+    };
+
+  assert.equal(serializer.extractId(modelClass, resourceHash), "ns:1", "With name-space");
+  assert.equal(serializer.extractId(modelClass, { data: {id: 2} }), 2, "Without name-space");
+
+  serializer.primaryKey = "entityID";
+  assert.equal(serializer.extractId(modelClass, resourceHash), "ns:3", "Different primary key");
+});
+
+test('extractAttributes test', function(assert) {
+  let serializer = this.subject(),
+    modelClass = {
+      eachAttribute: function (callback) {
+        callback("id", {type: "string"});
+        callback("appID", {type: "string"});
+        callback("status", {type: "string"});
+      }
+    },
+    resourceHash = {
+      nameSpace: "ns",
+      data: {
+        id: 1,
+        appID: 2,
+        applicationID: 3,
+        info: {
+          status: "SUCCESS"
+        }
+      }
+    };
+
+  assert.deepEqual(serializer.extractAttributes(modelClass, resourceHash), {
+    id: 1,
+    appID: 2
+  });
+
+  serializer.maps = {
+    id: "id",
+    appID: "applicationID",
+    status: "info.status"
+  };
+
+  assert.deepEqual(serializer.extractAttributes(modelClass, resourceHash), {
+    id: 1,
+    appID: 3,
+    status: "SUCCESS"
+  });
+});
+
+test('extractRelationships test', function(assert) {
+  let serializer = this.subject(),
+    modelClass = {
+      eachAttribute: Ember.K,
+      eachRelationship: function (callback) {
+        callback("app", {
+          key: "app",
+          kind: "belongsTo",
+          options: {},
+          parentType: "parent",
+          type: "app"
+        });
+      },
+      eachTransformedAttribute: Ember.K
+    },
+    resourceHash = {
+      nameSpace: "ns",
+      data: {
+        id: 1,
+        app: "",
+      }
+    };
+
+  assert.deepEqual(serializer.extractRelationships(modelClass, resourceHash), {
+    app: {
+      data: {
+        id: null,
+        type:"app"
+      }
+    }
+  });
+
+});
+
+test('normalizeSingleResponse test', function(assert) {
+  let serializer = this.subject(),
+    modelClass = {
+      eachAttribute: function (callback) {
+        callback("id", {type: "string"});
+        callback("appID", {type: "string"});
+        callback("status", {type: "string"});
+      },
+      eachRelationship: Ember.K,
+      eachTransformedAttribute: Ember.K
+    },
+    resourceHash = {
+      nameSpace: "ns",
+      data: {
+        id: 1,
+        appID: 2,
+        applicationID: 3,
+        info: {
+          status: "SUCCESS"
+        }
+      }
+    };
+
+  var response = serializer.normalizeSingleResponse({}, modelClass, resourceHash, null, null);
+
+  assert.equal(response.data.id, "ns:1");
+  assert.equal(response.data.attributes.id, 1);
+  assert.equal(response.data.attributes.appID, 2);
+});
+
+test('normalizeArrayResponse test', function(assert) {
+  let serializer = this.subject(),
+    modelClass = {
+      eachAttribute: function (callback) {
+        callback("id", {type: "string"});
+        callback("appID", {type: "string"});
+        callback("status", {type: "string"});
+      },
+      eachRelationship: Ember.K,
+      eachTransformedAttribute: Ember.K
+    },
+    resourceHash = {
+      nameSpace: "ns",
+      data: [{
+        id: 1,
+        appID: 2,
+      },{
+        id: 2,
+        appID: 4,
+      }]
+    };
+
+  var response = serializer.normalizeArrayResponse({}, modelClass, resourceHash, null, null);
+
+  assert.equal(response.data.length, 2);
+  assert.deepEqual(response.data[0].id, "ns:1");
+  assert.deepEqual(response.data[1].id, "ns:2");
+});

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


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

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


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

Branch: refs/heads/TEZ-2980
Commit: bfc4aeb9ea4b510e0f427e3af48a703d98d492a2
Parents: 025bbb7
Author: Sreenath Somarajapuram <sr...@apache.org>
Authored: Mon Jan 4 22:28:44 2016 +0530
Committer: Sreenath Somarajapuram <sr...@apache.org>
Committed: Wed Jan 20 22:26:21 2016 +0530

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


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

http://git-wip-us.apache.org/repos/asf/tez/blob/bfc4aeb9/tez-ui2/src/main/webapp/app/adapters/abstract.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/adapters/abstract.js b/tez-ui2/src/main/webapp/app/adapters/abstract.js
new file mode 100644
index 0000000..b412a46
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/adapters/abstract.js
@@ -0,0 +1,58 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+import LoaderAdapter from './loader';
+
+export default LoaderAdapter.extend({
+  serverName: null, //Must be set by inheriting classes
+
+  host: Ember.computed("serverName", function () {
+    var serverName = this.get("serverName");
+    return this.get(`hosts.${serverName}`);
+  }),
+  namespace: Ember.computed("serverName", function () {
+    var serverName = this.get("serverName"),
+        env = this.get("env");
+    return env.getAppConfig(`namespaces.webService.${serverName}`);
+  }),
+  pathTypeHash: Ember.computed("serverName", function () {
+    var serverName = this.get("serverName"),
+        env = this.get("env");
+
+    return env.getAppConfig(`paths.${serverName}`);
+  }),
+
+  ajaxOptions: function(url, method, options) {
+    options = options || {};
+    options.crossDomain = true;
+    options.xhrFields = {
+      withCredentials: true
+    };
+    options.targetServer = this.get('serverName');
+    return this._super(url, method, options);
+  },
+
+  pathForType: function(type) {
+    var serverName = this.get("serverName"),
+        path = this.get("pathTypeHash")[type];
+    Ember.assert(`Path not found for type:${type} to server:${serverName}`, path);
+    return path;
+  },
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/bfc4aeb9/tez-ui2/src/main/webapp/app/errors/unlinked-promise.js
----------------------------------------------------------------------
diff --git a/tez-ui2/src/main/webapp/app/errors/unlinked-promise.js b/tez-ui2/src/main/webapp/app/errors/unlinked-promise.js
new file mode 100644
index 0000000..770b095
--- /dev/null
+++ b/tez-ui2/src/main/webapp/app/errors/unlinked-promise.js
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+let UnlinkedPromise = function (errors, message = 'Promise chain was unlinked.') {
+  Ember.Error.call(this, message);
+
+  this.errors = errors || [
+    {
+      title: 'Unlinked promise chain.',
+      detail: message
+    }
+  ];
+};
+
+UnlinkedPromise.prototype = Object.create(Ember.Error.prototype);
+
+export default UnlinkedPromise;

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

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

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


[10/50] [abbrv] tez git commit: TEZ-2129. Task and Attempt views should contain links to the logs (jeagles)

Posted by sr...@apache.org.
TEZ-2129. Task and Attempt views should contain links to the logs (jeagles)


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

Branch: refs/heads/TEZ-2980
Commit: 85637c61a2cf2c16c147826b2908d459a7b1b7cf
Parents: d5c9649
Author: Jonathan Eagles <je...@yahoo-inc.com>
Authored: Fri Jan 8 14:37:03 2016 -0600
Committer: Jonathan Eagles <je...@yahoo-inc.com>
Committed: Fri Jan 8 14:37:03 2016 -0600

----------------------------------------------------------------------
 CHANGES.txt                                     |  2 ++
 .../controllers/task_attempt_controller.js      |  6 ++++-
 .../app/scripts/controllers/task_controller.js  |  5 +++-
 .../controllers/task_index_controller.js        | 27 +++++++++++++++++++-
 .../task_task_attempts_controller.js            | 13 ++++++++++
 .../main/webapp/app/templates/task/index.hbs    | 17 ++++++++++++
 .../webapp/app/templates/taskAttempt/index.hbs  | 17 ++++++++++++
 7 files changed, 84 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/85637c61/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 5e944b6..ea2b1d5 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -11,6 +11,7 @@ INCOMPATIBLE CHANGES
   TEZ-2972. Avoid task rescheduling when a node turns unhealthy
 
 ALL CHANGES:
+  TEZ-2129. Task and Attempt views should contain links to the logs
   TEZ-3025. InputInitializer creation should use the dag ugi.
   TEZ-3017. HistoryACLManager does not have a close method for cleanup
   TEZ-2914. Ability to limit vertex concurrency
@@ -302,6 +303,7 @@ INCOMPATIBLE CHANGES
   TEZ-2949. Allow duplicate dag names within session for Tez.
 
 ALL CHANGES
+  TEZ-2129. Task and Attempt views should contain links to the logs
   TEZ-3025. InputInitializer creation should use the dag ugi.
   TEZ-3017. HistoryACLManager does not have a close method for cleanup
   TEZ-2914. Ability to limit vertex concurrency

http://git-wip-us.apache.org/repos/asf/tez/blob/85637c61/tez-ui/src/main/webapp/app/scripts/controllers/task_attempt_controller.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/controllers/task_attempt_controller.js b/tez-ui/src/main/webapp/app/scripts/controllers/task_attempt_controller.js
index 3485c33..de24ccd 100644
--- a/tez-ui/src/main/webapp/app/scripts/controllers/task_attempt_controller.js
+++ b/tez-ui/src/main/webapp/app/scripts/controllers/task_attempt_controller.js
@@ -69,20 +69,24 @@ App.TaskAttemptController = App.BaseController.extend(App.Helpers.DisplayHelper,
 
   loadAdditional: function(attempt) {
     var that = this;
+    var applicationId = App.Helpers.misc.getAppIdFromVertexId(attempt.get('vertexID'));
 
     var dagLoader = this.store.find('dag', attempt.get('dagID'));
     var vertexLoader = this.store.find('vertex', attempt.get('vertexID'));
     var taskLoader = this.store.find('task', attempt.get('taskID'));
+    var appDetailLoader = App.Helpers.misc.loadApp(this.store, applicationId);
 
     var allLoaders = Em.RSVP.hash({
       dag: dagLoader,
       vertex: vertexLoader,
-      task: taskLoader
+      task: taskLoader,
+      appDetail: appDetailLoader
     });
     allLoaders.then(function(results) {
       attempt.set('task', results.task);
       attempt.set('task.vertex', results.vertex);
       attempt.set('task.vertex.dag', results.dag);
+      attempt.set('appDetail', results.appDetail);
     }).finally(function() {
       that.set('loading', false);
     });

http://git-wip-us.apache.org/repos/asf/tez/blob/85637c61/tez-ui/src/main/webapp/app/scripts/controllers/task_controller.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/controllers/task_controller.js b/tez-ui/src/main/webapp/app/scripts/controllers/task_controller.js
index b7a6036..829881f 100644
--- a/tez-ui/src/main/webapp/app/scripts/controllers/task_controller.js
+++ b/tez-ui/src/main/webapp/app/scripts/controllers/task_controller.js
@@ -64,18 +64,21 @@ App.TaskController = App.PollingController.extend(App.Helpers.DisplayHelper, App
     var dagLoader = this.store.find('dag', task.get('dagID'));
     var vertexLoader = this.store.find('vertex', task.get('vertexID'));
     var tezAppLoader = this.store.find('tezApp', 'tez_' + applicationId);
+    var appDetailLoader = App.Helpers.misc.loadApp(this.store, applicationId);
 
     task.set('progress', undefined);
     var allLoaders = Em.RSVP.hash({
       dag: dagLoader,
       vertex: vertexLoader,
-      tezApp: tezAppLoader
+      tezApp: tezAppLoader,
+      appDetail: appDetailLoader
     });
 
     allLoaders.then(function(results) {
       task.set('vertex', results.vertex);
       task.set('vertex.dag', results.dag);
       task.set('tezApp', results.tezApp);
+      task.set('appDetail', results.appDetail);
     }).finally(function() {
       that.set('loading', false);
     });

http://git-wip-us.apache.org/repos/asf/tez/blob/85637c61/tez-ui/src/main/webapp/app/scripts/controllers/task_index_controller.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/controllers/task_index_controller.js b/tez-ui/src/main/webapp/app/scripts/controllers/task_index_controller.js
index eca4ee1..96258f1 100644
--- a/tez-ui/src/main/webapp/app/scripts/controllers/task_index_controller.js
+++ b/tez-ui/src/main/webapp/app/scripts/controllers/task_index_controller.js
@@ -20,6 +20,8 @@
 App.TaskIndexController = App.PollingController.extend(App.ModelRefreshMixin, {
   controllerName: 'TaskIndexController',
 
+  needs: "task",
+
   taskStatus: function() {
     return App.Helpers.misc.getFixedupDisplayStatus(this.get('model.status'));
   }.property('id', 'model.status'),
@@ -40,4 +42,27 @@ App.TaskIndexController = App.PollingController.extend(App.ModelRefreshMixin, {
     }
   },
 
-});
\ No newline at end of file
+  logsLink: null,
+
+  logsLinkObserver: function() {
+
+    var model = this.get('content');
+    var taskAttemptId = model.get('successfulAttemptId') || model.get('attempts.lastObject');
+    var store = this.get('store');
+    var that = this;
+
+    if (taskAttemptId) {
+      store.find('taskAttempt', taskAttemptId).then(function(attempt) {
+          var cellContent = App.Helpers.misc.constructLogLinks(
+              attempt,
+              that.get('controllers.task.appDetail.status'),
+              that.get('controllers.task.tezApp.user')
+              );
+
+          cellContent.notAvailable = cellContent.viewUrl || cellContent.downloadUrl;
+          that.set('logsLink', cellContent);
+        });
+    }
+  }.observes('id', 'successfulAttemptId'),
+
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/85637c61/tez-ui/src/main/webapp/app/scripts/controllers/task_task_attempts_controller.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/controllers/task_task_attempts_controller.js b/tez-ui/src/main/webapp/app/scripts/controllers/task_task_attempts_controller.js
index 0f11379..580af05 100644
--- a/tez-ui/src/main/webapp/app/scripts/controllers/task_task_attempts_controller.js
+++ b/tez-ui/src/main/webapp/app/scripts/controllers/task_task_attempts_controller.js
@@ -223,6 +223,8 @@ App.TaskAttemptsController = App.TablePageController.extend(App.AutoCounterColum
 App.TaskAttemptIndexController = Em.ObjectController.extend(App.ModelRefreshMixin, {
   controllerName: 'TaskAttemptIndexController',
 
+  needs: "taskAttempt",
+
   taskAttemptStatus: function() {
     return App.Helpers.misc.getFixedupDisplayStatus(this.get('status'));
   }.property('id', 'status'),
@@ -242,4 +244,15 @@ App.TaskAttemptIndexController = Em.ObjectController.extend(App.ModelRefreshMixi
     }
   },
 
+  logsLink: function() {
+    var cellContent = App.Helpers.misc.constructLogLinks(
+      this.get('content'),
+      this.get('controllers.taskAttempt.appDetail.status'),
+      this.get('controllers.taskAttempt.tezApp.user')
+    );
+
+    cellContent.notAvailable = cellContent.viewUrl || cellContent.downloadUrl;
+    return cellContent;
+  }.property('id', 'controllers.taskAttempt'),
+
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/85637c61/tez-ui/src/main/webapp/app/templates/task/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/templates/task/index.hbs b/tez-ui/src/main/webapp/app/templates/task/index.hbs
index 05adec4..09cd986 100644
--- a/tez-ui/src/main/webapp/app/templates/task/index.hbs
+++ b/tez-ui/src/main/webapp/app/templates/task/index.hbs
@@ -64,6 +64,23 @@
 					<td>{{t 'common.time.duration'}}</td>
 					<td>{{formatDuration startTime endTime}}</td>
 				</tr>
+        <tr>
+          <td>Logs</td>
+          <td>
+            {{#if logsLink.viewUrl}}
+              <a target="_blank" href='//{{unbound logsLink.viewUrl}}'>View</a>
+              &nbsp;
+            {{/if}}
+            {{#if logsLink.downloadUrl}}
+              <a target="_blank" href='{{unbound logsLink.downloadUrl}}' download type="application/octet-stream">Download</a>
+            {{/if}}
+            {{#unless logsLink.viewUrl}}
+              {{#unless logsLink.downloadUrl}}
+                <span class="message">Not Available!</span>
+              {{/unless}}
+            {{/unless}}
+          </td>
+        </tr>
 			</tbody>
 		</table>
 	</div>

http://git-wip-us.apache.org/repos/asf/tez/blob/85637c61/tez-ui/src/main/webapp/app/templates/taskAttempt/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/templates/taskAttempt/index.hbs b/tez-ui/src/main/webapp/app/templates/taskAttempt/index.hbs
index c7e3330..e1c60d1 100644
--- a/tez-ui/src/main/webapp/app/templates/taskAttempt/index.hbs
+++ b/tez-ui/src/main/webapp/app/templates/taskAttempt/index.hbs
@@ -72,6 +72,23 @@
 					<td>{{t 'common.time.duration'}}</td>
 					<td>{{formatDuration startTime endTime}}</td>
 				</tr>
+        <tr>
+          <td>Logs</td>
+          <td>
+            {{#if logsLink.viewUrl}}
+              <a target="_blank" href='//{{unbound logsLink.viewUrl}}'>View</a>
+              &nbsp;
+            {{/if}}
+            {{#if logsLink.downloadUrl}}
+              <a target="_blank" href='{{unbound logsLink.downloadUrl}}' download type="application/octet-stream">Download</a>
+            {{/if}}
+            {{#unless logsLink.viewUrl}}
+              {{#unless logsLink.downloadUrl}}
+                <span class="message">Not Available!</span>
+              {{/unless}}
+            {{/unless}}
+          </td>
+        </tr>
 			</tbody>
 		</table>
 	</div>


[07/50] [abbrv] tez git commit: Fix CHANGES.txt for recent back-ports

Posted by sr...@apache.org.
Fix CHANGES.txt for recent back-ports


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

Branch: refs/heads/TEZ-2980
Commit: 5334d62215e5d4e633384bf9579c785f4cc629e8
Parents: 34eb75d
Author: Bikas Saha <bi...@apache.org>
Authored: Sat Dec 26 22:49:39 2015 -0800
Committer: Bikas Saha <bi...@apache.org>
Committed: Sat Dec 26 22:49:39 2015 -0800

----------------------------------------------------------------------
 CHANGES.txt | 8 ++++++++
 1 file changed, 8 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/5334d622/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 25cfd86..546c3fd 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -300,6 +300,14 @@ INCOMPATIBLE CHANGES
   TEZ-2949. Allow duplicate dag names within session for Tez.
 
 ALL CHANGES
+  TEZ-2914. Ability to limit vertex concurrency
+  TEZ-2918. Make progress notifications in IOs
+  TEZ-2952. NPE in TestOnFileUnorderedKVOutput
+  TEZ-808. Handle task attempts that are not making progress
+  TEZ-2987. TestVertexImpl.testTez2684 fails
+  TEZ-2599. Dont send obsoleted data movement events to tasks
+  TEZ-2943. Change shuffle vertex manager to use per vertex data for auto
+  TEZ-2633. Allow VertexManagerPlugins to receive and report based on attempts
   TEZ-3011. Link Vertex Name in Dag Tasks/Task Attempts to Vertex
   TEZ-2538. ADDITIONAL_SPILL_COUNT wrongly populated for DefaultSorter with multiple partitions.
   TEZ-3006. Remove unused import in TestHistoryParser.


[15/50] [abbrv] tez git commit: TEZ-3024. Move TaskCommunicator to correct package. (sseth)

Posted by sr...@apache.org.
TEZ-3024. Move TaskCommunicator to correct package. (sseth)


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

Branch: refs/heads/TEZ-2980
Commit: fad16425b7979970f29884343316e1a10f4d0872
Parents: 1d76543
Author: Siddharth Seth <ss...@apache.org>
Authored: Tue Jan 12 17:32:28 2016 -0800
Committer: Siddharth Seth <ss...@apache.org>
Committed: Tue Jan 12 17:32:28 2016 -0800

----------------------------------------------------------------------
 CHANGES.txt                                     |   1 +
 .../apache/tez/dag/api/TaskCommunicator.java    | 221 -----------------
 .../tez/dag/api/TaskCommunicatorContext.java    | 225 -----------------
 .../tez/dag/api/TaskHeartbeatRequest.java       |  68 ------
 .../tez/dag/api/TaskHeartbeatResponse.java      |  51 ----
 .../dag/app/TaskCommunicatorContextImpl.java    |   7 +-
 .../tez/dag/app/TaskCommunicatorManager.java    |   8 +-
 .../tez/dag/app/TaskCommunicatorWrapper.java    |   2 +-
 .../dag/app/TezLocalTaskCommunicatorImpl.java   |   2 +-
 .../tez/dag/app/TezTaskCommunicatorImpl.java    |   8 +-
 .../serviceplugins/api/TaskCommunicator.java    | 232 ++++++++++++++++++
 .../api/TaskCommunicatorContext.java            | 240 +++++++++++++++++++
 .../api/TaskHeartbeatRequest.java               |  82 +++++++
 .../api/TaskHeartbeatResponse.java              |  65 +++++
 .../app/TestTaskCommunicatorContextImpl.java    |   2 +-
 .../dag/app/TestTaskCommunicatorManager.java    |   4 +-
 .../dag/app/TestTaskCommunicatorManager1.java   |   8 +-
 .../dag/app/TestTaskCommunicatorWrapper.java    |   2 +-
 .../tez/dag/app/dag/impl/TestTaskAttempt.java   |   2 +-
 .../dag/app/rm/TestTaskSchedulerManager.java    |   4 -
 .../dag/app/rm/container/TestAMContainer.java   |   2 +-
 .../app/rm/container/TestAMContainerMap.java    |   2 +-
 .../TezTestServiceTaskCommunicatorImpl.java     |   2 +-
 ...ezTestServiceTaskCommunicatorWithErrors.java |   4 +-
 24 files changed, 647 insertions(+), 597 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/fad16425/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index d39cbb8..0645591 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -4,6 +4,7 @@ Apache Tez Change Log
 Release 0.8.2: Unreleased
 
 INCOMPATIBLE CHANGES
+  TEZ-3024. Move TaskCommunicator to correct package.
   TEZ-2679. Admin forms of launch env settings
   TEZ-2948. Stop using dagName in the dagComplete notification to TaskCommunicators.
   TEZ-2949. Allow duplicate dag names within session for Tez.

http://git-wip-us.apache.org/repos/asf/tez/blob/fad16425/tez-dag/src/main/java/org/apache/tez/dag/api/TaskCommunicator.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/api/TaskCommunicator.java b/tez-dag/src/main/java/org/apache/tez/dag/api/TaskCommunicator.java
deleted file mode 100644
index 1b6ad07..0000000
--- a/tez-dag/src/main/java/org/apache/tez/dag/api/TaskCommunicator.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tez.dag.api;
-
-import javax.annotation.Nullable;
-import java.net.InetSocketAddress;
-import java.util.Map;
-
-import org.apache.hadoop.security.Credentials;
-import org.apache.hadoop.yarn.api.records.ContainerId;
-import org.apache.hadoop.yarn.api.records.LocalResource;
-import org.apache.tez.common.ServicePluginLifecycle;
-import org.apache.tez.dag.api.event.VertexStateUpdate;
-import org.apache.tez.serviceplugins.api.ContainerEndReason;
-import org.apache.tez.serviceplugins.api.ServicePluginException;
-import org.apache.tez.serviceplugins.api.TaskAttemptEndReason;
-import org.apache.tez.dag.records.TezTaskAttemptID;
-import org.apache.tez.runtime.api.impl.TaskSpec;
-
-// TODO TEZ-2003 (post) TEZ-2665. Move to the tez-api module
-// TODO TEZ-2003 (post) TEZ-2664. Ideally, don't expose YARN containerId; instead expose a Tez specific construct.
-
-/**
- * This class represents the API for a custom TaskCommunicator which can be run within the Tez AM.
- * This is used to communicate with running services, potentially launching tasks, and getting
- * updates from running tasks.
- * <p/>
- * The plugin is initialized with an instance of {@link TaskCommunicatorContext} - which provides
- * a mechanism to notify the system about allocation decisions and resources to the Tez framework.
- *
- * If setting up a heartbeat between the task and the AM, the framework is responsible for error checking
- * of this heartbeat mechanism, handling lost or duplicate responses.
- *
- */
-public abstract class TaskCommunicator implements ServicePluginLifecycle {
-
-  // TODO TEZ-2003 (post) TEZ-2666 Enhancements to interface
-  // - registerContainerEnd should provide the end reason / possible rename
-  // - get rid of getAddress
-  // - Add methods to support task preemption
-  // - Add a dagStarted notification, along with a payload
-  // - taskSpec breakup into a clean interface
-  // - Add methods to report task / container completion
-
-  private final TaskCommunicatorContext taskCommunicatorContext;
-
-  public TaskCommunicator(TaskCommunicatorContext taskCommunicatorContext) {
-    this.taskCommunicatorContext = taskCommunicatorContext;
-  }
-
-  /**
-   * Get the {@link TaskCommunicatorContext} associated with this instance of the scheduler, which
-   * is
-   * used to communicate with the rest of the system
-   *
-   * @return an instance of {@link TaskCommunicatorContext}
-   */
-  public TaskCommunicatorContext getContext() {
-    return taskCommunicatorContext;
-  }
-
-  /**
-   * An entry point for initialization.
-   * Order of service setup. Constructor, initialize(), start() - when starting a service.
-   *
-   * @throws Exception
-   */
-  @Override
-  public void initialize() throws Exception {
-  }
-
-  /**
-   * An entry point for starting the service.
-   * Order of service setup. Constructor, initialize(), start() - when starting a service.
-   *
-   * @throws Exception
-   */
-  @Override
-  public void start() throws Exception {
-  }
-
-  /**
-   * Stop the service. This could be invoked at any point, when the service is no longer required -
-   * including in case of errors.
-   *
-   * @throws Exception
-   */
-  @Override
-  public void shutdown() throws Exception {
-  }
-
-
-  /**
-   * Register a new container.
-   *
-   * @param containerId the associated containerId
-   * @param hostname    the hostname on which the container runs
-   * @param port        the port for the service which is running the container
-   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
-   *                               This will cause the app to shutdown.
-   */
-  public abstract void registerRunningContainer(ContainerId containerId, String hostname,
-                                                int port) throws ServicePluginException;
-
-  /**
-   * Register the end of a container. This can be caused by preemption, the container completing
-   * successfully, etc.
-   *
-   * @param containerId the associated containerId
-   * @param endReason   the end reason for the container completing
-   * @param diagnostics diagnostics associated with the container end
-   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
-   *                               This will cause the app to shutdown.
-   */
-  public abstract void registerContainerEnd(ContainerId containerId, ContainerEndReason endReason,
-                                            @Nullable String diagnostics) throws
-      ServicePluginException;
-
-  /**
-   * Register a task attempt to execute on a container
-   *
-   * @param containerId         the containerId on which this task needs to run
-   * @param taskSpec            the task specifications for the task to be executed
-   * @param additionalResources additional local resources which may be required to run this task
-   *                            on
-   *                            the container
-   * @param credentials         the credentials required to run this task
-   * @param credentialsChanged  whether the credentials are different from the original credentials
-   *                            associated with this container
-   * @param priority            the priority of the task being executed
-   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
-   *                               This will cause the app to shutdown.
-   */
-  public abstract void registerRunningTaskAttempt(ContainerId containerId, TaskSpec taskSpec,
-                                                  Map<String, LocalResource> additionalResources,
-                                                  Credentials credentials,
-                                                  boolean credentialsChanged, int priority) throws
-      ServicePluginException;
-
-  /**
-   * Register the completion of a task. This may be a result of preemption, the container dying,
-   * the node dying, the task completing to success
-   *
-   * @param taskAttemptID the task attempt which has completed / needs to be completed
-   * @param endReason     the endReason for the task attempt.
-   * @param diagnostics   diagnostics associated with the task end
-   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
-   *                               This will cause the app to shutdown.
-   */
-  public abstract void unregisterRunningTaskAttempt(TezTaskAttemptID taskAttemptID,
-                                                    TaskAttemptEndReason endReason,
-                                                    @Nullable String diagnostics) throws
-      ServicePluginException;
-
-  /**
-   * Return the address, if any, that the service listens on
-   *
-   * @return the address
-   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
-   *                               This will cause the app to shutdown.
-   */
-  public abstract InetSocketAddress getAddress() throws ServicePluginException;
-
-  /**
-   * Receive notifications on vertex state changes.
-   * <p/>
-   * State changes will be received based on the registration via {@link
-   * org.apache.tez.runtime.api.InputInitializerContext#registerForVertexStateUpdates(String,
-   * java.util.Set)}. Notifications will be received for all registered state changes, and not just
-   * for the latest state update. They will be in order in which the state change occurred. </p>
-   * <p/>
-   * Extensive processing should not be performed via this method call. Instead this should just be
-   * used as a notification mechanism.
-   * <br>This method may be invoked concurrently with other invocations into the TaskCommunicator
-   * and
-   * multi-threading/concurrency implications must be considered.
-   *
-   * @param stateUpdate an event indicating the name of the vertex, and it's updated state.
-   *                    Additional information may be available for specific events, Look at the
-   *                    type hierarchy for {@link org.apache.tez.dag.api.event.VertexStateUpdate}
-   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
-   *                               This will cause the app to shutdown.
-   */
-  public abstract void onVertexStateUpdated(VertexStateUpdate stateUpdate) throws ServicePluginException;
-
-  /**
-   * Indicates the current running dag is complete. The TaskCommunicatorContext can be used to
-   * query information about the current dag during the duration of the dagComplete invocation.
-   * <p/>
-   * After this, the contents returned from querying the context may change at any point - due to
-   * the next dag being submitted.
-   *
-   * @param dagIdentifier the unique numerical identifier for the DAG in the specified execution context.
-   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
-   *                               This will cause the app to shutdown.
-   */
-  public abstract void dagComplete(int dagIdentifier) throws ServicePluginException;
-
-  /**
-   * Share meta-information such as host:port information where the Task Communicator may be
-   * listening.
-   * Primarily for use by compatible launchers to learn this information.
-   *
-   * @return meta info for the task communicator
-   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
-   *                               This will cause the app to shutdown.
-   */
-  public abstract Object getMetaInfo() throws ServicePluginException;
-}

http://git-wip-us.apache.org/repos/asf/tez/blob/fad16425/tez-dag/src/main/java/org/apache/tez/dag/api/TaskCommunicatorContext.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/api/TaskCommunicatorContext.java b/tez-dag/src/main/java/org/apache/tez/dag/api/TaskCommunicatorContext.java
deleted file mode 100644
index 7c5a648..0000000
--- a/tez-dag/src/main/java/org/apache/tez/dag/api/TaskCommunicatorContext.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tez.dag.api;
-
-import javax.annotation.Nullable;
-import java.io.IOException;
-import java.util.Set;
-
-import org.apache.hadoop.security.Credentials;
-import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
-import org.apache.hadoop.yarn.api.records.ContainerId;
-import org.apache.tez.dag.api.event.VertexState;
-import org.apache.tez.serviceplugins.api.TaskAttemptEndReason;
-import org.apache.tez.dag.records.TezTaskAttemptID;
-
-
-// Do not make calls into this from within a held lock.
-
-// TODO TEZ-2003 (post) TEZ-2665. Move to the tez-api module
-public interface TaskCommunicatorContext {
-
-  // TODO TEZ-2003 (post) TEZ-2666 Enhancements to API
-  // - Consolidate usage of IDs
-  // - Split the heartbeat API to a liveness check and a status update
-  // - Rename and consolidate TaskHeartbeatResponse and TaskHeartbeatRequest
-  // - Fix taskStarted needs to be invoked before launching the actual task.
-  // - Potentially add methods to report availability stats to the scheduler
-  // - Report taskSuccess via a method instead of the heartbeat
-  // - Add methods to signal container / task state changes
-  // - Maybe add book-keeping as a helper library, instead of each impl tracking container to task etc.
-  // - Handling of containres / tasks which no longer exist in the system (formalized interface instead of a shouldDie notification)
-
-  /**
-   * Get the UserPayload that was configured while setting up the task communicator
-   *
-   * @return the initially configured user payload
-   */
-  UserPayload getInitialUserPayload();
-
-  /**
-   * Get the application attempt id for the running application. Relevant when running under YARN
-   *
-   * @return the applicationAttemptId for the running app
-   */
-  ApplicationAttemptId getApplicationAttemptId();
-
-  /**
-   * Get credentials associated with the AppMaster
-   *
-   * @return credentials
-   */
-  Credentials getCredentials();
-
-  /**
-   * Check whether a running attempt can commit. This provides a leader election mechanism amongst
-   * multiple running attempts
-   *
-   * @param taskAttemptId the associated task attempt id
-   * @return whether the attempt can commit or not
-   * @throws IOException
-   */
-  boolean canCommit(TezTaskAttemptID taskAttemptId) throws IOException;
-
-  /**
-   * Mechanism for a {@link TaskCommunicator} to provide updates on a running task, as well as
-   * receive new information which may need to be propagated to the task. This includes events
-   * generated by the task and events which need to be sent to the task
-   * This method must be invoked periodically to receive updates for a running task
-   *
-   * @param request the update from the running task.
-   * @return the response that is requried by the task.
-   * @throws IOException
-   * @throws TezException
-   */
-  TaskHeartbeatResponse heartbeat(TaskHeartbeatRequest request) throws IOException, TezException;
-
-  /**
-   * Check whether the container is known by the framework. The state of this container is
-   * irrelevant
-   *
-   * @param containerId the relevant container id
-   * @return true if the container is known, false if it isn't
-   */
-  boolean isKnownContainer(ContainerId containerId);
-
-  /**
-   * Inform the framework that a task is alive. This needs to be invoked periodically to avoid the
-   * task attempt timing out.
-   * Invocations to heartbeat provides the same keep-alive functionality
-   *
-   * @param taskAttemptId the relevant task attempt
-   */
-  void taskAlive(TezTaskAttemptID taskAttemptId);
-
-  /**
-   * Inform the framework that a container is alive. This need to be invoked periodically to avoid
-   * the container attempt timing out.
-   * Invocations to heartbeat provides the same keep-alive functionality
-   *
-   * @param containerId the relevant container id
-   */
-  void containerAlive(ContainerId containerId);
-
-  /**
-   * Inform the framework that the task has started execution
-   *
-   * @param taskAttemptId the relevant task attempt id
-   * @param containerId   the containerId in which the task attempt is running
-   */
-  void taskStartedRemotely(TezTaskAttemptID taskAttemptId, ContainerId containerId);
-
-  /**
-   * Inform the framework that a task has been killed
-   *
-   * @param taskAttemptId        the relevant task attempt id
-   * @param taskAttemptEndReason the reason for the task attempt being killed
-   * @param diagnostics          any diagnostics messages which are relevant to the task attempt
-   *                             kill
-   */
-  void taskKilled(TezTaskAttemptID taskAttemptId, TaskAttemptEndReason taskAttemptEndReason,
-                  @Nullable String diagnostics);
-
-  /**
-   * Inform the framework that a task has failed
-   *
-   * @param taskAttemptId        the relevant task attempt id
-   * @param taskAttemptEndReason the reason for the task failure
-   * @param diagnostics          any diagnostics messages which are relevant to the task attempt
-   *                             failure
-   */
-  void taskFailed(TezTaskAttemptID taskAttemptId, TaskAttemptEndReason taskAttemptEndReason,
-                  @Nullable String diagnostics);
-
-  /**
-   * Register to get notifications on updates to the specified vertex. Notifications will be sent
-   * via {@link org.apache.tez.runtime.api.InputInitializer#onVertexStateUpdated(org.apache.tez.dag.api.event.VertexStateUpdate)}
-   * </p>
-   * <p/>
-   * This method can only be invoked once. Duplicate invocations will result in an error.
-   *
-   * @param vertexName the vertex name for which notifications are required.
-   * @param stateSet   the set of states for which notifications are required. null implies all
-   */
-  void registerForVertexStateUpdates(String vertexName, @Nullable Set<VertexState> stateSet);
-
-  /**
-   * Get the name of the currently executing dag
-   *
-   * @return the name of the currently executing dag
-   */
-  String getCurrentDagName();
-
-  /**
-   * Get an identifier for the executing context of the DAG.
-   * @return a String identifier for the exeucting context.
-   */
-  String getCurrentAppIdentifier();
-
-  /**
-   * Get the identifier for the currently executing dag.
-   * @return a numerical identifier for the currently running DAG. This is unique within the currently running application.
-   */
-  int getCurrentDagIdenitifer();
-
-  /**
-   * Get the name of the Input vertices for the specified vertex.
-   * Root Inputs are not returned.
-   *
-   * @param vertexName the vertex for which source vertex names will be returned
-   * @return an Iterable containing the list of input vertices for the specified vertex
-   */
-  Iterable<String> getInputVertexNames(String vertexName);
-
-  /**
-   * Get the total number of tasks in the given vertex
-   *
-   * @param vertexName the relevant vertex name
-   * @return total number of tasks in this vertex
-   */
-  int getVertexTotalTaskCount(String vertexName);
-
-  /**
-   * Get the number of completed tasks for a given vertex
-   *
-   * @param vertexName the vertex name
-   * @return the number of completed tasks for the vertex
-   */
-  int getVertexCompletedTaskCount(String vertexName);
-
-  /**
-   * Get the number of running tasks for a given vertex
-   *
-   * @param vertexName the vertex name
-   * @return the number of running tasks for the vertex
-   */
-  int getVertexRunningTaskCount(String vertexName);
-
-  /**
-   * Get the start time for the first attempt of the specified task
-   *
-   * @param vertexName the vertex to which the task belongs
-   * @param taskIndex  the index of the task
-   * @return the start time for the first attempt of the task
-   */
-  long getFirstAttemptStartTime(String vertexName, int taskIndex);
-
-  /**
-   * Get the start time for the currently executing DAG
-   *
-   * @return time when the current dag started executing
-   */
-  long getDagStartTime();
-}

http://git-wip-us.apache.org/repos/asf/tez/blob/fad16425/tez-dag/src/main/java/org/apache/tez/dag/api/TaskHeartbeatRequest.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/api/TaskHeartbeatRequest.java b/tez-dag/src/main/java/org/apache/tez/dag/api/TaskHeartbeatRequest.java
deleted file mode 100644
index d0c22d3..0000000
--- a/tez-dag/src/main/java/org/apache/tez/dag/api/TaskHeartbeatRequest.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tez.dag.api;
-
-import java.util.List;
-
-import org.apache.tez.dag.records.TezTaskAttemptID;
-import org.apache.tez.runtime.api.impl.TezEvent;
-
-// TODO TEZ-2003 (post) TEZ-2665. Move to the tez-api module
-public class TaskHeartbeatRequest {
-
-  // TODO TEZ-2003 (post) TEZ-2666 Ideally containerIdentifier should not be part of the request.
-  private final String containerIdentifier;
-  private final TezTaskAttemptID taskAttemptId;
-  private final List<TezEvent> events;
-  private final int startIndex;
-  private final int preRoutedStartIndex;
-  private final int maxEvents;
-
-
-  public TaskHeartbeatRequest(String containerIdentifier, TezTaskAttemptID taskAttemptId, List<TezEvent> events, int startIndex,
-                              int preRoutedStartIndex,
-                              int maxEvents) {
-    this.containerIdentifier = containerIdentifier;
-    this.taskAttemptId = taskAttemptId;
-    this.events = events;
-    this.startIndex = startIndex;
-    this.preRoutedStartIndex = preRoutedStartIndex;
-    this.maxEvents = maxEvents;
-  }
-
-  public String getContainerIdentifier() {
-    return containerIdentifier;
-  }
-
-  public TezTaskAttemptID getTaskAttemptId() {
-    return taskAttemptId;
-  }
-
-  public List<TezEvent> getEvents() {
-    return events;
-  }
-
-  public int getStartIndex() {
-    return startIndex;
-  }
-
-  public int getPreRoutedStartIndex() {
-    return preRoutedStartIndex;
-  }
-
-  public int getMaxEvents() {
-    return maxEvents;
-  }
-}

http://git-wip-us.apache.org/repos/asf/tez/blob/fad16425/tez-dag/src/main/java/org/apache/tez/dag/api/TaskHeartbeatResponse.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/api/TaskHeartbeatResponse.java b/tez-dag/src/main/java/org/apache/tez/dag/api/TaskHeartbeatResponse.java
deleted file mode 100644
index dcf89ff..0000000
--- a/tez-dag/src/main/java/org/apache/tez/dag/api/TaskHeartbeatResponse.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tez.dag.api;
-
-import java.util.List;
-
-import org.apache.tez.runtime.api.impl.TezEvent;
-
-// TODO TEZ-2003 (post) TEZ-2665. Move to the tez-api module
-public class TaskHeartbeatResponse {
-
-  private final boolean shouldDie;
-  private final int nextFromEventId;
-  private final int nextPreRoutedEventId;
-  private final List<TezEvent> events;
-
-  public TaskHeartbeatResponse(boolean shouldDie, List<TezEvent> events, int nextFromEventId, int nextPreRoutedEventId) {
-    this.shouldDie = shouldDie;
-    this.events = events;
-    this.nextFromEventId = nextFromEventId;
-    this.nextPreRoutedEventId = nextPreRoutedEventId;
-  }
-
-  public boolean isShouldDie() {
-    return shouldDie;
-  }
-
-  public List<TezEvent> getEvents() {
-    return events;
-  }
-
-  public int getNextFromEventId() {
-    return nextFromEventId;
-  }
-
-  public int getNextPreRoutedEventId() {
-    return nextPreRoutedEventId;
-  }
-}

http://git-wip-us.apache.org/repos/asf/tez/blob/fad16425/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorContextImpl.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorContextImpl.java b/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorContextImpl.java
index 2b7234c..7f88be2 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorContextImpl.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorContextImpl.java
@@ -29,11 +29,10 @@ import org.apache.hadoop.yarn.api.records.ContainerId;
 import org.apache.tez.dag.api.UserPayload;
 import org.apache.tez.dag.app.rm.container.AMContainer;
 import org.apache.tez.serviceplugins.api.TaskAttemptEndReason;
-import org.apache.tez.dag.api.TaskCommunicatorContext;
-import org.apache.tez.dag.api.TaskHeartbeatRequest;
-import org.apache.tez.dag.api.TaskHeartbeatResponse;
+import org.apache.tez.serviceplugins.api.TaskCommunicatorContext;
+import org.apache.tez.serviceplugins.api.TaskHeartbeatRequest;
+import org.apache.tez.serviceplugins.api.TaskHeartbeatResponse;
 import org.apache.tez.dag.api.TezException;
-import org.apache.tez.dag.api.TezUncheckedException;
 import org.apache.tez.dag.api.event.VertexState;
 import org.apache.tez.dag.api.event.VertexStateUpdate;
 import org.apache.tez.dag.app.dag.DAG;

http://git-wip-us.apache.org/repos/asf/tez/blob/fad16425/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorManager.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorManager.java b/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorManager.java
index 64a964b..a196114 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorManager.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorManager.java
@@ -33,7 +33,7 @@ import org.apache.commons.collections4.ListUtils;
 import org.apache.hadoop.yarn.event.Event;
 import org.apache.tez.Utils;
 import org.apache.tez.dag.api.NamedEntityDescriptor;
-import org.apache.tez.dag.api.TaskCommunicator;
+import org.apache.tez.serviceplugins.api.TaskCommunicator;
 import org.apache.tez.dag.api.TezConstants;
 import org.apache.tez.dag.api.UserPayload;
 import org.apache.tez.dag.app.dag.event.DAGAppMasterEventType;
@@ -53,14 +53,14 @@ import org.apache.hadoop.service.AbstractService;
 import org.apache.hadoop.yarn.api.records.NodeId;
 import org.apache.tez.common.ReflectionUtils;
 import org.apache.tez.common.TezUtilsInternal;
-import org.apache.tez.dag.api.TaskCommunicatorContext;
+import org.apache.tez.serviceplugins.api.TaskCommunicatorContext;
 import org.apache.tez.serviceplugins.api.TaskAttemptEndReason;
-import org.apache.tez.dag.api.TaskHeartbeatResponse;
+import org.apache.tez.serviceplugins.api.TaskHeartbeatResponse;
 import org.apache.tez.dag.api.TezException;
 import org.apache.tez.dag.api.TezUncheckedException;
 import org.apache.hadoop.yarn.api.records.ContainerId;
 import org.apache.hadoop.yarn.util.ConverterUtils;
-import org.apache.tez.dag.api.TaskHeartbeatRequest;
+import org.apache.tez.serviceplugins.api.TaskHeartbeatRequest;
 import org.apache.tez.dag.app.dag.DAG;
 import org.apache.tez.dag.app.dag.Task;
 import org.apache.tez.dag.app.dag.event.TaskAttemptEvent;

http://git-wip-us.apache.org/repos/asf/tez/blob/fad16425/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorWrapper.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorWrapper.java b/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorWrapper.java
index 4f9780e..4a75875 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorWrapper.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/TaskCommunicatorWrapper.java
@@ -21,7 +21,7 @@ import java.util.Map;
 import org.apache.hadoop.security.Credentials;
 import org.apache.hadoop.yarn.api.records.ContainerId;
 import org.apache.hadoop.yarn.api.records.LocalResource;
-import org.apache.tez.dag.api.TaskCommunicator;
+import org.apache.tez.serviceplugins.api.TaskCommunicator;
 import org.apache.tez.dag.api.event.VertexStateUpdate;
 import org.apache.tez.dag.records.TezTaskAttemptID;
 import org.apache.tez.runtime.api.impl.TaskSpec;

http://git-wip-us.apache.org/repos/asf/tez/blob/fad16425/tez-dag/src/main/java/org/apache/tez/dag/app/TezLocalTaskCommunicatorImpl.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/TezLocalTaskCommunicatorImpl.java b/tez-dag/src/main/java/org/apache/tez/dag/app/TezLocalTaskCommunicatorImpl.java
index 47688d1..15d90d3 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/TezLocalTaskCommunicatorImpl.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/TezLocalTaskCommunicatorImpl.java
@@ -18,7 +18,7 @@ import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.UnknownHostException;
 
-import org.apache.tez.dag.api.TaskCommunicatorContext;
+import org.apache.tez.serviceplugins.api.TaskCommunicatorContext;
 import org.apache.tez.dag.api.TezUncheckedException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

http://git-wip-us.apache.org/repos/asf/tez/blob/fad16425/tez-dag/src/main/java/org/apache/tez/dag/app/TezTaskCommunicatorImpl.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/TezTaskCommunicatorImpl.java b/tez-dag/src/main/java/org/apache/tez/dag/app/TezTaskCommunicatorImpl.java
index d071e0d..0bbe97a 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/TezTaskCommunicatorImpl.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/TezTaskCommunicatorImpl.java
@@ -47,10 +47,10 @@ import org.apache.tez.common.security.JobTokenSecretManager;
 import org.apache.tez.common.security.TokenCache;
 import org.apache.tez.serviceplugins.api.ContainerEndReason;
 import org.apache.tez.serviceplugins.api.TaskAttemptEndReason;
-import org.apache.tez.dag.api.TaskCommunicator;
-import org.apache.tez.dag.api.TaskCommunicatorContext;
-import org.apache.tez.dag.api.TaskHeartbeatRequest;
-import org.apache.tez.dag.api.TaskHeartbeatResponse;
+import org.apache.tez.serviceplugins.api.TaskCommunicator;
+import org.apache.tez.serviceplugins.api.TaskCommunicatorContext;
+import org.apache.tez.serviceplugins.api.TaskHeartbeatRequest;
+import org.apache.tez.serviceplugins.api.TaskHeartbeatResponse;
 import org.apache.tez.dag.api.TezConfiguration;
 import org.apache.tez.dag.api.TezException;
 import org.apache.tez.dag.api.TezUncheckedException;

http://git-wip-us.apache.org/repos/asf/tez/blob/fad16425/tez-dag/src/main/java/org/apache/tez/serviceplugins/api/TaskCommunicator.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/serviceplugins/api/TaskCommunicator.java b/tez-dag/src/main/java/org/apache/tez/serviceplugins/api/TaskCommunicator.java
new file mode 100644
index 0000000..8f919d1
--- /dev/null
+++ b/tez-dag/src/main/java/org/apache/tez/serviceplugins/api/TaskCommunicator.java
@@ -0,0 +1,232 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tez.serviceplugins.api;
+
+import javax.annotation.Nullable;
+import java.net.InetSocketAddress;
+import java.util.Map;
+
+import org.apache.hadoop.security.Credentials;
+import org.apache.hadoop.yarn.api.records.ContainerId;
+import org.apache.hadoop.yarn.api.records.LocalResource;
+import org.apache.tez.common.ServicePluginLifecycle;
+import org.apache.tez.dag.api.event.VertexStateUpdate;
+import org.apache.tez.dag.records.TezTaskAttemptID;
+import org.apache.tez.runtime.api.impl.TaskSpec;
+
+// TODO TEZ-2003 (post) TEZ-2665. Move to the tez-api module
+// TODO TEZ-2003 (post) TEZ-2664. Ideally, don't expose YARN containerId; instead expose a Tez specific construct.
+
+/**
+ * This class represents the API for a custom TaskCommunicator which can be run within the Tez AM.
+ * This is used to communicate with running services, potentially launching tasks, and getting
+ * updates from running tasks.
+ * <p/>
+ * The plugin is initialized with an instance of {@link TaskCommunicatorContext} - which provides
+ * a mechanism to notify the system about allocation decisions and resources to the Tez framework.
+ *
+ * If setting up a heartbeat between the task and the AM, the framework is responsible for error checking
+ * of this heartbeat mechanism, handling lost or duplicate responses.
+ *
+ */
+public abstract class TaskCommunicator implements ServicePluginLifecycle {
+
+  // TODO TEZ-2003 (post) TEZ-2666 Enhancements to interface
+  // - registerContainerEnd should provide the end reason / possible rename
+  // - get rid of getAddress
+  // - Add methods to support task preemption
+  // - Add a dagStarted notification, along with a payload
+  // - taskSpec breakup into a clean interface
+  // - Add methods to report task / container completion
+
+  private final TaskCommunicatorContext taskCommunicatorContext;
+
+  public TaskCommunicator(TaskCommunicatorContext taskCommunicatorContext) {
+    this.taskCommunicatorContext = taskCommunicatorContext;
+  }
+
+  /**
+   * Get the {@link TaskCommunicatorContext} associated with this instance of the scheduler, which
+   * is
+   * used to communicate with the rest of the system
+   *
+   * @return an instance of {@link TaskCommunicatorContext}
+   */
+  public TaskCommunicatorContext getContext() {
+    return taskCommunicatorContext;
+  }
+
+  /**
+   * An entry point for initialization.
+   * Order of service setup. Constructor, initialize(), start() - when starting a service.
+   *
+   * @throws Exception
+   */
+  @Override
+  public void initialize() throws Exception {
+  }
+
+  /**
+   * An entry point for starting the service.
+   * Order of service setup. Constructor, initialize(), start() - when starting a service.
+   *
+   * @throws Exception
+   */
+  @Override
+  public void start() throws Exception {
+  }
+
+  /**
+   * Stop the service. This could be invoked at any point, when the service is no longer required -
+   * including in case of errors.
+   *
+   * @throws Exception
+   */
+  @Override
+  public void shutdown() throws Exception {
+  }
+
+
+  /**
+   * Register a new container.
+   *
+   * @param containerId the associated containerId
+   * @param hostname    the hostname on which the container runs
+   * @param port        the port for the service which is running the container
+   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
+   *                               This will cause the app to shutdown.
+   */
+  public abstract void registerRunningContainer(ContainerId containerId, String hostname,
+                                                int port) throws ServicePluginException;
+
+  /**
+   * Register the end of a container. This can be caused by preemption, the container completing
+   * successfully, etc.
+   *
+   * @param containerId the associated containerId
+   * @param endReason   the end reason for the container completing
+   * @param diagnostics diagnostics associated with the container end
+   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
+   *                               This will cause the app to shutdown.
+   */
+  public abstract void registerContainerEnd(ContainerId containerId, ContainerEndReason endReason,
+                                            @Nullable String diagnostics) throws
+      ServicePluginException;
+
+  /**
+   * Register a task attempt to execute on a container
+   *
+   * @param containerId         the containerId on which this task needs to run
+   * @param taskSpec            the task specifications for the task to be executed
+   * @param additionalResources additional local resources which may be required to run this task
+   *                            on
+   *                            the container
+   * @param credentials         the credentials required to run this task
+   * @param credentialsChanged  whether the credentials are different from the original credentials
+   *                            associated with this container
+   * @param priority            the priority of the task being executed
+   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
+   *                               This will cause the app to shutdown.
+   */
+  public abstract void registerRunningTaskAttempt(ContainerId containerId, TaskSpec taskSpec,
+                                                  Map<String, LocalResource> additionalResources,
+                                                  Credentials credentials,
+                                                  boolean credentialsChanged, int priority) throws
+      ServicePluginException;
+
+  /**
+   * Register the completion of a task. This may be a result of preemption, the container dying,
+   * the node dying, the task completing to success
+   *
+   * @param taskAttemptID the task attempt which has completed / needs to be completed
+   * @param endReason     the endReason for the task attempt.
+   * @param diagnostics   diagnostics associated with the task end
+   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
+   *                               This will cause the app to shutdown.
+   */
+  public abstract void unregisterRunningTaskAttempt(TezTaskAttemptID taskAttemptID,
+                                                    TaskAttemptEndReason endReason,
+                                                    @Nullable String diagnostics) throws
+      ServicePluginException;
+
+  /**
+   * Return the address, if any, that the service listens on
+   *
+   * @return the address
+   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
+   *                               This will cause the app to shutdown.
+   */
+  public abstract InetSocketAddress getAddress() throws ServicePluginException;
+
+  /**
+   * Receive notifications on vertex state changes.
+   * <p/>
+   * State changes will be received based on the registration via {@link
+   * org.apache.tez.runtime.api.InputInitializerContext#registerForVertexStateUpdates(String,
+   * java.util.Set)}. Notifications will be received for all registered state changes, and not just
+   * for the latest state update. They will be in order in which the state change occurred. </p>
+   * <p/>
+   * Extensive processing should not be performed via this method call. Instead this should just be
+   * used as a notification mechanism.
+   * <br>This method may be invoked concurrently with other invocations into the TaskCommunicator
+   * and
+   * multi-threading/concurrency implications must be considered.
+   *
+   * @param stateUpdate an event indicating the name of the vertex, and it's updated state.
+   *                    Additional information may be available for specific events, Look at the
+   *                    type hierarchy for {@link org.apache.tez.dag.api.event.VertexStateUpdate}
+   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
+   *                               This will cause the app to shutdown.
+   */
+  public abstract void onVertexStateUpdated(VertexStateUpdate stateUpdate) throws ServicePluginException;
+
+  /**
+   * Indicates the current running dag is complete. The TaskCommunicatorContext can be used to
+   * query information about the current dag during the duration of the dagComplete invocation.
+   * <p/>
+   * After this, the contents returned from querying the context may change at any point - due to
+   * the next dag being submitted.
+   *
+   * @param dagIdentifier the unique numerical identifier for the DAG in the specified execution context.
+   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
+   *                               This will cause the app to shutdown.
+   */
+  public abstract void dagComplete(int dagIdentifier) throws ServicePluginException;
+
+  /**
+   * Share meta-information such as host:port information where the Task Communicator may be
+   * listening.
+   * Primarily for use by compatible launchers to learn this information.
+   *
+   * @return meta info for the task communicator
+   * @throws ServicePluginException when the service runs into a fatal error which it cannot handle.
+   *                               This will cause the app to shutdown.
+   */
+  public abstract Object getMetaInfo() throws ServicePluginException;
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/fad16425/tez-dag/src/main/java/org/apache/tez/serviceplugins/api/TaskCommunicatorContext.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/serviceplugins/api/TaskCommunicatorContext.java b/tez-dag/src/main/java/org/apache/tez/serviceplugins/api/TaskCommunicatorContext.java
new file mode 100644
index 0000000..c55bdbd
--- /dev/null
+++ b/tez-dag/src/main/java/org/apache/tez/serviceplugins/api/TaskCommunicatorContext.java
@@ -0,0 +1,240 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tez.serviceplugins.api;
+
+import javax.annotation.Nullable;
+import java.io.IOException;
+import java.util.Set;
+
+import org.apache.hadoop.security.Credentials;
+import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
+import org.apache.hadoop.yarn.api.records.ContainerId;
+import org.apache.tez.dag.api.TezException;
+import org.apache.tez.dag.api.UserPayload;
+import org.apache.tez.dag.api.event.VertexState;
+import org.apache.tez.dag.records.TezTaskAttemptID;
+
+
+// Do not make calls into this from within a held lock.
+
+// TODO TEZ-2003 (post) TEZ-2665. Move to the tez-api module
+public interface TaskCommunicatorContext {
+
+  // TODO TEZ-2003 (post) TEZ-2666 Enhancements to API
+  // - Consolidate usage of IDs
+  // - Split the heartbeat API to a liveness check and a status update
+  // - Rename and consolidate TaskHeartbeatResponse and TaskHeartbeatRequest
+  // - Fix taskStarted needs to be invoked before launching the actual task.
+  // - Potentially add methods to report availability stats to the scheduler
+  // - Report taskSuccess via a method instead of the heartbeat
+  // - Add methods to signal container / task state changes
+  // - Maybe add book-keeping as a helper library, instead of each impl tracking container to task etc.
+  // - Handling of containres / tasks which no longer exist in the system (formalized interface instead of a shouldDie notification)
+
+  /**
+   * Get the UserPayload that was configured while setting up the task communicator
+   *
+   * @return the initially configured user payload
+   */
+  UserPayload getInitialUserPayload();
+
+  /**
+   * Get the application attempt id for the running application. Relevant when running under YARN
+   *
+   * @return the applicationAttemptId for the running app
+   */
+  ApplicationAttemptId getApplicationAttemptId();
+
+  /**
+   * Get credentials associated with the AppMaster
+   *
+   * @return credentials
+   */
+  Credentials getCredentials();
+
+  /**
+   * Check whether a running attempt can commit. This provides a leader election mechanism amongst
+   * multiple running attempts
+   *
+   * @param taskAttemptId the associated task attempt id
+   * @return whether the attempt can commit or not
+   * @throws IOException
+   */
+  boolean canCommit(TezTaskAttemptID taskAttemptId) throws IOException;
+
+  /**
+   * Mechanism for a {@link TaskCommunicator} to provide updates on a running task, as well as
+   * receive new information which may need to be propagated to the task. This includes events
+   * generated by the task and events which need to be sent to the task
+   * This method must be invoked periodically to receive updates for a running task
+   *
+   * @param request the update from the running task.
+   * @return the response that is requried by the task.
+   * @throws IOException
+   * @throws TezException
+   */
+  TaskHeartbeatResponse heartbeat(TaskHeartbeatRequest request) throws IOException, TezException;
+
+  /**
+   * Check whether the container is known by the framework. The state of this container is
+   * irrelevant
+   *
+   * @param containerId the relevant container id
+   * @return true if the container is known, false if it isn't
+   */
+  boolean isKnownContainer(ContainerId containerId);
+
+  /**
+   * Inform the framework that a task is alive. This needs to be invoked periodically to avoid the
+   * task attempt timing out.
+   * Invocations to heartbeat provides the same keep-alive functionality
+   *
+   * @param taskAttemptId the relevant task attempt
+   */
+  void taskAlive(TezTaskAttemptID taskAttemptId);
+
+  /**
+   * Inform the framework that a container is alive. This need to be invoked periodically to avoid
+   * the container attempt timing out.
+   * Invocations to heartbeat provides the same keep-alive functionality
+   *
+   * @param containerId the relevant container id
+   */
+  void containerAlive(ContainerId containerId);
+
+  /**
+   * Inform the framework that the task has started execution
+   *
+   * @param taskAttemptId the relevant task attempt id
+   * @param containerId   the containerId in which the task attempt is running
+   */
+  void taskStartedRemotely(TezTaskAttemptID taskAttemptId, ContainerId containerId);
+
+  /**
+   * Inform the framework that a task has been killed
+   *
+   * @param taskAttemptId        the relevant task attempt id
+   * @param taskAttemptEndReason the reason for the task attempt being killed
+   * @param diagnostics          any diagnostics messages which are relevant to the task attempt
+   *                             kill
+   */
+  void taskKilled(TezTaskAttemptID taskAttemptId, TaskAttemptEndReason taskAttemptEndReason,
+                  @Nullable String diagnostics);
+
+  /**
+   * Inform the framework that a task has failed
+   *
+   * @param taskAttemptId        the relevant task attempt id
+   * @param taskAttemptEndReason the reason for the task failure
+   * @param diagnostics          any diagnostics messages which are relevant to the task attempt
+   *                             failure
+   */
+  void taskFailed(TezTaskAttemptID taskAttemptId, TaskAttemptEndReason taskAttemptEndReason,
+                  @Nullable String diagnostics);
+
+  /**
+   * Register to get notifications on updates to the specified vertex. Notifications will be sent
+   * via {@link org.apache.tez.runtime.api.InputInitializer#onVertexStateUpdated(org.apache.tez.dag.api.event.VertexStateUpdate)}
+   * </p>
+   * <p/>
+   * This method can only be invoked once. Duplicate invocations will result in an error.
+   *
+   * @param vertexName the vertex name for which notifications are required.
+   * @param stateSet   the set of states for which notifications are required. null implies all
+   */
+  void registerForVertexStateUpdates(String vertexName, @Nullable Set<VertexState> stateSet);
+
+  /**
+   * Get the name of the currently executing dag
+   *
+   * @return the name of the currently executing dag
+   */
+  String getCurrentDagName();
+
+  /**
+   * Get an identifier for the executing context of the DAG.
+   * @return a String identifier for the exeucting context.
+   */
+  String getCurrentAppIdentifier();
+
+  /**
+   * Get the identifier for the currently executing dag.
+   * @return a numerical identifier for the currently running DAG. This is unique within the currently running application.
+   */
+  int getCurrentDagIdenitifer();
+
+  /**
+   * Get the name of the Input vertices for the specified vertex.
+   * Root Inputs are not returned.
+   *
+   * @param vertexName the vertex for which source vertex names will be returned
+   * @return an Iterable containing the list of input vertices for the specified vertex
+   */
+  Iterable<String> getInputVertexNames(String vertexName);
+
+  /**
+   * Get the total number of tasks in the given vertex
+   *
+   * @param vertexName the relevant vertex name
+   * @return total number of tasks in this vertex
+   */
+  int getVertexTotalTaskCount(String vertexName);
+
+  /**
+   * Get the number of completed tasks for a given vertex
+   *
+   * @param vertexName the vertex name
+   * @return the number of completed tasks for the vertex
+   */
+  int getVertexCompletedTaskCount(String vertexName);
+
+  /**
+   * Get the number of running tasks for a given vertex
+   *
+   * @param vertexName the vertex name
+   * @return the number of running tasks for the vertex
+   */
+  int getVertexRunningTaskCount(String vertexName);
+
+  /**
+   * Get the start time for the first attempt of the specified task
+   *
+   * @param vertexName the vertex to which the task belongs
+   * @param taskIndex  the index of the task
+   * @return the start time for the first attempt of the task
+   */
+  long getFirstAttemptStartTime(String vertexName, int taskIndex);
+
+  /**
+   * Get the start time for the currently executing DAG
+   *
+   * @return time when the current dag started executing
+   */
+  long getDagStartTime();
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/fad16425/tez-dag/src/main/java/org/apache/tez/serviceplugins/api/TaskHeartbeatRequest.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/serviceplugins/api/TaskHeartbeatRequest.java b/tez-dag/src/main/java/org/apache/tez/serviceplugins/api/TaskHeartbeatRequest.java
new file mode 100644
index 0000000..40b006f
--- /dev/null
+++ b/tez-dag/src/main/java/org/apache/tez/serviceplugins/api/TaskHeartbeatRequest.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tez.serviceplugins.api;
+
+import java.util.List;
+
+import org.apache.tez.dag.records.TezTaskAttemptID;
+import org.apache.tez.runtime.api.impl.TezEvent;
+
+// TODO TEZ-2003 (post) TEZ-2665. Move to the tez-api module
+public class TaskHeartbeatRequest {
+
+  // TODO TEZ-2003 (post) TEZ-2666 Ideally containerIdentifier should not be part of the request.
+  private final String containerIdentifier;
+  private final TezTaskAttemptID taskAttemptId;
+  private final List<TezEvent> events;
+  private final int startIndex;
+  private final int preRoutedStartIndex;
+  private final int maxEvents;
+
+
+  public TaskHeartbeatRequest(String containerIdentifier, TezTaskAttemptID taskAttemptId, List<TezEvent> events, int startIndex,
+                              int preRoutedStartIndex,
+                              int maxEvents) {
+    this.containerIdentifier = containerIdentifier;
+    this.taskAttemptId = taskAttemptId;
+    this.events = events;
+    this.startIndex = startIndex;
+    this.preRoutedStartIndex = preRoutedStartIndex;
+    this.maxEvents = maxEvents;
+  }
+
+  public String getContainerIdentifier() {
+    return containerIdentifier;
+  }
+
+  public TezTaskAttemptID getTaskAttemptId() {
+    return taskAttemptId;
+  }
+
+  public List<TezEvent> getEvents() {
+    return events;
+  }
+
+  public int getStartIndex() {
+    return startIndex;
+  }
+
+  public int getPreRoutedStartIndex() {
+    return preRoutedStartIndex;
+  }
+
+  public int getMaxEvents() {
+    return maxEvents;
+  }
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/fad16425/tez-dag/src/main/java/org/apache/tez/serviceplugins/api/TaskHeartbeatResponse.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/serviceplugins/api/TaskHeartbeatResponse.java b/tez-dag/src/main/java/org/apache/tez/serviceplugins/api/TaskHeartbeatResponse.java
new file mode 100644
index 0000000..9145004
--- /dev/null
+++ b/tez-dag/src/main/java/org/apache/tez/serviceplugins/api/TaskHeartbeatResponse.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tez.serviceplugins.api;
+
+import java.util.List;
+
+import org.apache.tez.runtime.api.impl.TezEvent;
+
+// TODO TEZ-2003 (post) TEZ-2665. Move to the tez-api module
+public class TaskHeartbeatResponse {
+
+  private final boolean shouldDie;
+  private final int nextFromEventId;
+  private final int nextPreRoutedEventId;
+  private final List<TezEvent> events;
+
+  public TaskHeartbeatResponse(boolean shouldDie, List<TezEvent> events, int nextFromEventId, int nextPreRoutedEventId) {
+    this.shouldDie = shouldDie;
+    this.events = events;
+    this.nextFromEventId = nextFromEventId;
+    this.nextPreRoutedEventId = nextPreRoutedEventId;
+  }
+
+  public boolean isShouldDie() {
+    return shouldDie;
+  }
+
+  public List<TezEvent> getEvents() {
+    return events;
+  }
+
+  public int getNextFromEventId() {
+    return nextFromEventId;
+  }
+
+  public int getNextPreRoutedEventId() {
+    return nextPreRoutedEventId;
+  }
+}

http://git-wip-us.apache.org/repos/asf/tez/blob/fad16425/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorContextImpl.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorContextImpl.java b/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorContextImpl.java
index 5222a2d..869bfd5 100644
--- a/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorContextImpl.java
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorContextImpl.java
@@ -25,7 +25,7 @@ import static org.mockito.Mockito.verify;
 import org.apache.hadoop.yarn.api.records.Container;
 import org.apache.hadoop.yarn.api.records.ContainerId;
 import org.apache.tez.common.ContainerSignatureMatcher;
-import org.apache.tez.dag.api.TaskCommunicatorContext;
+import org.apache.tez.serviceplugins.api.TaskCommunicatorContext;
 import org.apache.tez.dag.app.rm.container.AMContainerMap;
 import org.junit.Test;
 

http://git-wip-us.apache.org/repos/asf/tez/blob/fad16425/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorManager.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorManager.java b/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorManager.java
index d76a5b3..5323928 100644
--- a/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorManager.java
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorManager.java
@@ -49,8 +49,8 @@ import org.apache.hadoop.yarn.event.Event;
 import org.apache.hadoop.yarn.event.EventHandler;
 import org.apache.tez.common.TezUtils;
 import org.apache.tez.dag.api.NamedEntityDescriptor;
-import org.apache.tez.dag.api.TaskCommunicator;
-import org.apache.tez.dag.api.TaskCommunicatorContext;
+import org.apache.tez.serviceplugins.api.TaskCommunicator;
+import org.apache.tez.serviceplugins.api.TaskCommunicatorContext;
 import org.apache.tez.dag.api.TezConstants;
 import org.apache.tez.dag.api.TezException;
 import org.apache.tez.dag.api.UserPayload;

http://git-wip-us.apache.org/repos/asf/tez/blob/fad16425/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorManager1.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorManager1.java b/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorManager1.java
index 2921a22..0f8afaa 100644
--- a/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorManager1.java
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorManager1.java
@@ -54,19 +54,19 @@ import org.apache.tez.common.security.JobTokenIdentifier;
 import org.apache.tez.common.security.JobTokenSecretManager;
 import org.apache.tez.common.security.TokenCache;
 import org.apache.tez.dag.api.NamedEntityDescriptor;
-import org.apache.tez.dag.api.TaskCommunicator;
+import org.apache.tez.serviceplugins.api.TaskCommunicator;
 import org.apache.tez.dag.api.TezConfiguration;
 import org.apache.tez.dag.api.TezConstants;
 import org.apache.tez.dag.api.TezUncheckedException;
 import org.apache.tez.dag.api.UserPayload;
 import org.apache.tez.serviceplugins.api.ContainerEndReason;
 import org.apache.tez.serviceplugins.api.TaskAttemptEndReason;
-import org.apache.tez.dag.api.TaskHeartbeatRequest;
-import org.apache.tez.dag.api.TaskHeartbeatResponse;
+import org.apache.tez.serviceplugins.api.TaskHeartbeatRequest;
+import org.apache.tez.serviceplugins.api.TaskHeartbeatResponse;
 import org.apache.tez.dag.api.TezException;
 import org.apache.hadoop.yarn.api.records.NodeId;
 import org.apache.tez.common.TezTaskUmbilicalProtocol;
-import org.apache.tez.dag.api.TaskCommunicatorContext;
+import org.apache.tez.serviceplugins.api.TaskCommunicatorContext;
 import org.apache.tez.dag.app.dag.DAG;
 import org.apache.tez.dag.app.dag.Vertex;
 import org.apache.tez.dag.app.dag.event.TaskAttemptEvent;

http://git-wip-us.apache.org/repos/asf/tez/blob/fad16425/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorWrapper.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorWrapper.java b/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorWrapper.java
index 212bca4..e89cc99 100644
--- a/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorWrapper.java
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/TestTaskCommunicatorWrapper.java
@@ -29,7 +29,7 @@
 package org.apache.tez.dag.app;
 
 import com.google.common.collect.Sets;
-import org.apache.tez.dag.api.TaskCommunicator;
+import org.apache.tez.serviceplugins.api.TaskCommunicator;
 import org.junit.Test;
 
 public class TestTaskCommunicatorWrapper {

http://git-wip-us.apache.org/repos/asf/tez/blob/fad16425/tez-dag/src/test/java/org/apache/tez/dag/app/dag/impl/TestTaskAttempt.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/dag/impl/TestTaskAttempt.java b/tez-dag/src/test/java/org/apache/tez/dag/app/dag/impl/TestTaskAttempt.java
index 4772492..3bb688e 100644
--- a/tez-dag/src/test/java/org/apache/tez/dag/app/dag/impl/TestTaskAttempt.java
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/dag/impl/TestTaskAttempt.java
@@ -60,7 +60,7 @@ import org.apache.hadoop.yarn.util.SystemClock;
 import org.apache.log4j.Level;
 import org.apache.log4j.LogManager;
 import org.apache.tez.common.MockDNSToSwitchMapping;
-import org.apache.tez.dag.api.TaskCommunicator;
+import org.apache.tez.serviceplugins.api.TaskCommunicator;
 import org.apache.tez.dag.api.TaskLocationHint;
 import org.apache.tez.dag.api.TezConfiguration;
 import org.apache.tez.dag.api.oldrecords.TaskAttemptState;

http://git-wip-us.apache.org/repos/asf/tez/blob/fad16425/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestTaskSchedulerManager.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestTaskSchedulerManager.java b/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestTaskSchedulerManager.java
index c649870..c62ff21 100644
--- a/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestTaskSchedulerManager.java
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/rm/TestTaskSchedulerManager.java
@@ -62,7 +62,6 @@ import org.apache.hadoop.yarn.event.EventHandler;
 import org.apache.tez.common.ContainerSignatureMatcher;
 import org.apache.tez.common.TezUtils;
 import org.apache.tez.dag.api.NamedEntityDescriptor;
-import org.apache.tez.dag.api.TaskCommunicator;
 import org.apache.tez.dag.api.TaskLocationHint;
 import org.apache.tez.dag.api.TezConfiguration;
 import org.apache.tez.dag.api.TezConstants;
@@ -71,10 +70,7 @@ import org.apache.tez.dag.api.UserPayload;
 import org.apache.tez.dag.api.client.DAGClientServer;
 import org.apache.tez.dag.app.AppContext;
 import org.apache.tez.dag.app.ContainerContext;
-import org.apache.tez.dag.app.ContainerHeartbeatHandler;
 import org.apache.tez.dag.app.ServicePluginLifecycleAbstractService;
-import org.apache.tez.dag.app.TaskCommunicatorManager;
-import org.apache.tez.dag.app.TaskHeartbeatHandler;
 import org.apache.tez.dag.app.dag.TaskAttempt;
 import org.apache.tez.dag.app.dag.event.DAGAppMasterEventType;
 import org.apache.tez.dag.app.dag.event.DAGAppMasterEventUserServiceFatalError;

http://git-wip-us.apache.org/repos/asf/tez/blob/fad16425/tez-dag/src/test/java/org/apache/tez/dag/app/rm/container/TestAMContainer.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/rm/container/TestAMContainer.java b/tez-dag/src/test/java/org/apache/tez/dag/app/rm/container/TestAMContainer.java
index 8b8b6d7..ed14871 100644
--- a/tez-dag/src/test/java/org/apache/tez/dag/app/rm/container/TestAMContainer.java
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/rm/container/TestAMContainer.java
@@ -67,7 +67,7 @@ import org.apache.tez.dag.app.TaskCommunicatorWrapper;
 import org.apache.tez.serviceplugins.api.ContainerEndReason;
 import org.apache.tez.serviceplugins.api.ServicePluginException;
 import org.apache.tez.serviceplugins.api.TaskAttemptEndReason;
-import org.apache.tez.dag.api.TaskCommunicator;
+import org.apache.tez.serviceplugins.api.TaskCommunicator;
 import org.apache.tez.dag.app.AppContext;
 import org.apache.tez.dag.app.ContainerHeartbeatHandler;
 import org.apache.tez.dag.app.ContainerContext;

http://git-wip-us.apache.org/repos/asf/tez/blob/fad16425/tez-dag/src/test/java/org/apache/tez/dag/app/rm/container/TestAMContainerMap.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/rm/container/TestAMContainerMap.java b/tez-dag/src/test/java/org/apache/tez/dag/app/rm/container/TestAMContainerMap.java
index e21dda1..2fcd0c8 100644
--- a/tez-dag/src/test/java/org/apache/tez/dag/app/rm/container/TestAMContainerMap.java
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/rm/container/TestAMContainerMap.java
@@ -31,7 +31,7 @@ import org.apache.hadoop.yarn.api.records.NodeId;
 import org.apache.hadoop.yarn.api.records.Priority;
 import org.apache.hadoop.yarn.api.records.Resource;
 import org.apache.hadoop.yarn.api.records.Token;
-import org.apache.tez.dag.api.TaskCommunicator;
+import org.apache.tez.serviceplugins.api.TaskCommunicator;
 import org.apache.tez.dag.app.AppContext;
 import org.apache.tez.dag.app.ContainerHeartbeatHandler;
 import org.apache.tez.dag.app.TaskCommunicatorManagerInterface;

http://git-wip-us.apache.org/repos/asf/tez/blob/fad16425/tez-ext-service-tests/src/test/java/org/apache/tez/dag/app/taskcomm/TezTestServiceTaskCommunicatorImpl.java
----------------------------------------------------------------------
diff --git a/tez-ext-service-tests/src/test/java/org/apache/tez/dag/app/taskcomm/TezTestServiceTaskCommunicatorImpl.java b/tez-ext-service-tests/src/test/java/org/apache/tez/dag/app/taskcomm/TezTestServiceTaskCommunicatorImpl.java
index 127967a..f199dcf 100644
--- a/tez-ext-service-tests/src/test/java/org/apache/tez/dag/app/taskcomm/TezTestServiceTaskCommunicatorImpl.java
+++ b/tez-ext-service-tests/src/test/java/org/apache/tez/dag/app/taskcomm/TezTestServiceTaskCommunicatorImpl.java
@@ -31,7 +31,7 @@ import org.apache.hadoop.yarn.api.records.ContainerId;
 import org.apache.hadoop.yarn.api.records.LocalResource;
 import org.apache.tez.serviceplugins.api.ContainerEndReason;
 import org.apache.tez.serviceplugins.api.TaskAttemptEndReason;
-import org.apache.tez.dag.api.TaskCommunicatorContext;
+import org.apache.tez.serviceplugins.api.TaskCommunicatorContext;
 import org.apache.tez.dag.app.TezTaskCommunicatorImpl;
 import org.apache.tez.dag.app.TezTestServiceCommunicator;
 import org.apache.tez.dag.records.TezTaskAttemptID;

http://git-wip-us.apache.org/repos/asf/tez/blob/fad16425/tez-ext-service-tests/src/test/java/org/apache/tez/dag/app/taskcomm/TezTestServiceTaskCommunicatorWithErrors.java
----------------------------------------------------------------------
diff --git a/tez-ext-service-tests/src/test/java/org/apache/tez/dag/app/taskcomm/TezTestServiceTaskCommunicatorWithErrors.java b/tez-ext-service-tests/src/test/java/org/apache/tez/dag/app/taskcomm/TezTestServiceTaskCommunicatorWithErrors.java
index 0a3d8d4..90313d4 100644
--- a/tez-ext-service-tests/src/test/java/org/apache/tez/dag/app/taskcomm/TezTestServiceTaskCommunicatorWithErrors.java
+++ b/tez-ext-service-tests/src/test/java/org/apache/tez/dag/app/taskcomm/TezTestServiceTaskCommunicatorWithErrors.java
@@ -22,8 +22,8 @@ import org.apache.hadoop.net.NetUtils;
 import org.apache.hadoop.security.Credentials;
 import org.apache.hadoop.yarn.api.records.ContainerId;
 import org.apache.hadoop.yarn.api.records.LocalResource;
-import org.apache.tez.dag.api.TaskCommunicator;
-import org.apache.tez.dag.api.TaskCommunicatorContext;
+import org.apache.tez.serviceplugins.api.TaskCommunicator;
+import org.apache.tez.serviceplugins.api.TaskCommunicatorContext;
 import org.apache.tez.dag.api.event.VertexStateUpdate;
 import org.apache.tez.dag.records.TezTaskAttemptID;
 import org.apache.tez.runtime.api.impl.TaskSpec;


[18/50] [abbrv] tez git commit: Fix CHANGES.txt for TEZ-3032

Posted by sr...@apache.org.
Fix CHANGES.txt for TEZ-3032


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

Branch: refs/heads/TEZ-2980
Commit: 885ad73b473d1669cdd029aa9c7facb65959d3ed
Parents: 37e7014
Author: Hitesh Shah <hi...@apache.org>
Authored: Thu Jan 14 13:51:09 2016 -0800
Committer: Hitesh Shah <hi...@apache.org>
Committed: Thu Jan 14 13:51:09 2016 -0800

----------------------------------------------------------------------
 CHANGES.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/885ad73b/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index ca668a0..a9dc823 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -6,6 +6,7 @@ Release 0.8.3: Unreleased
 INCOMPATIBLE CHANGES
 
 ALL CHANGES:
+  TEZ-3032. DAG start time getting logged using system time instead of recorded time in startTime field.
 
 Release 0.8.2: 2016-01-19
 
@@ -18,7 +19,6 @@ INCOMPATIBLE CHANGES
   TEZ-2972. Avoid task rescheduling when a node turns unhealthy
 
 ALL CHANGES:
-  TEZ-3032. DAG start time getting logged using system time instead of recorded time in startTime field.
   TEZ-2669. Propagation of errors from plugins to the AM for error reporting.
   TEZ-2978. Add an option to allow the SplitGrouper to generate node local only groups.
   TEZ-2129. Task and Attempt views should contain links to the logs