host.js 26 KB

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