host.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. var App = require('app');
  19. var validator = require('utils/validator');
  20. var componentHelper = require('utils/component');
  21. var batchUtils = require('utils/batch_scheduled_requests');
  22. App.MainHostController = Em.ArrayController.extend(App.UserPref, {
  23. name: 'mainHostController',
  24. dataSource: App.Host.find(),
  25. clearFilters: null,
  26. filteredCount: 0,
  27. /**
  28. * flag responsible for updating status counters of hosts
  29. */
  30. isCountersUpdating: false,
  31. hostsCountMap: {},
  32. /**
  33. * Components which will be shown in component filter
  34. * @returns {Array}
  35. */
  36. componentsForFilter: function () {
  37. var installedComponents = App.StackServiceComponent.find().toArray();
  38. installedComponents.setEach('checkedForHostFilter', false);
  39. return installedComponents;
  40. }.property('App.router.clusterController.isLoaded'),
  41. /**
  42. * Master components
  43. * @returns {Array}
  44. */
  45. masterComponents: function () {
  46. return this.get('componentsForFilter').filterProperty('isMaster', true);
  47. }.property('componentsForFilter'),
  48. /**
  49. * Slave components
  50. * @returns {Array}
  51. */
  52. slaveComponents: function () {
  53. return this.get('componentsForFilter').filterProperty('isSlave', true);
  54. }.property('componentsForFilter'),
  55. /**
  56. * Client components
  57. * @returns {Array}
  58. */
  59. clientComponents: function () {
  60. return this.get('componentsForFilter').filterProperty('isClient', true);
  61. }.property('componentsForFilter'),
  62. content: function () {
  63. return this.get('dataSource').filterProperty('isRequested');
  64. }.property('dataSource.@each.isRequested'),
  65. filterProperties: [
  66. {
  67. key: 'publicHostName',
  68. alias: 'Hosts/host_name',
  69. type: 'MATCH'
  70. },
  71. {
  72. key: 'ip',
  73. alias: 'Hosts/ip',
  74. type: 'MATCH'
  75. },
  76. {
  77. key: 'cpu',
  78. alias: 'Hosts/cpu_count',
  79. type: 'PLAIN'
  80. },
  81. {
  82. key: 'memoryFormatted',
  83. alias: 'Hosts/total_mem',
  84. type: 'PLAIN'
  85. },
  86. {
  87. key: 'loadAvg',
  88. alias: 'metrics/load/load_one',
  89. type: 'PLAIN'
  90. },
  91. {
  92. key: 'hostComponents',
  93. alias: 'host_components/HostRoles/component_name',
  94. type: 'MULTIPLE'
  95. },
  96. {
  97. key: 'healthClass',
  98. alias: 'Hosts/host_status',
  99. type: 'PLAIN'
  100. },
  101. {
  102. key: 'criticalAlertsCount',
  103. alias: 'alerts/summary/CRITICAL>0|alerts/summary/WARNING>0',
  104. type: 'CRITICAL_ALERTS'
  105. },
  106. {
  107. key: 'componentsWithStaleConfigsCount',
  108. alias: 'host_components/HostRoles/stale_configs',
  109. type: 'PLAIN'
  110. },
  111. {
  112. key: 'componentsInPassiveStateCount',
  113. alias: 'host_components/HostRoles/maintenance_state',
  114. type: 'PLAIN'
  115. },
  116. {
  117. key: 'selected',
  118. alias: 'Hosts/host_name',
  119. type: 'MULTIPLE'
  120. }
  121. ],
  122. viewProperties: [
  123. Em.Object.create({
  124. key: 'displayLength',
  125. getValue: function (controller) {
  126. var name = controller.get('name');
  127. var dbValue = App.db.getDisplayLength(name);
  128. if (Em.isNone(this.get('viewValue'))) {
  129. if (dbValue) {
  130. this.set('viewValue', dbValue);
  131. } else {
  132. controller.set('makeRequestAsync', false);
  133. controller.getUserPref(controller.displayLengthKey());
  134. App.db.setDisplayLength(name, this.get('viewValue'));
  135. }
  136. }
  137. return this.get('viewValue');
  138. },
  139. viewValue: null,
  140. alias: 'page_size'
  141. }),
  142. Em.Object.create({
  143. key: 'startIndex',
  144. getValue: function (controller) {
  145. var name = controller.get('name');
  146. var startIndex = App.db.getStartIndex(name);
  147. var value = this.get('viewValue');
  148. if (Em.isNone(value)) {
  149. if (Em.isNone(startIndex)) {
  150. value = 0;
  151. } else {
  152. value = startIndex;
  153. }
  154. }
  155. return (value > 0) ? value - 1 : value;
  156. },
  157. viewValue: null,
  158. alias: 'from'
  159. })
  160. ],
  161. sortProps: [
  162. {
  163. key: 'publicHostName',
  164. alias: 'Hosts/host_name'
  165. },
  166. {
  167. key: 'ip',
  168. alias: 'Hosts/ip'
  169. },
  170. {
  171. key: 'cpu',
  172. alias: 'Hosts/cpu_count'
  173. },
  174. {
  175. key: 'memoryFormatted',
  176. alias: 'Hosts/total_mem'
  177. },
  178. {
  179. key: 'diskUsage',
  180. //TODO disk_usage is relative property and need support from API, metrics/disk/disk_free used temporarily
  181. alias: 'metrics/disk/disk_free'
  182. },
  183. {
  184. key: 'loadAvg',
  185. alias: 'metrics/load/load_one'
  186. }
  187. ],
  188. /**
  189. * get query parameters computed from filter properties, sort properties and custom properties of view
  190. * @return {Array}
  191. */
  192. getQueryParameters: function () {
  193. var queryParams = [];
  194. var savedFilterConditions = App.db.getFilterConditions(this.get('name')) || [];
  195. var savedSortConditions = App.db.getSortingStatuses(this.get('name')) || [];
  196. var colPropAssoc = this.get('colPropAssoc');
  197. var filterProperties = this.get('filterProperties');
  198. var sortProperties = this.get('sortProps');
  199. this.get('viewProperties').forEach(function (property) {
  200. queryParams.push({
  201. key: property.get('alias'),
  202. value: property.getValue(this),
  203. type: 'PLAIN'
  204. })
  205. }, this);
  206. savedFilterConditions.forEach(function (filter) {
  207. var property = filterProperties.findProperty('key', colPropAssoc[filter.iColumn]);
  208. if (property && filter.value.length > 0 && !filter.skipFilter) {
  209. var result = {
  210. key: property.alias,
  211. value: filter.value,
  212. type: property.type
  213. };
  214. if (filter.type === 'number' || filter.type === 'ambari-bandwidth') {
  215. result.type = this.getComparisonType(filter.value);
  216. result.value = this.getProperValue(filter.value);
  217. }
  218. if (filter.type === 'ambari-bandwidth') {
  219. result.value = this.convertMemory(filter.value);
  220. }
  221. if (result.value) {
  222. queryParams.push(result);
  223. }
  224. }
  225. }, this);
  226. savedSortConditions.forEach(function (sort) {
  227. var property = sortProperties.findProperty('key', sort.name);
  228. if (property && (sort.status === 'sorting_asc' || sort.status === 'sorting_desc')) {
  229. queryParams.push({
  230. key: property.alias,
  231. value: sort.status.replace('sorting_', ''),
  232. type: 'SORT'
  233. });
  234. }
  235. });
  236. return queryParams;
  237. },
  238. /**
  239. * update status counters of hosts
  240. */
  241. updateStatusCounters: function () {
  242. var self = this;
  243. if (this.get('isCountersUpdating')) {
  244. App.ajax.send({
  245. name: 'host.status.counters',
  246. sender: this,
  247. data: {},
  248. success: 'updateStatusCountersSuccessCallback',
  249. error: 'updateStatusCountersErrorCallback'
  250. });
  251. setTimeout(function () {
  252. self.updateStatusCounters();
  253. }, App.get('componentsUpdateInterval'));
  254. }
  255. },
  256. /**
  257. * success callback on <code>updateStatusCounters()</code>
  258. * map counters' value to categories
  259. * @param data
  260. */
  261. updateStatusCountersSuccessCallback: function (data) {
  262. var hostsCountMap = {
  263. 'HEALTHY': data.Clusters.health_report['Host/host_status/HEALTHY'],
  264. 'UNHEALTHY': data.Clusters.health_report['Host/host_status/UNHEALTHY'],
  265. 'ALERT': data.Clusters.health_report['Host/host_status/ALERT'],
  266. 'UNKNOWN': data.Clusters.health_report['Host/host_status/UNKNOWN'],
  267. 'health-status-WITH-ALERTS': (data.alerts) ? data.alerts.summary.CRITICAL + data.alerts.summary.WARNING : 0,
  268. 'health-status-RESTART': data.Clusters.health_report['Host/stale_config'],
  269. 'health-status-PASSIVE_STATE': data.Clusters.health_report['Host/maintenance_state'],
  270. 'TOTAL': data.Clusters.total_hosts
  271. };
  272. this.set('hostsCountMap', hostsCountMap);
  273. },
  274. /**
  275. * success callback on <code>updateStatusCounters()</code>
  276. */
  277. updateStatusCountersErrorCallback: function() {
  278. console.warn('ERROR: updateStatusCounters failed')
  279. },
  280. /**
  281. * Return value without predicate
  282. * @param {String} value
  283. * @return {String}
  284. */
  285. getProperValue: function (value) {
  286. return (value.charAt(0) === '>' || value.charAt(0) === '<' || value.charAt(0) === '=') ? value.substr(1, value.length) : value;
  287. },
  288. /**
  289. * Return value converted to kilobytes
  290. * @param {String} value
  291. * @return {*}
  292. */
  293. convertMemory: function (value) {
  294. var scale = value.charAt(value.length - 1);
  295. // first char may be predicate for comparison
  296. value = this.getProperValue(value);
  297. var parsedValue = parseFloat(value);
  298. if (isNaN(parsedValue)) {
  299. return value;
  300. }
  301. switch (scale) {
  302. case 'g':
  303. parsedValue *= 1048576;
  304. break;
  305. case 'm':
  306. parsedValue *= 1024;
  307. break;
  308. case 'k':
  309. break;
  310. default:
  311. //default value in GB
  312. parsedValue *= 1048576;
  313. }
  314. return Math.round(parsedValue);
  315. },
  316. /**
  317. * Return comparison type depending on populated predicate
  318. * @param value
  319. * @return {String}
  320. */
  321. getComparisonType: function (value) {
  322. var comparisonChar = value.charAt(0);
  323. var result = 'PLAIN';
  324. if (isNaN(comparisonChar)) {
  325. switch (comparisonChar) {
  326. case '>':
  327. result = 'MORE';
  328. break;
  329. case '<':
  330. result = 'LESS';
  331. break;
  332. }
  333. }
  334. return result;
  335. },
  336. /**
  337. * Filter hosts by componentName of <code>component</code>
  338. * @param {App.HostComponent} component
  339. */
  340. filterByComponent: function (component) {
  341. if (!component)
  342. return;
  343. var id = component.get('componentName');
  344. var column = 6;
  345. this.get('componentsForFilter').setEach('checkedForHostFilter', false);
  346. var filterForComponent = {
  347. iColumn: column,
  348. value: id,
  349. type: 'multiple'
  350. };
  351. App.db.setFilterConditions(this.get('name'), [filterForComponent]);
  352. },
  353. /**
  354. * Persist-key of current table displayLength property
  355. * @param {String} loginName current user login name
  356. * @returns {String}
  357. */
  358. displayLengthKey: function (loginName) {
  359. if (App.get('testMode')) {
  360. return 'pagination_displayLength';
  361. }
  362. loginName = loginName ? loginName : App.router.get('loginName');
  363. return this.get('name') + '-pagination-displayLength-' + loginName;
  364. },
  365. /**
  366. * Set received from server value to <code>displayLengthOnLoad</code>
  367. * @param {Number} response
  368. * @param {Object} request
  369. * @param {Object} data
  370. * @returns {*}
  371. */
  372. getUserPrefSuccessCallback: function (response, request, data) {
  373. console.log('Got DisplayLength value from server with key ' + data.key + '. Value is: ' + response);
  374. this.get('viewProperties').findProperty('key', 'displayLength').set('viewValue', response);
  375. },
  376. /**
  377. * Set default value to <code>displayLengthOnLoad</code> (and send it on server) if value wasn't found on server
  378. * @returns {Number}
  379. */
  380. getUserPrefErrorCallback: function () {
  381. // this user is first time login, so set default value - '25'
  382. console.log('Persist did NOT find the key');
  383. this.get('viewProperties').findProperty('key', 'displayLength').set('viewValue', '25');
  384. if (App.get('isAdmin')) {
  385. this.postUserPref(this.displayLengthKey(), '25');
  386. }
  387. },
  388. /**
  389. * On click callback for delete button
  390. */
  391. deleteButtonPopup: function () {
  392. var self = this;
  393. App.showConfirmationPopup(function () {
  394. self.removeHosts();
  395. });
  396. },
  397. showAlertsPopup: function (event) {
  398. var host = event.context;
  399. App.router.get('mainAlertsController').loadAlerts(host.get('hostName'), "HOST");
  400. App.ModalPopup.show({
  401. header: this.t('services.alerts.headingOfList'),
  402. bodyClass: Ember.View.extend({
  403. templateName: require('templates/main/host/alerts_popup'),
  404. controllerBinding: 'App.router.mainAlertsController',
  405. alerts: function () {
  406. return this.get('controller.alerts');
  407. }.property('controller.alerts'),
  408. closePopup: function () {
  409. this.get('parentView').hide();
  410. }
  411. }),
  412. primary: Em.I18n.t('common.close'),
  413. secondary: null,
  414. didInsertElement: function () {
  415. this.$().find('.modal-footer').addClass('align-center');
  416. this.$().children('.modal').css({'margin-top': '-350px'});
  417. }
  418. });
  419. event.stopPropagation();
  420. },
  421. /**
  422. * remove selected hosts
  423. */
  424. removeHosts: function () {
  425. var hosts = this.get('content');
  426. var selectedHosts = hosts.filterProperty('isChecked', true);
  427. selectedHosts.forEach(function (_hostInfo) {
  428. console.log('Removing: ' + _hostInfo.hostName);
  429. });
  430. this.get('fullContent').removeObjects(selectedHosts);
  431. },
  432. /**
  433. * remove hosts with id equal host_id
  434. * @param {String} host_id
  435. */
  436. checkRemoved: function (host_id) {
  437. var hosts = this.get('content');
  438. var selectedHosts = hosts.filterProperty('id', host_id);
  439. this.get('fullContent').removeObjects(selectedHosts);
  440. },
  441. /**
  442. * Bulk operation wrapper
  443. * @param {Object} operationData - data about bulk operation (action, hosts or hostComponents etc)
  444. * @param {Array} hosts - list of affected hosts
  445. */
  446. bulkOperation: function (operationData, hosts) {
  447. if (operationData.componentNameFormatted) {
  448. if (operationData.action === 'RESTART') {
  449. this.bulkOperationForHostComponentsRestart(operationData, hosts);
  450. }
  451. else {
  452. if (operationData.action.indexOf('DECOMMISSION') != -1) {
  453. this.bulkOperationForHostComponentsDecommission(operationData, hosts);
  454. }
  455. else {
  456. this.bulkOperationForHostComponents(operationData, hosts);
  457. }
  458. }
  459. }
  460. else {
  461. if (operationData.action === 'RESTART') {
  462. this.bulkOperationForHostsRestart(operationData, hosts);
  463. }
  464. else {
  465. if (operationData.action === 'PASSIVE_STATE') {
  466. this.bulkOperationForHostsPassiveState(operationData, hosts);
  467. }
  468. else {
  469. this.bulkOperationForHosts(operationData, hosts);
  470. }
  471. }
  472. }
  473. },
  474. /**
  475. * Bulk operation (start/stop all) for selected hosts
  476. * @param {Object} operationData - data about bulk operation (action, hostComponents etc)
  477. * @param {Array} hosts - list of affected hosts
  478. */
  479. bulkOperationForHosts: function (operationData, hosts) {
  480. var self = this;
  481. batchUtils.getComponentsFromServer({
  482. hosts: hosts.mapProperty('hostName'),
  483. workStatus: operationData.actionToCheck,
  484. passiveState: 'OFF',
  485. displayParams: ['host_components/HostRoles/component_name']
  486. }, function (data) {
  487. self.bulkOperationForHostsCallback(operationData, data);
  488. });
  489. },
  490. /**
  491. * run Bulk operation (start/stop all) for selected hosts
  492. * after host and components are loaded
  493. * @param operationData
  494. * @param data
  495. */
  496. bulkOperationForHostsCallback: function (operationData, data) {
  497. var query = [];
  498. var hostNames = [];
  499. var hostsMap = {};
  500. data.items.forEach(function (host) {
  501. host.host_components.forEach(function (hostComponent) {
  502. if (!App.components.get('clients').contains((hostComponent.HostRoles.component_name))) {
  503. if (hostsMap[host.Hosts.host_name]) {
  504. hostsMap[host.Hosts.host_name].push(hostComponent.HostRoles.component_name);
  505. } else {
  506. hostsMap[host.Hosts.host_name] = [hostComponent.HostRoles.component_name];
  507. }
  508. }
  509. });
  510. });
  511. for (var hostName in hostsMap) {
  512. var subQuery = '(HostRoles/component_name.in(%@)&HostRoles/host_name=' + hostName + ')';
  513. var components = hostsMap[hostName];
  514. if (components.length) {
  515. query.push(subQuery.fmt(components.join(',')));
  516. }
  517. hostNames.push(hostName);
  518. }
  519. hostNames = hostNames.join(",");
  520. if (query.length) {
  521. query = query.join('|');
  522. App.ajax.send({
  523. name: 'bulk_request.hosts.all_components',
  524. sender: this,
  525. data: {
  526. query: query,
  527. state: operationData.action,
  528. requestInfo: operationData.message,
  529. hostName: hostNames
  530. },
  531. success: 'bulkOperationForHostComponentsSuccessCallback'
  532. });
  533. }
  534. else {
  535. App.ModalPopup.show({
  536. header: Em.I18n.t('rolling.nothingToDo.header'),
  537. body: Em.I18n.t('rolling.nothingToDo.body').format(Em.I18n.t('hosts.host.maintainance.allComponents.context')),
  538. secondary: false
  539. });
  540. }
  541. },
  542. /**
  543. * Bulk restart for selected hosts
  544. * @param {Object} operationData - data about bulk operation (action, hostComponents etc)
  545. * @param {Ember.Enumerable} hosts - list of affected hosts
  546. */
  547. bulkOperationForHostsRestart: function (operationData, hosts) {
  548. batchUtils.getComponentsFromServer({
  549. passiveState: 'OFF',
  550. hosts: hosts.mapProperty('hostName'),
  551. displayParams: ['host_components/HostRoles/component_name']
  552. }, function (data) {
  553. var hostComponents = [];
  554. data.items.forEach(function (host) {
  555. host.host_components.forEach(function (hostComponent) {
  556. hostComponents.push(Em.Object.create({
  557. componentName: hostComponent.HostRoles.component_name,
  558. hostName: host.Hosts.host_name
  559. }));
  560. })
  561. });
  562. batchUtils.restartHostComponents(hostComponents, Em.I18n.t('rollingrestart.context.allOnSelectedHosts'), "HOST");
  563. });
  564. },
  565. /**
  566. * Bulk turn on/off passive state for selected hosts
  567. * @param {Object} operationData - data about bulk operation (action, hostComponents etc)
  568. * @param {Array} hosts - list of affected hosts
  569. */
  570. bulkOperationForHostsPassiveState: function (operationData, hosts) {
  571. var self = this;
  572. batchUtils.getComponentsFromServer({
  573. displayParams: ['Hosts/maintenance_state']
  574. }, function (data) {
  575. var hostNames = [];
  576. data.items.forEach(function (host) {
  577. if (host.Hosts.maintenance_state !== operationData.state) {
  578. hostNames.push(host.Hosts.host_name);
  579. }
  580. });
  581. if (hostNames.length) {
  582. App.ajax.send({
  583. name: 'bulk_request.hosts.passive_state',
  584. sender: self,
  585. data: {
  586. hostNames: hostNames.join(','),
  587. passive_state: operationData.state,
  588. requestInfo: operationData.message
  589. },
  590. success: 'updateHostPassiveState'
  591. });
  592. } else {
  593. App.ModalPopup.show({
  594. header: Em.I18n.t('rolling.nothingToDo.header'),
  595. body: Em.I18n.t('hosts.bulkOperation.passiveState.nothingToDo.body'),
  596. secondary: false
  597. });
  598. }
  599. });
  600. },
  601. updateHostPassiveState: function (data, opt, params) {
  602. App.router.get('clusterController').loadUpdatedStatus(function () {
  603. batchUtils.infoPassiveState(params.passive_state);
  604. });
  605. },
  606. /**
  607. * Bulk operation for selected hostComponents
  608. * @param {Object} operationData - data about bulk operation (action, hostComponents etc)
  609. * @param {Array} hosts - list of affected hosts
  610. */
  611. bulkOperationForHostComponents: function (operationData, hosts) {
  612. var self = this;
  613. batchUtils.getComponentsFromServer({
  614. components: [operationData.componentName],
  615. hosts: hosts.mapProperty('hostName'),
  616. passiveState: 'OFF'
  617. }, function (data) {
  618. if (data.items.length) {
  619. var hostsWithComponentInProperState = data.items.mapProperty('Hosts.host_name');
  620. App.ajax.send({
  621. name: 'bulk_request.host_components',
  622. sender: self,
  623. data: {
  624. hostNames: hostsWithComponentInProperState.join(','),
  625. state: operationData.action,
  626. requestInfo: operationData.message + ' ' + operationData.componentNameFormatted,
  627. componentName: operationData.componentName
  628. },
  629. success: 'bulkOperationForHostComponentsSuccessCallback'
  630. });
  631. }
  632. else {
  633. App.ModalPopup.show({
  634. header: Em.I18n.t('rolling.nothingToDo.header'),
  635. body: Em.I18n.t('rolling.nothingToDo.body').format(operationData.componentNameFormatted),
  636. secondary: false
  637. });
  638. }
  639. });
  640. },
  641. /**
  642. * Bulk decommission/recommission for selected hostComponents
  643. * @param {Object} operationData
  644. * @param {Array} hosts
  645. */
  646. bulkOperationForHostComponentsDecommission: function (operationData, hosts) {
  647. var self = this;
  648. batchUtils.getComponentsFromServer({
  649. components: [operationData.realComponentName],
  650. hosts: hosts.mapProperty('hostName'),
  651. passiveState: 'OFF',
  652. displayParams: ['host_components/HostRoles/state']
  653. }, function (data) {
  654. self.bulkOperationForHostComponentsDecommissionCallBack(operationData, data)
  655. });
  656. },
  657. /**
  658. * run Bulk decommission/recommission for selected hostComponents
  659. * after host and components are loaded
  660. * @param operationData
  661. * @param data
  662. */
  663. bulkOperationForHostComponentsDecommissionCallBack: function (operationData, data) {
  664. var service = App.Service.find(operationData.serviceName);
  665. var components = [];
  666. data.items.forEach(function (host) {
  667. host.host_components.forEach(function (hostComponent) {
  668. components.push(Em.Object.create({
  669. componentName: hostComponent.HostRoles.component_name,
  670. hostName: host.Hosts.host_name,
  671. workStatus: hostComponent.HostRoles.state
  672. }))
  673. });
  674. });
  675. if (components.length) {
  676. var hostsWithComponentInProperState = components.mapProperty('hostName');
  677. var turn_off = operationData.action.indexOf('OFF') !== -1;
  678. var svcName = operationData.serviceName;
  679. var masterName = operationData.componentName;
  680. var slaveName = operationData.realComponentName;
  681. var hostNames = hostsWithComponentInProperState.join(',');
  682. if (turn_off) {
  683. // For recommession
  684. if (svcName === "YARN" || svcName === "HBASE" || svcName === "HDFS") {
  685. App.router.get('mainHostDetailsController').doRecommissionAndStart(hostNames, svcName, masterName, slaveName);
  686. }
  687. else if (svcName === "MAPREDUCE") {
  688. App.router.get('mainHostDetailsController').doRecommissionAndRestart(hostNames, svcName, masterName, slaveName);
  689. }
  690. } else {
  691. hostsWithComponentInProperState = components.filterProperty('workStatus', 'STARTED').mapProperty('hostName');
  692. //For decommession
  693. if (svcName == "HBASE") {
  694. // HBASE service, decommission RegionServer in batch requests
  695. App.router.get('mainHostDetailsController').doDecommissionRegionServer(hostNames, svcName, masterName, slaveName);
  696. } else {
  697. var parameters = {
  698. "slave_type": slaveName
  699. };
  700. var contextString = turn_off ? 'hosts.host.' + slaveName.toLowerCase() + '.recommission' :
  701. 'hosts.host.' + slaveName.toLowerCase() + '.decommission';
  702. if (turn_off) {
  703. parameters['included_hosts'] = hostsWithComponentInProperState.join(',')
  704. }
  705. else {
  706. parameters['excluded_hosts'] = hostsWithComponentInProperState.join(',');
  707. }
  708. App.ajax.send({
  709. name: 'bulk_request.decommission',
  710. sender: this,
  711. data: {
  712. context: Em.I18n.t(contextString),
  713. serviceName: service.get('serviceName'),
  714. componentName: operationData.componentName,
  715. parameters: parameters
  716. },
  717. success: 'bulkOperationForHostComponentsSuccessCallback'
  718. });
  719. }
  720. }
  721. }
  722. else {
  723. App.ModalPopup.show({
  724. header: Em.I18n.t('rolling.nothingToDo.header'),
  725. body: Em.I18n.t('rolling.nothingToDo.body').format(operationData.componentNameFormatted),
  726. secondary: false
  727. });
  728. }
  729. },
  730. /**
  731. * Bulk restart for selected hostComponents
  732. * @param {Object} operationData
  733. * @param {Array} hosts
  734. */
  735. bulkOperationForHostComponentsRestart: function (operationData, hosts) {
  736. var service = App.Service.find(operationData.serviceName);
  737. batchUtils.getComponentsFromServer({
  738. components: [operationData.componentName],
  739. hosts: hosts.mapProperty('hostName'),
  740. passiveState: 'OFF',
  741. displayParams: ['Hosts/maintenance_state', 'host_components/HostRoles/stale_configs', 'host_components/HostRoles/maintenance_state']
  742. }, function (data) {
  743. var wrappedHostComponents = [];
  744. data.items.forEach(function (host) {
  745. host.host_components.forEach(function (hostComponent) {
  746. wrappedHostComponents.push(Em.Object.create({
  747. componentName: hostComponent.HostRoles.component_name,
  748. hostName: host.Hosts.host_name,
  749. hostPassiveState: host.Hosts.maintenance_state,
  750. staleConfigs: hostComponent.HostRoles.stale_configs,
  751. passiveState: hostComponent.HostRoles.maintenance_state
  752. }))
  753. });
  754. });
  755. if (wrappedHostComponents.length) {
  756. batchUtils.showRollingRestartPopup(wrappedHostComponents.objectAt(0).get('componentName'), service.get('displayName'), service.get('passiveState') === "ON", false, wrappedHostComponents);
  757. } else {
  758. App.ModalPopup.show({
  759. header: Em.I18n.t('rolling.nothingToDo.header'),
  760. body: Em.I18n.t('rolling.nothingToDo.body').format(operationData.componentNameFormatted),
  761. secondary: false
  762. });
  763. }
  764. });
  765. },
  766. updateHostComponentsPassiveState: function (data, opt, params) {
  767. App.router.get('clusterController').loadUpdatedStatus(function () {
  768. batchUtils.infoPassiveState(params.passive_state);
  769. });
  770. },
  771. /**
  772. * Show BO popup after bulk request
  773. */
  774. bulkOperationForHostComponentsSuccessCallback: function () {
  775. App.router.get('applicationController').dataLoading().done(function (initValue) {
  776. if (initValue) {
  777. App.router.get('backgroundOperationsController').showPopup();
  778. }
  779. });
  780. },
  781. /**
  782. * associations between host property and column index
  783. * @type {Array}
  784. */
  785. colPropAssoc: function () {
  786. var associations = [];
  787. associations[0] = 'healthClass';
  788. associations[1] = 'publicHostName';
  789. associations[2] = 'ip';
  790. associations[3] = 'cpu';
  791. associations[4] = 'memoryFormatted';
  792. associations[5] = 'loadAvg';
  793. associations[6] = 'hostComponents';
  794. associations[7] = 'criticalAlertsCount';
  795. associations[8] = 'componentsWithStaleConfigsCount';
  796. associations[9] = 'componentsInPassiveStateCount';
  797. associations[10] = 'selected';
  798. return associations;
  799. }.property()
  800. });