Forráskód Böngészése

YARN-3334. [YARN-3368] Introduce REFRESH button in various UI pages (Sreenath Somarajapuram via Sunil G)

sunilg 8 éve
szülő
commit
8652d4af96
43 módosított fájl, 417 hozzáadás és 77 törlés
  1. 0 5
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-usage-donut-chart.js
  2. 2 2
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/bar-chart.js
  3. 31 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/breadcrumb-bar.js
  4. 4 4
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/donut-chart.js
  5. 1 1
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-usage-donut-chart.js
  6. 40 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-container-log.js
  7. 36 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node-app.js
  8. 32 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/abstract.js
  9. 10 2
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/cluster-overview.js
  10. 8 1
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app-attempt.js
  11. 7 1
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app-attempts.js
  12. 10 1
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app.js
  13. 8 1
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-apps.js
  14. 9 1
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-container-log.js
  15. 7 1
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-node-app.js
  16. 7 1
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-node-apps.js
  17. 7 1
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-node-container.js
  18. 7 1
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-node-containers.js
  19. 8 1
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-node.js
  20. 8 1
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-nodes.js
  21. 9 3
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-queue-apps.js
  22. 9 5
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-queue.js
  23. 9 5
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-queues.js
  24. 6 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/styles/app.css
  25. 1 3
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/cluster-overview.hbs
  26. 22 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/breadcrumb-bar.hbs
  27. 1 3
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-app-attempt.hbs
  28. 1 3
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-app-attempts.hbs
  29. 1 3
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-app.hbs
  30. 1 3
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps.hbs
  31. 2 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-container-log.hbs
  32. 2 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-node-app.hbs
  33. 1 3
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-node-apps.hbs
  34. 1 3
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-node-container.hbs
  35. 1 3
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-node-containers.hbs
  36. 1 3
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-node.hbs
  37. 1 3
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-nodes.hbs
  38. 1 3
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-queue-apps.hbs
  39. 1 3
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-queue.hbs
  40. 1 3
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-queues.hbs
  41. 43 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/breadcrumb-bar-test.js
  42. 30 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-container-log-test.js
  43. 30 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-node-app-test.js

+ 0 - 5
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-usage-donut-chart.js

@@ -26,7 +26,6 @@ export default BaseUsageDonutChart.extend({
   colors: d3.scale.category20().range(),
 
   draw: function() {
-    this.initChart();
     var usageByApps = [];
     var avail = 100;
 
@@ -60,8 +59,4 @@ export default BaseUsageDonutChart.extend({
     this.renderDonutChart(usageByApps, this.get("title"), this.get("showLabels"),
       this.get("middleLabel"), "100%", "%");
   },
-
-  didInsertElement: function() {
-    this.draw();
-  },
 })

+ 2 - 2
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/bar-chart.js

@@ -112,16 +112,16 @@ export default BaseChartComponent.extend({
   },
 
   draw: function() {
-    this.initChart();
     this.renderBarChart(this.get("data"), this.get("title"), this.get("textWidth"));
   },
 
   _dataChange: Ember.observer("data", function() {
     this.chart.g.selectAll("*").remove();
-    this.renderBarChart(this.get("data"), this.get("title"), this.get("textWidth"));
+    this.draw();
   }),
 
   didInsertElement: function() {
+    this.initChart();
     this.draw();
   },
 })

+ 31 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/breadcrumb-bar.js

@@ -0,0 +1,31 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+
+  breadcrumbs: null,
+
+  actions:{
+    refresh: function () {
+      this.get("targetObject").send("refresh");
+    }
+  }
+
+});

+ 4 - 4
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/donut-chart.js

@@ -169,13 +169,12 @@ export default BaseChartComponent.extend({
 
   _dataChange: Ember.observer("data", function() {
     this.chart.g.selectAll("*").remove();
-    this.renderDonutChart(this.get("data"), this.get("title"), this.get("showLabels"),
-                          this.get("middleLabel"), this.get("middleValue"));
+    if(this.get("data")) {
+      this.draw();
+    }
   }),
 
   draw: function() {
-    this.initChart();
-
     var colorTargets = this.get("colorTargets");
     if (colorTargets) {
       var colorTargetReverse = Boolean(this.get("colorTargetReverse"));
@@ -188,6 +187,7 @@ export default BaseChartComponent.extend({
   },
 
   didInsertElement: function() {
+    this.initChart();
     this.draw();
   },
 })

+ 1 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/queue-usage-donut-chart.js

@@ -26,7 +26,6 @@ export default BaseUsageDonutChart.extend({
   colors: d3.scale.category20().range(),
 
   draw: function() {
-    this.initChart();
     var usageByQueues = [];
     var avail = 100;
 
@@ -64,6 +63,7 @@ export default BaseUsageDonutChart.extend({
   },
 
   didInsertElement: function() {
+    this.initChart();
     this.draw();
   },
 })

+ 40 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-container-log.js

@@ -0,0 +1,40 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Controller.extend({
+
+  breadcrumbs: Ember.computed('model.nodeInfo', 'model.containerInfo', function () {
+    var nodeInfo = this.get('model.nodeInfo'),
+        containerInfo = this.get('model.containerInfo');
+    return [{
+      text: "Home",
+      routeName: 'application'
+    }, {
+      text: `Node [ ${nodeInfo.id} ]`,
+      href: `/#/yarn-node/${nodeInfo.id}/${nodeInfo.addr}`,
+    }, {
+      text: `Container [ ${containerInfo.id} ]`,
+      href: `/#/yarn-node-container/${nodeInfo.id}/${nodeInfo.addr}/${containerInfo.id}`,
+    }, {
+      text: "Log",
+    }];
+  })
+
+});

+ 36 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-node-app.js

@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Controller.extend({
+
+  breadcrumbs: Ember.computed('model.nodeInfo', function () {
+    var nodeInfo = this.get('model.nodeInfo');
+    return [{
+      text: "Home",
+      routeName: 'application'
+    }, {
+      text: `Node [ ${nodeInfo.id} ]`,
+      href: `/#/yarn-node/${nodeInfo.id}/${nodeInfo.addr}`,
+    }, {
+      text: "Application",
+    }];
+  })
+
+});

+ 32 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/abstract.js

@@ -0,0 +1,32 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Route.extend({
+  unloadAll() {
+    // Must be implemented by inheriting classes
+  },
+
+  actions: {
+    refresh: function () {
+      this.unloadAll();
+      this.refresh();
+    }
+  }
+});

+ 10 - 2
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/cluster-overview.js

@@ -18,7 +18,9 @@
 
 import Ember from 'ember';
 
-export default Ember.Route.extend({
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
   model() {
     return Ember.RSVP.hash({
       clusterMetrics: this.store.findAll('ClusterMetric'),
@@ -26,11 +28,17 @@ export default Ember.Route.extend({
         {
           state: "RUNNING"
         }),
-      queues: this.store.findAll('yarn-queue'),
+      queues: this.store.query('yarn-queue', {}),
     });
   },
 
   afterModel() {
     this.controllerFor("ClusterOverview").set("loading", false);
+  },
+
+  unloadAll() {
+    this.store.unloadAll('ClusterMetric');
+    this.store.unloadAll('yarn-app');
+    this.store.unloadAll('yarn-queue');
   }
 });

+ 8 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app-attempt.js

@@ -18,7 +18,9 @@
 
 import Ember from 'ember';
 
-export default Ember.Route.extend({
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
   model(param) {
     return Ember.RSVP.hash({
       attempt: this.store.findRecord('yarn-app-attempt', param.app_attempt_id),
@@ -39,5 +41,10 @@ export default Ember.Route.extend({
           return [];
         })
     });
+  },
+
+  unloadAll() {
+    this.store.unloadAll('yarn-app-attempt');
+    this.store.unloadAll('yarn-container');
   }
 });

+ 7 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app-attempts.js

@@ -18,7 +18,9 @@
 
 import Ember from 'ember';
 
-export default Ember.Route.extend({
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
   model(param) {
     return this.store.query('yarn-app-attempt', { appId: param.app_id}).then(function (attempts) {
       return {
@@ -26,5 +28,9 @@ export default Ember.Route.extend({
         attempts: attempts
       };
     });
+  },
+
+  unloadAll() {
+    this.store.unloadAll('yarn-app-attempt');
   }
 });

+ 10 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app.js

@@ -18,7 +18,9 @@
 
 import Ember from 'ember';
 
-export default Ember.Route.extend({
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
   model(param) {
     return Ember.RSVP.hash({
       app: this.store.find('yarn-app', param.app_id),
@@ -39,5 +41,12 @@ export default Ember.Route.extend({
 
       nodes: this.store.findAll('yarn-rm-node'),
     });
+  },
+
+  unloadAll() {
+    this.store.unloadAll('yarn-app');
+    this.store.unloadAll('yarn-app-attempt');
+    this.store.unloadAll('yarn-container');
+    this.store.unloadAll('yarn-rm-node');
   }
 });

+ 8 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-apps.js

@@ -18,11 +18,18 @@
 
 import Ember from 'ember';
 
-export default Ember.Route.extend({
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
   model() {
     return Ember.RSVP.hash({
       apps: this.store.findAll('yarn-app'),
       clusterMetrics: this.store.findAll('ClusterMetric'),
     });
+  },
+
+  unloadAll() {
+    this.store.unloadAll('yarn-app');
+    this.store.unloadAll('ClusterMetric');
   }
 });

+ 9 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-container-log.js

@@ -19,12 +19,15 @@
 import Ember from 'ember';
 import Constants from 'yarn-ui/constants';
 
-export default Ember.Route.extend({
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
   model(param) {
     var id = param.node_addr + Constants.PARAM_SEPARATOR + param.container_id +
         Constants.PARAM_SEPARATOR + param.filename;
     return Ember.RSVP.hash({
       containerLog: this.store.findRecord('yarn-container-log', id),
+      containerInfo: { id: param.container_id },
       nodeInfo: { id: param.node_id, addr: param.node_addr }
     }).then(function(hash) {
       // Just return as its success.
@@ -36,6 +39,7 @@ export default Ember.Route.extend({
       } else {
         // Assume empty response received from server.
         return { nodeInfo: { id: param.node_id, addr: param.node_addr },
+            containerInfo: { id: param.container_id },
             containerLog: { logs: "", containerID: param.container_id,
                 logFileName: param.filename}};
       }
@@ -51,5 +55,9 @@ export default Ember.Route.extend({
         this.replaceWith('/error');
       }
     }
+  },
+
+  unloadAll() {
+    this.store.unloadAll('yarn-container-log');
   }
 });

+ 7 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-node-app.js

@@ -18,12 +18,18 @@
 
 import Ember from 'ember';
 
-export default Ember.Route.extend({
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
   model(param) {
     return Ember.RSVP.hash({
       nodeApp: this.store.queryRecord('yarn-node-app',
           { nodeAddr : param.node_addr, appId: param.app_id }),
       nodeInfo: { id: param.node_id, addr: param.node_addr }
     });
+  },
+
+  unloadAll() {
+    this.store.unloadAll('yarn-node-app');
   }
 });

+ 7 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-node-apps.js

@@ -18,12 +18,18 @@
 
 import Ember from 'ember';
 
-export default Ember.Route.extend({
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
   model(param) {
     // Get all apps running on a specific node. Node is contacted by using node_addr.
     return Ember.RSVP.hash({
       apps: this.store.query('yarn-node-app', { nodeAddr: param.node_addr }),
       nodeInfo: { id: param.node_id, addr: param.node_addr }
     });
+  },
+
+  unloadAll() {
+    this.store.unloadAll('yarn-node-app');
   }
 });

+ 7 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-node-container.js

@@ -18,7 +18,9 @@
 
 import Ember from 'ember';
 
-export default Ember.Route.extend({
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
   model(param) {
     // Get a specific container running on a specific node.
     return Ember.RSVP.hash({
@@ -26,5 +28,9 @@ export default Ember.Route.extend({
           { nodeHttpAddr: param.node_addr, containerId: param.container_id }),
       nodeInfo: { id: param.node_id, addr: param.node_addr }
     });
+  },
+
+  unloadAll() {
+    this.store.unloadAll('yarn-node-container');
   }
 });

+ 7 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-node-containers.js

@@ -17,12 +17,18 @@
  */
 import Ember from 'ember';
 
-export default Ember.Route.extend({
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
   model(param) {
     // Get all containers running on specific node.
     return Ember.RSVP.hash({
       containers: this.store.query('yarn-node-container', { nodeHttpAddr: param.node_addr }),
       nodeInfo: { id: param.node_id, addr: param.node_addr }
     });
+  },
+
+  unloadAll() {
+    this.store.unloadAll('yarn-node-container');
   }
 });

+ 8 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-node.js

@@ -18,7 +18,9 @@
 
 import Ember from 'ember';
 
-export default Ember.Route.extend({
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
   model(param) {
     // Fetches data from both NM and RM. RM is queried to get node usage info.
     return Ember.RSVP.hash({
@@ -26,5 +28,10 @@ export default Ember.Route.extend({
       node: this.store.findRecord('yarn-node', param.node_addr),
       rmNode: this.store.findRecord('yarn-rm-node', param.node_id)
     });
+  },
+
+  unloadAll() {
+    this.store.unloadAll('yarn-node');
+    this.store.unloadAll('yarn-rm-node');
   }
 });

+ 8 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-nodes.js

@@ -18,11 +18,18 @@
 
 import Ember from 'ember';
 
-export default Ember.Route.extend({
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
   model() {
     return Ember.RSVP.hash({
       nodes: this.store.findAll('yarn-rm-node'),
       clusterMetrics: this.store.findAll('ClusterMetric'),
     });
+  },
+
+  unloadAll() {
+    this.store.unloadAll('yarn-rm-node');
+    this.store.unloadAll('ClusterMetric');
   }
 });

+ 9 - 3
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-queue-apps.js

@@ -18,7 +18,9 @@
 
 import Ember from 'ember';
 
-export default Ember.Route.extend({
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
   model(param) {
     return Ember.RSVP.hash({
       selected : param.queue_name,
@@ -29,8 +31,12 @@ export default Ember.Route.extend({
   },
 
   afterModel(model) {
-    var store = this.store;
     model.selectedQueue = this.store.peekRecord('yarn-queue', model.selected);
-    model.apps = store.findAll('yarn-app');
+    model.apps = this.store.findAll('yarn-app');
+  },
+
+  unloadAll() {
+    this.store.unloadAll('yarn-queue');
+    this.store.unloadAll('yarn-app');
   }
 });

+ 9 - 5
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-queue.js

@@ -18,11 +18,13 @@
 
 import Ember from 'ember';
 
-export default Ember.Route.extend({
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
   model(param) {
     return Ember.RSVP.hash({
       selected : param.queue_name,
-      queues: this.store.findAll('yarn-queue'),
+      queues: this.store.query('yarn-queue', {}),
       selectedQueue : undefined,
       apps: undefined, // apps of selected queue
     });
@@ -31,8 +33,10 @@ export default Ember.Route.extend({
   afterModel(model) {
     model.selectedQueue = this.store.peekRecord('yarn-queue', model.selected);
     model.apps = this.store.findAll('yarn-app');
-    model.apps.forEach(function(o) {
-      console.log(o);
-    })
+  },
+
+  unloadAll() {
+    this.store.unloadAll('yarn-queue');
+    this.store.unloadAll('yarn-app');
   }
 });

+ 9 - 5
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-queues.js

@@ -18,11 +18,13 @@
 
 import Ember from 'ember';
 
-export default Ember.Route.extend({
+import AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
   model(param) {
     return Ember.RSVP.hash({
       selected : param.queue_name,
-      queues: this.store.findAll('yarn-queue'),
+      queues: this.store.query('yarn-queue', {}),
       selectedQueue : undefined,
       apps: undefined, // apps of selected queue
     });
@@ -31,8 +33,10 @@ export default Ember.Route.extend({
   afterModel(model) {
     model.selectedQueue = this.store.peekRecord('yarn-queue', model.selected);
     model.apps = this.store.findAll('yarn-app');
-    model.apps.forEach(function(o) {
-      console.log(o);
-    })
+  },
+
+  unloadAll() {
+    this.store.unloadAll('yarn-queue');
+    this.store.unloadAll('yarn-app');
   }
 });

+ 6 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/styles/app.css

@@ -267,3 +267,9 @@ li a.navigation-link.ember-view {
   color: #2196f3;
   font-weight: bold;
 }
+
+.breadcrumb-bar .refresh {
+  position: absolute;
+  right: 20px;
+  top: 3px;
+}

+ 1 - 3
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/cluster-overview.hbs

@@ -16,9 +16,7 @@
  * limitations under the License.
 }}
 
-<div class="col-md-12 container-fluid">
-  {{em-breadcrumbs items=breadcrumbs}}
-</div>
+{{breadcrumb-bar breadcrumbs=breadcrumbs}}
 
 {{#if model}}
 

+ 22 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/breadcrumb-bar.hbs

@@ -0,0 +1,22 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+}}
+
+<div class="col-md-12 container-fluid breadcrumb-bar">
+  {{em-breadcrumbs items=breadcrumbs}}
+  <button type="button" class="btn btn-sm btn-primary refresh" {{action "refresh"}}>Refresh</button>
+</div>

+ 1 - 3
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-app-attempt.hbs

@@ -16,9 +16,7 @@
  * limitations under the License.
 }}
 
-<div class="col-md-12 container-fluid">
-  {{em-breadcrumbs items=breadcrumbs}}
-</div>
+{{breadcrumb-bar breadcrumbs=breadcrumbs}}
 <br/><br/><br/>
 <div class="container-fluid">
   <div class="row">

+ 1 - 3
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-app-attempts.hbs

@@ -16,9 +16,7 @@
  * limitations under the License.
 }}
 
-<div class="col-md-12 container-fluid">
-  {{em-breadcrumbs items=breadcrumbs}}
-</div>
+{{breadcrumb-bar breadcrumbs=breadcrumbs}}
 
 <div class="col-md-12 container-fluid">
   <div class="row">

+ 1 - 3
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-app.hbs

@@ -16,9 +16,7 @@
  * limitations under the License.
 }}
 
-<div class="col-md-12 container-fluid">
-  {{em-breadcrumbs items=breadcrumbs}}
-</div>
+{{breadcrumb-bar breadcrumbs=breadcrumbs}}
 
 {{#if model.app}}
 <div class="col-md-12 container-fluid">

+ 1 - 3
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps.hbs

@@ -16,9 +16,7 @@
  * limitations under the License.
 }}
 
-<div class="col-md-12 container-fluid">
-  {{em-breadcrumbs items=breadcrumbs}}
-</div>
+{{breadcrumb-bar breadcrumbs=breadcrumbs}}
 
 <div class="col-md-12 container-fluid">
   <div class="row">

+ 2 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-container-log.hbs

@@ -16,6 +16,8 @@
   limitations under the License.
 --}}
 
+{{breadcrumb-bar breadcrumbs=breadcrumbs}}
+
 <div class="col-md-12 container-fluid">
   {{node-menu path="yarn-container-log" nodeAddr=model.nodeInfo.addr nodeId=model.nodeInfo.id}}
   <div class="col-md-10">

+ 2 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-node-app.hbs

@@ -16,6 +16,8 @@
   limitations under the License.
 --}}
 
+{{breadcrumb-bar breadcrumbs=breadcrumbs}}
+
 <div class="col-md-12 container-fluid">
   <div class="row">
     {{node-menu-panel path="yarn-node-app" nodeAddr=model.nodeInfo.addr nodeId=model.nodeInfo.id}}

+ 1 - 3
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-node-apps.hbs

@@ -16,9 +16,7 @@
   limitations under the License.
 --}}
 
-<div class="col-md-12 container-fluid">
-  {{em-breadcrumbs items=breadcrumbs}}
-</div>
+{{breadcrumb-bar breadcrumbs=breadcrumbs}}
 
 <div class="col-md-12 container-fluid">
   <div class="row">

+ 1 - 3
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-node-container.hbs

@@ -16,9 +16,7 @@
   limitations under the License.
 --}}
 
-<div class="col-md-12 container-fluid">
-  {{em-breadcrumbs items=breadcrumbs}}
-</div>
+{{breadcrumb-bar breadcrumbs=breadcrumbs}}
 
 <div class="col-md-12 container-fluid">
   <div class="row">

+ 1 - 3
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-node-containers.hbs

@@ -16,9 +16,7 @@
   limitations under the License.
 --}}
 
-<div class="col-md-12 container-fluid">
-  {{em-breadcrumbs items=breadcrumbs}}
-</div>
+{{breadcrumb-bar breadcrumbs=breadcrumbs}}
 
 <div class="col-md-12 container-fluid">
   <div class="row">

+ 1 - 3
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-node.hbs

@@ -16,9 +16,7 @@
   limitations under the License.
 --}}
 
-<div class="col-md-12 container-fluid">
-  {{em-breadcrumbs items=breadcrumbs}}
-</div>
+{{breadcrumb-bar breadcrumbs=breadcrumbs}}
 
 <div class="col-md-12 container-fluid">
   <div class="row">

+ 1 - 3
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-nodes.hbs

@@ -16,9 +16,7 @@
   limitations under the License.
 --}}
 
-<div class="col-md-12 container-fluid">
-  {{em-breadcrumbs items=breadcrumbs}}
-</div>
+{{breadcrumb-bar breadcrumbs=breadcrumbs}}
 
 <div class="row">
   <div class="col-md-2 container-fluid">

+ 1 - 3
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-queue-apps.hbs

@@ -16,9 +16,7 @@
  * limitations under the License.
 }}
 
-<div class="col-md-12 container-fluid">
-  {{em-breadcrumbs items=breadcrumbs}}
-</div>
+{{breadcrumb-bar breadcrumbs=breadcrumbs}}
 
 <div class="col-md-12 container-fluid">
   <div class="row">

+ 1 - 3
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-queue.hbs

@@ -16,9 +16,7 @@
  * limitations under the License.
 }}
 
-<div class="col-md-12 container-fluid">
-  {{em-breadcrumbs items=breadcrumbs}}
-</div>
+{{breadcrumb-bar breadcrumbs=breadcrumbs}}
 
 <div class="col-md-12 container-fluid">
   <div class="row">

+ 1 - 3
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-queues.hbs

@@ -16,9 +16,7 @@
  * limitations under the License.
 }}
 
-<div class="col-md-12 container-fluid">
-  {{em-breadcrumbs items=breadcrumbs}}
-</div>
+{{breadcrumb-bar breadcrumbs=breadcrumbs}}
 
 <div class="container-fluid">
   {{queue-navigator model=model.queues selected=model.selected}}

+ 43 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/breadcrumb-bar-test.js

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

+ 30 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-container-log-test.js

@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:yarn-container-log', 'Unit | Controller | yarn container log', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+// Replace this with your real tests.
+test('it exists', function(assert) {
+  let controller = this.subject();
+  assert.ok(controller);
+});

+ 30 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-node-app-test.js

@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:yarn-node-app', 'Unit | Controller | yarn node app', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+// Replace this with your real tests.
+test('it exists', function(assert) {
+  let controller = this.subject();
+  assert.ok(controller);
+});