Updated Branches: refs/heads/trunk a4cba0e17 -> 9eb83fd99
AMBARI-3700 Status mapper upgrade. (atkach) Project: http://git-wip-us.apache.org/repos/asf/incubator-ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ambari/commit/9eb83fd9 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ambari/tree/9eb83fd9 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ambari/diff/9eb83fd9 Branch: refs/heads/trunk Commit: 9eb83fd998644b28c083c18ced3569c6c7eefc4b Parents: a4cba0e Author: atkach <[email protected]> Authored: Wed Nov 6 14:00:00 2013 +0200 Committer: atkach <[email protected]> Committed: Wed Nov 6 14:00:00 2013 +0200 ---------------------------------------------------------------------- .../assets/data/hosts/HDP2/hc_host_status.json | 204 ++++++++++ .../controllers/global/cluster_controller.js | 39 +- .../app/controllers/global/update_controller.js | 12 +- ambari-web/app/mappers/service_mapper.js | 200 ++++++++- ambari-web/app/mappers/status_mapper.js | 407 +++++-------------- ambari-web/app/models/host.js | 22 +- 6 files changed, 542 insertions(+), 342 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/9eb83fd9/ambari-web/app/assets/data/hosts/HDP2/hc_host_status.json ---------------------------------------------------------------------- diff --git a/ambari-web/app/assets/data/hosts/HDP2/hc_host_status.json b/ambari-web/app/assets/data/hosts/HDP2/hc_host_status.json new file mode 100644 index 0000000..3f8a1a3 --- /dev/null +++ b/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" + } + } + ] + } + ] +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/9eb83fd9/ambari-web/app/controllers/global/cluster_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/global/cluster_controller.js b/ambari-web/app/controllers/global/cluster_controller.js index 009ef1e..6cd0b95 100644 --- a/ambari-web/app/controllers/global/cluster_controller.js +++ b/ambari-web/app/controllers/global/cluster_controller.js @@ -262,22 +262,17 @@ App.ClusterController = Em.Controller.extend({ * @return {Boolean} Whether we have errors */ 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(); 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 - servicesUrl = this.getUrl(testUrl, servicesUrl); + statusUrl = this.getUrl(testUrl, statusUrl); - App.HttpClient.get(servicesUrl, App.statusMapper, { + App.HttpClient.get(statusUrl, App.statusMapper, { complete: callback }); return true; @@ -380,17 +375,17 @@ App.ClusterController = Em.Controller.extend({ 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(){ self.updateLoadStatus('alerts'); http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/9eb83fd9/ambari-web/app/controllers/global/update_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/global/update_controller.js b/ambari-web/app/controllers/global/update_controller.js index fc50f10..d3a46ed 100644 --- a/ambari-web/app/controllers/global/update_controller.js +++ b/ambari-web/app/controllers/global/update_controller.js @@ -45,9 +45,17 @@ App.UpdateController = Em.Controller.extend({ } } }.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) { var location = App.router.get('location.lastSetURL'); - if (/\/main\/hosts.*/.test(location)) { + if (/\/main\/(hosts|charts\/heatmap).*/.test(location)) { this.updateHost(callback); } else { callback(); @@ -56,7 +64,7 @@ App.UpdateController = Em.Controller.extend({ updateHost:function(callback) { 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'); App.HttpClient.get(hostsUrl, App.hostsMapper, { complete: callback http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/9eb83fd9/ambari-web/app/mappers/service_mapper.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/mappers/service_mapper.js b/ambari-web/app/mappers/service_mapper.js index 3d652a7..fe6e215 100644 --- a/ambari-web/app/mappers/service_mapper.js +++ b/ambari-web/app/mappers/service_mapper.js @@ -173,10 +173,7 @@ App.servicesMapper = App.QuickDataMapper.create({ if (!this.get('model')) { return; } - - var start = new Date().getTime(); - console.log('in service mapper'); - + console.time('App.servicesMapper execution time'); if (json.items) { var result = []; json.items.forEach(function (item) { @@ -263,6 +260,7 @@ App.servicesMapper = App.QuickDataMapper.create({ var currentHCWithComponentNames = {}; var currentComponentNameHostNames = {}; var doHostComponentsLoad = false; + var servicesMap = {}; oldHostComponents.forEach(function (item) { if (item) { if (!hostComponentsMap[item.get('id')]) { @@ -278,9 +276,12 @@ App.servicesMapper = App.QuickDataMapper.create({ } currentComponentNameHostNames[componentName].pushObject(item.get('host.hostName')); } + this.countServiceComponents(item, servicesMap, servicesMap[item.get('service.id')]); } }, this); + this.updateServicesStatus(App.Service.find(), servicesMap); + for(var i in hostComponentsMap) { if(!currentHCWithComponentNames[i]) { doHostComponentsLoad = true; @@ -298,7 +299,196 @@ App.servicesMapper = App.QuickDataMapper.create({ 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); }, /** http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/9eb83fd9/ambari-web/app/mappers/status_mapper.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/mappers/status_mapper.js b/ambari-web/app/mappers/status_mapper.js index 18a9bf5..3ae39cd 100644 --- a/ambari-web/app/mappers/status_mapper.js +++ b/ambari-web/app/mappers/status_mapper.js @@ -17,322 +17,129 @@ 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) { - 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 { - 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) { - 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'); } - }); http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/9eb83fd9/ambari-web/app/models/host.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/models/host.js b/ambari-web/app/models/host.js index 59cc855..614d1ef 100644 --- a/ambari-web/app/models/host.js +++ b/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); }.property('loadOne', 'loadFive', 'loadFifteen'), - // Instead of making healthStatus a computed property that listens on [email protected], - // 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(){ var hostComponents = this.get('hostComponents').filter(function(item){
