host_progress_popup.js 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910
  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 batchUtils = require('utils/batch_scheduled_requests');
  20. var date = require('utils/date');
  21. /**
  22. * App.HostPopup is for the popup that shows up upon clicking already-performed or currently-in-progress operations
  23. */
  24. App.HostPopup = Em.Object.create({
  25. servicesInfo: null,
  26. hosts: null,
  27. inputData: null,
  28. serviceName: "",
  29. currentServiceId: null,
  30. previousServiceId: null,
  31. popupHeaderName: "",
  32. dataSourceController: null,
  33. isBackgroundOperations: false,
  34. currentHostName: null,
  35. isPopup: null,
  36. /**
  37. * Sort object array
  38. * @param array
  39. * @param p
  40. * @return {*}
  41. */
  42. sortArray: function (array, p) {
  43. return array.sort(function (a, b) {
  44. return (a[p] > b[p]) ? 1 : (a[p] < b[p]) ? -1 : 0;
  45. });
  46. },
  47. /**
  48. * Entering point of this component
  49. * @param serviceName
  50. * @param controller
  51. * @param isBackgroundOperations
  52. */
  53. initPopup: function (serviceName, controller, isBackgroundOperations) {
  54. if (!isBackgroundOperations) {
  55. this.clearHostPopup();
  56. this.set("popupHeaderName", serviceName);
  57. }
  58. this.set("serviceName", serviceName);
  59. this.set("dataSourceController", controller);
  60. this.set("isBackgroundOperations", isBackgroundOperations);
  61. this.set("inputData", this.get("dataSourceController.services"));
  62. if(isBackgroundOperations){
  63. this.onServiceUpdate();
  64. } else {
  65. this.onHostUpdate();
  66. }
  67. return this.createPopup();
  68. },
  69. clearHostPopup: function () {
  70. this.set('servicesInfo', null);
  71. this.set('hosts', null);
  72. this.set('inputData', null);
  73. this.set('serviceName', "");
  74. this.set('currentServiceId', null);
  75. this.set('previousServiceId', null);
  76. this.set('popupHeaderName', "");
  77. this.set('dataSourceController', null);
  78. this.set('currentHostName', null);
  79. this.get('isPopup') ? this.get('isPopup').remove() : null;
  80. },
  81. /**
  82. * Depending on tasks status
  83. * @param tasks
  84. * @return {Array} [Status, Icon type, Progressbar color, is IN_PROGRESS]
  85. */
  86. getStatus: function(tasks){
  87. var isCompleted = true;
  88. var status;
  89. var tasksLength = tasks.length;
  90. var isFailed = false;
  91. var isAborted = false;
  92. var isTimedout = false;
  93. var isInProgress = false;
  94. for (var i = 0; i < tasksLength; i++) {
  95. if (tasks[i].Tasks.status !== 'COMPLETED') {
  96. isCompleted = false;
  97. }
  98. if(tasks[i].Tasks.status === 'FAILED'){
  99. isFailed = true;
  100. }
  101. if (tasks[i].Tasks.status === 'ABORTED') {
  102. isAborted = true;
  103. }
  104. if (tasks[i].Tasks.status === 'TIMEDOUT') {
  105. isTimedout = true;
  106. }
  107. if (tasks[i].Tasks.status === 'IN_PROGRESS') {
  108. isInProgress = true;
  109. }
  110. }
  111. if (isFailed) {
  112. status = ['FAILED', 'icon-exclamation-sign', 'progress-danger', false];
  113. } else if (isAborted) {
  114. status = ['CANCELLED', 'icon-minus', 'progress-warning', false];
  115. } else if (isTimedout) {
  116. status = ['TIMEDOUT', 'icon-time', 'progress-warning', false];
  117. } else if (isInProgress) {
  118. status = ['IN_PROGRESS', 'icon-cogs', 'progress-info', true];
  119. }
  120. if(status){
  121. return status;
  122. } else if(isCompleted){
  123. return ['SUCCESS', 'icon-ok', 'progress-success', false];
  124. } else {
  125. return ['PENDING', 'icon-cog', 'progress-info', true];
  126. }
  127. },
  128. /**
  129. * Progress of host or service depending on tasks status
  130. * @param tasks
  131. * @return {Number} percent of completion
  132. */
  133. getProgress: function (tasks) {
  134. var completedActions = 0;
  135. var queuedActions = 0;
  136. var inProgressActions = 0;
  137. tasks.forEach(function(task){
  138. if(['COMPLETED', 'FAILED', 'ABORTED', 'TIMEDOUT'].contains(task.Tasks.status)){
  139. completedActions++;
  140. } else if(task.Tasks.status === 'QUEUED'){
  141. queuedActions++;
  142. } else if(task.Tasks.status === 'IN_PROGRESS'){
  143. inProgressActions++;
  144. }
  145. });
  146. return Math.ceil(((queuedActions * 0.09) + (inProgressActions * 0.35) + completedActions ) / tasks.length * 100);
  147. },
  148. /**
  149. * Count number of operations for select box options
  150. * @param obj
  151. * @param categories
  152. */
  153. setSelectCount: function (obj, categories) {
  154. if (!obj) return;
  155. var countAll = obj.length;
  156. var countPending = 0;
  157. var countInProgress = 0;
  158. var countFailed = 0;
  159. var countCompleted = 0;
  160. var countAborted = 0;
  161. var countTimedout = 0;
  162. obj.forEach(function(item){
  163. switch (item.status){
  164. case 'pending':
  165. countPending++;
  166. break;
  167. case 'queued':
  168. countPending++;
  169. break;
  170. case 'in_progress':
  171. countInProgress++;
  172. break;
  173. case 'failed':
  174. countFailed++;
  175. break;
  176. case 'success':
  177. countCompleted++;
  178. break;
  179. case 'completed':
  180. countCompleted++;
  181. break;
  182. case 'aborted':
  183. countAborted++;
  184. break;
  185. case 'timedout':
  186. countTimedout++;
  187. break;
  188. }
  189. }, this);
  190. categories.findProperty("value", 'all').set("count", countAll);
  191. categories.findProperty("value", 'pending').set("count", countPending);
  192. categories.findProperty("value", 'in_progress').set("count", countInProgress);
  193. categories.findProperty("value", 'failed').set("count", countFailed);
  194. categories.findProperty("value", 'completed').set("count", countCompleted);
  195. categories.findProperty("value", 'aborted').set("count", countAborted);
  196. categories.findProperty("value", 'timedout').set("count", countTimedout);
  197. },
  198. /**
  199. * For Background operation popup calculate number of running Operations, and set popup header
  200. * @param isServiceListHidden
  201. */
  202. setBackgroundOperationHeader: function (isServiceListHidden) {
  203. if (this.get('isBackgroundOperations') && !isServiceListHidden) {
  204. var numRunning = App.router.get('backgroundOperationsController.allOperationsCount');
  205. this.set("popupHeaderName", numRunning + Em.I18n.t('hostPopup.header.postFix'));
  206. }
  207. },
  208. /**
  209. * Create services obj data structure for popup
  210. * Set data for services
  211. */
  212. onServiceUpdate: function (isServiceListHidden) {
  213. if (this.get('isBackgroundOperations') && this.get("inputData")) {
  214. var self = this;
  215. var allNewServices = [];
  216. var statuses = {
  217. 'FAILED': ['FAILED', 'icon-exclamation-sign', 'progress-danger', false],
  218. 'ABORTED': ['CANCELLED', 'icon-minus', 'progress-warning', false],
  219. 'TIMEDOUT': ['TIMEDOUT', 'icon-time', 'progress-warning', false],
  220. 'IN_PROGRESS': ['IN_PROGRESS', 'icon-cogs', 'progress-info', true],
  221. 'COMPLETED': ['SUCCESS', 'icon-ok', 'progress-success', false]
  222. };
  223. var pendingStatus = ['PENDING', 'icon-cog', 'progress-info', true];
  224. this.set("servicesInfo", null);
  225. this.get("inputData").forEach(function (service) {
  226. var status = statuses[service.status] || pendingStatus;
  227. var newService = Ember.Object.create({
  228. id: service.id,
  229. displayName: service.displayName,
  230. progress: service.progress,
  231. status: App.format.taskStatus(status[0]),
  232. isRunning: service.isRunning,
  233. name: service.name,
  234. isVisible: true,
  235. startTime: date.startTime(service.startTime),
  236. duration: date.durationSummary(service.startTime, service.endTime),
  237. icon: status[1],
  238. barColor: status[2],
  239. isInProgress: status[3],
  240. barWidth: "width:" + service.progress + "%;",
  241. sourceRequestScheduleId: service.get('sourceRequestScheduleId'),
  242. contextCommand: service.get('contextCommand')
  243. });
  244. allNewServices.push(newService);
  245. });
  246. self.set('servicesInfo', allNewServices);
  247. this.setBackgroundOperationHeader(isServiceListHidden);
  248. }
  249. },
  250. /**
  251. * create task Ember object
  252. * @param _task
  253. * @return {*}
  254. */
  255. createTask: function (_task) {
  256. return Ember.Object.create({
  257. id: _task.Tasks.id,
  258. hostName: _task.Tasks.host_name,
  259. command: ( _task.Tasks.command.toLowerCase() != 'service_check') ? _task.Tasks.command.toLowerCase() : '',
  260. status: App.format.taskStatus(_task.Tasks.status),
  261. role: App.format.role(_task.Tasks.role),
  262. outputLog: Em.I18n.t('common.hostLog.popup.logDir.path') + Em.I18n.t('common.hostLog.popup.outputLog.value').format(_task.Tasks.id),
  263. errorLog: Em.I18n.t('common.hostLog.popup.logDir.path') + Em.I18n.t('common.hostLog.popup.errorLog.value').format(_task.Tasks.id),
  264. stderr: _task.Tasks.stderr,
  265. stdout: _task.Tasks.stdout,
  266. isVisible: true,
  267. startTime: date.startTime(_task.Tasks.start_time),
  268. duration: date.durationSummary(_task.Tasks.start_time, _task.Tasks.end_time),
  269. icon: function () {
  270. var statusIconMap = {
  271. 'pending': 'icon-cog',
  272. 'queued': 'icon-cog',
  273. 'in_progress': 'icon-cogs',
  274. 'completed': 'icon-ok',
  275. 'failed': 'icon-exclamation-sign',
  276. 'aborted': 'icon-minus',
  277. 'timedout': 'icon-time'
  278. };
  279. return statusIconMap[this.get('status')] || 'icon-cog';
  280. }.property('status')
  281. });
  282. },
  283. /**
  284. * Create hosts and tasks data structure for popup
  285. * Set data for hosts and tasks
  286. */
  287. onHostUpdate: function () {
  288. var self = this;
  289. var inputData = this.get("inputData");
  290. if (inputData) {
  291. var hostsArr = [];
  292. var hostsData;
  293. var hostsMap = {};
  294. if(this.get('isBackgroundOperations') && this.get("currentServiceId")){
  295. //hosts popup for Background Operations
  296. hostsData = inputData.findProperty("id", this.get("currentServiceId"));
  297. } else if (this.get("serviceName")) {
  298. //hosts popup for Wizards
  299. hostsData = inputData.findProperty("name", this.get("serviceName"));
  300. }
  301. if (hostsData) {
  302. if (hostsData.hostsMap) {
  303. //hosts data come from Background Operations as object map
  304. hostsMap = hostsData.hostsMap;
  305. } else if (hostsData.hosts) {
  306. //hosts data come from Wizard as array
  307. hostsData.hosts.forEach(function (_host) {
  308. hostsMap[_host.name] = _host;
  309. });
  310. }
  311. }
  312. var existedHosts = self.get('hosts');
  313. if (existedHosts && (existedHosts.length > 0) && this.get('currentServiceId') === this.get('previousServiceId')) {
  314. existedHosts.forEach(function (host) {
  315. var newHostInfo = hostsMap[host.get('name')];
  316. //update only hosts with changed tasks or currently opened tasks of host
  317. if (newHostInfo && (newHostInfo.isModified || this.get('currentHostName') === host.get('name'))) {
  318. var hostStatus = self.getStatus(newHostInfo.logTasks);
  319. var hostProgress = self.getProgress(newHostInfo.logTasks);
  320. host.set('status', App.format.taskStatus(hostStatus[0]));
  321. host.set('icon', hostStatus[1]);
  322. host.set('barColor', hostStatus[2]);
  323. host.set('isInProgress', hostStatus[3]);
  324. host.set('progress', hostProgress);
  325. host.set('barWidth', "width:" + hostProgress + "%;");
  326. host.set('logTasks', newHostInfo.logTasks);
  327. var existTasks = host.get('tasks');
  328. if (existTasks) {
  329. newHostInfo.logTasks.forEach(function (_task) {
  330. var existTask = existTasks.findProperty('id', _task.Tasks.id);
  331. if (existTask) {
  332. existTask.set('status', App.format.taskStatus(_task.Tasks.status));
  333. existTask.set('stdout', _task.Tasks.stdout);
  334. existTask.set('stderr', _task.Tasks.stderr);
  335. existTask.set('startTime', date.startTime(_task.Tasks.start_time));
  336. existTask.set('duration', date.durationSummary(_task.Tasks.start_time, _task.Tasks.end_time));
  337. } else {
  338. existTasks.pushObject(this.createTask(_task));
  339. }
  340. }, this);
  341. }
  342. }
  343. }, this);
  344. } else {
  345. for (var hostName in hostsMap) {
  346. var _host = hostsMap[hostName];
  347. var tasks = _host.logTasks;
  348. var hostInfo = Ember.Object.create({
  349. name: hostName,
  350. publicName: _host.publicName,
  351. displayName: function () {
  352. return this.get('name').length < 43 ? this.get('name') : (this.get('name').substr(0, 40) + '...');
  353. }.property('name'),
  354. progress: 0,
  355. status: App.format.taskStatus("PENDING"),
  356. serviceName: _host.serviceName,
  357. isVisible: true,
  358. icon: "icon-cog",
  359. barColor: "progress-info",
  360. barWidth: "width:0%;"
  361. });
  362. if (tasks.length) {
  363. tasks = self.sortTasksById(tasks);
  364. var hostStatus = self.getStatus(tasks);
  365. var hostProgress = self.getProgress(tasks);
  366. hostInfo.set('status', App.format.taskStatus(hostStatus[0]));
  367. hostInfo.set('icon', hostStatus[1]);
  368. hostInfo.set('barColor', hostStatus[2]);
  369. hostInfo.set('isInProgress', hostStatus[3]);
  370. hostInfo.set('progress', hostProgress);
  371. hostInfo.set('barWidth', "width:" + hostProgress + "%;");
  372. }
  373. hostInfo.set('logTasks', tasks);
  374. hostsArr.push(hostInfo);
  375. }
  376. //sort hosts by name
  377. this.sortArray(hostsArr, "name");
  378. hostsArr.setEach("serviceName", this.get("serviceName"));
  379. self.set("hosts", hostsArr);
  380. self.set('previousServiceId', this.get('currentServiceId'));
  381. }
  382. }
  383. },
  384. /**
  385. * Sort tasks by it`s id
  386. * @param tasks
  387. * @return {Array}
  388. */
  389. sortTasksById: function (tasks) {
  390. return tasks.sort(function (a, b) {
  391. return (a.Tasks.id > b.Tasks.id) ? 1 : (a.Tasks.id < b.Tasks.id) ? -1 : 0;
  392. });
  393. },
  394. /**
  395. * Show popup
  396. * @return PopupObject For testing purposes
  397. */
  398. createPopup: function () {
  399. var self = this;
  400. var hostsInfo = this.get("hosts");
  401. var servicesInfo = this.get("servicesInfo");
  402. var isBackgroundOperations = this.get('isBackgroundOperations');
  403. var categoryObject = Em.Object.extend({
  404. value: '',
  405. count: 0,
  406. labelPath: '',
  407. label: function(){
  408. return Em.I18n.t(this.get('labelPath')).format(this.get('count'));
  409. }.property('count')
  410. });
  411. self.set('isPopup', App.ModalPopup.show({
  412. //no need to track is it loaded when popup contain only list of hosts
  413. isLoaded: !isBackgroundOperations,
  414. isOpen: false,
  415. didInsertElement: function(){
  416. this._super();
  417. this.set('isOpen', true);
  418. },
  419. headerClass: Ember.View.extend({
  420. controller: this,
  421. template: Ember.Handlebars.compile('{{popupHeaderName}}')
  422. }),
  423. classNames: ['sixty-percent-width-modal', 'host-progress-popup'],
  424. // for the checkbox: do not show this dialog again
  425. hasFooterCheckbox: true,
  426. isNotShowBgChecked : null,
  427. updateNotShowBgChecked: function () {
  428. var curVal = !this.get('isNotShowBgChecked');
  429. var key = App.router.get('applicationController').persistKey();
  430. if (!App.testMode) {
  431. App.router.get('applicationController').postUserPref(key, curVal);
  432. }
  433. }.observes('isNotShowBgChecked'),
  434. autoHeight: false,
  435. closeModelPopup: function () {
  436. this.set('isOpen', false);
  437. if(isBackgroundOperations){
  438. $(this.get('element')).detach();
  439. App.router.get('backgroundOperationsController').set('levelInfo.name', 'REQUESTS_LIST');
  440. } else {
  441. this.hide();
  442. self.set('isPopup', null);
  443. }
  444. },
  445. onPrimary: function () {
  446. this.closeModelPopup();
  447. },
  448. onClose: function () {
  449. this.closeModelPopup();
  450. },
  451. secondary: null,
  452. bodyClass: Ember.View.extend({
  453. templateName: require('templates/common/host_progress_popup'),
  454. isLogWrapHidden: true,
  455. isTaskListHidden: true,
  456. isHostListHidden: true,
  457. isServiceListHidden: false,
  458. showTextArea: false,
  459. isServiceEmptyList: true,
  460. isHostEmptyList: true,
  461. isTasksEmptyList: true,
  462. controller: this,
  463. sourceRequestScheduleId: -1,
  464. sourceRequestScheduleRunning: false,
  465. sourceRequestScheduleAborted: false,
  466. sourceRequestScheduleCommand: null,
  467. hosts: self.get('hosts'),
  468. services: self.get('servicesInfo'),
  469. currentHost: function () {
  470. return this.get('hosts') && this.get('hosts').findProperty('name', this.get('controller.currentHostName'));
  471. }.property('controller.currentHostName'),
  472. tasks: function () {
  473. var currentHost = this.get('currentHost');
  474. if (currentHost) {
  475. return currentHost.get('tasks');
  476. }
  477. return [];
  478. }.property('currentHost.tasks', 'currentHost.tasks.@each.status'),
  479. /**
  480. * Preset values on init
  481. */
  482. setOnStart: function () {
  483. if (this.get("controller.isBackgroundOperations")) {
  484. this.get('controller').setSelectCount(this.get("services"), this.get('categories'));
  485. this.updateHostInfo();
  486. } else {
  487. this.set("isHostListHidden", false);
  488. this.set("isServiceListHidden", true);
  489. }
  490. },
  491. /**
  492. * force popup to show list of operations
  493. */
  494. resetState: function(){
  495. if(this.get('parentView.isOpen')){
  496. this.set('isLogWrapHidden', true);
  497. this.set('isTaskListHidden', true);
  498. this.set('isHostListHidden', true);
  499. this.set('isServiceListHidden', false);
  500. this.get("controller").setBackgroundOperationHeader(false);
  501. this.setOnStart();
  502. }
  503. }.observes('parentView.isOpen'),
  504. /**
  505. * When popup is opened, and data after polling has changed, update this data in component
  506. */
  507. updateHostInfo: function () {
  508. if(!this.get('parentView.isOpen')) return;
  509. this.set('parentView.isLoaded', false);
  510. this.get("controller").set("inputData", this.get("controller.dataSourceController.services"));
  511. this.get("controller").onServiceUpdate(this.get('isServiceListHidden'));
  512. this.get("controller").onHostUpdate();
  513. this.set('parentView.isLoaded', true);
  514. //push hosts into view when none or all hosts are loaded
  515. if(this.get('hosts') == null || this.get('hosts').length === this.get("controller.hosts").length){
  516. this.set("hosts", this.get("controller.hosts"));
  517. }
  518. this.set("services", this.get("controller.servicesInfo"));
  519. }.observes("controller.dataSourceController.serviceTimestamp"),
  520. /**
  521. * Depending on service filter, set which services should be shown
  522. */
  523. visibleServices: function () {
  524. if (this.get("services")) {
  525. this.set("isServiceEmptyList", true);
  526. if (this.get('serviceCategory.value')) {
  527. var filter = this.get('serviceCategory.value');
  528. var services = this.get('services');
  529. this.set("isServiceEmptyList", this.setVisibility(filter, services));
  530. }
  531. }
  532. }.observes('serviceCategory', 'services', 'services.@each.status'),
  533. /**
  534. * Depending on hosts filter, set which hosts should be shown
  535. */
  536. visibleHosts: function () {
  537. this.set("isHostEmptyList", true);
  538. if (this.get('hostCategory.value') && this.get('hosts')) {
  539. var filter = this.get('hostCategory.value');
  540. var hosts = this.get('hosts');
  541. this.set("isHostEmptyList", this.setVisibility(filter, hosts));
  542. }
  543. }.observes('hostCategory', 'hosts', 'hosts.@each.status'),
  544. /**
  545. * Depending on tasks filter, set which tasks should be shown
  546. */
  547. visibleTasks: function () {
  548. this.set("isTasksEmptyList", true);
  549. if (this.get('taskCategory.value') && this.get('tasks')) {
  550. var filter = this.get('taskCategory.value');
  551. var tasks = this.get('tasks');
  552. this.set("isTasksEmptyList", this.setVisibility(filter, tasks));
  553. }
  554. }.observes('taskCategory', 'tasks', 'tasks.@each.status'),
  555. /**
  556. * Depending on selected filter type, set object visibility value
  557. * @param filter
  558. * @param obj
  559. * @return {Boolean} isEmptyList
  560. */
  561. setVisibility: function (filter, obj) {
  562. var isEmptyList = true;
  563. if (filter == "all") {
  564. obj.setEach("isVisible", true);
  565. isEmptyList = !(obj.length > 0);
  566. } else {
  567. obj.forEach(function(item){
  568. if (filter == "pending") {
  569. item.set('isVisible', ["pending", "queued"].contains(item.status));
  570. } else if (filter == "in_progress") {
  571. item.set('isVisible', ["in_progress", "upgrading"].contains(item.status));
  572. } else if (filter == "failed") {
  573. item.set('isVisible', (item.status === "failed"));
  574. } else if (filter == "completed") {
  575. item.set('isVisible', ["completed", "success"].contains(item.status));
  576. } else if (filter == "aborted") {
  577. item.set('isVisible', (item.status === "aborted"));
  578. } else if (filter == "timedout") {
  579. item.set('isVisible', (item.status === "timedout"));
  580. }
  581. isEmptyList = (isEmptyList) ? !item.get('isVisible') : false;
  582. })
  583. }
  584. return isEmptyList;
  585. },
  586. /**
  587. * Select box, display names and values
  588. */
  589. categories: [
  590. categoryObject.create({value: 'all', labelPath: 'hostPopup.status.category.all'}),
  591. categoryObject.create({value: 'pending', labelPath: 'hostPopup.status.category.pending'}),
  592. categoryObject.create({value: 'in_progress', labelPath: 'hostPopup.status.category.inProgress'}),
  593. categoryObject.create({value: 'failed', labelPath: 'hostPopup.status.category.failed'}),
  594. categoryObject.create({value: 'completed', labelPath: 'hostPopup.status.category.success'}),
  595. categoryObject.create({value: 'aborted', labelPath: 'hostPopup.status.category.aborted'}),
  596. categoryObject.create({value: 'timedout', labelPath: 'hostPopup.status.category.timedout'})
  597. ],
  598. /**
  599. * Selected option is binded to this values
  600. */
  601. serviceCategory: null,
  602. hostCategory: null,
  603. taskCategory: null,
  604. /**
  605. * Depending on currently viewed tab, call setSelectCount function
  606. */
  607. updateSelectView: function () {
  608. if (!this.get('isHostListHidden')) {
  609. //since lazy loading used for hosts, we need to get hosts info directly from controller, that always contains entire array of data
  610. this.get('controller').setSelectCount(this.get("controller.hosts"), this.get('categories'));
  611. } else if (!this.get('isTaskListHidden')) {
  612. this.get('controller').setSelectCount(this.get("tasks"), this.get('categories'));
  613. } else if (!this.get('isServiceListHidden')) {
  614. this.get('controller').setSelectCount(this.get("services"), this.get('categories'));
  615. }
  616. }.observes('tasks.@each.status', 'hosts.@each.status', 'isTaskListHidden', 'isHostListHidden', 'services.length', 'services.@each.status'),
  617. /**
  618. * control data uploading, depending on which display level is showed
  619. * @param levelName
  620. */
  621. switchLevel: function (levelName) {
  622. if (this.get("controller.isBackgroundOperations")) {
  623. var BGController = App.router.get('backgroundOperationsController');
  624. var levelInfo = BGController.get('levelInfo');
  625. levelInfo.set('taskId', this.get('openedTaskId'));
  626. levelInfo.set('requestId', this.get('controller.currentServiceId'));
  627. levelInfo.set('name', levelName);
  628. if (levelName === 'HOSTS_LIST') {
  629. levelInfo.set('sync', (this.get('controller.hosts').length === 0));
  630. BGController.requestMostRecent();
  631. } else if (levelName === 'TASK_DETAILS') {
  632. levelInfo.set('sync', true);
  633. BGController.requestMostRecent();
  634. } else if (levelName === 'REQUESTS_LIST') {
  635. this.get('controller.hosts').clear();
  636. BGController.requestMostRecent();
  637. }
  638. }
  639. },
  640. /**
  641. * Onclick handler for button <-Tasks
  642. * @param event
  643. * @param context
  644. */
  645. backToTaskList: function (event, context) {
  646. this.destroyClipBoard();
  647. this.set("openedTaskId", 0);
  648. this.set("isLogWrapHidden", true);
  649. this.set("isTaskListHidden", false);
  650. },
  651. /**
  652. * Onclick handler for button <-Hosts
  653. * @param event
  654. * @param context
  655. */
  656. backToHostList: function (event, context) {
  657. this.set("isHostListHidden", false);
  658. this.set("isTaskListHidden", true);
  659. this.get("controller").set("popupHeaderName", this.get("controller.serviceName"));
  660. this.switchLevel("HOSTS_LIST");
  661. },
  662. /**
  663. * Onclick handler for button <-Services
  664. * @param event
  665. * @param context
  666. */
  667. backToServiceList: function (event, context) {
  668. this.get("controller").set("serviceName", "");
  669. this.set("isHostListHidden", true);
  670. this.set("isServiceListHidden", false);
  671. this.set("isTaskListHidden", true);
  672. this.set("hosts", null);
  673. this.get("controller").setBackgroundOperationHeader(false);
  674. this.switchLevel("REQUESTS_LIST");
  675. },
  676. /**
  677. * Onclick handler for selected Service
  678. * @param event
  679. * @param context
  680. */
  681. gotoHosts: function (event, context) {
  682. this.get("controller").set("serviceName", event.context.get("name"));
  683. this.get("controller").set("currentServiceId", event.context.get("id"));
  684. this.get("controller").set("currentHostName", null);
  685. this.get("controller").onHostUpdate();
  686. this.switchLevel("HOSTS_LIST");
  687. var servicesInfo = this.get("controller.hosts");
  688. if (servicesInfo.length) {
  689. this.get("controller").set("popupHeaderName", event.context.get("name"));
  690. }
  691. //apply lazy loading on cluster with more than 100 nodes
  692. if (servicesInfo.length > 100) {
  693. this.set('hosts', servicesInfo.slice(0, 50));
  694. } else {
  695. this.set('hosts', servicesInfo);
  696. }
  697. this.set("isServiceListHidden", true);
  698. this.set("isHostListHidden", false);
  699. $(".modal").scrollTop(0);
  700. $(".modal-body").scrollTop(0);
  701. if (servicesInfo.length > 100) {
  702. Ember.run.next(this, function(){
  703. this.set('hosts', this.get('hosts').concat(servicesInfo.slice(50, servicesInfo.length)));
  704. });
  705. }
  706. // Determine if source request schedule is present
  707. this.set('sourceRequestScheduleId', event.context.get("sourceRequestScheduleId"));
  708. this.set('sourceRequestScheduleCommand', event.context.get('contextCommand'));
  709. this.refreshRequestScheduleInfo();
  710. },
  711. isRequestSchedule : function() {
  712. var id = this.get('sourceRequestScheduleId');
  713. return id != null && !isNaN(id) && id > -1;
  714. }.property('sourceRequestScheduleId'),
  715. refreshRequestScheduleInfo : function() {
  716. var self = this;
  717. var id = this.get('sourceRequestScheduleId');
  718. batchUtils.getRequestSchedule(id, function(data) {
  719. if (data != null && data.RequestSchedule != null &&
  720. data.RequestSchedule.status != null) {
  721. switch (data.RequestSchedule.status) {
  722. case 'DISABLED':
  723. self.set('sourceRequestScheduleRunning', false);
  724. self.set('sourceRequestScheduleAborted', true);
  725. break;
  726. case 'COMPLETED':
  727. self.set('sourceRequestScheduleRunning', false);
  728. self.set('sourceRequestScheduleAborted', false);
  729. break;
  730. case 'SCHEDULED':
  731. self.set('sourceRequestScheduleRunning', true);
  732. self.set('sourceRequestScheduleAborted', false);
  733. break;
  734. }
  735. } else {
  736. self.set('sourceRequestScheduleRunning', false);
  737. self.set('sourceRequestScheduleAborted', false);
  738. }
  739. }, function(xhr, textStatus, error, opt) {
  740. console.log("Error getting request schedule information: ", textStatus, error, opt);
  741. self.set('sourceRequestScheduleRunning', false);
  742. self.set('sourceRequestScheduleAborted', false);
  743. });
  744. }.observes('sourceRequestScheduleId'),
  745. /**
  746. * Attempts to abort the current request schedule
  747. */
  748. doAbortRequestSchedule: function(event){
  749. var self = this;
  750. var id = event.context;
  751. console.log("Aborting request schedule: ", id);
  752. batchUtils.doAbortRequestSchedule(id, function(){
  753. self.refreshRequestScheduleInfo();
  754. });
  755. },
  756. requestScheduleAbortLabel : function() {
  757. var label = Em.I18n.t("common.abort");
  758. var command = this.get('sourceRequestScheduleCommand');
  759. if (command != null && "ROLLING-RESTART" == command) {
  760. label = Em.I18n.t("hostPopup.bgop.abort.rollingRestart");
  761. }
  762. return label;
  763. }.property('sourceRequestScheduleCommand'),
  764. /**
  765. * Onclick handler for selected Host
  766. * @param event
  767. * @param context
  768. */
  769. gotoTasks: function (event, context) {
  770. var tasksInfo = [];
  771. event.context.logTasks.forEach(function (_task) {
  772. tasksInfo.pushObject(this.get("controller").createTask(_task));
  773. }, this);
  774. if (tasksInfo.length) {
  775. this.get("controller").set("popupHeaderName", event.context.publicName);
  776. this.get("controller").set("currentHostName", event.context.publicName);
  777. }
  778. this.switchLevel("TASKS_LIST");
  779. this.set('currentHost.tasks', tasksInfo);
  780. this.set("isHostListHidden", true);
  781. this.set("isTaskListHidden", false);
  782. $(".modal").scrollTop(0);
  783. $(".modal-body").scrollTop(0);
  784. },
  785. /**
  786. * Onclick handler for selected Task
  787. */
  788. openTaskLogInDialog: function () {
  789. if ($(".task-detail-log-clipboard").length > 0) {
  790. this.destroyClipBoard();
  791. }
  792. var newWindow = window.open();
  793. var newDocument = newWindow.document;
  794. newDocument.write($(".task-detail-log-info").html());
  795. newDocument.close();
  796. },
  797. openedTaskId: 0,
  798. /**
  799. * Return task detail info of opened task
  800. */
  801. openedTask: function () {
  802. if (!this.get('openedTaskId')) {
  803. return Ember.Object.create();
  804. }
  805. return this.get('tasks').findProperty('id', this.get('openedTaskId'));
  806. }.property('tasks', 'tasks.@each.stderr', 'tasks.@each.stdout', 'openedTaskId'),
  807. /**
  808. * Onclick event for show task detail info
  809. * @param event
  810. * @param context
  811. */
  812. toggleTaskLog: function (event, context) {
  813. var taskInfo = event.context;
  814. this.set("isLogWrapHidden", false);
  815. if ($(".task-detail-log-clipboard").length > 0) {
  816. this.destroyClipBoard();
  817. }
  818. this.set("isHostListHidden", true);
  819. this.set("isTaskListHidden", true);
  820. this.set('openedTaskId', taskInfo.id);
  821. this.switchLevel("TASK_DETAILS");
  822. $(".modal").scrollTop(0);
  823. $(".modal-body").scrollTop(0);
  824. },
  825. /**
  826. * Onclick event for copy to clipboard button
  827. * @param event
  828. */
  829. textTrigger: function (event) {
  830. if ($(".task-detail-log-clipboard").length > 0) {
  831. this.destroyClipBoard();
  832. } else {
  833. this.createClipBoard();
  834. }
  835. },
  836. /**
  837. * Create Clip Board
  838. */
  839. createClipBoard: function () {
  840. var logElement = $(".task-detail-log-maintext");
  841. $(".task-detail-log-clipboard-wrap").html('<textarea class="task-detail-log-clipboard"></textarea>');
  842. $(".task-detail-log-clipboard")
  843. .html("stderr: \n" + $(".stderr").html() + "\n stdout:\n" + $(".stdout").html())
  844. .css("display", "block")
  845. .width(logElement.width())
  846. .height(logElement.height())
  847. .select();
  848. logElement.css("display", "none")
  849. },
  850. /**
  851. * Destroy Clip Board
  852. */
  853. destroyClipBoard: function () {
  854. $(".task-detail-log-clipboard").remove();
  855. $(".task-detail-log-maintext").css("display", "block");
  856. }
  857. })
  858. }));
  859. return self.get('isPopup');
  860. }
  861. });