configs.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759
  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. App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, App.ServerValidatorMixin, App.EnhancedConfigsMixin, App.ThemesMappingMixin, App.ConfigsSaverMixin, App.ConfigsComparator, App.ComponentActionsByConfigs, {
  21. name: 'mainServiceInfoConfigsController',
  22. isHostsConfigsPage: false,
  23. isRecommendedLoaded: true,
  24. dataIsLoaded: false,
  25. stepConfigs: [], //contains all field properties that are viewed in this service
  26. selectedService: null,
  27. selectedConfigGroup: null,
  28. requestsInProgress: [],
  29. groupsStore: App.ServiceConfigGroup.find(),
  30. /**
  31. * config groups for current service
  32. * @type {App.ConfigGroup[]}
  33. */
  34. configGroups: function() {
  35. return this.get('groupsStore').filterProperty('serviceName', this.get('content.serviceName'));
  36. }.property('content.serviceName', 'groupsStore.@each.serviceName'),
  37. dependentConfigGroups: function() {
  38. if (this.get('dependentServiceNames.length') === 0) return [];
  39. return this.get('groupsStore').filter(function(group) {
  40. return this.get('dependentServiceNames').contains(group.get('serviceName'));
  41. }, this);
  42. }.property('content.serviceName', 'dependentServiceNames', 'groupsStore.length', 'groupsStore.@each.name'),
  43. allConfigs: [],
  44. /**
  45. * Determines if save configs is in progress
  46. * @type {boolean}
  47. */
  48. saveInProgress: false,
  49. isCompareMode: false,
  50. preSelectedConfigVersion: null,
  51. /**
  52. * contain Service Config Property, when user proceed from Select Config Group dialog
  53. */
  54. overrideToAdd: null,
  55. /**
  56. * version selected to view
  57. */
  58. selectedVersion: null,
  59. /**
  60. * note passed on configs save
  61. * @type {string}
  62. */
  63. serviceConfigVersionNote: '',
  64. versionLoaded: false,
  65. /**
  66. * Determines when data about config groups is loaded
  67. * Including recommendations with information about hosts in the each group
  68. * @type {boolean}
  69. */
  70. configGroupsAreLoaded: false,
  71. dependentServiceNames: [],
  72. /**
  73. * defines which service configs need to be loaded to stepConfigs
  74. * @type {string[]}
  75. */
  76. servicesToLoad: function() {
  77. return [this.get('content.serviceName')].concat(this.get('dependentServiceNames')).uniq();
  78. }.property('content.serviceName', 'dependentServiceNames.length'),
  79. /**
  80. * @type {boolean}
  81. */
  82. isCurrentSelected: function () {
  83. return App.ServiceConfigVersion.find(this.get('content.serviceName') + "_" + this.get('selectedVersion')).get('isCurrent');
  84. }.property('selectedVersion', 'content.serviceName', 'dataIsLoaded', 'versionLoaded'),
  85. /**
  86. * @type {boolean}
  87. */
  88. canEdit: function () {
  89. return (this.get('selectedVersion') == this.get('currentDefaultVersion') || !this.get('selectedConfigGroup.isDefault'))
  90. && !this.get('isCompareMode') && App.isAuthorized('SERVICE.MODIFY_CONFIGS');
  91. }.property('selectedVersion', 'isCompareMode', 'currentDefaultVersion', 'selectedConfigGroup.isDefault'),
  92. serviceConfigs: Em.computed.alias('App.config.preDefinedServiceConfigs'),
  93. /**
  94. * Number of errors in the configs in the selected service (only for AdvancedTab if App supports Enhanced Configs)
  95. * @type {number}
  96. */
  97. errorsCount: function() {
  98. return this.get('selectedService.configsWithErrors').filter(function(c) {
  99. return Em.isNone(c.get('widget'));
  100. }).length;
  101. }.property('selectedService.configsWithErrors'),
  102. /**
  103. * Determines if Save-button should be disabled
  104. * Disabled if some configs have invalid values for selected service
  105. * or save-process currently in progress
  106. *
  107. * @type {boolean}
  108. */
  109. isSubmitDisabled: function () {
  110. if (!this.get('selectedService')) return true;
  111. return this.get('selectedService').get('errorCount') !== 0 || this.get('saveInProgress');
  112. }.property('selectedService.errorCount', 'saveInProgress'),
  113. /**
  114. * Determines if some config value is changed
  115. * @type {boolean}
  116. */
  117. isPropertiesChanged: Em.computed.alias('selectedService.isPropertiesChanged'),
  118. /**
  119. * Filter text will be located here
  120. * @type {string}
  121. */
  122. filter: '',
  123. /**
  124. * List of filters for config properties to populate filter combobox
  125. * @type {{attributeName: string, attributeValue: boolean, caption: string}[]}
  126. */
  127. propertyFilters: [
  128. {
  129. attributeName: 'isOverridden',
  130. attributeValue: true,
  131. caption: 'common.combobox.dropdown.overridden'
  132. },
  133. {
  134. attributeName: 'isFinal',
  135. attributeValue: true,
  136. caption: 'common.combobox.dropdown.final'
  137. },
  138. {
  139. attributeName: 'hasCompareDiffs',
  140. attributeValue: true,
  141. caption: 'common.combobox.dropdown.changed',
  142. dependentOn: 'isCompareMode'
  143. },
  144. {
  145. attributeName: 'hasIssues',
  146. attributeValue: true,
  147. caption: 'common.combobox.dropdown.issues'
  148. }
  149. ],
  150. /**
  151. * Dropdown menu items in filter combobox
  152. * @type {{attributeName: string, attributeValue: string, name: string, selected: boolean}[]}
  153. */
  154. filterColumns: function () {
  155. var filterColumns = [];
  156. this.get('propertyFilters').forEach(function(filter) {
  157. if (Em.isNone(filter.dependentOn) || this.get(filter.dependentOn)) {
  158. filterColumns.push(Ember.Object.create({
  159. attributeName: filter.attributeName,
  160. attributeValue: filter.attributeValue,
  161. name: this.t(filter.caption),
  162. selected: filter.dependentOn ? this.get(filter.dependentOn) : false
  163. }));
  164. }
  165. }, this);
  166. return filterColumns;
  167. }.property('propertyFilters', 'isCompareMode'),
  168. /**
  169. * Detects of some of the `password`-configs has not default value
  170. *
  171. * @type {boolean}
  172. */
  173. passwordConfigsAreChanged: function () {
  174. return this.get('stepConfigs')
  175. .findProperty('serviceName', this.get('selectedService.serviceName'))
  176. .get('configs')
  177. .filterProperty('displayType', 'password')
  178. .someProperty('isNotDefaultValue');
  179. }.property('stepConfigs.[].configs', 'selectedService.serviceName'),
  180. /**
  181. * indicate whether service config version belongs to default config group
  182. * @param {object} version
  183. * @return {Boolean}
  184. * @private
  185. * @method isVersionDefault
  186. */
  187. isVersionDefault: function(version) {
  188. return (App.ServiceConfigVersion.find(this.get('content.serviceName') + "_" + version).get('groupName') === 'default');
  189. },
  190. /**
  191. * register request to view to track his progress
  192. * @param {$.ajax} request
  193. * @method trackRequest
  194. */
  195. trackRequest: function (request) {
  196. this.get('requestsInProgress').push(request);
  197. },
  198. /**
  199. * clear and set properties to default value
  200. * @method clearStep
  201. */
  202. clearStep: function () {
  203. this.get('requestsInProgress').forEach(function(r) {
  204. if (r && r.readyState !== 4) {
  205. r.abort();
  206. }
  207. });
  208. this.get('requestsInProgress').clear();
  209. App.set('componentToBeAdded', {});
  210. App.set('componentToBeDeleted', {});
  211. this.clearLoadInfo();
  212. this.clearSaveInfo();
  213. this.clearRecommendationsInfo();
  214. this.clearAllRecommendations();
  215. this.setProperties({
  216. saveInProgress: false,
  217. isInit: true,
  218. hash: null,
  219. dataIsLoaded: false,
  220. versionLoaded: false,
  221. filter: '',
  222. serviceConfigVersionNote: '',
  223. dependentServiceNames: [],
  224. configGroupsAreLoaded: false
  225. });
  226. this.get('filterColumns').setEach('selected', false);
  227. this.clearConfigs();
  228. },
  229. clearConfigs: function() {
  230. this.get('selectedConfigGroup', null);
  231. this.get('allConfigs').invoke('destroy');
  232. this.get('stepConfigs').invoke('destroy');
  233. this.set('stepConfigs', []);
  234. this.set('allConfigs', []);
  235. this.set('selectedService', null);
  236. },
  237. /**
  238. * "Finger-print" of the <code>stepConfigs</code>. Filled after first configGroup selecting
  239. * Used to determine if some changes were made (when user navigates away from this page)
  240. * @type {String|null}
  241. */
  242. hash: null,
  243. /**
  244. * Is this initial config group changing
  245. * @type {Boolean}
  246. */
  247. isInit: true,
  248. /**
  249. * On load function
  250. * @method loadStep
  251. */
  252. loadStep: function () {
  253. var serviceName = this.get('content.serviceName');
  254. this.clearStep();
  255. this.set('dependentServiceNames', App.StackService.find(serviceName).get('dependentServiceNames'));
  256. this.loadConfigTheme(serviceName).always(this.loadCurrentVersions.bind(this));
  257. this.loadServiceConfigVersions();
  258. },
  259. /**
  260. * Generate "finger-print" for current <code>stepConfigs[0]</code>
  261. * Used to determine, if user has some unsaved changes (comparing with <code>hash</code>)
  262. * @returns {string|null}
  263. * @method getHash
  264. */
  265. getHash: function () {
  266. if (!this.get('selectedService.configs.length')) {
  267. return null;
  268. }
  269. var hash = {};
  270. this.get('selectedService.configs').forEach(function (config) {
  271. hash[config.get('name')] = {value: App.config.formatPropertyValue(config), overrides: [], isFinal: config.get('isFinal')};
  272. if (!config.get('overrides')) return;
  273. if (!config.get('overrides.length')) return;
  274. config.get('overrides').forEach(function (override) {
  275. hash[config.get('name')].overrides.push(App.config.formatPropertyValue(override));
  276. });
  277. });
  278. return JSON.stringify(hash);
  279. },
  280. parseConfigData: function(data) {
  281. this.prepareConfigObjects(data, this.get('content.serviceName'));
  282. var self = this;
  283. this.loadCompareVersionConfigs(this.get('allConfigs')).done(function() {
  284. self.addOverrides(data, self.get('allConfigs'));
  285. self.onLoadOverrides(self.get('allConfigs'));
  286. });
  287. },
  288. prepareConfigObjects: function(data, serviceName) {
  289. this.get('stepConfigs').clear();
  290. var configs = [];
  291. data.items.forEach(function (version) {
  292. if (version.group_name == 'default') {
  293. version.configurations.forEach(function (configObject) {
  294. configs = configs.concat(App.config.getConfigsFromJSON(configObject, true));
  295. });
  296. }
  297. });
  298. configs = App.config.sortConfigs(configs);
  299. /**
  300. * if property defined in stack but somehow it missed from cluster properties (can be after stack upgrade)
  301. * ui should add this properties to step configs
  302. */
  303. configs = this.mergeWithStackProperties(configs);
  304. var filenames = configs.mapProperty('fileName').uniq();
  305. //put properties from capacity-scheduler.xml into one config with textarea view
  306. if (filenames.contains('capacity-scheduler.xml')) {
  307. configs = App.config.addYarnCapacityScheduler(configs);
  308. }
  309. this.setPropertyIsVisible(configs);
  310. this.setPropertyIsEditable(configs);
  311. this.set('allConfigs', configs);
  312. },
  313. setPropertyIsVisible: function (configs) {
  314. if (this.get('content.serviceName') === 'KERBEROS') {
  315. var kdc_type = configs.findProperty('name', 'kdc_type');
  316. if (kdc_type.get('value') === 'none') {
  317. configs.findProperty('name', 'kdc_hosts').set('isVisible', false);
  318. configs.findProperty('name', 'admin_server_host').set('isVisible', false);
  319. configs.findProperty('name', 'domains').set('isVisible', false);
  320. } else if (kdc_type.get('value') === 'active-directory') {
  321. configs.findProperty('name', 'container_dn').set('isVisible', true);
  322. configs.findProperty('name', 'ldap_url').set('isVisible', true);
  323. } else if (kdc_type.get('value') === 'ipa') {
  324. configs.findProperty('name', 'group').set('isVisible', true);
  325. configs.findProperty('name', 'manage_krb5_conf').set('value', false);//TODO
  326. configs.findProperty('name', 'install_packages').set('value', false);//TODO
  327. configs.findProperty('name', 'admin_server_host').set('isVisible', false);
  328. configs.findProperty('name', 'domains').set('isVisible', false);
  329. }
  330. }
  331. },
  332. /**
  333. * Set <code>isEditable<code> proeperty based on selected group, security
  334. * and controller restriction
  335. * @param configs
  336. */
  337. setPropertyIsEditable: function(configs) {
  338. if (!this.get('selectedConfigGroup.isDefault') || !this.get('canEdit')) {
  339. configs.setEach('isEditable', false);
  340. } else if (App.get('isKerberosEnabled')) {
  341. configs.filterProperty('isSecureConfig').setEach('isEditable', false);
  342. }
  343. },
  344. /**
  345. * adds properties form stack that doesn't belong to cluster
  346. * to step configs
  347. * also set recommended value if isn't exists
  348. *
  349. * @return {App.ServiceConfigProperty[]}
  350. * @method mergeWithStackProperties
  351. */
  352. mergeWithStackProperties: function (configs) {
  353. App.config.getPropertiesFromTheme(this.get('content.serviceName')).forEach(function (advanced_id) {
  354. if (!configs.someProperty('id', advanced_id)) {
  355. var advanced = App.configsCollection.getConfig(advanced_id);
  356. if (advanced) {
  357. advanced.savedValue = null;
  358. advanced.isNotSaved = true;
  359. configs.pushObject(App.ServiceConfigProperty.create(advanced));
  360. }
  361. }
  362. });
  363. return configs;
  364. },
  365. addOverrides: function(data, allConfigs) {
  366. var self = this;
  367. data.items.forEach(function(group) {
  368. if (group.group_name != 'default') {
  369. var configGroup = App.ServiceConfigGroup.find().filterProperty('serviceName', group.service_name).findProperty('name', group.group_name);
  370. group.configurations.forEach(function(config) {
  371. for (var prop in config.properties) {
  372. var fileName = App.config.getOriginalFileName(config.type);
  373. var serviceConfig = allConfigs.filterProperty('name', prop).findProperty('filename', fileName);
  374. if (serviceConfig) {
  375. var value = App.config.formatPropertyValue(serviceConfig, config.properties[prop]);
  376. var isFinal = !!(config.properties_attributes && config.properties_attributes.final && config.properties_attributes.final[prop]);
  377. if (self.get('selectedConfigGroup.isDefault') || configGroup.get('name') == self.get('selectedConfigGroup.name')) {
  378. var overridePlainObject = {
  379. "value": value,
  380. "savedValue": value,
  381. "isFinal": isFinal,
  382. "savedIsFinal": isFinal,
  383. "isEditable": self.get('canEdit') && configGroup.get('name') == self.get('selectedConfigGroup.name')
  384. };
  385. App.config.createOverride(serviceConfig, overridePlainObject, configGroup);
  386. }
  387. } else {
  388. var isEditable = self.get('canEdit') && configGroup.get('name') == self.get('selectedConfigGroup.name');
  389. allConfigs.push(App.config.createCustomGroupConfig({
  390. propertyName: prop,
  391. filename: fileName,
  392. value: config.properties[prop],
  393. savedValue: config.properties[prop],
  394. isEditable: isEditable
  395. }, configGroup));
  396. }
  397. }
  398. });
  399. }
  400. });
  401. },
  402. /**
  403. * @param allConfigs
  404. * @private
  405. * @method onLoadOverrides
  406. */
  407. onLoadOverrides: function (allConfigs) {
  408. this.get('servicesToLoad').forEach(function(serviceName) {
  409. var configGroups = serviceName == this.get('content.serviceName') ? this.get('configGroups') : this.get('dependentConfigGroups').filterProperty('serviceName', serviceName);
  410. var configTypes = App.StackService.find(serviceName).get('configTypeList');
  411. var configsByService = this.get('allConfigs').filter(function (c) {
  412. return configTypes.contains(App.config.getConfigTagFromFileName(c.get('filename')));
  413. });
  414. var serviceConfig = App.config.createServiceConfig(serviceName, configGroups, configsByService, configsByService.length);
  415. this.addHostNamesToConfigs(serviceConfig);
  416. this.get('stepConfigs').pushObject(serviceConfig);
  417. }, this);
  418. var selectedService = this.get('stepConfigs').findProperty('serviceName', this.get('content.serviceName'));
  419. this.set('selectedService', selectedService);
  420. this.checkOverrideProperty(selectedService);
  421. if (App.Service.find().someProperty('serviceName', 'RANGER')) {
  422. this.setVisibilityForRangerProperties(selectedService);
  423. } else {
  424. App.config.removeRangerConfigs(this.get('stepConfigs'));
  425. }
  426. this.loadConfigRecommendations(null, this._onLoadComplete.bind(this));
  427. App.loadTimer.finish('Service Configs Page');
  428. },
  429. /**
  430. * @method _getRecommendationsForDependenciesCallback
  431. */
  432. _onLoadComplete: function () {
  433. this.get('stepConfigs').forEach(function(serviceConfig){
  434. serviceConfig.set('initConfigsLength', serviceConfig.get('configs.length'));
  435. });
  436. this.setProperties({
  437. dataIsLoaded: true,
  438. versionLoaded: true,
  439. isInit: false,
  440. hash: this.getHash()
  441. });
  442. },
  443. /**
  444. * hide properties from Advanced ranger category that match pattern
  445. * if property with dependentConfigPattern is false otherwise don't hide
  446. * @param serviceConfig
  447. * @private
  448. * @method setVisibilityForRangerProperties
  449. */
  450. setVisibilityForRangerProperties: function(serviceConfig) {
  451. var category = "Advanced ranger-{0}-plugin-properties".format(this.get('content.serviceName').toLowerCase());
  452. if (serviceConfig.configCategories.findProperty('name', category)) {
  453. var patternConfig = serviceConfig.configs.findProperty('dependentConfigPattern');
  454. if (patternConfig) {
  455. var value = patternConfig.get('value') === true || ["yes", "true"].contains(patternConfig.get('value').toLowerCase());
  456. serviceConfig.configs.filter(function(c) {
  457. if (c.get('category') === category && c.get('name').match(patternConfig.get('dependentConfigPattern')) && c.get('name') != patternConfig.get('name'))
  458. c.set('isVisible', value);
  459. });
  460. }
  461. }
  462. },
  463. /**
  464. * Allow update property if recommendations
  465. * is based on changing property
  466. *
  467. * @param parentProperties
  468. * @returns {boolean}
  469. * @override
  470. */
  471. allowUpdateProperty: function(parentProperties) {
  472. return !!(parentProperties && parentProperties.length);
  473. },
  474. /**
  475. * trigger App.config.createOverride
  476. * @param {Object[]} stepConfig
  477. * @private
  478. * @method checkOverrideProperty
  479. */
  480. checkOverrideProperty: function (stepConfig) {
  481. var overrideToAdd = this.get('overrideToAdd');
  482. var value = !!this.get('overrideToAdd.widget') ? Em.get(overrideToAdd, 'value') : '';
  483. if (overrideToAdd) {
  484. overrideToAdd = stepConfig.configs.filter(function(c){
  485. return c.name == overrideToAdd.name && c.filename == overrideToAdd.filename;
  486. });
  487. if (overrideToAdd[0]) {
  488. App.config.createOverride(overrideToAdd[0], {"isEditable": true, "value": value}, this.get('selectedConfigGroup'));
  489. this.set('overrideToAdd', null);
  490. }
  491. }
  492. },
  493. /**
  494. *
  495. * @param serviceConfig
  496. */
  497. addHostNamesToConfigs: function(serviceConfig) {
  498. serviceConfig.get('configCategories').forEach(function(c) {
  499. if (c.showHost) {
  500. var stackComponent = App.StackServiceComponent.find(c.name),
  501. value = this.getComponentHostValue(c.name);
  502. var hProperty = App.config.createHostNameProperty(serviceConfig.get('serviceName'), c.name, value, stackComponent);
  503. serviceConfig.get('configs').push(App.ServiceConfigProperty.create(hProperty));
  504. }
  505. }, this);
  506. App.ConfigAction.find().forEach(function(item){
  507. var hostComponentConfig = item.get('hostComponentConfig');
  508. var config = serviceConfig.get('configs').filterProperty('filename', hostComponentConfig.fileName).findProperty('name', hostComponentConfig.configName);
  509. if (config){
  510. var componentHostName = App.HostComponent.find().findProperty('componentName', item.get('componentName')) ;
  511. if (componentHostName) {
  512. var setConfigValue = !config.get('value');
  513. if (setConfigValue) {
  514. config.set('value', componentHostName.get('hostName'));
  515. config.set('recommendedValue', componentHostName.get('hostName'));
  516. }
  517. }
  518. }
  519. }, this);
  520. },
  521. /**
  522. * Method to get host for master or slave component
  523. *
  524. * @param componentName
  525. * @returns {Array}
  526. */
  527. getComponentHostValue: function(componentName) {
  528. var stackComponent = App.StackServiceComponent.find(componentName);
  529. var component = stackComponent.get('isMaster') ? App.MasterComponent.find(componentName) : App.SlaveComponent.find(componentName);
  530. return component.get('hostNames') || []
  531. },
  532. /**
  533. * Trigger loadSelectedVersion
  534. * @method doCancel
  535. */
  536. doCancel: function () {
  537. this.set('preSelectedConfigVersion', null);
  538. this.clearAllRecommendations();
  539. this.loadSelectedVersion(this.get('selectedVersion'), this.get('selectedConfigGroup'));
  540. },
  541. /**
  542. * trigger restartAllServiceHostComponents(batchUtils) if confirmed in popup
  543. * @method restartAllStaleConfigComponents
  544. * @return App.showConfirmationFeedBackPopup
  545. */
  546. restartAllStaleConfigComponents: function () {
  547. var self = this;
  548. var serviceDisplayName = this.get('content.displayName');
  549. var bodyMessage = Em.Object.create({
  550. confirmMsg: Em.I18n.t('services.service.restartAll.confirmMsg').format(serviceDisplayName),
  551. confirmButton: Em.I18n.t('services.service.restartAll.confirmButton'),
  552. additionalWarningMsg: this.get('content.passiveState') === 'OFF' ? Em.I18n.t('services.service.restartAll.warningMsg.turnOnMM').format(serviceDisplayName) : null
  553. });
  554. var isNNAffected = false;
  555. var restartRequiredHostsAndComponents = this.get('content.restartRequiredHostsAndComponents');
  556. for (var hostName in restartRequiredHostsAndComponents) {
  557. restartRequiredHostsAndComponents[hostName].forEach(function (hostComponent) {
  558. if (hostComponent == 'NameNode')
  559. isNNAffected = true;
  560. })
  561. }
  562. if (this.get('content.serviceName') == 'HDFS' && isNNAffected &&
  563. this.get('content.hostComponents').filterProperty('componentName', 'NAMENODE').someProperty('workStatus', App.HostComponentStatus.started)) {
  564. App.router.get('mainServiceItemController').checkNnLastCheckpointTime(function () {
  565. return App.showConfirmationFeedBackPopup(function (query) {
  566. var selectedService = self.get('content.id');
  567. batchUtils.restartAllServiceHostComponents(serviceDisplayName, selectedService, true, query);
  568. }, bodyMessage);
  569. });
  570. } else {
  571. return App.showConfirmationFeedBackPopup(function (query) {
  572. var selectedService = self.get('content.id');
  573. batchUtils.restartAllServiceHostComponents(serviceDisplayName, selectedService, true, query);
  574. }, bodyMessage);
  575. }
  576. },
  577. /**
  578. * trigger launchHostComponentRollingRestart(batchUtils)
  579. * @method rollingRestartStaleConfigSlaveComponents
  580. */
  581. rollingRestartStaleConfigSlaveComponents: function (componentName) {
  582. batchUtils.launchHostComponentRollingRestart(componentName.context, this.get('content.displayName'), this.get('content.passiveState') === "ON", true);
  583. },
  584. /**
  585. * trigger showItemsShouldBeRestarted popup with hosts that requires restart
  586. * @param {{context: object}} event
  587. * @method showHostsShouldBeRestarted
  588. */
  589. showHostsShouldBeRestarted: function (event) {
  590. var restartRequiredHostsAndComponents = event.context.restartRequiredHostsAndComponents;
  591. var hosts = [];
  592. for (var hostName in restartRequiredHostsAndComponents) {
  593. hosts.push(hostName);
  594. }
  595. var hostsText = hosts.length == 1 ? Em.I18n.t('common.host') : Em.I18n.t('common.hosts');
  596. hosts = hosts.join(', ');
  597. this.showItemsShouldBeRestarted(hosts, Em.I18n.t('service.service.config.restartService.shouldBeRestarted').format(hostsText));
  598. },
  599. /**
  600. * trigger showItemsShouldBeRestarted popup with components that requires restart
  601. * @param {{context: object}} event
  602. * @method showComponentsShouldBeRestarted
  603. */
  604. showComponentsShouldBeRestarted: function (event) {
  605. var restartRequiredHostsAndComponents = event.context.restartRequiredHostsAndComponents;
  606. var hostsComponets = [];
  607. var componentsObject = {};
  608. for (var hostName in restartRequiredHostsAndComponents) {
  609. restartRequiredHostsAndComponents[hostName].forEach(function (hostComponent) {
  610. hostsComponets.push(hostComponent);
  611. if (componentsObject[hostComponent] != undefined) {
  612. componentsObject[hostComponent]++;
  613. } else {
  614. componentsObject[hostComponent] = 1;
  615. }
  616. })
  617. }
  618. var componentsList = [];
  619. for (var obj in componentsObject) {
  620. var componentDisplayName = (componentsObject[obj] > 1) ? obj + 's' : obj;
  621. componentsList.push(componentsObject[obj] + ' ' + componentDisplayName);
  622. }
  623. var componentsText = componentsList.length == 1 ? Em.I18n.t('common.component') : Em.I18n.t('common.components');
  624. hostsComponets = componentsList.join(', ');
  625. this.showItemsShouldBeRestarted(hostsComponets, Em.I18n.t('service.service.config.restartService.shouldBeRestarted').format(componentsText));
  626. },
  627. /**
  628. * Show popup with selectable (@see App.SelectablePopupBodyView) list of items
  629. * @param {string} content string with comma-separated list of hostNames or componentNames
  630. * @param {string} header popup header
  631. * @returns {App.ModalPopup}
  632. * @method showItemsShouldBeRestarted
  633. */
  634. showItemsShouldBeRestarted: function (content, header) {
  635. return App.ModalPopup.show({
  636. content: content,
  637. header: header,
  638. bodyClass: App.SelectablePopupBodyView,
  639. secondary: null
  640. });
  641. },
  642. /**
  643. * trigger manageConfigurationGroups
  644. * @method manageConfigurationGroup
  645. */
  646. manageConfigurationGroup: function () {
  647. App.router.get('manageConfigGroupsController').manageConfigurationGroups(null, this.get('content'));
  648. },
  649. /**
  650. * If user changes cfg group if some configs was changed popup with propose to save changes must be shown
  651. * @param {object} event - triggered event for selecting another config-group
  652. * @method selectConfigGroup
  653. */
  654. selectConfigGroup: function (event) {
  655. var self = this;
  656. function callback() {
  657. self.doSelectConfigGroup(event);
  658. }
  659. if (!this.get('isInit')) {
  660. if (this.hasUnsavedChanges()) {
  661. this.showSavePopup(null, callback);
  662. return;
  663. }
  664. }
  665. callback();
  666. },
  667. /**
  668. * switch view to selected group
  669. * @param event
  670. * @method selectConfigGroup
  671. */
  672. doSelectConfigGroup: function (event) {
  673. App.loadTimer.start('Service Configs Page');
  674. var configGroupVersions = App.ServiceConfigVersion.find().filterProperty('groupId', event.context.get('id'));
  675. //check whether config group has config versions
  676. if (event.context.get('isDefault')) {
  677. this.loadCurrentVersions();
  678. } else if (configGroupVersions.length > 0) {
  679. this.loadSelectedVersion(configGroupVersions.findProperty('isCurrent').get('version'), event.context);
  680. } else {
  681. this.loadSelectedVersion(null, event.context);
  682. }
  683. }
  684. });