瀏覽代碼

AMBARI-3185. HDFS links widget should accommodate NameNode HA. (xiwang)

Yusaku Sako 11 年之前
父節點
當前提交
7a26b7ef89

+ 46 - 2
ambari-web/app/mappers/service_mapper.js

@@ -61,6 +61,9 @@ App.servicesMapper = App.QuickDataMapper.create({
     version: 'nameNodeComponent.ServiceComponentInfo.Version',
     name_node_id: 'nameNodeComponent.host_components[0].HostRoles.host_name',
     sname_node_id: 'snameNodeComponent.host_components[0].HostRoles.host_name',
+    active_name_node_id: 'active_name_node_id',
+    standby_name_node_id: 'standby_name_node_id',
+    standby_name_node2_id: 'standby_name_node2_id',
     data_nodes: 'data_nodes',
     journal_nodes: 'journal_nodes',
     name_node_start_time: 'nameNodeComponent.ServiceComponentInfo.StartTime',
@@ -333,13 +336,54 @@ App.servicesMapper = App.QuickDataMapper.create({
     var hdfsConfig = this.hdfsConfig;
     item.components.forEach(function (component) {
       if (component.ServiceComponentInfo && component.ServiceComponentInfo.component_name == "NAMENODE") {
-        // make active nameNode as host_components[0].
+
         if ( component.host_components.length == 2) { //enabled HA
+          var haState1;
           var haState2;
           if (component.host_components[1].metrics && component.host_components[1].metrics.dfs) {
             haState2 = component.host_components[1].metrics.dfs.FSNamesystem.HAState;
           }
-          if (haState2 == "active") { // change places
+          if (component.host_components[0].metrics.dfs) {
+            haState1 = component.host_components[0].metrics.dfs.FSNamesystem.HAState;
+          }
+          var active_name_node = [];
+          var standby_name_nodes = [];
+          switch (haState1) {
+            case "active":
+              active_name_node.push(component.host_components[0].HostRoles.host_name);
+              break;
+            case "standby":
+              standby_name_nodes.push(component.host_components[0].HostRoles.host_name);
+              break;
+          }
+          switch (haState2) {
+            case "active":
+              active_name_node.push(component.host_components[1].HostRoles.host_name);
+              break;
+            case "standby":
+              standby_name_nodes.push(component.host_components[1].HostRoles.host_name);
+              break;
+          }
+          item.active_name_node_id = null;
+          item.standby_name_node_id = null;
+          item.standby_name_node2_id = null;
+          switch (active_name_node.length) {
+            case 1:
+              item.active_name_node_id = active_name_node[0];
+              break;
+          }
+          switch (standby_name_nodes.length) {
+            case 1:
+              item.standby_name_node_id = standby_name_nodes[0];
+              break;
+            case 2:
+              item.standby_name_node_id = standby_name_nodes[0];
+              item.standby_name_node2_id = standby_name_nodes[1];
+              break;
+          }
+
+          // make sure: active nameNode always at host_components[0].
+          if (haState2 == "active") { // change places for all model bind with host_component[0]
             var tmp = component.host_components[1];
             component.host_components[1] = component.host_components[0];
             component.host_components[0] = tmp;

+ 3 - 0
ambari-web/app/messages.js

@@ -1276,6 +1276,9 @@ Em.I18n.translations = {
   'dashboard.widgets.NameNodeUptime': 'NameNode Uptime',
   'dashboard.widgets.JobTrackerUptime': 'JobTracker Uptime',
   'dashboard.widgets.HDFSLinks': 'HDFS Links',
+  'dashboard.widgets.HDFSLinks.activeNameNode': 'Active NameNode',
+  'dashboard.widgets.HDFSLinks.standbyNameNode': 'Standby NameNode',
+  'dashboard.widgets.HDFSLinks.standbyNameNodes': '2 Standby NameNodes',
   'dashboard.widgets.MapReduceLinks': 'MapReduce Links',
   'dashboard.widgets.HBaseLinks': 'HBase Links',
   'dashboard.widgets.HBaseAverageLoad': 'HBase Ave Load',

+ 3 - 0
ambari-web/app/models/service/hdfs.js

@@ -21,6 +21,9 @@ App.HDFSService = App.Service.extend({
   version: DS.attr('string'),
   nameNode: DS.belongsTo('App.Host'),
   snameNode: DS.belongsTo('App.Host'),
+  activeNameNode: DS.belongsTo('App.Host'),
+  standbyNameNode: DS.belongsTo('App.Host'),
+  standbyNameNode2: DS.belongsTo('App.Host'),
   dataNodes: DS.hasMany('App.Host'),
   journalNodes: DS.hasMany('App.Host'),
   nameNodeStartTime: DS.attr('number'),

+ 5 - 0
ambari-web/app/styles/application.less

@@ -2235,6 +2235,11 @@ table.graphs {
       font-size: 35px;
       padding-top: 40px; //svg
       position: relative;
+      .disabled-hdfs-link {
+        pointer-events: none;
+        color: grey;
+        cursor: default;
+      }
       .screensaver{ // graph onload wait
         width: 90%;
         height: 105px;

+ 49 - 15
ambari-web/app/templates/main/dashboard/widgets/hdfs_links.hbs

@@ -24,22 +24,56 @@
     <div class="caption span10"> {{view.title}}</div>
 
     <div class="widget-content" >
-      <table>
-        <!--NameNode-->
-        <tr>
-          <td><a href="#" {{action showDetails view.model.nameNode}}>{{t dashboard.services.hdfs.nanmenode}}</a></td>
-        </tr>
-        <!--SecondaryNameNode-->
-        <tr>
-          <td><a href="#" {{action showDetails view.model.snameNode}}>{{t dashboard.services.hdfs.snanmenode}}</a></td>
-        </tr>
-        <!--Data Nodes-->
-        <tr>
-          <td>
+      {{#if view.isHAEnabled }}
+        <table>
+          <!--Active NameNode-->
+          <tr>
+            {{#if view.isActiveNNValid}}
+              <td><a href="#" {{action showDetails view.model.activeNameNode}}>{{t dashboard.widgets.HDFSLinks.activeNameNode}}</a></td>
+            {{else}}
+              <td><a class="disabled-hdfs-link">{{t dashboard.widgets.HDFSLinks.activeNameNode}}</a></td>
+            {{/if}}
+          </tr>
+          <!--Standby NameNodes-->
+          <tr>
+            {{#if view.isStandbyNNValid}}
+              {{#if view.isTwoStandbyNN}}
+                <!--Two Standby NameNodes-->
+                <td><a href="#" {{action filterHosts view.twoStandbyComponent}}>{{t dashboard.widgets.HDFSLinks.standbyNameNodes}}</a></td>
+              {{else}}
+                <!--One Standby NameNode-->
+                <td><a href="#" {{action showDetails view.model.standbyNameNode}}>{{t dashboard.widgets.HDFSLinks.standbyNameNode}}</a></td>
+              {{/if}}
+            {{else}}
+              <td><a class="disabled-hdfs-link">{{t dashboard.widgets.HDFSLinks.standbyNameNode}}</a></td>
+            {{/if}}
+          </tr>
+          <!--Data Nodes-->
+          <tr>
+            <td>
               <a href="#" {{action filterHosts view.component}}>{{view.model.dataNodes.length}} {{t dashboard.services.hdfs.datanodes}}</a>
-          </td>
-        </tr>
-      </table>
+            </td>
+          </tr>
+        </table>
+      {{else}}
+        <table>
+          <!--NameNode-->
+          <tr>
+            <td><a href="#" {{action showDetails view.model.nameNode}}>{{t dashboard.services.hdfs.nanmenode}}</a></td>
+          </tr>
+          <!--SecondaryNameNode-->
+          <tr>
+            <td><a href="#" {{action showDetails view.model.snameNode}}>{{t dashboard.services.hdfs.snanmenode}}</a></td>
+          </tr>
+          <!--Data Nodes-->
+          <tr>
+            <td>
+              <a href="#" {{action filterHosts view.component}}>{{view.model.dataNodes.length}} {{t dashboard.services.hdfs.datanodes}}</a>
+            </td>
+          </tr>
+        </table>
+      {{/if}}
+
     </div>
 
     <div class="link-button">

+ 17 - 2
ambari-web/app/views/main/dashboard/widgets/hdfs_links.js

@@ -35,6 +35,21 @@ App.HDFSLinksView = App.LinkDashboardWidgetView.extend({
   didInsertElement: function() {
     this._super();
     this.calc();
-  }
-
+  },
+
+  isHAEnabled: function() {
+    return !this.get('model.snameNode');
+  }.property('model.snameNode'),
+  isActiveNNValid: function () {
+    return this.get('model.activeNameNode') != null;
+  }.property('model.activeNameNode'),
+  isStandbyNNValid: function () {
+    return this.get('model.standbyNameNode') != null;
+  }.property('model.standbyNameNode'),
+  isTwoStandbyNN: function () {
+    return (this.get('model.standbyNameNode') != null && this.get('model.standbyNameNode2') != null);
+  }.property('model.standbyNameNode', 'model.standbyNameNode2'),
+  twoStandbyComponent: function () {
+    return App.HostComponent.find().findProperty('componentName', 'NAMENODE');
+  }.property()
 });