configs.js 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814
  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. require('controllers/wizard/slave_component_groups_controller');
  20. var batchUtils = require('utils/batch_scheduled_requests');
  21. var databaseUtils = require('utils/configs/database');
  22. App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, App.ServerValidatorMixin, App.EnhancedConfigsMixin, App.ThemesMappingMixin, App.VersionsMappingMixin, App.ConfigsSaverMixin, App.ConfigsComparator, {
  23. name: 'mainServiceInfoConfigsController',
  24. isHostsConfigsPage: false,
  25. forceTransition: false,
  26. isRecommendedLoaded: true,
  27. dataIsLoaded: false,
  28. stepConfigs: [], //contains all field properties that are viewed in this service
  29. selectedService: null,
  30. selectedConfigGroup: null,
  31. requestsInProgress: [],
  32. groupsStore: App.ServiceConfigGroup.find(),
  33. /**
  34. * config groups for current service
  35. * @type {App.ConfigGroup[]}
  36. */
  37. configGroups: function() {
  38. return this.get('groupsStore').filterProperty('serviceName', this.get('content.serviceName'));
  39. }.property('content.serviceName', 'groupsStore.length', 'groupStore.@each.name'),
  40. dependentConfigGroups: function() {
  41. if (this.get('dependentServiceNames.length') === 0) return [];
  42. return this.get('groupsStore').filter(function(group) {
  43. return this.get('dependentServiceNames').contains(group.get('serviceName'));
  44. }, this);
  45. }.property('content.serviceName', 'dependentServiceNames', 'groupsStore.length', 'groupStore.@each.name'),
  46. allConfigs: [],
  47. /**
  48. * Determines if save configs is in progress
  49. * @type {boolean}
  50. */
  51. saveInProgress: false,
  52. isCompareMode: false,
  53. preSelectedConfigVersion: null,
  54. /**
  55. * contain Service Config Property, when user proceed from Select Config Group dialog
  56. */
  57. overrideToAdd: null,
  58. /**
  59. * version selected to view
  60. */
  61. selectedVersion: null,
  62. /**
  63. * note passed on configs save
  64. * @type {string}
  65. */
  66. serviceConfigVersionNote: '',
  67. versionLoaded: false,
  68. dependentServiceNames: [],
  69. /**
  70. * defines which service configs need to be loaded to stepConfigs
  71. * @type {string[]}
  72. */
  73. servicesToLoad: function() {
  74. return this.get('dependentServiceNames').concat([this.get('content.serviceName')]).uniq();
  75. }.property('content.serviceName', 'dependentServiceNames.length'),
  76. /**
  77. * @type {boolean}
  78. */
  79. isCurrentSelected: function () {
  80. return App.ServiceConfigVersion.find(this.get('content.serviceName') + "_" + this.get('selectedVersion')).get('isCurrent');
  81. }.property('selectedVersion', 'content.serviceName', 'dataIsLoaded', 'versionLoaded'),
  82. /**
  83. * @type {boolean}
  84. */
  85. canEdit: function () {
  86. return (this.get('selectedVersion') == this.get('currentDefaultVersion') || !this.get('selectedConfigGroup.isDefault'))
  87. && !this.get('isCompareMode') && App.isAccessible('MANAGER') && !this.get('isHostsConfigsPage');
  88. }.property('selectedVersion', 'isCompareMode', 'currentDefaultVersion'),
  89. serviceConfigs: function () {
  90. return App.config.get('preDefinedServiceConfigs');
  91. }.property('App.config.preDefinedServiceConfigs'),
  92. showConfigHistoryFeature: true,
  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.configs').filter(function (config) {
  99. return Em.isNone(config.get('widget'));
  100. }).filter(function(config) {
  101. return !config.get('isValid') || (config.get('overrides') || []).someProperty('isValid', false);
  102. }).filterProperty('isVisible').length;
  103. }.property('selectedService.configs.@each.isValid', 'selectedService.configs.@each.overrideErrorTrigger'),
  104. /**
  105. * Determines if Save-button should be disabled
  106. * Disabled if some configs have invalid values for selected service
  107. * or save-process currently in progress
  108. *
  109. * @type {boolean}
  110. */
  111. isSubmitDisabled: function () {
  112. if (!this.get('selectedService')) return true;
  113. return this.get('selectedService').get('errorCount') !== 0 || this.get('saveInProgress');
  114. }.property('selectedService.errorCount', 'saveInProgress'),
  115. /**
  116. * Determines if some config value is changed
  117. * @type {boolean}
  118. */
  119. isPropertiesChanged: function(){
  120. return this.get('stepConfigs').someProperty('isPropertiesChanged', true);
  121. }.property('stepConfigs.@each.isPropertiesChanged'),
  122. /**
  123. * Filter text will be located here
  124. * @type {string}
  125. */
  126. filter: '',
  127. /**
  128. * List of filters for config properties to populate filter combobox
  129. * @type {{attributeName: string, attributeValue: boolean, caption: string}[]}
  130. */
  131. propertyFilters: [
  132. {
  133. attributeName: 'isOverridden',
  134. attributeValue: true,
  135. caption: 'common.combobox.dropdown.overridden'
  136. },
  137. {
  138. attributeName: 'isFinal',
  139. attributeValue: true,
  140. caption: 'common.combobox.dropdown.final'
  141. },
  142. {
  143. attributeName: 'hasCompareDiffs',
  144. attributeValue: true,
  145. caption: 'common.combobox.dropdown.changed',
  146. dependentOn: 'isCompareMode'
  147. },
  148. {
  149. attributeName: 'hasIssues',
  150. attributeValue: true,
  151. caption: 'common.combobox.dropdown.issues'
  152. }
  153. ],
  154. /**
  155. * get array of config properties that are shown in settings tab
  156. * @type {App.StackConfigProperty[]}
  157. */
  158. settingsTabProperties: function() {
  159. var properties = [];
  160. App.Tab.find(this.get('content.serviceName') + '_settings').get('sections').forEach(function(s) {
  161. s.get('subSections').forEach(function(ss) {
  162. properties = properties.concat(ss.get('configProperties').filterProperty('id'));
  163. });
  164. });
  165. return properties;
  166. }.property('content.serviceName', 'App.router.clusterController.isStackConfigsLoaded'),
  167. /**
  168. * Dropdown menu items in filter combobox
  169. * @type {{attributeName: string, attributeValue: string, name: string, selected: boolean}[]}
  170. */
  171. filterColumns: function () {
  172. var filterColumns = [];
  173. this.get('propertyFilters').forEach(function(filter) {
  174. if (Em.isNone(filter.dependentOn) || this.get(filter.dependentOn)) {
  175. filterColumns.push(Ember.Object.create({
  176. attributeName: filter.attributeName,
  177. attributeValue: filter.attributeValue,
  178. name: this.t(filter.caption),
  179. selected: filter.dependentOn ? this.get(filter.dependentOn) : false
  180. }));
  181. }
  182. }, this);
  183. return filterColumns;
  184. }.property('propertyFilters', 'isCompareMode'),
  185. /**
  186. * indicate whether service config version belongs to default config group
  187. * @param {object} version
  188. * @return {Boolean}
  189. * @private
  190. * @method isVersionDefault
  191. */
  192. isVersionDefault: function(version) {
  193. return (App.ServiceConfigVersion.find(this.get('content.serviceName') + "_" + version).get('groupId') == -1);
  194. },
  195. /**
  196. * register request to view to track his progress
  197. * @param {$.ajax} request
  198. * @method trackRequest
  199. */
  200. trackRequest: function (request) {
  201. this.get('requestsInProgress').push(request);
  202. },
  203. /**
  204. * clear and set properties to default value
  205. * @method clearStep
  206. */
  207. clearStep: function () {
  208. this.get('requestsInProgress').forEach(function(r) {
  209. if (r && r.readyState !== 4) {
  210. r.abort();
  211. }
  212. });
  213. this.get('requestsInProgress').clear();
  214. this.clearLoadInfo();
  215. this.clearSaveInfo();
  216. this.clearDependentConfigs();
  217. this.setProperties({
  218. saveInProgress: false,
  219. isInit: true,
  220. hash: null,
  221. forceTransition: false,
  222. dataIsLoaded: false,
  223. versionLoaded: false,
  224. filter: '',
  225. serviceConfigVersionNote: '',
  226. dependentServiceNames: []
  227. });
  228. this.get('filterColumns').setEach('selected', false);
  229. this.clearConfigs();
  230. },
  231. clearConfigs: function() {
  232. this.get('selectedConfigGroup', null);
  233. this.get('allConfigs').invoke('destroy');
  234. this.get('stepConfigs').invoke('destroy');
  235. this.set('stepConfigs', []);
  236. this.set('allConfigs', []);
  237. this.set('selectedService', null);
  238. },
  239. /**
  240. * "Finger-print" of the <code>stepConfigs</code>. Filled after first configGroup selecting
  241. * Used to determine if some changes were made (when user navigates away from this page)
  242. * @type {String|null}
  243. */
  244. hash: null,
  245. /**
  246. * Is this initial config group changing
  247. * @type {Boolean}
  248. */
  249. isInit: true,
  250. /**
  251. * On load function
  252. * @method loadStep
  253. */
  254. loadStep: function () {
  255. var serviceName = this.get('content.serviceName');
  256. this.set('dependentServiceNames', App.StackService.find(serviceName).get('dependentServiceNames'));
  257. this.clearStep();
  258. if (App.get('isClusterSupportsEnhancedConfigs')) {
  259. this.loadConfigTheme(serviceName).always(function() {
  260. App.themesMapper.generateAdvancedTabs([serviceName]);
  261. });
  262. }
  263. if (!this.get('preSelectedConfigVersion')) {
  264. this.loadCurrentVersions();
  265. }
  266. this.loadServiceConfigVersions();
  267. },
  268. /**
  269. * Generate "finger-print" for current <code>stepConfigs[0]</code>
  270. * Used to determine, if user has some unsaved changes (comparing with <code>hash</code>)
  271. * @returns {string|null}
  272. * @method getHash
  273. */
  274. getHash: function () {
  275. if (!this.get('selectedService.configs.length')) {
  276. return null;
  277. }
  278. var hash = {};
  279. this.get('selectedService.configs').forEach(function (config) {
  280. hash[config.get('name')] = {value: App.config.formatPropertyValue(config), overrides: [], isFinal: config.get('isFinal')};
  281. if (!config.get('overrides')) return;
  282. if (!config.get('overrides.length')) return;
  283. config.get('overrides').forEach(function (override) {
  284. hash[config.get('name')].overrides.push(App.config.formatPropertyValue(override));
  285. });
  286. });
  287. return JSON.stringify(hash);
  288. },
  289. parseConfigData: function(data) {
  290. this.prepareConfigObjects(data, this.get('content.serviceName'));
  291. var self = this;
  292. this.loadCompareVersionConfigs(this.get('allConfigs')).done(function() {
  293. self.addOverrides(data, self.get('allConfigs'));
  294. self.onLoadOverrides(self.get('allConfigs'));
  295. });
  296. },
  297. prepareConfigObjects: function(data, serviceName) {
  298. this.get('stepConfigs').clear();
  299. var configGroups = [];
  300. data.items.forEach(function (v) {
  301. if (v.group_name == 'default') {
  302. v.configurations.forEach(function (c) {
  303. configGroups.pushObject(c);
  304. });
  305. }
  306. });
  307. var configs = App.config.mergePredefinedWithSaved(configGroups, serviceName, this.get('selectedConfigGroup'), this.get('canEdit'));
  308. configs = App.config.sortConfigs(configs);
  309. /**
  310. * if property defined in stack but somehow it missed from cluster properties (can be after stack upgrade)
  311. * ui should add this properties to step configs
  312. */
  313. configs = this.mergeWithStackProperties(configs);
  314. //put properties from capacity-scheduler.xml into one config with textarea view
  315. if (this.get('content.serviceName') === 'YARN') {
  316. var configsToSkip = this.get('settingsTabProperties').filterProperty('filename', 'capacity-scheduler.xml');
  317. configs = App.config.fileConfigsIntoTextarea(configs, 'capacity-scheduler.xml', configsToSkip);
  318. }
  319. if (this.get('content.serviceName') === 'KERBEROS') {
  320. var kdc_type = configs.findProperty('name', 'kdc_type');
  321. if (kdc_type.get('value') === 'none') {
  322. configs.findProperty('name', 'kdc_host').set('isRequired', false).set('isVisible', false);
  323. configs.findProperty('name', 'admin_server_host').set('isRequired', false).set('isVisible', false);
  324. configs.findProperty('name', 'domains').set('isRequired', false).set('isVisible', false);
  325. } else if (kdc_type.get('value') === 'active-directory') {
  326. configs.findProperty('name', 'container_dn').set('isVisible', true);
  327. configs.findProperty('name', 'ldap_url').set('isVisible', true);
  328. }
  329. }
  330. this.set('allConfigs', configs);
  331. //add configs as names of host components
  332. this.addHostNamesToConfig();
  333. },
  334. /**
  335. * adds properties form stack that doesn't belong to cluster
  336. * to step configs
  337. * also set recommended value if isn't exists
  338. *
  339. * @return {App.ServiceConfigProperty[]}
  340. * @method mergeWithStackProperties
  341. */
  342. mergeWithStackProperties: function (configs) {
  343. this.get('settingsTabProperties').forEach(function (advanced) {
  344. if (!configs.someProperty('name', advanced.get('name'))) {
  345. configs.pushObject(App.ServiceConfigProperty.create({
  346. name: advanced.get('name'),
  347. displayName: advanced.get('displayName'),
  348. value: advanced.get('value'),
  349. savedValue: null,
  350. filename: advanced.get('fileName'),
  351. isUserProperty: false,
  352. isNotSaved: true,
  353. recommendedValue: advanced.get('value'),
  354. isFinal: advanced.get('isFinal'),
  355. recommendedIsFinal: advanced.get('recommendedIsFinal'),
  356. serviceName: advanced.get('serviceName'),
  357. supportsFinal: advanced.get('supportsFinal'),
  358. category: 'Advanced ' + App.config.getConfigTagFromFileName(advanced.get('fileName')),
  359. widget: advanced.get('widget')
  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. var value = App.config.formatOverrideValue(serviceConfig, config.properties[prop]);
  375. var isFinal = !!(config.properties_attributes && config.properties_attributes.final && config.properties_attributes.final[prop]);
  376. if (serviceConfig) {
  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(prop, config, configGroup, isEditable));
  390. }
  391. }
  392. });
  393. }
  394. });
  395. },
  396. /**
  397. * @param serviceConfig
  398. * @private
  399. * @method checkDatabaseProperties
  400. */
  401. checkDatabaseProperties: function (serviceConfig) {
  402. this.hideHiveDatabaseProperties(serviceConfig.configs);
  403. this.hideOozieDatabaseProperties(serviceConfig.configs);
  404. },
  405. /**
  406. * @param configs
  407. * @private
  408. * @method hideHiveDatabaseProperties
  409. */
  410. hideHiveDatabaseProperties: function (configs) {
  411. if (!['HIVE'].contains(this.get('content.serviceName'))) return;
  412. var property = configs.findProperty('name', 'hive_hostname');
  413. if (property) property.set('isVisible', false);
  414. if (configs.someProperty('name', 'hive_database')) {
  415. var hiveDb = configs.findProperty('name', 'hive_database');
  416. if (hiveDb.value === 'Existing MSSQL Server database with integrated authentication') {
  417. configs.findProperty('name', 'javax.jdo.option.ConnectionUserName').setProperties({
  418. isVisible: false,
  419. isRequired: false
  420. });
  421. configs.findProperty('name', 'javax.jdo.option.ConnectionPassword').setProperties({
  422. isVisible: false,
  423. isRequired: false
  424. });
  425. }
  426. }
  427. },
  428. /**
  429. * @param configs
  430. * @private
  431. * @method hideOozieDatabaseProperties
  432. */
  433. hideOozieDatabaseProperties: function (configs) {
  434. if (!['OOZIE'].contains(this.get('content.serviceName'))) return;
  435. var property = configs.findProperty('name', 'oozie_hostname');
  436. if (property) property.set('isVisible', false);
  437. if (configs.someProperty('name', 'oozie_database')) {
  438. var oozieDb = configs.findProperty('name', 'oozie_database');
  439. if (oozieDb.value === 'Existing MSSQL Server database with integrated authentication') {
  440. configs.findProperty('name', 'oozie.service.JPAService.jdbc.username').setProperties({
  441. isVisible: false,
  442. isRequired: false
  443. });
  444. configs.findProperty('name', 'oozie.service.JPAService.jdbc.password').setProperties({
  445. isVisible: false,
  446. isRequired: false
  447. });
  448. }
  449. }
  450. },
  451. /**
  452. * @param allConfigs
  453. * @private
  454. * @method onLoadOverrides
  455. */
  456. onLoadOverrides: function (allConfigs) {
  457. this.get('servicesToLoad').forEach(function(serviceName) {
  458. var configGroups = serviceName == this.get('content.serviceName') ? this.get('configGroups') : this.get('dependentConfigGroups').filterProperty('serviceName', serviceName);
  459. var serviceNames = [ serviceName ];
  460. if(serviceName === 'OOZIE') {
  461. // For Oozie, also add ELService properties which are marked as FALCON properties.
  462. serviceNames.push('FALCON')
  463. }
  464. var configsByService = this.get('allConfigs').filter(function (c) {
  465. return serviceNames.contains(c.get('serviceName'));
  466. });
  467. databaseUtils.bootstrapDatabaseProperties(configsByService, serviceName);
  468. var serviceConfig = App.config.createServiceConfig(serviceName, configGroups, configsByService, configsByService.length);
  469. if (serviceConfig.get('serviceName') === 'HDFS') {
  470. if (App.get('isHaEnabled')) {
  471. var c = serviceConfig.configs,
  472. removedConfigs = c.filterProperty('category', 'SECONDARY_NAMENODE');
  473. removedConfigs.setEach('isVisible', false);
  474. serviceConfig.configs = c;
  475. }
  476. }
  477. this.get('stepConfigs').pushObject(serviceConfig);
  478. }, this);
  479. var selectedService = this.get('stepConfigs').findProperty('serviceName', this.get('content.serviceName'));
  480. this.set('selectedService', selectedService);
  481. this.checkOverrideProperty(selectedService);
  482. this.checkDatabaseProperties(selectedService);
  483. if (!App.Service.find().someProperty('serviceName', 'RANGER')) {
  484. App.config.removeRangerConfigs(this.get('stepConfigs'));
  485. } else {
  486. this.setVisibilityForRangerProperties(selectedService);
  487. }
  488. this._onLoadComplete();
  489. this.get('configGroups').forEach(function (configGroup) {
  490. this.getRecommendationsForDependencies(null, true, Em.K, configGroup);
  491. }, this);
  492. },
  493. /**
  494. * @method _getRecommendationsForDependenciesCallback
  495. */
  496. _onLoadComplete: function () {
  497. this.get('stepConfigs').forEach(function(serviceConfig){
  498. serviceConfig.set('initConfigsLength', serviceConfig.get('configs.length'));
  499. });
  500. this.setProperties({
  501. dataIsLoaded: true,
  502. versionLoaded: true,
  503. isInit: false,
  504. hash: this.getHash()
  505. });
  506. },
  507. /**
  508. * hide properties from Advanced ranger category that match pattern
  509. * if property with dependentConfigPattern is false otherwise don't hide
  510. * @param serviceConfig
  511. * @private
  512. * @method setVisibilityForRangerProperties
  513. */
  514. setVisibilityForRangerProperties: function(serviceConfig) {
  515. var category = "Advanced ranger-{0}-plugin-properties".format(this.get('content.serviceName').toLowerCase());
  516. if (serviceConfig.configCategories.findProperty('name', category)) {
  517. var patternConfig = serviceConfig.configs.findProperty('dependentConfigPattern');
  518. if (patternConfig) {
  519. var value = patternConfig.get('value') === true || ["yes", "true"].contains(patternConfig.get('value').toLowerCase());
  520. serviceConfig.configs.filter(function(c) {
  521. if (c.get('category') === category && c.get('name').match(patternConfig.get('dependentConfigPattern')) && c.get('name') != patternConfig.get('name'))
  522. c.set('isVisible', value);
  523. });
  524. }
  525. }
  526. },
  527. /**
  528. * trigger App.config.createOverride
  529. * @param {Object[]} stepConfig
  530. * @private
  531. * @method checkOverrideProperty
  532. */
  533. checkOverrideProperty: function (stepConfig) {
  534. var overrideToAdd = this.get('overrideToAdd');
  535. var value = !!this.get('overrideToAdd.widget') ? Em.get(overrideToAdd, 'value') : '';
  536. if (overrideToAdd) {
  537. overrideToAdd = stepConfig.configs.filter(function(c){
  538. return c.name == overrideToAdd.name && c.filename == overrideToAdd.filename;
  539. });
  540. if (overrideToAdd[0]) {
  541. App.config.createOverride(overrideToAdd[0], {"isEditable": true, "value": value}, this.get('selectedConfigGroup'));
  542. this.set('overrideToAdd', null);
  543. }
  544. }
  545. },
  546. /**
  547. * Adds host name of master component to config
  548. * @private
  549. * @method addHostNamesToGlobalConfig
  550. */
  551. addHostNamesToConfig: function () {
  552. var serviceName = this.get('content.serviceName');
  553. var hostComponentMapping = require('data/host_component_mapping');
  554. //namenode_host is required to derive "fs.default.name" a property of core-site
  555. try {
  556. this.setHostForService('HDFS', 'NAMENODE', 'namenode_host', true);
  557. } catch (err) {
  558. console.log("No NameNode Host available. This is expected if you're using GLUSTERFS rather than HDFS.");
  559. }
  560. var hostProperties = hostComponentMapping.filter(function (h) {
  561. return h.serviceUseThis.contains(serviceName) || h.serviceName == serviceName;
  562. });
  563. hostProperties.forEach(function (h) {
  564. this.setHostForService(h.serviceName, h.componentName, h.hostProperty, h.m);
  565. }, this);
  566. },
  567. /**
  568. * set host name(s) property for component
  569. * @param {String} serviceName - service name of component
  570. * @param {String} componentName - component name which host we want to know
  571. * @param {String} hostProperty - name of host property for current component
  572. * @param {Boolean} multiple - true if can be more than one component
  573. * @private
  574. * @method setHostForService
  575. */
  576. setHostForService: function (serviceName, componentName, hostProperty, multiple) {
  577. var configs = this.get('allConfigs');
  578. var serviceConfigs = this.get('serviceConfigs').findProperty('serviceName', serviceName).get('configs');
  579. var hostConfig = serviceConfigs.findProperty('name', hostProperty);
  580. if (hostConfig) {
  581. hostConfig.recommendedValue = this.getMasterComponentHostValue(componentName, multiple);
  582. configs.push(App.ServiceConfigProperty.create(hostConfig));
  583. }
  584. },
  585. /**
  586. * get hostName of component
  587. * @param {String} componentName
  588. * @param {Boolean} multiple - true if can be more than one component installed on cluster
  589. * @return {String|Array|Boolean} hostName|hostNames|false if missing component
  590. * @private
  591. * @method getMasterComponentHostValue
  592. */
  593. getMasterComponentHostValue: function (componentName, multiple) {
  594. var components = App.HostComponent.find().filterProperty('componentName', componentName);
  595. if (components.length > 0) {
  596. return multiple ? components.mapProperty('hostName') : components[0].get('hostName');
  597. }
  598. return false;
  599. },
  600. /**
  601. * Trigger loadSelectedVersion
  602. * @method doCancel
  603. */
  604. doCancel: function () {
  605. this.set('preSelectedConfigVersion', null);
  606. this.clearDependentConfigs();
  607. this.loadSelectedVersion(this.get('selectedVersion'), this.get('selectedConfigGroup'));
  608. },
  609. /**
  610. * trigger restartAllServiceHostComponents(batchUtils) if confirmed in popup
  611. * @method restartAllStaleConfigComponents
  612. * @return App.showConfirmationFeedBackPopup
  613. */
  614. restartAllStaleConfigComponents: function () {
  615. var self = this;
  616. var serviceDisplayName = this.get('content.displayName');
  617. var bodyMessage = Em.Object.create({
  618. confirmMsg: Em.I18n.t('services.service.restartAll.confirmMsg').format(serviceDisplayName),
  619. confirmButton: Em.I18n.t('services.service.restartAll.confirmButton'),
  620. additionalWarningMsg: this.get('content.passiveState') === 'OFF' ? Em.I18n.t('services.service.restartAll.warningMsg.turnOnMM').format(serviceDisplayName) : null
  621. });
  622. return App.showConfirmationFeedBackPopup(function (query) {
  623. var selectedService = self.get('content.id');
  624. batchUtils.restartAllServiceHostComponents(selectedService, true, query);
  625. }, bodyMessage);
  626. },
  627. /**
  628. * trigger launchHostComponentRollingRestart(batchUtils)
  629. * @method rollingRestartStaleConfigSlaveComponents
  630. */
  631. rollingRestartStaleConfigSlaveComponents: function (componentName) {
  632. batchUtils.launchHostComponentRollingRestart(componentName.context, this.get('content.displayName'), this.get('content.passiveState') === "ON", true);
  633. },
  634. /**
  635. * trigger showItemsShouldBeRestarted popup with hosts that requires restart
  636. * @param {{context: object}} event
  637. * @method showHostsShouldBeRestarted
  638. */
  639. showHostsShouldBeRestarted: function (event) {
  640. var restartRequiredHostsAndComponents = event.context.restartRequiredHostsAndComponents;
  641. var hosts = [];
  642. for (var hostName in restartRequiredHostsAndComponents) {
  643. hosts.push(hostName);
  644. }
  645. var hostsText = hosts.length == 1 ? Em.I18n.t('common.host') : Em.I18n.t('common.hosts');
  646. hosts = hosts.join(', ');
  647. this.showItemsShouldBeRestarted(hosts, Em.I18n.t('service.service.config.restartService.shouldBeRestarted').format(hostsText));
  648. },
  649. /**
  650. * trigger showItemsShouldBeRestarted popup with components that requires restart
  651. * @param {{context: object}} event
  652. * @method showComponentsShouldBeRestarted
  653. */
  654. showComponentsShouldBeRestarted: function (event) {
  655. var restartRequiredHostsAndComponents = event.context.restartRequiredHostsAndComponents;
  656. var hostsComponets = [];
  657. var componentsObject = {};
  658. for (var hostName in restartRequiredHostsAndComponents) {
  659. restartRequiredHostsAndComponents[hostName].forEach(function (hostComponent) {
  660. hostsComponets.push(hostComponent);
  661. if (componentsObject[hostComponent] != undefined) {
  662. componentsObject[hostComponent]++;
  663. } else {
  664. componentsObject[hostComponent] = 1;
  665. }
  666. })
  667. }
  668. var componentsList = [];
  669. for (var obj in componentsObject) {
  670. var componentDisplayName = (componentsObject[obj] > 1) ? obj + 's' : obj;
  671. componentsList.push(componentsObject[obj] + ' ' + componentDisplayName);
  672. }
  673. var componentsText = componentsList.length == 1 ? Em.I18n.t('common.component') : Em.I18n.t('common.components');
  674. hostsComponets = componentsList.join(', ');
  675. this.showItemsShouldBeRestarted(hostsComponets, Em.I18n.t('service.service.config.restartService.shouldBeRestarted').format(componentsText));
  676. },
  677. /**
  678. * Show popup with selectable (@see App.SelectablePopupBodyView) list of items
  679. * @param {string} content string with comma-separated list of hostNames or componentNames
  680. * @param {string} header popup header
  681. * @returns {App.ModalPopup}
  682. * @method showItemsShouldBeRestarted
  683. */
  684. showItemsShouldBeRestarted: function (content, header) {
  685. return App.ModalPopup.show({
  686. content: content,
  687. header: header,
  688. bodyClass: App.SelectablePopupBodyView,
  689. secondary: null
  690. });
  691. },
  692. /**
  693. * trigger manageConfigurationGroups
  694. * @method manageConfigurationGroup
  695. */
  696. manageConfigurationGroup: function () {
  697. App.router.get('manageConfigGroupsController').manageConfigurationGroups(null, this.get('content'));
  698. },
  699. /**
  700. * If user changes cfg group if some configs was changed popup with propose to save changes must be shown
  701. * @param {object} event - triggered event for selecting another config-group
  702. * @method selectConfigGroup
  703. */
  704. selectConfigGroup: function (event) {
  705. var self = this;
  706. function callback() {
  707. self.doSelectConfigGroup(event);
  708. }
  709. if (!this.get('isInit')) {
  710. if (this.hasUnsavedChanges()) {
  711. this.showSavePopup(null, callback);
  712. return;
  713. }
  714. }
  715. callback();
  716. },
  717. /**
  718. * switch view to selected group
  719. * @param event
  720. * @method selectConfigGroup
  721. */
  722. doSelectConfigGroup: function (event) {
  723. var configGroupVersions = App.ServiceConfigVersion.find().filterProperty('groupId', event.context.get('configGroupId'));
  724. //check whether config group has config versions
  725. if (event.context.get('configGroupId') == -1) {
  726. this.loadCurrentVersions();
  727. } else if (configGroupVersions.length > 0) {
  728. this.loadSelectedVersion(configGroupVersions.findProperty('isCurrent').get('version'), event.context);
  729. } else {
  730. this.loadSelectedVersion(null, event.context);
  731. }
  732. }
  733. });