status_mapper.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with this
  4. * work for additional information regarding copyright ownership. The ASF
  5. * licenses this file to you under the Apache License, Version 2.0 (the
  6. * "License"); you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  13. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  14. * License for the specific language governing permissions and limitations under
  15. * the License.
  16. */
  17. var App = require('app');
  18. App.statusMapper = App.QuickDataMapper.create({
  19. config:{
  20. id:'ServiceInfo.service_name',
  21. work_status:'ServiceInfo.state'
  22. },
  23. config3:{
  24. id:'id',
  25. work_status:'HostRoles.state',
  26. desired_status: 'HostRoles.desired_state'
  27. },
  28. map:function (json) {
  29. var start = new Date().getTime();
  30. console.log('in status mapper');
  31. if (json.items) {
  32. var result = {};
  33. //host_components
  34. result = this.parse_host_components(json);
  35. var hostComponents = App.HostComponent.find();
  36. var servicesMap = {};
  37. var hostsMap = {};
  38. hostComponents.forEach(function(hostComponent) {
  39. var item = result[hostComponent.get('id')];
  40. if (item) {
  41. hostComponent.set('workStatus', item.work_status);
  42. hostComponent.set('haStatus', item.ha_status);
  43. this.countHostComponents(hostComponent, hostsMap, hostsMap[hostComponent.get('host.id')]);
  44. this.countServiceComponents(hostComponent, servicesMap, servicesMap[hostComponent.get('service.id')]);
  45. }
  46. }, this);
  47. json.items.forEach(function (item) {
  48. item = this.parseIt(item, this.config);
  49. result[item.id] = item;
  50. }, this);
  51. var services = App.Service.find();
  52. services.forEach(function(service) {
  53. var item = result[service.get('id')];
  54. if (item) {
  55. service.set('workStatus', item.work_status);
  56. }
  57. });
  58. this.updateHostsStatus(App.Host.find(), hostsMap);
  59. this.updateServicesStatus(App.Service.find(), servicesMap);
  60. console.log('out status mapper. Took ' + (new Date().getTime() - start) + 'ms');
  61. }
  62. },
  63. /**
  64. * fill serviceMap with aggregated data of hostComponents for each service
  65. * @param hostComponent
  66. * @param servicesMap
  67. * @param service
  68. */
  69. countServiceComponents: function(hostComponent, servicesMap, service){
  70. if (!service) {
  71. service = {
  72. everyStarted: true,
  73. everyStartedOrMaintenance: true,
  74. masterComponents: [],
  75. isStarted: false,
  76. isUnknown: false,
  77. isStarting: false,
  78. isStopped: false,
  79. isHbaseActive: false,
  80. serviceName: this.get('serviceName'),
  81. isRunning: true,
  82. runningHCs: [],
  83. unknownHCs: [],
  84. hdfsHealthStatus: '',
  85. toolTipContent: ''
  86. };
  87. servicesMap[hostComponent.get('service.id')] = service;
  88. }
  89. if (hostComponent.get('isMaster')) {
  90. if (service.everyStartedOrMaintenance) {
  91. service.everyStartedOrMaintenance = (hostComponent.get('componentName') === 'NAMENODE' && !App.HostComponent.find().someProperty('componentName', 'SECONDARY_NAMENODE') && App.HDFSService.find().filterProperty('activeNameNode.hostName').length > 0)
  92. ? true : service.everyStartedOrMaintenance = ([App.HostComponentStatus.started, App.HostComponentStatus.maintenance].contains(hostComponent.get('workStatus')));
  93. } else {
  94. service.everyStartedOrMaintenance = false;
  95. }
  96. service.everyStarted = (service.everyStarted)
  97. ? (hostComponent.get('workStatus') === App.HostComponentStatus.started)
  98. : false;
  99. service.isStarted = (!service.isStarted)
  100. ? (hostComponent.get('workStatus') === App.HostComponentStatus.started)
  101. : true;
  102. service.isUnknown = (!service.isUnknown)
  103. ? (hostComponent.get('workStatus') === App.HostComponentStatus.unknown)
  104. : true;
  105. service.isStarting = (!service.isStarting)
  106. ? (hostComponent.get('workStatus') === App.HostComponentStatus.starting)
  107. : true;
  108. service.isStopped = (!service.isStopped)
  109. ? (hostComponent.get('workStatus') === App.HostComponentStatus.stopped)
  110. : true;
  111. service.isHbaseActive = (!service.isHbaseActive)
  112. ? (hostComponent.get('haStatus') === 'active')
  113. : true;
  114. service.masterComponents.push(hostComponent);
  115. // set advanced nameNode display name for HA, active or standby NameNode
  116. // this is useful on three places: hdfs health status hover tooltip, hdfs service summary and NN component on host detail page
  117. if (hostComponent.get('componentName') === 'NAMENODE' && !App.HostComponent.find().someProperty('componentName', 'SECONDARY_NAMENODE')) {
  118. var hostName = hostComponent.get('host.hostName');
  119. var services = App.Service.find();
  120. var hdfs;
  121. services.forEach(function (item) {
  122. if (item.get("serviceName") == "HDFS") {
  123. hdfs = App.HDFSService.find(item.get('id'));
  124. }
  125. }, this);
  126. var activeNNText = Em.I18n.t('services.service.summary.nameNode.active');
  127. var standbyNNText = Em.I18n.t('services.service.summary.nameNode.standby');
  128. if (hdfs) {
  129. if (hdfs.get('activeNameNode') && hdfs.get('activeNameNode').get('hostName')) {
  130. var activeHostname = hdfs.get('activeNameNode').get('hostName');
  131. }
  132. if (hdfs.get('standbyNameNode') && hdfs.get('standbyNameNode').get('hostName')) {
  133. var standbyHostname1 = hdfs.get('standbyNameNode').get('hostName');
  134. }
  135. if (hdfs.get('standbyNameNode2') && hdfs.get('standbyNameNode2').get('hostName')) {
  136. var standbyHostname2 = hdfs.get('standbyNameNode2').get('hostName');
  137. }
  138. if ( hostName == activeHostname) {
  139. hostComponent.set('displayNameAdvanced', activeNNText);
  140. } else if ( hostName == standbyHostname1 || hostName == standbyHostname2) {
  141. hostComponent.set('displayNameAdvanced', standbyNNText);
  142. } else {
  143. hostComponent.set('displayNameAdvanced', null);
  144. }
  145. }
  146. } else if(hostComponent.get('componentName') === 'HBASE_MASTER') {
  147. if (hostComponent.get('workStatus') === 'STARTED') {
  148. hostComponent.get('haStatus') == 'active' ? hostComponent.set('displayNameAdvanced', this.t('dashboard.services.hbase.masterServer.active')) : hostComponent.set('displayNameAdvanced', this.t('dashboard.services.hbase.masterServer.standby'));
  149. } else {
  150. hostComponent.set('displayNameAdvanced', null);
  151. }
  152. }
  153. if (hostComponent.get("displayNameAdvanced")) {
  154. service.toolTipContent += hostComponent.get("displayNameAdvanced") + " " + hostComponent.get("componentTextStatus") + "<br/>";
  155. } else {
  156. service.toolTipContent += hostComponent.get("displayName") + " " + hostComponent.get("componentTextStatus") + "<br/>";
  157. }
  158. }
  159. if (hostComponent.get('workStatus') !== App.HostComponentStatus.stopped &&
  160. hostComponent.get('workStatus') !== App.HostComponentStatus.install_failed &&
  161. hostComponent.get('workStatus') !== App.HostComponentStatus.unknown &&
  162. hostComponent.get('workStatus') !== App.HostComponentStatus.maintenance) {
  163. service.isRunning = false;
  164. service.runningHCs.addObject(hostComponent);
  165. } else if (hostComponent.get('workStatus') == App.HostComponentStatus.unknown) {
  166. service.unknownHCs.addObject(hostComponent);
  167. }
  168. },
  169. /**
  170. * compute service status and properties by servicesMap of hostComponents
  171. * @param services
  172. * @param servicesMap
  173. */
  174. updateServicesStatus: function(services, servicesMap){
  175. services.forEach(function(_service){
  176. var service = servicesMap[_service.get('id')];
  177. var serviceName = _service.get('serviceName');
  178. var serviceSpecificObj = null;
  179. switch (serviceName) {
  180. case "HDFS":
  181. serviceSpecificObj = App.HDFSService.find(_service.get('id'));
  182. break;
  183. case "YARN":
  184. serviceSpecificObj = App.YARNService.find(_service.get('id'));
  185. break;
  186. case "MAPREDUCE":
  187. serviceSpecificObj = App.MapReduceService.find(_service.get('id'));
  188. break;
  189. case "HBASE":
  190. serviceSpecificObj = App.HBaseService.find(_service.get('id'));
  191. break;
  192. }
  193. //computation of service health status
  194. var isGreen = serviceName === 'HBASE' && App.supports.multipleHBaseMasters ? service.isStarted : service.everyStartedOrMaintenance;
  195. if (isGreen) {
  196. _service.set('healthStatus', 'green');
  197. if (serviceSpecificObj != null) {
  198. serviceSpecificObj.set('healthStatus', 'green');
  199. }
  200. } else if (service.isUnknown) {
  201. _service.set('healthStatus', 'yellow');
  202. if (serviceSpecificObj != null) {
  203. serviceSpecificObj.set('healthStatus', 'yellow');
  204. }
  205. } else if (service.isStarting) {
  206. _service.set('healthStatus', 'green-blinking');
  207. if (serviceSpecificObj != null) {
  208. serviceSpecificObj.set('healthStatus', 'green-blinking');
  209. }
  210. } else if (service.isStopped) {
  211. _service.set('healthStatus', 'red');
  212. if (serviceSpecificObj != null) {
  213. serviceSpecificObj.set('healthStatus', 'red');
  214. }
  215. } else {
  216. _service.set('healthStatus', 'red-blinking');
  217. if (serviceSpecificObj != null) {
  218. serviceSpecificObj.set('healthStatus', 'red-blinking');
  219. }
  220. }
  221. if (serviceName === 'HBASE' && App.supports.multipleHBaseMasters) {
  222. if (!service.isHbaseActive) {
  223. _service.set('healthStatus', 'red');
  224. if (serviceSpecificObj != null) {
  225. serviceSpecificObj.set('healthStatus', 'red');
  226. }
  227. }
  228. }
  229. _service.set('isStarted', service.everyStarted);
  230. _service.set('runningHostComponents', service.runningHCs);
  231. _service.set('unknownHostComponents', service.unknownHCs);
  232. _service.set('isStopped', service.isRunning);
  233. _service.set('toolTipContent', service.toolTipContent);
  234. if (serviceSpecificObj != null) {
  235. serviceSpecificObj.set('isStarted', service.everyStarted);
  236. serviceSpecificObj.set('isStopped', service.isRunning);
  237. serviceSpecificObj.set('toolTipContent', service.toolTipContent);
  238. }
  239. }, this);
  240. },
  241. /**
  242. * fill hostsMap with aggregated data of hostComponents for each host
  243. * @param hostComponent
  244. * @param hostsMap
  245. * @param host
  246. */
  247. countHostComponents: function(hostComponent, hostsMap, host){
  248. var isMasterRunning = (hostComponent.get('isMaster') && hostComponent.get('workStatus') === App.HostComponentStatus.started);
  249. var isSlaveRunning = (hostComponent.get('isSlave') && hostComponent.get('workStatus') === App.HostComponentStatus.started);
  250. if (host) {
  251. host.mastersRunning = host.mastersRunning + ~~isMasterRunning;
  252. host.slavesRunning = host.slavesRunning + ~~isSlaveRunning;
  253. host.totalMasters = host.totalMasters + ~~hostComponent.get('isMaster');
  254. host.totalSlaves = host.totalSlaves + ~~hostComponent.get('isSlave');
  255. } else {
  256. hostsMap[hostComponent.get('host.id')] = {
  257. mastersRunning: ~~isMasterRunning,
  258. slavesRunning: ~~isSlaveRunning,
  259. totalMasters: ~~hostComponent.get('isMaster'),
  260. totalSlaves: ~~hostComponent.get('isSlave')
  261. }
  262. }
  263. },
  264. /**
  265. * compute host status by hostsMap of hostComponents
  266. * @param hosts
  267. * @param hostsMap
  268. */
  269. updateHostsStatus: function(hosts, hostsMap){
  270. hosts.forEach(function(_host){
  271. var healthStatus = _host.get('healthStatus');
  272. var host = hostsMap[_host.get('id')];
  273. var status;
  274. var masterComponentsRunning = (host.mastersRunning === host.totalMasters);
  275. var slaveComponentsRunning = (host.slavesRunning === host.totalSlaves);
  276. if (_host.get('isNotHeartBeating') || healthStatus == 'UNKNOWN') {
  277. status = 'DEAD-YELLOW';
  278. } else if (masterComponentsRunning && slaveComponentsRunning) {
  279. status = 'LIVE';
  280. } else if (host.totalMasters > 0 && !masterComponentsRunning) {
  281. status = 'DEAD-RED';
  282. } else {
  283. status = 'DEAD-ORANGE';
  284. }
  285. if (status) {
  286. healthStatus = status;
  287. }
  288. _host.set('healthClass', 'health-status-' + healthStatus);
  289. }, this);
  290. },
  291. parse_host_components: function(json) {
  292. var result = {};
  293. json.items.forEach(function (item) {
  294. item.components.forEach(function (component) {
  295. component.host_components.forEach(function (host_component) {
  296. host_component.id = host_component.HostRoles.component_name + "_" + host_component.HostRoles.host_name;
  297. result[host_component.id] = {
  298. work_status: host_component.HostRoles.state,
  299. ha_status: host_component.HostRoles.ha_status
  300. };
  301. }, this)
  302. }, this)
  303. }, this);
  304. return result;
  305. }
  306. });