step6_controller.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  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 db = require('utils/db');
  20. /**
  21. * By Step 6, we have the following information stored in App.db and set on this
  22. * controller by the router:
  23. *
  24. * hosts: App.db.hosts (list of all hosts the user selected in Step 3)
  25. * selectedServiceNames: App.db.selectedServiceNames (the services that the user selected in Step 4)
  26. * masterComponentHosts: App.db.masterComponentHosts (master-components-to-hosts mapping the user selected in Step 5)
  27. *
  28. * Step 6 will set the following information in App.db:
  29. * slaveComponentHosts: App.db.slaveComponentHosts (slave-components-to-hosts mapping the user selected in Step 6)
  30. *
  31. */
  32. App.WizardStep6Controller = Em.Controller.extend({
  33. /**
  34. * List of hosts
  35. * @type {object[]}
  36. */
  37. hosts: [],
  38. /**
  39. * List of components info about selecting/deselecting status for components.
  40. *
  41. * @type {Array}
  42. * @item {Em.Object}
  43. * @property name {String} - component name
  44. * @property label {String} - component display name
  45. * @property allChecked {bool} - all checkboxes are checked
  46. * @property noChecked {bool} - no checkboxes checked
  47. */
  48. headers: [],
  49. /**
  50. * @type {bool}
  51. */
  52. isLoaded: false,
  53. /**
  54. * Check if <code>addHostWizard</code> used
  55. * @type {bool}
  56. */
  57. isAddHostWizard: function () {
  58. return this.get('content.controllerName') === 'addHostController';
  59. }.property('content.controllerName'),
  60. /**
  61. * Check if <code>installerWizard</code> used
  62. * @type {bool}
  63. */
  64. isInstallerWizard: function () {
  65. return this.get('content.controllerName') === 'installerController';
  66. }.property('content.controllerName'),
  67. /**
  68. * Check if <code>addServiceWizard</code> used
  69. * @type {bool}
  70. */
  71. isAddServiceWizard: function () {
  72. return this.get('content.controllerName') === 'addServiceController';
  73. }.property('content.controllerName'),
  74. /**
  75. * Verify condition that at least one checkbox of each component was checked
  76. * @method clearError
  77. */
  78. clearError: function () {
  79. var self = this;
  80. var isError = false;
  81. var err = false;
  82. var hosts = this.get('hosts');
  83. var headers = this.get('headers');
  84. var headersMap = {};
  85. headers.forEach(function (header) {
  86. headersMap[header.name] = true;
  87. });
  88. hosts.forEach(function (host) {
  89. host.get('checkboxes').forEach(function (checkbox) {
  90. if (headersMap[checkbox.get('component')]) {
  91. headersMap[checkbox.get('component')] = !checkbox.get('checked');
  92. }
  93. });
  94. });
  95. for (var i in headersMap) {
  96. err |= headersMap[i];
  97. }
  98. if (!err) {
  99. this.set('errorMessage', '');
  100. }
  101. if (this.get('isAddHostWizard')) {
  102. hosts.forEach(function (host) {
  103. isError = false;
  104. headers.forEach(function (header) {
  105. isError |= host.get('checkboxes').findProperty('title', header.get('label')).checked;
  106. });
  107. isError = !isError;
  108. if (!isError) {
  109. self.set('errorMessage', '');
  110. }
  111. });
  112. }
  113. },
  114. /**
  115. * Clear Step6 data like <code>hosts</code>, <code>headers</code> etc
  116. * @method clearStep
  117. */
  118. clearStep: function () {
  119. this.set('hosts', []);
  120. this.set('headers', []);
  121. this.clearError();
  122. this.set('isLoaded', false);
  123. },
  124. /**
  125. * Enable some service for all hosts
  126. * @param {object} event
  127. * @method selectAllNodes
  128. */
  129. selectAllNodes: function (event) {
  130. var name = Em.get(event, 'context.name');
  131. if (name) {
  132. this.setAllNodes(name, true);
  133. }
  134. },
  135. /**
  136. * Disable some services for all hosts
  137. * @param {object} event
  138. * @method deselectAllNodes
  139. */
  140. deselectAllNodes: function (event) {
  141. var name = Em.get(event, 'context.name');
  142. if (name) {
  143. this.setAllNodes(name, false);
  144. }
  145. },
  146. /**
  147. * Enable/disable some service for all hosts
  148. * @param {String} component - component name
  149. * @param {bool} checked - true - enable, false - disable
  150. * @method setAllNodes
  151. */
  152. setAllNodes: function (component, checked) {
  153. this.get('hosts').forEach(function (host) {
  154. host.get('checkboxes').filterProperty('isInstalled', false).forEach(function (checkbox) {
  155. if (checkbox.get('component') === component) {
  156. checkbox.set('checked', checked);
  157. }
  158. });
  159. });
  160. this.checkCallback(component);
  161. },
  162. /**
  163. * Return whether service was selected or not
  164. * @param {string} name serviceName
  165. * @return {bool}
  166. * @method isServiceSelected
  167. */
  168. isServiceSelected: function (name) {
  169. var serviceName = this.get('content.services').findProperty('serviceName', name);
  170. if (!serviceName) {
  171. return !!serviceName;
  172. }
  173. return serviceName.get('isSelected') || serviceName.get('isInstalled');
  174. },
  175. /**
  176. * Checkbox check callback
  177. * Verify if all/none checkboxes for current component are checked
  178. * @param {String} component
  179. * @method checkCallback
  180. */
  181. checkCallback: function (component) {
  182. var header = this.get('headers').findProperty('name', component);
  183. if (header) {
  184. var hosts = this.get('hosts');
  185. var allTrue = true;
  186. var allFalse = true;
  187. hosts.forEach(function (host) {
  188. host.get('checkboxes').forEach(function (checkbox) {
  189. if (checkbox.get('component') === component && !checkbox.get('isInstalled')) {
  190. allTrue = allTrue && checkbox.get('checked');
  191. allFalse = allFalse && !checkbox.get('checked');
  192. }
  193. });
  194. });
  195. header.set('allChecked', allTrue);
  196. header.set('noChecked', allFalse);
  197. }
  198. this.clearError();
  199. },
  200. /**
  201. * Init step6 data
  202. * @method loadStep
  203. */
  204. loadStep: function () {
  205. var self = this;
  206. console.log("WizardStep6Controller: Loading step6: Assign Slaves");
  207. this.clearStep();
  208. var selectedServices = App.StackService.find().filterProperty('isSelected');
  209. var installedServices = App.StackService.find().filterProperty('isInstalled');
  210. var services;
  211. if (this.get('isInstallerWizard')) services = selectedServices;
  212. else if (this.get('isAddHostWizard')) services = installedServices;
  213. else if (this.get('isAddServiceWizard')) services = installedServices.concat(selectedServices);
  214. var headers = Em.A([]);
  215. services.forEach(function (stackService) {
  216. stackService.get('serviceComponents').forEach(function (serviceComponent) {
  217. if (serviceComponent.get('isShownOnInstallerSlaveClientPage')) {
  218. headers.pushObject(Em.Object.create({
  219. name: serviceComponent.get('componentName'),
  220. label: serviceComponent.get('displayName'),
  221. allChecked: false,
  222. noChecked: true
  223. }));
  224. }
  225. }, this);
  226. }, this);
  227. headers.pushObject(Em.Object.create({
  228. name: 'CLIENT',
  229. label: App.format.role('CLIENT'),
  230. allChecked: false,
  231. noChecked: true
  232. }));
  233. this.get('headers').pushObjects(headers);
  234. this.render();
  235. if (this.get('content.skipSlavesStep')) {
  236. App.router.send('next');
  237. }
  238. },
  239. /**
  240. * Get active host names
  241. * @return {string[]}
  242. * @method getHostNames
  243. */
  244. getHostNames: function () {
  245. var hostInfo = this.get('content.hosts');
  246. var hostNames = [];
  247. //flag identify whether get all hosts or only uninstalled(newly added) hosts
  248. var getUninstalledHosts = (this.get('content.controllerName') !== 'addServiceController');
  249. for (var index in hostInfo) {
  250. if (hostInfo.hasOwnProperty(index)) {
  251. if (hostInfo[index].bootStatus === 'REGISTERED') {
  252. if(!getUninstalledHosts || !hostInfo[index].isInstalled) {
  253. hostNames.push(hostInfo[index].name);
  254. }
  255. }
  256. }
  257. }
  258. return hostNames;
  259. },
  260. /**
  261. * Load all data needed for this module. Then it automatically renders in template
  262. * @method render
  263. */
  264. render: function () {
  265. var hostsObj = [],
  266. masterHosts = [],
  267. headers = this.get('headers'),
  268. masterHostNames = this.get('content.masterComponentHosts').mapProperty('hostName').uniq();
  269. this.getHostNames().forEach(function (_hostName) {
  270. var hasMaster = masterHostNames.contains(_hostName);
  271. var obj = Em.Object.create({
  272. hostName: _hostName,
  273. hasMaster: hasMaster,
  274. checkboxes: []
  275. });
  276. headers.forEach(function (header) {
  277. obj.checkboxes.pushObject(Em.Object.create({
  278. component: header.name,
  279. title: header.label,
  280. checked: false,
  281. isInstalled: false
  282. }));
  283. });
  284. if (hasMaster) {
  285. masterHosts.pushObject(obj)
  286. } else {
  287. hostsObj.pushObject(obj);
  288. }
  289. });
  290. //hosts with master components should be in the beginning of list
  291. hostsObj.unshift.apply(hostsObj, masterHosts);
  292. hostsObj = this.renderSlaves(hostsObj);
  293. this.set('hosts', hostsObj);
  294. headers.forEach(function (header) {
  295. this.checkCallback(header.get('name'));
  296. }, this);
  297. this.set('isLoaded', true);
  298. },
  299. /**
  300. * Set checked values for slaves checkboxes
  301. * @param {Array} hostsObj
  302. * @return {Array}
  303. * @method renderSlaves
  304. */
  305. renderSlaves: function (hostsObj) {
  306. var headers = this.get('headers');
  307. var slaveComponents = this.get('content.slaveComponentHosts');
  308. if (!slaveComponents) { // we are at this page for the first time
  309. var client_is_set = false;
  310. hostsObj.forEach(function (host) {
  311. var checkboxes = host.get('checkboxes');
  312. checkboxes.setEach('checked', !host.hasMaster);
  313. checkboxes.setEach('isInstalled', false);
  314. checkboxes.findProperty('title', headers.findProperty('name', 'CLIENT').get('label')).set('checked', false);
  315. // First not Master should have Client (only first!)
  316. if (!client_is_set) {
  317. var dfs = App.StackService.find().findProperty('isPrimaryDFS');
  318. if (dfs.get('isSelected') || dfs.get('isInstalled')) {
  319. var checkboxServiceComponent = checkboxes.findProperty('title', headers.findProperty('name', dfs.get('serviceComponents').
  320. findProperty('isShownOnInstallerSlaveClientPage').get('componentName')).get('label'));
  321. if (checkboxServiceComponent && checkboxServiceComponent.get('checked')) {
  322. checkboxes.findProperty('title', headers.findProperty('name', 'CLIENT').get('label')).set('checked', true);
  323. client_is_set = true;
  324. }
  325. }
  326. }
  327. });
  328. if (this.get('isInstallerWizard') && hostsObj.everyProperty('hasMaster', true)) {
  329. var lastHost = hostsObj[hostsObj.length - 1];
  330. lastHost.get('checkboxes').setEach('checked', true);
  331. }
  332. } else {
  333. this.get('headers').forEach(function (header) {
  334. var nodes = slaveComponents.findProperty('componentName', header.get('name'));
  335. if (nodes) {
  336. nodes.hosts.forEach(function (_node) {
  337. var node = hostsObj.findProperty('hostName', _node.hostName);
  338. if (node) {
  339. node.get('checkboxes').findProperty('title', header.get('label')).set('checked', true);
  340. node.get('checkboxes').findProperty('title', header.get('label')).set('isInstalled', _node.isInstalled);
  341. }
  342. });
  343. }
  344. });
  345. }
  346. return hostsObj;
  347. },
  348. /**
  349. * Select checkboxes which correspond to master components
  350. *
  351. * @param {Array} hostsObj
  352. * @return {Array}
  353. * @method selectMasterComponents
  354. */
  355. selectMasterComponents: function (hostsObj) {
  356. var masterComponentHosts = this.get('content.masterComponentHosts');
  357. console.log('Master components selected on:', masterComponentHosts.mapProperty('hostName').uniq().join(", "));
  358. if (masterComponentHosts) {
  359. masterComponentHosts.forEach(function (item) {
  360. var host = hostsObj.findProperty('hostName', item.hostName);
  361. if (host) {
  362. var checkbox = host.get('checkboxes').findProperty('component', item.component);
  363. if (checkbox) {
  364. checkbox.set('checked', true);
  365. }
  366. }
  367. });
  368. }
  369. return hostsObj;
  370. },
  371. /**
  372. * Return list of master components for specified <code>hostname</code>
  373. * @param {string} hostName
  374. * @return {string[]}
  375. * @method getMasterComponentsForHost
  376. */
  377. getMasterComponentsForHost: function (hostName) {
  378. return this.get('content.masterComponentHosts').filterProperty('hostName', hostName).mapProperty('component');
  379. },
  380. /**
  381. * Validate form. Return do we have errors or not
  382. * @return {bool}
  383. * @method validate
  384. */
  385. validate: function () {
  386. if (this.get('isAddHostWizard')) {
  387. return this.validateEachHost(Em.I18n.t('installer.step6.error.mustSelectOneForHost'));
  388. }
  389. else {
  390. if (this.get('isInstallerWizard')) {
  391. return this.validateEachComponent() && this.validateEachHost(Em.I18n.t('installer.step6.error.mustSelectOneForSlaveHost'));
  392. }
  393. else {
  394. if (this.get('isAddServiceWizard')) {
  395. return this.validateEachComponent();
  396. }
  397. return true;
  398. }
  399. }
  400. },
  401. /**
  402. * Validate all components for each host. Return do we have errors or not
  403. * @return {bool}
  404. * @method validateEachHost
  405. */
  406. validateEachHost: function (errorMsg) {
  407. var isError = false;
  408. var hosts = this.get('hosts');
  409. var headers = this.get('headers');
  410. for (var i = 0; i < hosts.length; i++) {
  411. if (this.get('isInstallerWizard') && this.get('content.masterComponentHosts').someProperty('hostName', hosts[i].hostName)) {
  412. continue;
  413. }
  414. var checkboxes = hosts[i].get('checkboxes');
  415. isError = false;
  416. headers.forEach(function (header) {
  417. isError = isError || checkboxes.findProperty('title', header.get('label')).checked;
  418. });
  419. isError = !isError;
  420. if (isError) {
  421. this.set('errorMessage', errorMsg);
  422. break;
  423. }
  424. }
  425. return !isError;
  426. },
  427. /**
  428. * Validate a component for all hosts. Return do we have errors or not
  429. * @return {bool}
  430. * @method validateEachComponent
  431. */
  432. validateEachComponent: function () {
  433. var isError = false;
  434. var hosts = this.get('hosts');
  435. var headers = this.get('headers');
  436. headers.forEach(function (header) {
  437. var all_false = true;
  438. hosts.forEach(function (host) {
  439. var checkboxes = host.get('checkboxes');
  440. all_false = all_false && !checkboxes.findProperty('title', header.get('label')).checked;
  441. });
  442. isError = isError || all_false;
  443. });
  444. if (isError) {
  445. this.set('errorMessage', Em.I18n.t('installer.step6.error.mustSelectOne'));
  446. }
  447. return !isError;
  448. }
  449. });