Browse Source

AMBARI-3700 Status mapper upgrade. (atkach)

atkach 11 years ago
parent
commit
9eb83fd998

+ 204 - 0
ambari-web/app/assets/data/hosts/HDP2/hc_host_status.json

@@ -0,0 +1,204 @@
+{
+  "href" : "http://192.168.56.101:8080/api/v1/clusters/perf/hosts?fields=Hosts/host_status,host_components/HostRoles/state",
+  "items" : [
+    {
+      "href" : "http://192.168.56.101:8080/api/v1/clusters/perf/hosts/dev01.hortonworks.com",
+      "Hosts" : {
+        "cluster_name" : "perf",
+        "host_name" : "dev01.hortonworks.com",
+        "host_status" : "HEALTHY"
+      },
+      "host_components" : [
+        {
+          "href" : "http://192.168.56.101:8080/api/v1/clusters/perf/hosts/dev01.hortonworks.com/host_components/DATANODE",
+          "HostRoles" : {
+            "cluster_name" : "perf",
+            "component_name" : "DATANODE",
+            "host_name" : "dev01.hortonworks.com",
+            "state" : "STARTED"
+          }
+        },
+        {
+          "href" : "http://192.168.56.101:8080/api/v1/clusters/perf/hosts/dev01.hortonworks.com/host_components/GANGLIA_MONITOR",
+          "HostRoles" : {
+            "cluster_name" : "perf",
+            "component_name" : "GANGLIA_MONITOR",
+            "host_name" : "dev01.hortonworks.com",
+            "state" : "STARTED"
+          }
+        },
+        {
+          "href" : "http://192.168.56.101:8080/api/v1/clusters/perf/hosts/dev01.hortonworks.com/host_components/GANGLIA_SERVER",
+          "HostRoles" : {
+            "cluster_name" : "perf",
+            "component_name" : "GANGLIA_SERVER",
+            "host_name" : "dev01.hortonworks.com",
+            "state" : "STARTED"
+          }
+        },
+        {
+          "href" : "http://192.168.56.101:8080/api/v1/clusters/perf/hosts/dev01.hortonworks.com/host_components/HBASE_CLIENT",
+          "HostRoles" : {
+            "cluster_name" : "perf",
+            "component_name" : "HBASE_CLIENT",
+            "host_name" : "dev01.hortonworks.com",
+            "state" : "INSTALLED"
+          }
+        },
+        {
+          "href" : "http://192.168.56.101:8080/api/v1/clusters/perf/hosts/dev01.hortonworks.com/host_components/HBASE_MASTER",
+          "HostRoles" : {
+            "cluster_name" : "perf",
+            "component_name" : "HBASE_MASTER",
+            "host_name" : "dev01.hortonworks.com",
+            "state" : "STARTED"
+          }
+        },
+        {
+          "href" : "http://192.168.56.101:8080/api/v1/clusters/perf/hosts/dev01.hortonworks.com/host_components/HBASE_REGIONSERVER",
+          "HostRoles" : {
+            "cluster_name" : "perf",
+            "component_name" : "HBASE_REGIONSERVER",
+            "host_name" : "dev01.hortonworks.com",
+            "state" : "STARTED"
+          }
+        },
+        {
+          "href" : "http://192.168.56.101:8080/api/v1/clusters/perf/hosts/dev01.hortonworks.com/host_components/HDFS_CLIENT",
+          "HostRoles" : {
+            "cluster_name" : "perf",
+            "component_name" : "HDFS_CLIENT",
+            "host_name" : "dev01.hortonworks.com",
+            "state" : "INSTALLED"
+          }
+        },
+        {
+          "href" : "http://192.168.56.101:8080/api/v1/clusters/perf/hosts/dev01.hortonworks.com/host_components/HISTORYSERVER",
+          "HostRoles" : {
+            "cluster_name" : "perf",
+            "component_name" : "HISTORYSERVER",
+            "host_name" : "dev01.hortonworks.com",
+            "state" : "STARTED"
+          }
+        },
+        {
+          "href" : "http://192.168.56.101:8080/api/v1/clusters/perf/hosts/dev01.hortonworks.com/host_components/MAPREDUCE2_CLIENT",
+          "HostRoles" : {
+            "cluster_name" : "perf",
+            "component_name" : "MAPREDUCE2_CLIENT",
+            "host_name" : "dev01.hortonworks.com",
+            "state" : "INSTALLED"
+          }
+        },
+        {
+          "href" : "http://192.168.56.101:8080/api/v1/clusters/perf/hosts/dev01.hortonworks.com/host_components/NAGIOS_SERVER",
+          "HostRoles" : {
+            "cluster_name" : "perf",
+            "component_name" : "NAGIOS_SERVER",
+            "host_name" : "dev01.hortonworks.com",
+            "state" : "STARTED"
+          }
+        },
+        {
+          "href" : "http://192.168.56.101:8080/api/v1/clusters/perf/hosts/dev01.hortonworks.com/host_components/NAMENODE",
+          "HostRoles" : {
+            "cluster_name" : "perf",
+            "component_name" : "NAMENODE",
+            "host_name" : "dev01.hortonworks.com",
+            "state" : "STARTED"
+          }
+        },
+        {
+          "href" : "http://192.168.56.101:8080/api/v1/clusters/perf/hosts/dev01.hortonworks.com/host_components/NODEMANAGER",
+          "HostRoles" : {
+            "cluster_name" : "perf",
+            "component_name" : "NODEMANAGER",
+            "host_name" : "dev01.hortonworks.com",
+            "state" : "STARTED"
+          }
+        },
+        {
+          "href" : "http://192.168.56.101:8080/api/v1/clusters/perf/hosts/dev01.hortonworks.com/host_components/OOZIE_CLIENT",
+          "HostRoles" : {
+            "cluster_name" : "perf",
+            "component_name" : "OOZIE_CLIENT",
+            "host_name" : "dev01.hortonworks.com",
+            "state" : "INSTALLED"
+          }
+        },
+        {
+          "href" : "http://192.168.56.101:8080/api/v1/clusters/perf/hosts/dev01.hortonworks.com/host_components/OOZIE_SERVER",
+          "HostRoles" : {
+            "cluster_name" : "perf",
+            "component_name" : "OOZIE_SERVER",
+            "host_name" : "dev01.hortonworks.com",
+            "state" : "STARTED"
+          }
+        },
+        {
+          "href" : "http://192.168.56.101:8080/api/v1/clusters/perf/hosts/dev01.hortonworks.com/host_components/PIG",
+          "HostRoles" : {
+            "cluster_name" : "perf",
+            "component_name" : "PIG",
+            "host_name" : "dev01.hortonworks.com",
+            "state" : "INSTALLED"
+          }
+        },
+        {
+          "href" : "http://192.168.56.101:8080/api/v1/clusters/perf/hosts/dev01.hortonworks.com/host_components/RESOURCEMANAGER",
+          "HostRoles" : {
+            "cluster_name" : "perf",
+            "component_name" : "RESOURCEMANAGER",
+            "host_name" : "dev01.hortonworks.com",
+            "state" : "STARTED"
+          }
+        },
+        {
+          "href" : "http://192.168.56.101:8080/api/v1/clusters/perf/hosts/dev01.hortonworks.com/host_components/SECONDARY_NAMENODE",
+          "HostRoles" : {
+            "cluster_name" : "perf",
+            "component_name" : "SECONDARY_NAMENODE",
+            "host_name" : "dev01.hortonworks.com",
+            "state" : "STARTED"
+          }
+        },
+        {
+          "href" : "http://192.168.56.101:8080/api/v1/clusters/perf/hosts/dev01.hortonworks.com/host_components/SQOOP",
+          "HostRoles" : {
+            "cluster_name" : "perf",
+            "component_name" : "SQOOP",
+            "host_name" : "dev01.hortonworks.com",
+            "state" : "INSTALLED"
+          }
+        },
+        {
+          "href" : "http://192.168.56.101:8080/api/v1/clusters/perf/hosts/dev01.hortonworks.com/host_components/YARN_CLIENT",
+          "HostRoles" : {
+            "cluster_name" : "perf",
+            "component_name" : "YARN_CLIENT",
+            "host_name" : "dev01.hortonworks.com",
+            "state" : "INSTALLED"
+          }
+        },
+        {
+          "href" : "http://192.168.56.101:8080/api/v1/clusters/perf/hosts/dev01.hortonworks.com/host_components/ZOOKEEPER_CLIENT",
+          "HostRoles" : {
+            "cluster_name" : "perf",
+            "component_name" : "ZOOKEEPER_CLIENT",
+            "host_name" : "dev01.hortonworks.com",
+            "state" : "INSTALLED"
+          }
+        },
+        {
+          "href" : "http://192.168.56.101:8080/api/v1/clusters/perf/hosts/dev01.hortonworks.com/host_components/ZOOKEEPER_SERVER",
+          "HostRoles" : {
+            "cluster_name" : "perf",
+            "component_name" : "ZOOKEEPER_SERVER",
+            "host_name" : "dev01.hortonworks.com",
+            "state" : "STARTED"
+          }
+        }
+      ]
+    }
+  ]
+}

+ 17 - 22
ambari-web/app/controllers/global/cluster_controller.js

@@ -262,22 +262,17 @@ App.ClusterController = Em.Controller.extend({
    * @return {Boolean} Whether we have errors
    * @return {Boolean} Whether we have errors
    */
    */
   loadUpdatedStatus: function(callback){
   loadUpdatedStatus: function(callback){
-
-    if(!this.get('clusterName')){
+    var location = App.router.get('location.lastSetURL');
+    if(!this.get('clusterName') || (this.get('isLoaded') && !(/\/main\/hosts.*/.test(location)))){
       callback();
       callback();
       return false;
       return false;
     }
     }
-    var testUrl = App.get('isHadoop2Stack') ? '/data/dashboard/HDP2/services.json':'/data/dashboard/services.json';
-    var servicesUrl = '/services?fields=ServiceInfo,components/host_components/HostRoles/state';
-    if (App.Service.find('HBASE')) {
-      // HBase installed. We need the haStatus field as it has
-      // moved to another field.
-      servicesUrl += ',components/host_components/metrics/hbase/master/IsActiveMaster';
-    }
+    var testUrl = App.get('isHadoop2Stack') ? '/data/hosts/HDP2/hc_host_status.json':'/data/dashboard/services.json';
+    var statusUrl = '/hosts?fields=Hosts/host_status,host_components/HostRoles/state';
     //desired_state property is eliminated since calculateState function is commented out, it become useless
     //desired_state property is eliminated since calculateState function is commented out, it become useless
-    servicesUrl = this.getUrl(testUrl, servicesUrl);
+    statusUrl = this.getUrl(testUrl, statusUrl);
 
 
-    App.HttpClient.get(servicesUrl, App.statusMapper, {
+    App.HttpClient.get(statusUrl, App.statusMapper, {
       complete: callback
       complete: callback
     });
     });
     return true;
     return true;
@@ -380,17 +375,17 @@ App.ClusterController = Em.Controller.extend({
         self.updateLoadStatus('users');
         self.updateLoadStatus('users');
     });
     });
 
 
-    App.router.get('updateController').updateServiceMetric(function(){
-      self.loadUpdatedStatus(function(){
-        self.updateLoadStatus('status');
-      });
-      if (App.supports.hostOverrides) {
-        App.router.get('updateController').updateComponentConfig(function () {
-          self.updateLoadStatus('componentConfigs');
-        });
-      }
-      self.updateLoadStatus('services');
-    }, true);
+    self.loadUpdatedStatus(function () {
+      self.updateLoadStatus('status');
+      App.router.get('updateController').updateServiceMetric(function () {
+        if (App.supports.hostOverrides) {
+          App.router.get('updateController').updateComponentConfig(function () {
+            self.updateLoadStatus('componentConfigs');
+          });
+        }
+        self.updateLoadStatus('services');
+      }, true);
+    });
 
 
     this.loadAlerts(function(){
     this.loadAlerts(function(){
         self.updateLoadStatus('alerts');
         self.updateLoadStatus('alerts');

+ 10 - 2
ambari-web/app/controllers/global/update_controller.js

@@ -45,9 +45,17 @@ App.UpdateController = Em.Controller.extend({
       }
       }
     }
     }
   }.observes('isWorking'),
   }.observes('isWorking'),
+  /**
+   * Update hosts depending on which page is open
+   * Make a call only on follow pages:
+   * /main/hosts
+   * /main/hosts/*
+   * /main/charts/heatmap
+   * @param callback
+   */
   updateHostConditionally: function (callback) {
   updateHostConditionally: function (callback) {
     var location = App.router.get('location.lastSetURL');
     var location = App.router.get('location.lastSetURL');
-    if (/\/main\/hosts.*/.test(location)) {
+    if (/\/main\/(hosts|charts\/heatmap).*/.test(location)) {
       this.updateHost(callback);
       this.updateHost(callback);
     } else {
     } else {
       callback();
       callback();
@@ -56,7 +64,7 @@ App.UpdateController = Em.Controller.extend({
 
 
   updateHost:function(callback) {
   updateHost:function(callback) {
     var testUrl = App.get('isHadoop2Stack') ? '/data/hosts/HDP2/hosts.json' : '/data/hosts/hosts.json';
     var testUrl = App.get('isHadoop2Stack') ? '/data/hosts/HDP2/hosts.json' : '/data/hosts/hosts.json';
-    var hostsUrl = this.getUrl(testUrl, '/hosts?fields=Hosts/host_name,Hosts/last_heartbeat_time,Hosts/disk_info,' +
+    var hostsUrl = this.getUrl(testUrl, '/hosts?fields=Hosts/host_name,Hosts/host_status,Hosts/last_heartbeat_time,Hosts/disk_info,' +
       'metrics/disk,metrics/load/load_one,metrics/cpu/cpu_system,metrics/cpu/cpu_user,metrics/memory/mem_total,metrics/memory/mem_free');
       'metrics/disk,metrics/load/load_one,metrics/cpu/cpu_system,metrics/cpu/cpu_user,metrics/memory/mem_total,metrics/memory/mem_free');
     App.HttpClient.get(hostsUrl, App.hostsMapper, {
     App.HttpClient.get(hostsUrl, App.hostsMapper, {
       complete: callback
       complete: callback

+ 195 - 5
ambari-web/app/mappers/service_mapper.js

@@ -173,10 +173,7 @@ App.servicesMapper = App.QuickDataMapper.create({
     if (!this.get('model')) {
     if (!this.get('model')) {
       return;
       return;
     }
     }
-
-    var start = new Date().getTime();
-    console.log('in service mapper');
-
+    console.time('App.servicesMapper execution time');
     if (json.items) {
     if (json.items) {
       var result = [];
       var result = [];
       json.items.forEach(function (item) {
       json.items.forEach(function (item) {
@@ -263,6 +260,7 @@ App.servicesMapper = App.QuickDataMapper.create({
       var currentHCWithComponentNames = {};
       var currentHCWithComponentNames = {};
       var currentComponentNameHostNames = {};
       var currentComponentNameHostNames = {};
       var doHostComponentsLoad = false;
       var doHostComponentsLoad = false;
+      var servicesMap = {};
       oldHostComponents.forEach(function (item) {
       oldHostComponents.forEach(function (item) {
         if (item) {
         if (item) {
           if (!hostComponentsMap[item.get('id')]) {
           if (!hostComponentsMap[item.get('id')]) {
@@ -278,9 +276,12 @@ App.servicesMapper = App.QuickDataMapper.create({
             }
             }
             currentComponentNameHostNames[componentName].pushObject(item.get('host.hostName'));
             currentComponentNameHostNames[componentName].pushObject(item.get('host.hostName'));
           }
           }
+          this.countServiceComponents(item, servicesMap, servicesMap[item.get('service.id')]);
         }
         }
       }, this);
       }, this);
 
 
+      this.updateServicesStatus(App.Service.find(), servicesMap);
+
       for(var i in hostComponentsMap) {
       for(var i in hostComponentsMap) {
         if(!currentHCWithComponentNames[i]) {
         if(!currentHCWithComponentNames[i]) {
           doHostComponentsLoad = true;
           doHostComponentsLoad = true;
@@ -298,7 +299,196 @@ App.servicesMapper = App.QuickDataMapper.create({
         App.store.loadMany(this.get('model3'), result);
         App.store.loadMany(this.get('model3'), result);
       }
       }
     }
     }
-    console.log('out service mapper.  Took ' + (new Date().getTime() - start) + 'ms');
+    console.timeEnd('App.servicesMapper execution time');
+  },
+
+  /**
+   * fill serviceMap with aggregated data of hostComponents for each service
+   * @param hostComponent
+   * @param servicesMap
+   * @param service
+   */
+  countServiceComponents: function (hostComponent, servicesMap, service) {
+    if (!service) {
+      service = {
+        everyStarted: true,
+        everyStartedOrMaintenance: true,
+        masterComponents: [],
+        isStarted: false,
+        isUnknown: false,
+        isStarting: false,
+        isStopped: false,
+        isHbaseActive: false,
+        serviceName: hostComponent.get('service.id'),
+        isRunning: true,
+        runningHCs: [],
+        unknownHCs: [],
+        hdfsHealthStatus: '',
+        toolTipContent: ''
+      };
+      servicesMap[hostComponent.get('service.id')] = service;
+    }
+    if (hostComponent.get('isMaster')) {
+      if (service.everyStartedOrMaintenance) {
+        service.everyStartedOrMaintenance = (((hostComponent.get('componentName') === 'NAMENODE' && !App.HostComponent.find().someProperty('componentName', 'SECONDARY_NAMENODE')) || hostComponent.get('componentName') === 'JOURNALNODE') && App.HDFSService.find().filterProperty('activeNameNode.hostName').length > 0)
+          ? true : service.everyStartedOrMaintenance = ([App.HostComponentStatus.started, App.HostComponentStatus.maintenance].contains(hostComponent.get('workStatus')));
+      } else {
+        service.everyStartedOrMaintenance = false;
+      }
+      service.everyStarted = (service.everyStarted)
+        ? (hostComponent.get('workStatus') === App.HostComponentStatus.started)
+        : false;
+      service.isStarted = (!service.isStarted)
+        ? (hostComponent.get('workStatus') === App.HostComponentStatus.started)
+        : true;
+      service.isUnknown = (!service.isUnknown)
+        ? (hostComponent.get('workStatus') === App.HostComponentStatus.unknown)
+        : true;
+      service.isStarting = (!service.isStarting)
+        ? (hostComponent.get('workStatus') === App.HostComponentStatus.starting)
+        : true;
+      service.isStopped = (!service.isStopped)
+        ? (hostComponent.get('workStatus') === App.HostComponentStatus.stopped)
+        : true;
+      service.isHbaseActive = (!service.isHbaseActive)
+        ? (hostComponent.get('haStatus') === 'true')
+        : true;
+
+      service.masterComponents.push(hostComponent);
+
+      // set advanced nameNode display name for HA, active or standby NameNode
+      // this is useful on three places: hdfs health status hover tooltip, hdfs service summary and NN component on host detail page
+      if (hostComponent.get('componentName') === 'NAMENODE' && !App.HostComponent.find().someProperty('componentName', 'SECONDARY_NAMENODE')) {
+        var hostName = hostComponent.get('host.hostName');
+        var services = App.Service.find();
+        var hdfs;
+        services.forEach(function (item) {
+          if (item.get("serviceName") == "HDFS") {
+            hdfs = App.HDFSService.find(item.get('id'));
+          }
+        }, this);
+        var activeNNText = Em.I18n.t('services.service.summary.nameNode.active');
+        var standbyNNText = Em.I18n.t('services.service.summary.nameNode.standby');
+        if (hdfs) {
+          if (hdfs.get('activeNameNode') && hdfs.get('activeNameNode').get('hostName')) {
+            var activeHostname = hdfs.get('activeNameNode').get('hostName');
+          }
+          if (hdfs.get('standbyNameNode') && hdfs.get('standbyNameNode').get('hostName')) {
+            var standbyHostname1 = hdfs.get('standbyNameNode').get('hostName');
+          }
+          if (hdfs.get('standbyNameNode2') && hdfs.get('standbyNameNode2').get('hostName')) {
+            var standbyHostname2 = hdfs.get('standbyNameNode2').get('hostName');
+          }
+          if (hostName == activeHostname) {
+            hostComponent.set('displayNameAdvanced', activeNNText);
+          } else if (hostName == standbyHostname1 || hostName == standbyHostname2) {
+            hostComponent.set('displayNameAdvanced', standbyNNText);
+          } else {
+            hostComponent.set('displayNameAdvanced', null);
+          }
+        }
+      } else if (hostComponent.get('componentName') === 'HBASE_MASTER') {
+        if (hostComponent.get('workStatus') === 'STARTED') {
+          hostComponent.get('haStatus') == 'true' ? hostComponent.set('displayNameAdvanced', this.t('dashboard.services.hbase.masterServer.active')) : hostComponent.set('displayNameAdvanced', this.t('dashboard.services.hbase.masterServer.standby'));
+        } else {
+          hostComponent.set('displayNameAdvanced', null);
+        }
+      }
+
+      if (hostComponent.get("displayNameAdvanced")) {
+        service.toolTipContent += hostComponent.get("displayNameAdvanced") + " " + hostComponent.get("componentTextStatus") + "<br/>";
+      } else {
+        service.toolTipContent += hostComponent.get("displayName") + " " + hostComponent.get("componentTextStatus") + "<br/>";
+      }
+
+    }
+
+    if (hostComponent.get('workStatus') !== App.HostComponentStatus.stopped &&
+      hostComponent.get('workStatus') !== App.HostComponentStatus.install_failed &&
+      hostComponent.get('workStatus') !== App.HostComponentStatus.unknown &&
+      hostComponent.get('workStatus') !== App.HostComponentStatus.maintenance) {
+      service.isRunning = false;
+      service.runningHCs.addObject(hostComponent);
+    } else if (hostComponent.get('workStatus') == App.HostComponentStatus.unknown) {
+      service.unknownHCs.addObject(hostComponent);
+    }
+  },
+
+  /**
+   * compute service status and properties by servicesMap of hostComponents
+   * @param services
+   * @param servicesMap
+   */
+  updateServicesStatus: function(services, servicesMap){
+    services.forEach(function(_service){
+      var service = servicesMap[_service.get('id')];
+      if (service) {
+        var serviceName = _service.get('serviceName');
+        var serviceSpecificObj = null;
+        switch (serviceName) {
+          case "HDFS":
+            serviceSpecificObj = App.HDFSService.find(_service.get('id'));
+            break;
+          case "YARN":
+            serviceSpecificObj = App.YARNService.find(_service.get('id'));
+            break;
+          case "MAPREDUCE":
+            serviceSpecificObj = App.MapReduceService.find(_service.get('id'));
+            break;
+          case "HBASE":
+            serviceSpecificObj = App.HBaseService.find(_service.get('id'));
+            break;
+        }
+        //computation of service health status
+        var isGreen = serviceName === 'HBASE' && App.supports.multipleHBaseMasters ? service.isStarted : service.everyStartedOrMaintenance;
+        if (isGreen) {
+          _service.set('healthStatus', 'green');
+          if (serviceSpecificObj != null) {
+            serviceSpecificObj.set('healthStatus', 'green');
+          }
+        } else if (service.isUnknown) {
+          _service.set('healthStatus', 'yellow');
+          if (serviceSpecificObj != null) {
+            serviceSpecificObj.set('healthStatus', 'yellow');
+          }
+        } else if (service.isStarting) {
+          _service.set('healthStatus', 'green-blinking');
+          if (serviceSpecificObj != null) {
+            serviceSpecificObj.set('healthStatus', 'green-blinking');
+          }
+        } else if (service.isStopped) {
+          _service.set('healthStatus', 'red');
+          if (serviceSpecificObj != null) {
+            serviceSpecificObj.set('healthStatus', 'red');
+          }
+        } else {
+          _service.set('healthStatus', 'red-blinking');
+          if (serviceSpecificObj != null) {
+            serviceSpecificObj.set('healthStatus', 'red-blinking');
+          }
+        }
+
+        if (serviceName === 'HBASE' && App.supports.multipleHBaseMasters) {
+          if (!service.isHbaseActive) {
+            _service.set('healthStatus', 'red');
+            if (serviceSpecificObj != null) {
+              serviceSpecificObj.set('healthStatus', 'red');
+            }
+          }
+        }
+
+        _service.set('isStarted', service.everyStarted);
+        _service.set('runningHostComponents', service.runningHCs);
+        _service.set('unknownHostComponents', service.unknownHCs);
+        _service.set('isStopped', service.isRunning);
+        _service.set('toolTipContent', service.toolTipContent);
+        if (serviceSpecificObj != null) {
+          serviceSpecificObj.set('isStarted', service.everyStarted);
+          serviceSpecificObj.set('isStopped', service.isRunning);
+          serviceSpecificObj.set('toolTipContent', service.toolTipContent);
+        }
+      }
+    }, this);
   },
   },
 
 
   /**
   /**

+ 107 - 300
ambari-web/app/mappers/status_mapper.js

@@ -17,322 +17,129 @@
 
 
 var App = require('app');
 var App = require('app');
 
 
-App.statusMapper = App.QuickDataMapper.create({
+var previousComponentStatuses = {};
+var previousHostStatuses = {};
 
 
-  config:{
-    id:'ServiceInfo.service_name',
-    work_status:'ServiceInfo.state'
+App.statusMapper = App.QuickDataMapper.create({
+  model: App.HostComponent,
+  componentServiceMap: {
+    'NAMENODE': 'HDFS',
+    'SECONDARY_NAMENODE': 'HDFS',
+    'DATANODE': 'HDFS',
+    'HDFS_CLIENT': 'HDFS',
+    'JOBTRACKER': 'MAPREDUCE',
+    'TASKTRACKER': 'MAPREDUCE',
+    'MAPREDUCE_CLIENT': 'MAPREDUCE',
+    'MAPREDUCE2_CLIENT': 'MAPREDUCE2',
+    'HISTORYSERVER': 'MAPREDUCE2',
+    'TEZ_CLIENT': 'TEZ',
+    'RESOURCEMANAGER': 'YARN',
+    'YARN_CLIENT': 'YARN',
+    'NODEMANAGER': 'YARN',
+    'ZOOKEEPER_SERVER': 'ZOOKEEPER',
+    'ZOOKEEPER_CLIENT': 'ZOOKEEPER',
+    'HBASE_MASTER': 'HBASE',
+    'HBASE_REGIONSERVER': 'HBASE',
+    'HBASE_CLIENT': 'HBASE',
+    'PIG': 'PIG',
+    'SQOOP': 'SQOOP',
+    'OOZIE_SERVER': 'OOZIE',
+    'OOZIE_CLIENT': 'OOZIE',
+    'HIVE_SERVER': 'HIVE',
+    'HIVE_METASTORE': 'HIVE',
+    'HIVE_CLIENT': 'HIVE',
+    'MYSQL_SERVER': 'HIVE',
+    'HCAT': 'HCATALOG',
+    'WEBHCAT_SERVER': 'WEBHCAT',
+    'NAGIOS_SERVER': 'NAGIOS',
+    'GANGLIA_SERVER': 'GANGLIA',
+    'GANGLIA_MONITOR': 'GANGLIA',
+    'KERBEROS_SERVER': 'KERBEROS',
+    'KERBEROS_ADMIN_CLIENT': 'KERBEROS',
+    'KERBEROS_CLIENT': 'KERBEROS',
+    'HUE_SERVER': 'HUE',
+    'HCFS_CLIENT': 'HCFS'
   },
   },
 
 
-  map:function (json) {
-    var start = new Date().getTime();
-    console.log('in status mapper');
-
+  map: function (json) {
+    console.time('App.statusMapper execution time');
     if (json.items) {
     if (json.items) {
-      var result = {};
-
-      //host_components
-      result = this.parse_host_components(json);
-
-      var hostComponents = App.HostComponent.find();
-      var servicesMap = {};
-      var hostsMap = {};
-
-      hostComponents.forEach(function(hostComponent) {
-        var item = result[hostComponent.get('id')];
-        if (item) {
-          hostComponent.set('workStatus', item.work_status);
-          if (item.ha_status) {
-            hostComponent.set('haStatus', item.ha_status);
-          }
-          this.countHostComponents(hostComponent, hostsMap, hostsMap[hostComponent.get('host.id')]);
-          this.countServiceComponents(hostComponent, servicesMap, servicesMap[hostComponent.get('service.id')]);
+      var hostsCache = App.cache['Hosts'];
+      var hostStatuses = {};
+      var hostComponentStatuses = {};
+      var addedHostComponents = [];
+      var componentServiceMap = this.get('componentServiceMap');
+      var currentComponentStatuses = {};
+      var currentHostStatuses = {};
+
+      json.items.forEach(function (host) {
+        //update hosts, which have status changed
+        if (previousHostStatuses[host.Hosts.host_name] !== host.Hosts.host_status) {
+          hostStatuses[host.Hosts.host_name] = host.Hosts.host_status;
         }
         }
-      }, this);
-
-      json.items.forEach(function (item) {
-        item = this.parseIt(item, this.config);
-        result[item.id] = item;
-      }, this);
-
-      var services = App.Service.find();
-      services.forEach(function(service) {
-        var item = result[service.get('id')];
-        if (item) {
-          service.set('workStatus', item.work_status);
-        }
-      });
-
-      this.updateHostsStatus(App.Host.find(), hostsMap);
-      this.updateServicesStatus(App.Service.find(), servicesMap);
-
-      console.log('out status mapper.  Took ' + (new Date().getTime() - start) + 'ms');
-    }
-  },
-
-  /**
-   * fill serviceMap with aggregated data of hostComponents for each service
-   * @param hostComponent
-   * @param servicesMap
-   * @param service
-   */
-  countServiceComponents: function(hostComponent, servicesMap, service){
-    if (!service) {
-      service = {
-        everyStarted: true,
-        everyStartedOrMaintenance: true,
-        masterComponents: [],
-        isStarted: false,
-        isUnknown: false,
-        isStarting: false,
-        isStopped: false,
-        isHbaseActive: false,
-        serviceName: this.get('serviceName'),
-        isRunning: true,
-        runningHCs: [],
-        unknownHCs: [],
-        hdfsHealthStatus: '',
-        toolTipContent: ''
-      };
-      servicesMap[hostComponent.get('service.id')] = service;
-    }
-    if (hostComponent.get('isMaster')) {
-      if (service.everyStartedOrMaintenance) {
-        service.everyStartedOrMaintenance = (((hostComponent.get('componentName') === 'NAMENODE' && !App.HostComponent.find().someProperty('componentName', 'SECONDARY_NAMENODE')) || hostComponent.get('componentName') === 'JOURNALNODE') && App.HDFSService.find().filterProperty('activeNameNode.hostName').length > 0)
-          ? true : service.everyStartedOrMaintenance = ([App.HostComponentStatus.started, App.HostComponentStatus.maintenance].contains(hostComponent.get('workStatus')));
-      } else {
-        service.everyStartedOrMaintenance = false;
-      }
-      service.everyStarted = (service.everyStarted)
-        ? (hostComponent.get('workStatus') === App.HostComponentStatus.started)
-        : false;
-      service.isStarted = (!service.isStarted)
-        ? (hostComponent.get('workStatus') === App.HostComponentStatus.started)
-        : true;
-      service.isUnknown = (!service.isUnknown)
-        ? (hostComponent.get('workStatus') === App.HostComponentStatus.unknown)
-        : true;
-      service.isStarting = (!service.isStarting)
-        ? (hostComponent.get('workStatus') === App.HostComponentStatus.starting)
-        : true;
-      service.isStopped = (!service.isStopped)
-        ? (hostComponent.get('workStatus') === App.HostComponentStatus.stopped)
-        : true;
-      service.isHbaseActive = (!service.isHbaseActive)
-        ? (hostComponent.get('haStatus') === 'true')
-        : true;
-
-      service.masterComponents.push(hostComponent);
-
-      // set advanced nameNode display name for HA, active or standby NameNode
-      // this is useful on three places: hdfs health status hover tooltip, hdfs service summary and NN component on host detail page
-      if (hostComponent.get('componentName') === 'NAMENODE' && !App.HostComponent.find().someProperty('componentName', 'SECONDARY_NAMENODE')) {
-        var hostName = hostComponent.get('host.hostName');
-        var services = App.Service.find();
-        var hdfs;
-        services.forEach(function (item) {
-          if (item.get("serviceName") == "HDFS") {
-            hdfs = App.HDFSService.find(item.get('id'));
-          }
-        }, this);
-        var activeNNText = Em.I18n.t('services.service.summary.nameNode.active');
-        var standbyNNText = Em.I18n.t('services.service.summary.nameNode.standby');
-        if (hdfs) {
-          if (hdfs.get('activeNameNode') && hdfs.get('activeNameNode').get('hostName')) {
-            var activeHostname = hdfs.get('activeNameNode').get('hostName');
-          }
-          if (hdfs.get('standbyNameNode') && hdfs.get('standbyNameNode').get('hostName')) {
-            var standbyHostname1 = hdfs.get('standbyNameNode').get('hostName');
-          }
-          if (hdfs.get('standbyNameNode2') && hdfs.get('standbyNameNode2').get('hostName')) {
-            var standbyHostname2 = hdfs.get('standbyNameNode2').get('hostName');
-          }
-          if ( hostName == activeHostname) {
-            hostComponent.set('displayNameAdvanced', activeNNText);
-          } else if ( hostName == standbyHostname1 || hostName == standbyHostname2) {
-            hostComponent.set('displayNameAdvanced', standbyNNText);
+        currentHostStatuses[host.Hosts.host_name] = host.Hosts.host_status;
+        var hostComponentsOnHost = [];
+        host.host_components.forEach(function (host_component) {
+          host_component.id = host_component.HostRoles.component_name + "_" + host_component.HostRoles.host_name;
+          var existedComponent = previousComponentStatuses[host_component.id];
+          if (existedComponent) {
+            //update host-components, which have status changed
+            if (existedComponent !== host_component.HostRoles.state) {
+              hostComponentStatuses[host_component.id] = host_component.HostRoles.state;
+            }
           } else {
           } else {
-            hostComponent.set('displayNameAdvanced', null);
+            addedHostComponents.push({
+              id: host_component.id,
+              component_name: host_component.HostRoles.component_name,
+              work_status: host_component.HostRoles.state,
+              host_id: host.Hosts.host_name,
+              service_id: componentServiceMap[host_component.HostRoles.component_name]
+            });
           }
           }
+          hostComponentsOnHost.push(host_component.id);
+          currentComponentStatuses[host_component.id] = host_component.HostRoles.state;
+        }, this);
+        /**
+         * updating relation between Host and his host-components
+         */
+        if (hostsCache[host.Hosts.host_name]) {
+          hostsCache[host.Hosts.host_name].host_components = hostComponentsOnHost;
         }
         }
-      } else if(hostComponent.get('componentName') === 'HBASE_MASTER') {
-        if (hostComponent.get('workStatus') === 'STARTED') {
-          hostComponent.get('haStatus') == 'true' ? hostComponent.set('displayNameAdvanced', this.t('dashboard.services.hbase.masterServer.active')) : hostComponent.set('displayNameAdvanced', this.t('dashboard.services.hbase.masterServer.standby'));
-        } else {
-          hostComponent.set('displayNameAdvanced', null);
-        }
-      }
-
-      if (hostComponent.get("displayNameAdvanced")) {
-        service.toolTipContent += hostComponent.get("displayNameAdvanced") + " " + hostComponent.get("componentTextStatus") + "<br/>";
-      } else {
-        service.toolTipContent += hostComponent.get("displayName") + " " + hostComponent.get("componentTextStatus") + "<br/>";
-      }
-
-    }
-
-    if (hostComponent.get('workStatus') !== App.HostComponentStatus.stopped &&
-      hostComponent.get('workStatus') !== App.HostComponentStatus.install_failed &&
-      hostComponent.get('workStatus') !== App.HostComponentStatus.unknown &&
-      hostComponent.get('workStatus') !== App.HostComponentStatus.maintenance) {
-      service.isRunning = false;
-      service.runningHCs.addObject(hostComponent);
-    } else if (hostComponent.get('workStatus') == App.HostComponentStatus.unknown) {
-      service.unknownHCs.addObject(hostComponent);
-    }
-  },
-
-  /**
-   * compute service status and properties by servicesMap of hostComponents
-   * @param services
-   * @param servicesMap
-   */
-  updateServicesStatus: function(services, servicesMap){
-    services.forEach(function(_service){
-      var service = servicesMap[_service.get('id')];
-      if (service) {
-      var serviceName = _service.get('serviceName');
-      var serviceSpecificObj = null;
-      switch (serviceName) {
-        case "HDFS":
-          serviceSpecificObj = App.HDFSService.find(_service.get('id'));
-          break;
-        case "YARN":
-          serviceSpecificObj = App.YARNService.find(_service.get('id'));
-          break;
-        case "MAPREDUCE":
-          serviceSpecificObj = App.MapReduceService.find(_service.get('id'));
-          break;
-        case "HBASE":
-          serviceSpecificObj = App.HBaseService.find(_service.get('id'));
-          break;
-      }
-      //computation of service health status
-      var isGreen = serviceName === 'HBASE' && App.supports.multipleHBaseMasters ? service.isStarted : service.everyStartedOrMaintenance;
-      if (isGreen) {
-        _service.set('healthStatus', 'green');
-        if (serviceSpecificObj != null) {
-          serviceSpecificObj.set('healthStatus', 'green');
-        }
-      } else if (service.isUnknown) {
-        _service.set('healthStatus', 'yellow');
-        if (serviceSpecificObj != null) {
-          serviceSpecificObj.set('healthStatus', 'yellow');
-        }
-      } else if (service.isStarting) {
-        _service.set('healthStatus', 'green-blinking');
-        if (serviceSpecificObj != null) {
-          serviceSpecificObj.set('healthStatus', 'green-blinking');
-        }
-      } else if (service.isStopped) {
-        _service.set('healthStatus', 'red');
-        if (serviceSpecificObj != null) {
-          serviceSpecificObj.set('healthStatus', 'red');
-        }
-      } else {
-        _service.set('healthStatus', 'red-blinking');
-        if (serviceSpecificObj != null) {
-          serviceSpecificObj.set('healthStatus', 'red-blinking');
-        }
-      }
+      }, this);
 
 
-      if (serviceName === 'HBASE' && App.supports.multipleHBaseMasters) {
-        if (!service.isHbaseActive) {
-          _service.set('healthStatus', 'red');
-          if (serviceSpecificObj != null) {
-            serviceSpecificObj.set('healthStatus', 'red');
+      var hostComponents = App.HostComponent.find();
+      var hosts = App.Host.find();
+
+      hostComponents.forEach(function (hostComponent) {
+        if (hostComponent) {
+          var status = currentComponentStatuses[hostComponent.get('id')];
+          //check whether component present in current response
+          if (status) {
+            //check whether component has status changed
+            if (hostComponentStatuses[hostComponent.get('id')]) {
+              hostComponent.set('workStatus', status);
+            }
+          } else {
+            hostComponent.deleteRecord();
+            hostComponent.get('stateManager').transitionTo('loading');
           }
           }
         }
         }
-      }
+      }, this);
 
 
-      _service.set('isStarted', service.everyStarted);
-      _service.set('runningHostComponents', service.runningHCs);
-      _service.set('unknownHostComponents', service.unknownHCs);
-      _service.set('isStopped', service.isRunning);
-      _service.set('toolTipContent', service.toolTipContent);
-      if (serviceSpecificObj != null) {
-        serviceSpecificObj.set('isStarted', service.everyStarted);
-        serviceSpecificObj.set('isStopped', service.isRunning);
-        serviceSpecificObj.set('toolTipContent', service.toolTipContent);
+      if (addedHostComponents.length) {
+        App.store.loadMany(this.get('model'), addedHostComponents);
       }
       }
-      }
-    }, this);
-  },
 
 
-  /**
-   * fill hostsMap with aggregated data of hostComponents for each host
-   * @param hostComponent
-   * @param hostsMap
-   * @param host
-   */
-  countHostComponents: function(hostComponent, hostsMap, host){
-    var isMasterRunning = (hostComponent.get('isMaster') && hostComponent.get('workStatus') === App.HostComponentStatus.started);
-    var isSlaveRunning = (hostComponent.get('isSlave') && hostComponent.get('workStatus') === App.HostComponentStatus.started);
-    if (host) {
-      host.mastersRunning = host.mastersRunning + ~~isMasterRunning;
-      host.slavesRunning = host.slavesRunning + ~~isSlaveRunning;
-      host.totalMasters = host.totalMasters + ~~hostComponent.get('isMaster');
-      host.totalSlaves = host.totalSlaves + ~~hostComponent.get('isSlave');
-    } else {
-      hostsMap[hostComponent.get('host.id')] = {
-        mastersRunning: ~~isMasterRunning,
-        slavesRunning: ~~isSlaveRunning,
-        totalMasters: ~~hostComponent.get('isMaster'),
-        totalSlaves: ~~hostComponent.get('isSlave')
-      }
-    }
-  },
+      previousComponentStatuses = currentComponentStatuses;
+      previousHostStatuses = currentHostStatuses;
 
 
-  /**
-   * compute host status by hostsMap of hostComponents
-   * @param hosts
-   * @param hostsMap
-   */
-  updateHostsStatus: function(hosts, hostsMap){
-    hosts.forEach(function(_host){
-      var healthStatus = _host.get('healthStatus');
-      var host = hostsMap[_host.get('id')];
-      if(host) {
-        //hostComponents of host are loaded to model
-        var status;
-        var masterComponentsRunning = (host.mastersRunning === host.totalMasters);
-        var slaveComponentsRunning = (host.slavesRunning === host.totalSlaves);
-        if (_host.get('isNotHeartBeating') || healthStatus == 'UNKNOWN') {
-          status = 'DEAD-YELLOW';
-        } else if (masterComponentsRunning && slaveComponentsRunning) {
-          status = 'LIVE';
-        } else if (host.totalMasters > 0 && !masterComponentsRunning) {
-          status = 'DEAD-RED';
-        } else {
-          status = 'DEAD-ORANGE';
-        }
+      hosts.forEach(function (host) {
+        var status = hostStatuses[host.get('id')];
         if (status) {
         if (status) {
-          healthStatus = status;
+          host.set('healthStatus', status);
         }
         }
-      }
-      _host.set('healthClass', 'health-status-' + healthStatus);
-    }, this);
-  },
-
-  parse_host_components: function(json) {
-    var result = {};
-    json.items.forEach(function (item) {
-      item.components.forEach(function (component) {
-        component.host_components.forEach(function (host_component) {
-          host_component.id = host_component.HostRoles.component_name + "_" + host_component.HostRoles.host_name;
-          result[host_component.id] = {
-            work_status: host_component.HostRoles.state
-          };
-          if (host_component.metrics &&
-              host_component.metrics.hbase &&
-              host_component.metrics.hbase.master &&
-              host_component.metrics.hbase.master.IsActiveMaster) {
-            result[host_component.id]['ha_status'] = host_component.metrics.hbase.master.IsActiveMaster;
-          }
-        }, this)
-      }, this)
-    }, this);
-    return result;
+      });
+    }
+    console.timeEnd('App.statusMapper execution time');
   }
   }
-
 });
 });

+ 9 - 13
ambari-web/app/models/host.js

@@ -128,19 +128,15 @@ App.Host = DS.Model.extend({
     if (this.get('loadFifteen') != null) return this.get('loadFifteen').toFixed(2);
     if (this.get('loadFifteen') != null) return this.get('loadFifteen').toFixed(2);
   }.property('loadOne', 'loadFive', 'loadFifteen'),
   }.property('loadOne', 'loadFive', 'loadFifteen'),
 
 
-  // Instead of making healthStatus a computed property that listens on hostComponents.@each.workStatus,
-  // we are creating a separate observer _updateHealthStatus.  This is so that healthStatus is updated
-  // only once after the run loop.  This is because Ember invokes the computed property every time
-  // a property that it depends on changes.  For example, App.statusMapper's map function would invoke
-  // the computed property too many times and freezes the UI without this hack.
-  // See http://stackoverflow.com/questions/12467345/ember-js-collapsing-deferring-expensive-observers-or-computed-properties
-  healthClass: '',
-
-  updateHealthClass: function(){
-    if(this.get('isNotHeartBeating') || this.get('healthStatus') == 'UNKNOWN'){
-      this.set('healthClass', 'health-status-DEAD-YELLOW');
-    }
-  }.observes('healthStatus'),
+  healthClass: function(){
+    var statusMap = {
+      'UNKNOWN': 'health-status-DEAD-YELLOW',
+      'HEALTHY': 'health-status-LIVE',
+      'UNHEALTHY': 'health-status-DEAD-RED',
+      'ALERT ': 'health-status-DEAD-ORANGE'
+    };
+    return statusMap[this.get('healthStatus')] || 'health-status-DEAD-ORANGE';
+  }.property('healthStatus'),
 
 
   healthToolTip: function(){
   healthToolTip: function(){
     var hostComponents = this.get('hostComponents').filter(function(item){
     var hostComponents = this.get('hostComponents').filter(function(item){