configs.js 86 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311
  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 lazyLoading = require('utils/lazy_loading');
  22. App.MainServiceInfoConfigsController = Em.Controller.extend({
  23. name: 'mainServiceInfoConfigsController',
  24. isHostsConfigsPage: false,
  25. forceTransition: false,
  26. dataIsLoaded: false,
  27. stepConfigs: [], //contains all field properties that are viewed in this service
  28. selectedService: null,
  29. serviceConfigTags: null,
  30. selectedConfigGroup: null,
  31. selectedServiceConfigTypes: [],
  32. selectedServiceSupportsFinal: [],
  33. configGroups: [],
  34. globalConfigs: [],
  35. uiConfigs: [],
  36. customConfig: [],
  37. isApplyingChanges: false,
  38. saveConfigsFlag: true,
  39. putClusterConfigsCallsNumber: null,
  40. // contain Service Config Property, when user proceed from Select Config Group dialog
  41. overrideToAdd: null,
  42. serviceConfigs: function () {
  43. return App.config.get('preDefinedServiceConfigs');
  44. }.property('App.config.preDefinedServiceConfigs'),
  45. customConfigs: function () {
  46. return App.config.get('preDefinedCustomConfigs');
  47. }.property('App.config.preDefinedCustomConfigs'),
  48. configMapping: function () {
  49. return App.config.get('configMapping');
  50. }.property('App.config.configMapping'),
  51. configs: function () {
  52. return App.config.get('preDefinedGlobalProperties');
  53. }.property('App.config.preDefinedGlobalProperties'),
  54. secureConfigs: function () {
  55. if (App.get('isHadoop2Stack')) {
  56. return require('data/HDP2/secure_mapping');
  57. } else {
  58. return require('data/secure_mapping');
  59. }
  60. }.property('App.isHadoop2Stack'),
  61. /**
  62. * Map, which contains relation between group and site
  63. * to upload overridden properties
  64. */
  65. loadedGroupToOverrideSiteToTagMap: {},
  66. /**
  67. * During page load time the cluster level site to tag
  68. * mapping is stored here.
  69. *
  70. * Example:
  71. * {
  72. * 'global': 'version1',
  73. * 'hdfs-site': 'version1',
  74. * 'core-site': 'version1'
  75. * }
  76. */
  77. loadedClusterSiteToTagMap: {},
  78. /**
  79. * Holds the actual base service-config server data uploaded.
  80. * This is used by the host-override mechanism to update host
  81. * specific values.
  82. */
  83. savedSiteNameToServerServiceConfigDataMap: {},
  84. isSubmitDisabled: function () {
  85. return (!(this.stepConfigs.everyProperty('errorCount', 0)) || this.get('isApplyingChanges'));
  86. }.property('stepConfigs.@each.errorCount', 'isApplyingChanges'),
  87. slaveComponentGroups: null,
  88. /**
  89. * Filter text will be located here
  90. */
  91. filter: '',
  92. /**
  93. * Dropdown menu items in filter combobox
  94. */
  95. filterColumns: function () {
  96. var result = [];
  97. for (var i = 1; i < 2; i++) {
  98. result.push(Ember.Object.create({
  99. name: this.t('common.combobox.dropdown.' + i),
  100. selected: false
  101. }));
  102. }
  103. return result;
  104. }.property(),
  105. /**
  106. * clear and set properties to default value
  107. */
  108. clearStep: function () {
  109. this.set("isApplyingChanges", false)
  110. this.set('isInit', true);
  111. this.set('hash', null);
  112. this.set('forceTransition', false);
  113. this.set('dataIsLoaded', false);
  114. this.set('filter', '');
  115. this.get('filterColumns').setEach('selected', false);
  116. this.get('stepConfigs').clear();
  117. this.get('globalConfigs').clear();
  118. this.get('uiConfigs').clear();
  119. this.get('customConfig').clear();
  120. this.set('loadedGroupToOverrideSiteToTagMap', {});
  121. this.set('savedSiteNameToServerServiceConfigDataMap', {});
  122. if (this.get('serviceConfigTags')) {
  123. this.set('serviceConfigTags', null);
  124. }
  125. },
  126. serviceConfigProperties: function () {
  127. return App.db.getServiceConfigProperties();
  128. }.property('content'),
  129. /**
  130. * "Finger-print" of the <code>stepConfigs</code>. Filled after first configGroup selecting
  131. * Used to determine if some changes were made (when user navigates away from this page)
  132. * {String}
  133. */
  134. hash: null,
  135. /**
  136. * Is this initial config group changing
  137. * {Boolean}
  138. */
  139. isInit: true,
  140. restartHosts: Em.A(),
  141. defaultsInfo: null,
  142. /**
  143. * On load function
  144. */
  145. loadStep: function () {
  146. console.log("TRACE: Loading configure for service");
  147. this.clearStep();
  148. this.loadServiceConfigs();
  149. },
  150. getHash: function () {
  151. if (!this.get('stepConfigs')[0]) {
  152. return null;
  153. }
  154. var hash = {};
  155. this.get('stepConfigs')[0].configs.forEach(function (config) {
  156. hash[config.get('name')] = {value: config.get('value'), overrides: []};
  157. if (!config.get('overrides')) return;
  158. if (!config.get('overrides.length')) return;
  159. config.get('overrides').forEach(function (override) {
  160. hash[config.get('name')].overrides.push(override.get('value'));
  161. });
  162. });
  163. return JSON.stringify(hash);
  164. },
  165. /**
  166. * Loads service configurations
  167. */
  168. loadServiceConfigs: function () {
  169. var advancedConfigs = [];
  170. var self = this;
  171. var serviceName = this.get('content.serviceName');
  172. var stackService = App.StackService.find().findProperty('serviceName', serviceName);
  173. if (stackService != null) {
  174. var configTypes = stackService.get('configTypes');
  175. if (configTypes) {
  176. var configTypesInfo = {
  177. items : [],
  178. supportsFinal : []
  179. };
  180. for ( var key in configTypes) {
  181. if (configTypes.hasOwnProperty(key)) {
  182. configTypesInfo.items.push(key);
  183. if (configTypes[key].supports && configTypes[key].supports.final === "true") {
  184. configTypesInfo.supportsFinal.push(key);
  185. }
  186. }
  187. }
  188. for ( var configType in configTypes) {
  189. self.set('selectedServiceConfigTypes', configTypesInfo.items || []);
  190. self.set('selectedServiceSupportsFinal', configTypesInfo.supportsFinal || []);
  191. }
  192. }
  193. }
  194. App.config.loadAdvancedConfig(serviceName, function (properties) {
  195. advancedConfigs.pushObjects(properties);
  196. self.set('advancedConfigs', advancedConfigs);
  197. self.loadServiceTags();
  198. });
  199. },
  200. /**
  201. * load config tags of service
  202. */
  203. loadServiceTags: function () {
  204. App.ajax.send({
  205. name: 'config.tags_and_groups',
  206. sender: this,
  207. data: {
  208. serviceName: this.get('content.serviceName'),
  209. serviceConfigsDef: this.get('serviceConfigs').findProperty('serviceName', this.get('content.serviceName')),
  210. urlParams: "&config_groups/ConfigGroup/tag=" + this.get('content.serviceName')
  211. },
  212. success: 'loadServiceConfigsSuccess'
  213. });
  214. },
  215. loadServiceConfigsSuccess: function (data, opt, params) {
  216. if (data) {
  217. this.setConfigGroups.apply(this, Array.prototype.slice.call(arguments, 0));
  218. } else {
  219. App.ajax.send({
  220. name: 'config.tags',
  221. sender: this,
  222. data: App.permit(params, ['clusterName', 'serviceConfigsDef', 'serviceName']),
  223. success: 'setConfigGroups'
  224. });
  225. }
  226. },
  227. setConfigGroups: function (data, opt, params) {
  228. var serviceConfigsDef = params.serviceConfigsDef;
  229. var serviceName = this.get('content.serviceName');
  230. var displayName = this.get('content.displayName');
  231. console.debug("loadServiceConfigs(): data=", data);
  232. // Create default configuration group
  233. var selectedConfigGroup;
  234. var siteToTagMap = {};
  235. var hostsLength = App.router.get('mainHostController.hostsCountMap.TOTAL');
  236. var configTypesRendered = Object.keys(serviceConfigsDef.get('configTypesRendered'));
  237. configTypesRendered.forEach(function (siteName) {
  238. if (data.Clusters.desired_configs[siteName]) {
  239. siteToTagMap[siteName] = data.Clusters.desired_configs[siteName].tag;
  240. } else {
  241. siteToTagMap[siteName] = 'version1';
  242. }
  243. }, this);
  244. this.loadedClusterSiteToTagMap = siteToTagMap;
  245. //parse loaded config groups
  246. if (App.supports.hostOverrides) {
  247. var configGroups = [];
  248. if (data.config_groups && data.config_groups.length) {
  249. data.config_groups.forEach(function (item) {
  250. item = item.ConfigGroup;
  251. if (item.tag === this.get('content.serviceName')) {
  252. var groupHosts = item.hosts.mapProperty('host_name');
  253. var newConfigGroup = App.ConfigGroup.create({
  254. id: item.id,
  255. name: item.group_name,
  256. description: item.description,
  257. isDefault: false,
  258. parentConfigGroup: null,
  259. service: App.Service.find().findProperty('serviceName', item.tag),
  260. hosts: groupHosts,
  261. configSiteTags: []
  262. });
  263. hostsLength -= groupHosts.length;
  264. item.desired_configs.forEach(function (config) {
  265. newConfigGroup.configSiteTags.push(App.ConfigSiteTag.create({
  266. site: config.type,
  267. tag: config.tag
  268. }));
  269. }, this);
  270. // select default selected group for hosts page
  271. if (!selectedConfigGroup && this.get('isHostsConfigsPage') && newConfigGroup.get('hosts').contains(this.get('host.hostName')) && this.get('content.serviceName') === item.tag) {
  272. selectedConfigGroup = newConfigGroup;
  273. }
  274. configGroups.push(newConfigGroup);
  275. }
  276. }, this);
  277. }
  278. this.set('configGroups', configGroups);
  279. }
  280. var defaultConfigGroup = App.ConfigGroup.create({
  281. name: displayName + " Default",
  282. description: "Default cluster level " + serviceName + " configuration",
  283. isDefault: true,
  284. hosts: {
  285. length: hostsLength
  286. },
  287. parentConfigGroup: null,
  288. service: this.get('content'),
  289. serviceName: serviceName,
  290. configSiteTags: []
  291. });
  292. if (!selectedConfigGroup) {
  293. selectedConfigGroup = defaultConfigGroup;
  294. }
  295. this.get('configGroups').sort(function (configGroupA, configGroupB) {
  296. return (configGroupA.name > configGroupB.name);
  297. });
  298. this.get('configGroups').unshift(defaultConfigGroup);
  299. this.set('selectedConfigGroup', selectedConfigGroup);
  300. },
  301. onConfigGroupChange: function () {
  302. this.get('stepConfigs').clear();
  303. var selectedConfigGroup = this.get('selectedConfigGroup');
  304. var serviceName = this.get('content.serviceName');
  305. //STEP 1: handle tags from JSON data for host overrides
  306. this.loadedGroupToOverrideSiteToTagMap = {};
  307. var configGroupsWithOverrides = selectedConfigGroup.get('isDefault') && !this.get('isHostsConfigsPage') ? this.get('configGroups') : [selectedConfigGroup];
  308. configGroupsWithOverrides.forEach(function (item) {
  309. var groupName = item.get('name');
  310. this.loadedGroupToOverrideSiteToTagMap[groupName] = {};
  311. item.get('configSiteTags').forEach(function (siteTag) {
  312. var site = siteTag.get('site');
  313. this.loadedGroupToOverrideSiteToTagMap[groupName][site] = siteTag.get('tag');
  314. }, this);
  315. }, this);
  316. //STEP 2: Create an array of objects defining tag names to be polled and new tag names to be set after submit
  317. this.setServiceConfigTags(this.loadedClusterSiteToTagMap);
  318. //STEP 3: Load advanced configs
  319. var advancedConfigs = this.get('advancedConfigs');
  320. //STEP 4: Load on-site config by service from server
  321. var configGroups = App.router.get('configurationController').getConfigsByTags(this.get('serviceConfigTags'));
  322. //STEP 5: Merge global and on-site configs with pre-defined
  323. var configSet = App.config.mergePreDefinedWithLoaded(configGroups, advancedConfigs, this.get('serviceConfigTags'), serviceName);
  324. configSet = App.config.syncOrderWithPredefined(configSet);
  325. //var serviceConfigs = this.getSitesConfigProperties(advancedConfigs);
  326. var configs = configSet.configs;
  327. //put global configs into globalConfigs to save them separately
  328. this.set('globalConfigs', configSet.globalConfigs);
  329. //STEP 6: add advanced configs
  330. //App.config.addAdvancedConfigs(configs, advancedConfigs, serviceName);
  331. //STEP 7: add custom configs
  332. App.config.addCustomConfigs(configs);
  333. //put properties from capacity-scheduler.xml into one config with textarea view
  334. if (this.get('content.serviceName') === 'YARN' && !App.supports.capacitySchedulerUi) {
  335. configs = App.config.fileConfigsIntoTextarea(configs, 'capacity-scheduler.xml');
  336. }
  337. //STEP 8: add configs as names of host components
  338. this.addHostNamesToGlobalConfig();
  339. var allConfigs = this.get('globalConfigs').concat(configs);
  340. //STEP 9: Load and add overriden configs of group
  341. App.config.loadServiceConfigGroupOverrides(allConfigs, this.loadedGroupToOverrideSiteToTagMap, this.get('configGroups'), this.onLoadOverrides, this);
  342. }.observes('selectedConfigGroup'),
  343. checkDatabaseProperties: function (serviceConfig) {
  344. if (!['OOZIE', 'HIVE'].contains(this.get('content.serviceName'))) return;
  345. var configsToHide = ['oozie_hostname'];
  346. configsToHide.forEach(function (configName) {
  347. var property = serviceConfig.configs.findProperty('name', configName);
  348. if (property) property.set('isVisible', false);
  349. });
  350. },
  351. onLoadOverrides: function (allConfigs) {
  352. var serviceName = this.get('content.serviceName');
  353. var advancedConfigs = this.get('advancedConfigs');
  354. //STEP 10: creation of serviceConfig object which contains configs for current service
  355. var serviceConfig = App.config.createServiceConfig(serviceName);
  356. //STEP11: Make SecondaryNameNode invisible on enabling namenode HA
  357. if (serviceConfig.get('serviceName') === 'HDFS') {
  358. App.config.OnNnHAHideSnn(serviceConfig);
  359. }
  360. if (serviceName || serviceConfig.serviceName === 'MISC') {
  361. //STEP 11: render configs and wrap each in ServiceConfigProperty object
  362. var self = this;
  363. // set recommended Defaults first then load the configs (including set validator)
  364. this.setRecommendedDefaults(advancedConfigs).done(function () {
  365. self.loadConfigs(allConfigs, serviceConfig);
  366. self.checkOverrideProperty(serviceConfig);
  367. self.checkDatabaseProperties(serviceConfig);
  368. self.get('stepConfigs').pushObject(serviceConfig);
  369. self.set('selectedService', self.get('stepConfigs').objectAt(0));
  370. self.checkForSecureConfig(self.get('selectedService'));
  371. self.set('dataIsLoaded', true);
  372. self.set('hash', self.getHash());
  373. self.set('isInit', false);
  374. });
  375. } else {
  376. this.set('selectedService', this.get('stepConfigs').objectAt(0));
  377. this.checkForSecureConfig(this.get('selectedService'));
  378. this.set('dataIsLoaded', true);
  379. this.set('hash', this.getHash());
  380. this.set('isInit', false);
  381. }
  382. },
  383. /**
  384. * Changes format from Object to Array
  385. *
  386. * {
  387. * 'core-site': 'version1',
  388. * 'hdfs-site': 'version1',
  389. * 'global': 'version2',
  390. * ...
  391. * }
  392. *
  393. * to
  394. *
  395. * [
  396. * {
  397. * siteName: 'core-site',
  398. * tagName: 'version1',
  399. * newTageName: null
  400. * },
  401. * ...
  402. * ]
  403. *
  404. * set tagnames for configuration of the *-site.xml
  405. */
  406. setServiceConfigTags: function (desiredConfigsSiteTags) {
  407. console.debug("setServiceConfigTags(): Trying to set ", desiredConfigsSiteTags);
  408. var newServiceConfigTags = [];
  409. for (var index in desiredConfigsSiteTags) {
  410. newServiceConfigTags.pushObject({
  411. siteName: index,
  412. tagName: desiredConfigsSiteTags[index],
  413. newTagName: null
  414. }, this);
  415. }
  416. console.debug("setServiceConfigTags(): Setting 'serviceConfigTags' to ", newServiceConfigTags);
  417. this.set('serviceConfigTags', newServiceConfigTags);
  418. },
  419. /**
  420. * check whether the config property is a security related knob
  421. * @param serviceConfig
  422. */
  423. checkForSecureConfig: function (serviceConfig) {
  424. serviceConfig.get('configs').forEach(function (_config) {
  425. this.get('secureConfigs').forEach(function (_secureConfig) {
  426. if (_config.get('name') === _secureConfig.name) {
  427. _config.set('isSecureConfig', true);
  428. }
  429. }, this)
  430. }, this)
  431. },
  432. /**
  433. * Get info about hosts and host components to configDefaultsProviders
  434. * @returns {{masterComponentHosts: Array, slaveComponentHosts: Array, hosts: {}}}
  435. */
  436. getInfoForDefaults: function (providers) {
  437. var requiredComponents = [];
  438. providers.forEach(function (provider) {
  439. requiredComponents = provider.get('slaveHostDependency').concat(provider.get('masterHostDependency'));
  440. });
  441. if (requiredComponents.length > 0) {
  442. App.ajax.send({
  443. name: 'hosts.by_component.' + ((requiredComponents.length === 1) ? 'one' : 'all'),
  444. sender: this,
  445. data: {
  446. componentNames: requiredComponents.join(',')
  447. },
  448. success: 'getInfoForDefaultsSuccessCallback'
  449. });
  450. } else {
  451. //if no components required then slaveComponentHosts and hosts stay empty
  452. this.set('defaultsInfo', {
  453. masterComponentHosts: this.getMasterComponents(),
  454. slaveComponentHosts: [],
  455. hosts: {}
  456. });
  457. }
  458. },
  459. getInfoForDefaultsSuccessCallback: function (response) {
  460. var defaultsInfo = {
  461. masterComponentHosts: this.getMasterComponents(),
  462. slaveComponentHosts: this.getSlaveComponents(response),
  463. hosts: this.getHostsInfo(response)
  464. };
  465. this.set('defaultsInfo', defaultsInfo);
  466. },
  467. /**
  468. * parse json response and build slave components array
  469. * @param response
  470. * @return {Array}
  471. */
  472. getSlaveComponents: function (response) {
  473. var hostComponentMap = {};
  474. var slaves = App.StackServiceComponent.find().filterProperty('isSlave').mapProperty('componentName');
  475. var slaveComponentHosts = [];
  476. response.items.forEach(function (host) {
  477. host.host_components.forEach(function (hostComponent) {
  478. if (slaves.contains(hostComponent.HostRoles.component_name)) {
  479. if (!hostComponentMap[hostComponent.HostRoles.component_name]) {
  480. hostComponentMap[hostComponent.HostRoles.component_name] = [];
  481. }
  482. hostComponentMap[hostComponent.HostRoles.component_name].push({hostName: host.Hosts.host_name});
  483. }
  484. })
  485. });
  486. for (var componentName in hostComponentMap) {
  487. slaveComponentHosts.push({
  488. componentName: componentName,
  489. hosts: hostComponentMap[componentName]
  490. });
  491. }
  492. return slaveComponentHosts;
  493. },
  494. /**
  495. * build master components array of data from HostComponent model
  496. * @return {Array}
  497. */
  498. getMasterComponents: function () {
  499. var masterComponentHosts = [];
  500. App.HostComponent.find().filterProperty('isMaster').forEach(function (masterComponent) {
  501. masterComponentHosts.push({
  502. component: masterComponent.get('componentName'),
  503. serviceId: masterComponent.get('service.serviceName'),
  504. host: masterComponent.get('hostName')
  505. });
  506. });
  507. return masterComponentHosts;
  508. },
  509. /**
  510. * parse json response and build hosts map
  511. * @param response
  512. * @return {Object}
  513. */
  514. getHostsInfo: function (response) {
  515. var hosts = {};
  516. response.items.mapProperty('Hosts').map(function (host) {
  517. hosts[host.host_name] = {
  518. name: host.host_name,
  519. cpu: host.cpu_count,
  520. memory: host.total_mem,
  521. disk_info: host.disk_info
  522. };
  523. });
  524. return hosts;
  525. },
  526. /**
  527. * Load child components to service config object
  528. * @param {Array} configs - array of configs
  529. * @param {Object} componentConfig - component config object
  530. * @method loadConfigs
  531. */
  532. loadConfigs: function (configs, componentConfig) {
  533. var serviceConfigsData = App.StackService.find().findProperty('serviceName', this.get('content.serviceName'));
  534. var defaultGroupSelected = this.get('selectedConfigGroup.isDefault');
  535. configs.forEach(function (_serviceConfigProperty) {
  536. var serviceConfigProperty = this.createConfigProperty(_serviceConfigProperty, defaultGroupSelected, serviceConfigsData);
  537. componentConfig.configs.pushObject(serviceConfigProperty);
  538. serviceConfigProperty.validate();
  539. }, this);
  540. },
  541. /**
  542. * create {Em.Object}service_cfg_property based on {Object}_serviceConfigProperty and additional info
  543. * @param {Object} _serviceConfigProperty - config object
  544. * @param {Boolean} defaultGroupSelected - true if selected cfg group is default
  545. * @param {Object} serviceConfigsData - service cfg object
  546. * @returns {Ember.Object|null}
  547. * @method createConfigProperty
  548. */
  549. createConfigProperty: function (_serviceConfigProperty, defaultGroupSelected, serviceConfigsData) {
  550. console.log("config", _serviceConfigProperty);
  551. if (!_serviceConfigProperty) return null;
  552. var overrides = _serviceConfigProperty.overrides;
  553. // we will populate the override properties below
  554. _serviceConfigProperty.overrides = null;
  555. _serviceConfigProperty.isOverridable = Em.isNone(_serviceConfigProperty.isOverridable) ? true : _serviceConfigProperty.isOverridable;
  556. var serviceConfigProperty = App.ServiceConfigProperty.create(_serviceConfigProperty);
  557. this.setValueForCheckBox(serviceConfigProperty);
  558. this.setValidator(serviceConfigProperty, serviceConfigsData);
  559. this.setValuesForOverrides(overrides, _serviceConfigProperty, serviceConfigProperty, defaultGroupSelected);
  560. this.setEditability(serviceConfigProperty, defaultGroupSelected);
  561. this.setSupportsFinal(serviceConfigProperty);
  562. return serviceConfigProperty;
  563. },
  564. /**
  565. * trigger addOverrideProperty
  566. * @param {Object} componentConfig
  567. * @method checkOverrideProperty
  568. */
  569. checkOverrideProperty: function (componentConfig) {
  570. var overrideToAdd = this.get('overrideToAdd');
  571. if (overrideToAdd) {
  572. overrideToAdd = componentConfig.configs.findProperty('name', overrideToAdd.name);
  573. if (overrideToAdd) {
  574. this.addOverrideProperty(overrideToAdd);
  575. this.set('overrideToAdd', null);
  576. }
  577. }
  578. },
  579. /**
  580. * set recommended defaults for advanced configs for current service
  581. * @param {Array} advancedConfigs
  582. * @mrethod setRecommendedDefaults
  583. */
  584. setRecommendedDefaults: function (advancedConfigs) {
  585. var s = App.StackService.find().findProperty('serviceName', this.get('content.serviceName'));
  586. var dfd = $.Deferred();
  587. var defaultsProvider = s.get('defaultsProviders');
  588. var configsValidator = s.get('configsValidator');
  589. if (!defaultsProvider) {
  590. dfd.resolve();
  591. return dfd.promise();
  592. }
  593. this.getInfoForDefaults(defaultsProvider);
  594. this.addObserver('defaultsInfo.hosts.length', this, function () {
  595. var localDB = this.get('defaultsInfo');
  596. var recommendedDefaults = {};
  597. if (defaultsProvider) {
  598. defaultsProvider.forEach(function (defaultsProvider) {
  599. var d = defaultsProvider.getDefaults(localDB);
  600. for (var name in d) {
  601. if (!!d[name]) {
  602. recommendedDefaults[name] = d[name];
  603. } else {
  604. var defaultValueFromStack = advancedConfigs.findProperty('name', name);
  605. // If property default value is not declared on client, fetch it from stack definition
  606. // If it's not declared with any valid value in both server stack and client, then js reference error is expected to be thrown
  607. recommendedDefaults[name] = defaultValueFromStack && defaultValueFromStack.value
  608. }
  609. }
  610. });
  611. }
  612. if (configsValidator) {
  613. configsValidator.set('recommendedDefaults', recommendedDefaults);
  614. }
  615. dfd.resolve();
  616. });
  617. return dfd.promise();
  618. },
  619. /**
  620. * set isEditable property of config for admin
  621. * if default cfg group and not on the host config page
  622. * @param {Ember.Object} serviceConfigProperty
  623. * @param {Boolean} defaultGroupSelected
  624. * @method setEditability
  625. */
  626. setEditability: function (serviceConfigProperty, defaultGroupSelected) {
  627. serviceConfigProperty.set('isEditable', false);
  628. if (App.get('isAdmin') && defaultGroupSelected && !this.get('isHostsConfigsPage')) {
  629. serviceConfigProperty.set('isEditable', serviceConfigProperty.get('isReconfigurable'));
  630. }
  631. },
  632. /**
  633. * set supportsFinal property of config for admin
  634. * @param {Ember.Object} serviceConfigProperty
  635. * @method setSupportsFinal
  636. */
  637. setSupportsFinal: function (serviceConfigProperty) {
  638. var fileName = serviceConfigProperty.get('filename');
  639. var matchingConfigTypes = this.get('selectedServiceSupportsFinal').filter(function(configType) {
  640. return fileName.startsWith(configType);
  641. });
  642. serviceConfigProperty.set('supportsFinal', matchingConfigTypes.length > 0);
  643. },
  644. /**
  645. * set serviceValidator for config property
  646. * hide properties for other services
  647. * @param {Ember.Object} serviceConfigProperty
  648. * @param {Object} serviceConfigsData
  649. * @method setValidator
  650. */
  651. setValidator: function (serviceConfigProperty, serviceConfigsData) {
  652. if (serviceConfigProperty.get('serviceName') === this.get('content.serviceName')) {
  653. if (serviceConfigsData.get('configsValidator')) {
  654. for (var validatorName in serviceConfigsData.get('configsValidator.configValidators')) {
  655. if (serviceConfigProperty.get("name") == validatorName) {
  656. serviceConfigProperty.set('serviceValidator', serviceConfigsData.get('configsValidator'));
  657. }
  658. }
  659. }
  660. console.log("config result", serviceConfigProperty);
  661. } else {
  662. serviceConfigProperty.set('isVisible', false);
  663. }
  664. },
  665. /**
  666. * set override values
  667. * @param overrides
  668. * @param _serviceConfigProperty
  669. * @param serviceConfigProperty
  670. * @param defaultGroupSelected
  671. */
  672. setValuesForOverrides: function (overrides, _serviceConfigProperty, serviceConfigProperty, defaultGroupSelected) {
  673. if (Em.isNone(overrides)) return;
  674. overrides.forEach(function (override) {
  675. var newSCP = this.createNewSCP(override, _serviceConfigProperty, serviceConfigProperty, defaultGroupSelected);
  676. var parentOverridesArray = serviceConfigProperty.get('overrides');
  677. if (parentOverridesArray == null) {
  678. parentOverridesArray = Em.A([]);
  679. serviceConfigProperty.set('overrides', parentOverridesArray);
  680. }
  681. parentOverridesArray.pushObject(newSCP);
  682. console.debug("createOverrideProperty(): Added:", newSCP, " to main-property:", serviceConfigProperty)
  683. }, this);
  684. },
  685. /**
  686. * create new overiden property and set approperiate fields
  687. * @param override
  688. * @param _serviceConfigProperty
  689. * @param serviceConfigProperty
  690. * @param defaultGroupSelected
  691. * @returns {*}
  692. */
  693. createNewSCP: function (override, _serviceConfigProperty, serviceConfigProperty, defaultGroupSelected) {
  694. var newSCP = App.ServiceConfigProperty.create(_serviceConfigProperty);
  695. newSCP.set('value', override.value);
  696. newSCP.set('isOriginalSCP', false); // indicated this is overridden value,
  697. newSCP.set('parentSCP', serviceConfigProperty);
  698. if (App.supports.hostOverrides && defaultGroupSelected) {
  699. newSCP.set('group', override.group);
  700. newSCP.set('isEditable', false);
  701. }
  702. return newSCP;
  703. },
  704. /**
  705. * convert string values to boolean for checkboxes
  706. * @param {Ember.Object} serviceConfigProperty
  707. */
  708. setValueForCheckBox: function (serviceConfigProperty) {
  709. if (serviceConfigProperty.get("displayType") == 'checkbox') {
  710. switch (serviceConfigProperty.get("value")) {
  711. case 'true':
  712. serviceConfigProperty.set("value", true);
  713. serviceConfigProperty.set("defaultValue", true);
  714. break;
  715. case 'false':
  716. serviceConfigProperty.set("value", false);
  717. serviceConfigProperty.set("defaultValue", false);
  718. break;
  719. }
  720. }
  721. },
  722. /**
  723. * Initialize save configs popup
  724. */
  725. restartServicePopup: function () {
  726. if (this.get("isSubmitDisabled")) {
  727. return;
  728. }
  729. this.set("isApplyingChanges", true);
  730. var self = this;
  731. var header, message, messageClass, status;
  732. var serviceName = this.get('content.serviceName'),
  733. displayName = this.get('content.displayName'),
  734. urlParams = '';
  735. if (App.supports.hostOverrides ||
  736. (serviceName !== 'HDFS' && this.get('content.isStopped') === true) ||
  737. ((serviceName === 'HDFS') && this.get('content.isStopped') === true && (!App.Service.find().someProperty('id', 'MAPREDUCE') || App.Service.find('MAPREDUCE').get('isStopped')))) {
  738. if (this.isDirChanged()) {
  739. App.showConfirmationPopup(function () {
  740. self.saveConfigs();
  741. }, Em.I18n.t('services.service.config.confirmDirectoryChange').format(displayName), function () {
  742. self.set('isApplyingChanges', false)
  743. });
  744. } else {
  745. this.saveConfigs();
  746. }
  747. } else {
  748. status = 'started';
  749. if (this.get('content.serviceName') !== 'HDFS' || (this.get('content.serviceName') === 'HDFS' && !App.Service.find().someProperty('id', 'MAPREDUCE'))) {
  750. header = Em.I18n.t('services.service.config.notSaved');
  751. message = Em.I18n.t('services.service.config.msgServiceStop');
  752. } else {
  753. header = Em.I18n.t('services.service.config.notSaved');
  754. message = Em.I18n.t('services.service.config.msgHDFSMapRServiceStop');
  755. urlParams += '&ServiceComponentInfo/service_name.in(HDFS,MAPREDUCE)';
  756. }
  757. messageClass = 'alert alert-error';
  758. this.showSaveConfigsPopup(header, false, message, messageClass, null, status, urlParams);
  759. }
  760. },
  761. /**
  762. * Define if user has changed some dir properties
  763. * @return {Boolean}
  764. */
  765. isDirChanged: function () {
  766. var dirChanged = false;
  767. var serviceName = this.get('content.serviceName');
  768. if (serviceName === 'HDFS') {
  769. var hdfsConfigs = this.get('stepConfigs').findProperty('serviceName', 'HDFS').get('configs');
  770. if (App.get('isHadoop2Stack')) {
  771. if (hdfsConfigs.findProperty('name', 'dfs.namenode.name.dir').get('isNotDefaultValue') ||
  772. hdfsConfigs.findProperty('name', 'dfs.namenode.checkpoint.dir').get('isNotDefaultValue') ||
  773. hdfsConfigs.findProperty('name', 'dfs.datanode.data.dir').get('isNotDefaultValue')) {
  774. dirChanged = true;
  775. }
  776. } else {
  777. if (hdfsConfigs.findProperty('name', 'dfs.name.dir').get('isNotDefaultValue') ||
  778. hdfsConfigs.findProperty('name', 'fs.checkpoint.dir').get('isNotDefaultValue') ||
  779. hdfsConfigs.findProperty('name', 'dfs.data.dir').get('isNotDefaultValue')) {
  780. dirChanged = true;
  781. }
  782. }
  783. } else if (serviceName === 'MAPREDUCE') {
  784. var mapredConfigs = this.get('stepConfigs').findProperty('serviceName', 'MAPREDUCE').get('configs');
  785. if (mapredConfigs.findProperty('name', 'mapred.local.dir').get('isNotDefaultValue') ||
  786. mapredConfigs.findProperty('name', 'mapred.system.dir').get('isNotDefaultValue')) {
  787. dirChanged = true;
  788. }
  789. }
  790. return dirChanged;
  791. },
  792. /**
  793. * Save changed configs and config groups
  794. */
  795. saveConfigs: function () {
  796. var selectedConfigGroup = this.get('selectedConfigGroup');
  797. var configs = this.get('stepConfigs').findProperty('serviceName', this.get('content.serviceName')).get('configs');
  798. if (selectedConfigGroup.get('isDefault')) {
  799. this.saveGlobalConfigs(configs);
  800. if (this.get('content.serviceName') === 'YARN' && !App.supports.capacitySchedulerUi) {
  801. configs = App.config.textareaIntoFileConfigs(configs, 'capacity-scheduler.xml');
  802. }
  803. this.saveSiteConfigs(configs);
  804. /**
  805. * First we put cluster configurations, which automatically creates /configurations
  806. * resources. Next we update host level overrides.
  807. */
  808. this.doPUTClusterConfigurations();
  809. } else {
  810. var overridenConfigs = [];
  811. var groupHosts = [];
  812. configs.filterProperty('isOverridden', true).forEach(function (config) {
  813. overridenConfigs = overridenConfigs.concat(config.get('overrides'));
  814. });
  815. this.formatConfigValues(overridenConfigs);
  816. selectedConfigGroup.get('hosts').forEach(function (hostName) {
  817. groupHosts.push({"host_name": hostName});
  818. });
  819. this.putConfigGroupChanges({
  820. ConfigGroup: {
  821. "id": selectedConfigGroup.get('id'),
  822. "cluster_name": App.get('clusterName'),
  823. "group_name": selectedConfigGroup.get('name'),
  824. "tag": selectedConfigGroup.get('service.id'),
  825. "description": selectedConfigGroup.get('description'),
  826. "hosts": groupHosts,
  827. "desired_configs": this.buildGroupDesiredConfigs(overridenConfigs)
  828. }
  829. }, true);
  830. }
  831. },
  832. /**
  833. * On save configs handler. Open save configs popup with appropriate message.
  834. */
  835. onDoPUTClusterConfigurations: function () {
  836. var header, message, messageClass, value, status, urlParams = '';
  837. var result = {
  838. flag: this.get('saveConfigsFlag'),
  839. message: null,
  840. value: null
  841. };
  842. if (!result.flag) {
  843. result.message = Em.I18n.t('services.service.config.failSaveConfig');
  844. } else {
  845. if (!result.flag) {
  846. result.message = Em.I18n.t('services.service.config.failSaveConfigHostOverrides');
  847. }
  848. }
  849. App.router.get('clusterController').updateClusterData();
  850. App.router.get('updateController').updateComponentConfig(function () {
  851. });
  852. var flag = result.flag;
  853. if (result.flag === true) {
  854. header = Em.I18n.t('services.service.config.saved');
  855. message = Em.I18n.t('services.service.config.saved.message');
  856. messageClass = 'alert alert-success';
  857. // warn the user if any of the components are in UNKNOWN state
  858. status = 'unknown';
  859. urlParams += ',ServiceComponentInfo/installed_count,ServiceComponentInfo/total_count';
  860. if (this.get('content.serviceName') === 'HDFS' || App.Service.find().someProperty('id', 'MAPREDUCE')) {
  861. urlParams += '&ServiceComponentInfo/service_name.in(HDFS,MAPREDUCE)'
  862. }
  863. } else {
  864. header = Em.I18n.t('common.failure');
  865. message = result.message;
  866. messageClass = 'alert alert-error';
  867. value = result.value;
  868. }
  869. this.showSaveConfigsPopup(header, flag, message, messageClass, value, status, urlParams);
  870. },
  871. /**
  872. * Show save configs popup
  873. */
  874. showSaveConfigsPopup: function (header, flag, message, messageClass, value, status, urlParams) {
  875. var self = this;
  876. App.ModalPopup.show({
  877. header: header,
  878. primary: Em.I18n.t('ok'),
  879. secondary: null,
  880. onPrimary: function () {
  881. this.hide();
  882. if (flag) {
  883. self.loadStep();
  884. } else {
  885. self.set('isApplyingChanges', false)
  886. }
  887. },
  888. onClose: function () {
  889. this.hide();
  890. self.set('isApplyingChanges', false)
  891. },
  892. disablePrimary: true,
  893. bodyClass: Ember.View.extend({
  894. flag: flag,
  895. message: function () {
  896. return this.get('isLoaded') ? message : Em.I18n.t('services.service.config.saving.message');
  897. }.property('isLoaded'),
  898. messageClass: function () {
  899. return this.get('isLoaded') ? messageClass : 'alert alert-info';
  900. }.property('isLoaded'),
  901. setDisablePrimary: function () {
  902. this.get('parentView').set('disablePrimary', !this.get('isLoaded'));
  903. }.observes('isLoaded'),
  904. runningHosts: [],
  905. runningComponentCount: 0,
  906. unknownHosts: [],
  907. unknownComponentCount: 0,
  908. siteProperties: value,
  909. isLoaded: false,
  910. componentsFilterSuccessCallback: function (response) {
  911. var count = 0,
  912. view = this,
  913. lazyLoadHosts = function (dest) {
  914. lazyLoading.run({
  915. initSize: 20,
  916. chunkSize: 50,
  917. delay: 50,
  918. destination: dest,
  919. source: hosts,
  920. context: view
  921. });
  922. },
  923. setComponents = function (item, components) {
  924. item.host_components.forEach(function (c) {
  925. var name = c.HostRoles.host_name;
  926. if (!components[name]) {
  927. components[name] = [];
  928. } else {
  929. components[name].push(App.format.role(item.ServiceComponentInfo.component_name));
  930. }
  931. });
  932. return components;
  933. },
  934. setHosts = function (components) {
  935. var hosts = [];
  936. Em.keys(components).forEach(function (key) {
  937. hosts.push({
  938. name: key,
  939. components: components[key].join(', ')
  940. });
  941. });
  942. return hosts;
  943. },
  944. components = {},
  945. hosts = [];
  946. switch (status) {
  947. case 'unknown':
  948. response.items.filter(function (item) {
  949. return (item.ServiceComponentInfo.total_count > item.ServiceComponentInfo.started_count + item.ServiceComponentInfo.installed_count);
  950. }).forEach(function (item) {
  951. var total = item.ServiceComponentInfo.total_count,
  952. started = item.ServiceComponentInfo.started_count,
  953. installed = item.ServiceComponentInfo.installed_count,
  954. unknown = total - started + installed;
  955. components = setComponents(item, components);
  956. count += unknown;
  957. });
  958. hosts = setHosts(components);
  959. this.set('unknownComponentCount', count);
  960. lazyLoadHosts(this.get('unknownHosts'));
  961. break;
  962. case 'started':
  963. response.items.filterProperty('ServiceComponentInfo.started_count').forEach(function (item) {
  964. var started = item.ServiceComponentInfo.started_count;
  965. components = setComponents(item, components);
  966. count += started;
  967. hosts = setHosts(components);
  968. });
  969. this.set('runningComponentCount', count);
  970. lazyLoadHosts(this.get('runningHosts'));
  971. break;
  972. }
  973. },
  974. componentsFilterErrorCallback: function () {
  975. this.set('isLoaded', true);
  976. },
  977. didInsertElement: function () {
  978. App.ajax.send({
  979. name: 'components.filter_by_status',
  980. sender: this,
  981. data: {
  982. clusterName: App.get('clusterName'),
  983. urlParams: urlParams
  984. },
  985. success: 'componentsFilterSuccessCallback',
  986. error: 'componentsFilterErrorCallback'
  987. });
  988. },
  989. getDisplayMessage: function () {
  990. var displayMsg = [];
  991. var siteProperties = this.get('siteProperties');
  992. if (siteProperties) {
  993. siteProperties.forEach(function (_siteProperty) {
  994. var displayProperty = _siteProperty.siteProperty;
  995. var displayNames = _siteProperty.displayNames;
  996. if (displayNames && displayNames.length) {
  997. if (displayNames.length === 1) {
  998. displayMsg.push(displayProperty + Em.I18n.t('as') + displayNames[0]);
  999. } else {
  1000. var name;
  1001. displayNames.forEach(function (_name, index) {
  1002. if (index === 0) {
  1003. name = _name;
  1004. } else if (index === siteProperties.length - 1) {
  1005. name = name + Em.I18n.t('and') + _name;
  1006. } else {
  1007. name = name + ', ' + _name;
  1008. }
  1009. }, this);
  1010. displayMsg.push(displayProperty + Em.I18n.t('as') + name);
  1011. }
  1012. } else {
  1013. displayMsg.push(displayProperty);
  1014. }
  1015. }, this);
  1016. }
  1017. return displayMsg;
  1018. }.property('siteProperties'),
  1019. runningHostsMessage: function () {
  1020. return Em.I18n.t('services.service.config.stopService.runningHostComponents').format(this.get('runningComponentCount'), this.get('runningHosts.length'));
  1021. }.property('runningComponentCount', 'runningHosts.length'),
  1022. unknownHostsMessage: function () {
  1023. return Em.I18n.t('services.service.config.stopService.unknownHostComponents').format(this.get('unknownComponentCount'), this.get('unknownHosts.length'));
  1024. }.property('unknownComponentCount', 'unknownHosts.length'),
  1025. templateName: require('templates/main/service/info/configs_save_popup')
  1026. })
  1027. })
  1028. },
  1029. /**
  1030. * construct desired_configs for config groups from overriden properties
  1031. * @param configs
  1032. * @param timeTag
  1033. * @return {Array}
  1034. */
  1035. buildGroupDesiredConfigs: function (configs, timeTag) {
  1036. var sites = [];
  1037. var time = timeTag || (new Date).getTime();
  1038. configs.forEach(function (config) {
  1039. var type = config.get('filename').replace('.xml', '');
  1040. var site = sites.findProperty('type', type);
  1041. if (site) {
  1042. site.properties.push({
  1043. name: config.get('name'),
  1044. value: config.get('value')
  1045. });
  1046. } else {
  1047. site = {
  1048. type: type,
  1049. tag: 'version' + time,
  1050. properties: [
  1051. {
  1052. name: config.get('name'),
  1053. value: config.get('value')
  1054. }
  1055. ]
  1056. };
  1057. sites.push(site);
  1058. }
  1059. });
  1060. sites.forEach(function (site) {
  1061. if (site.type === 'global') {
  1062. site.properties = this.createGlobalSiteObj(site.tag, site.properties).properties;
  1063. } else {
  1064. site.properties = this.createSiteObj(site.type, site.tag, site.properties).properties;
  1065. }
  1066. }, this);
  1067. return sites;
  1068. },
  1069. /**
  1070. * persist properties of config groups to server
  1071. * show result popup if <code>showPopup</code> is true
  1072. * @param data {Object}
  1073. * @param showPopup {Boolean}
  1074. */
  1075. putConfigGroupChanges: function (data, showPopup) {
  1076. var ajaxOptions = {
  1077. name: 'config_groups.update_config_group',
  1078. sender: this,
  1079. data: {
  1080. id: data.ConfigGroup.id,
  1081. configGroup: data
  1082. }
  1083. };
  1084. if (showPopup) {
  1085. ajaxOptions.success = "putConfigGroupChangesSuccess";
  1086. }
  1087. App.ajax.send(ajaxOptions);
  1088. },
  1089. putConfigGroupChangesSuccess: function () {
  1090. this.set('saveConfigsFlag', true);
  1091. this.onDoPUTClusterConfigurations();
  1092. },
  1093. /**
  1094. * save new or change exist configs in global configs
  1095. * @param configs
  1096. */
  1097. saveGlobalConfigs: function (configs) {
  1098. var globalConfigs = this.get('globalConfigs');
  1099. configs.filterProperty('id', 'puppet var').forEach(function (uiConfigProperty) {
  1100. uiConfigProperty.set('value', App.config.trimProperty(uiConfigProperty));
  1101. if (globalConfigs.someProperty('name', uiConfigProperty.name)) {
  1102. var modelGlobalConfig = globalConfigs.findProperty('name', uiConfigProperty.name);
  1103. modelGlobalConfig.value = uiConfigProperty.value;
  1104. } else {
  1105. globalConfigs.pushObject({
  1106. name: uiConfigProperty.name,
  1107. value: uiConfigProperty.value
  1108. });
  1109. }
  1110. }, this);
  1111. this.setHiveHostName(globalConfigs);
  1112. this.setOozieHostName(globalConfigs);
  1113. this.set('globalConfigs', globalConfigs);
  1114. },
  1115. /**
  1116. * set hive hostnames in global configs
  1117. * @param globals
  1118. */
  1119. setHiveHostName: function (globals) {
  1120. if (globals.someProperty('name', 'hive_database')) {
  1121. var hiveDb = globals.findProperty('name', 'hive_database');
  1122. if (hiveDb.value === 'New MySQL Database') {
  1123. var ambariHost = globals.findProperty('name', 'hive_ambari_host');
  1124. if (ambariHost) {
  1125. ambariHost.name = 'hive_hostname';
  1126. }
  1127. globals = globals.without(globals.findProperty('name', 'hive_existing_mysql_host'));
  1128. globals = globals.without(globals.findProperty('name', 'hive_existing_mysql_database'));
  1129. globals = globals.without(globals.findProperty('name', 'hive_existing_oracle_host'));
  1130. globals = globals.without(globals.findProperty('name', 'hive_existing_oracle_database'));
  1131. globals = globals.without(globals.findProperty('name', 'hive_existing_postgresql_host'));
  1132. globals = globals.without(globals.findProperty('name', 'hive_existing_postgresql_database'));
  1133. } else if (hiveDb.value === 'Existing MySQL Database') {
  1134. var existingMySqlHost = globals.findProperty('name', 'hive_existing_mysql_host');
  1135. if (existingMySqlHost) {
  1136. existingMySqlHost.name = 'hive_hostname';
  1137. }
  1138. globals = globals.without(globals.findProperty('name', 'hive_ambari_host'));
  1139. globals = globals.without(globals.findProperty('name', 'hive_ambari_database'));
  1140. globals = globals.without(globals.findProperty('name', 'hive_existing_oracle_host'));
  1141. globals = globals.without(globals.findProperty('name', 'hive_existing_oracle_database'));
  1142. globals = globals.without(globals.findProperty('name', 'hive_existing_postgresql_host'));
  1143. globals = globals.without(globals.findProperty('name', 'hive_existing_postgresql_database'));
  1144. } else if (hiveDb.value === Em.I18n.t('services.service.config.hive.oozie.postgresql')) {
  1145. var existingPostgreSqlHost = globals.findProperty('name', 'hive_existing_postgresql_host');
  1146. if (existingPostgreSqlHost) {
  1147. existingPostgreSqlHost.name = 'hive_hostname';
  1148. }
  1149. globals = globals.without(globals.findProperty('name', 'hive_ambari_host'));
  1150. globals = globals.without(globals.findProperty('name', 'hive_ambari_database'));
  1151. globals = globals.without(globals.findProperty('name', 'hive_existing_mysql_host'));
  1152. globals = globals.without(globals.findProperty('name', 'hive_existing_mysql_database'));
  1153. globals = globals.without(globals.findProperty('name', 'hive_existing_oracle_host'));
  1154. globals = globals.without(globals.findProperty('name', 'hive_existing_oracle_database'));
  1155. }
  1156. else { //existing oracle database
  1157. var existingOracleHost = globals.findProperty('name', 'hive_existing_oracle_host');
  1158. if (existingOracleHost) {
  1159. existingOracleHost.name = 'hive_hostname';
  1160. }
  1161. globals = globals.without(globals.findProperty('name', 'hive_ambari_host'));
  1162. globals = globals.without(globals.findProperty('name', 'hive_ambari_database'));
  1163. globals = globals.without(globals.findProperty('name', 'hive_existing_mysql_host'));
  1164. globals = globals.without(globals.findProperty('name', 'hive_existing_mysql_database'));
  1165. globals = globals.without(globals.findProperty('name', 'hive_existing_postgresql_host'));
  1166. globals = globals.without(globals.findProperty('name', 'hive_existing_postgresql_database'));
  1167. }
  1168. }
  1169. },
  1170. /**
  1171. * set oozie hostnames in global configs
  1172. * @param globals
  1173. */
  1174. setOozieHostName: function (globals) {
  1175. var dbHostPropertyName = null;
  1176. if (globals.someProperty('name', 'oozie_database')) {
  1177. var oozieDb = globals.findProperty('name', 'oozie_database');
  1178. if (oozieDb.value === 'New Derby Database') {
  1179. globals = globals.without(globals.findProperty('name', 'oozie_ambari_host'));
  1180. globals = globals.without(globals.findProperty('name', 'oozie_ambari_database'));
  1181. globals = globals.without(globals.findProperty('name', 'oozie_existing_mysql_host'));
  1182. globals = globals.without(globals.findProperty('name', 'oozie_existing_mysql_database'));
  1183. globals = globals.without(globals.findProperty('name', 'oozie_existing_oracle_host'));
  1184. globals = globals.without(globals.findProperty('name', 'oozie_existing_oracle_database'));
  1185. globals = globals.without(globals.findProperty('name', 'oozie_existing_postgresql_host'));
  1186. globals = globals.without(globals.findProperty('name', 'oozie_existing_postgresql_database'));
  1187. } else if (oozieDb.value === 'New MySQL Database') {
  1188. var ambariHost = globals.findProperty('name', 'oozie_ambari_host');
  1189. if (ambariHost) {
  1190. ambariHost.name = 'oozie_hostname';
  1191. }
  1192. globals = globals.without(globals.findProperty('name', 'oozie_existing_mysql_host'));
  1193. globals = globals.without(globals.findProperty('name', 'oozie_existing_mysql_database'));
  1194. globals = globals.without(globals.findProperty('name', 'oozie_existing_oracle_host'));
  1195. globals = globals.without(globals.findProperty('name', 'oozie_existing_oracle_database'));
  1196. globals = globals.without(globals.findProperty('name', 'oozie_derby_database'));
  1197. globals = globals.without(globals.findProperty('name', 'oozie_existing_postgresql_host'));
  1198. globals = globals.without(globals.findProperty('name', 'oozie_existing_postgresql_database'));
  1199. } else if (oozieDb.value === 'Existing MySQL Database') {
  1200. var existingMySqlHost = globals.findProperty('name', 'oozie_existing_mysql_host');
  1201. if (existingMySqlHost) {
  1202. dbHostPropertyName = 'oozie_existing_mysql_host';
  1203. }
  1204. globals = globals.without(globals.findProperty('name', 'oozie_ambari_host'));
  1205. globals = globals.without(globals.findProperty('name', 'oozie_ambari_database'));
  1206. globals = globals.without(globals.findProperty('name', 'oozie_existing_oracle_host'));
  1207. globals = globals.without(globals.findProperty('name', 'oozie_existing_oracle_database'));
  1208. globals = globals.without(globals.findProperty('name', 'oozie_derby_database'));
  1209. globals = globals.without(globals.findProperty('name', 'oozie_existing_postgresql_host'));
  1210. globals = globals.without(globals.findProperty('name', 'oozie_existing_postgresql_database'));
  1211. } else if (oozieDb.value === Em.I18n.t('services.service.config.hive.oozie.postgresql')) {
  1212. var existingPostgreSqlHost = globals.findProperty('name', 'oozie_existing_postgresql_host');
  1213. if (existingPostgreSqlHost) {
  1214. dbHostPropertyName = 'oozie_existing_postgresql_host';
  1215. }
  1216. globals = globals.without(globals.findProperty('name', 'oozie_ambari_host'));
  1217. globals = globals.without(globals.findProperty('name', 'oozie_ambari_database'));
  1218. globals = globals.without(globals.findProperty('name', 'oozie_existing_mysql_host'));
  1219. globals = globals.without(globals.findProperty('name', 'oozie_existing_mysql_database'));
  1220. globals = globals.without(globals.findProperty('name', 'oozie_existing_oracle_host'));
  1221. globals = globals.without(globals.findProperty('name', 'oozie_existing_oracle_database'));
  1222. }
  1223. else { //existing oracle database
  1224. var existingOracleHost = globals.findProperty('name', 'oozie_existing_oracle_host');
  1225. if (existingOracleHost) {
  1226. dbHostPropertyName = 'oozie_existing_oracle_host';
  1227. }
  1228. globals = globals.without(globals.findProperty('name', 'oozie_ambari_host'));
  1229. globals = globals.without(globals.findProperty('name', 'oozie_ambari_database'));
  1230. globals = globals.without(globals.findProperty('name', 'oozie_existing_mysql_host'));
  1231. globals = globals.without(globals.findProperty('name', 'oozie_existing_mysql_database'));
  1232. globals = globals.without(globals.findProperty('name', 'oozie_derby_database'));
  1233. }
  1234. }
  1235. if (dbHostPropertyName) {
  1236. var oozieHostNameProperty = App.ServiceConfigProperty.create(App.config.get('preDefinedGlobalProperties').findProperty('name', 'oozie_hostname'));
  1237. oozieHostNameProperty.set('value', globals.findProperty('name', dbHostPropertyName).get('value'));
  1238. globals.pushObject(oozieHostNameProperty);
  1239. }
  1240. },
  1241. /**
  1242. * save site configs
  1243. * @param configs
  1244. */
  1245. saveSiteConfigs: function (configs) {
  1246. //storedConfigs contains custom configs as well
  1247. var serviceConfigProperties = configs.filterProperty('id', 'site property');
  1248. this.formatConfigValues(serviceConfigProperties);
  1249. var mappedConfigs = App.config.excludeUnsupportedConfigs(this.get('configMapping').all(), App.Service.find().mapProperty('serviceName'));
  1250. var allUiConfigs = this.loadUiSideConfigs(mappedConfigs);
  1251. this.set('uiConfigs', serviceConfigProperties.concat(allUiConfigs));
  1252. },
  1253. formatConfigValues: function (serviceConfigProperties) {
  1254. serviceConfigProperties.forEach(function (_config) {
  1255. if (typeof _config.get('value') === "boolean") _config.set('value', _config.value.toString());
  1256. _config.set('value', App.config.trimProperty(_config, true));
  1257. });
  1258. },
  1259. /**
  1260. * return configs from the UI side
  1261. * @param configMapping array with configs
  1262. * @return {Array}
  1263. */
  1264. loadUiSideConfigs: function (configMapping) {
  1265. var uiConfig = [];
  1266. var configs = configMapping.filterProperty('foreignKey', null);
  1267. this.addDynamicProperties(configs);
  1268. configs.forEach(function (_config) {
  1269. var valueWithOverrides = this.getGlobConfigValueWithOverrides(_config.templateName, _config.value);
  1270. if (valueWithOverrides !== null) {
  1271. uiConfig.pushObject({
  1272. "id": "site property",
  1273. "name": _config.name,
  1274. "value": valueWithOverrides.value,
  1275. "filename": _config.filename,
  1276. "overrides": valueWithOverrides.overrides
  1277. });
  1278. }
  1279. }, this);
  1280. return uiConfig;
  1281. },
  1282. addDynamicProperties: function (configs) {
  1283. var allConfigs = this.get('stepConfigs').findProperty('serviceName', this.get('content.serviceName')).get('configs');
  1284. var templetonHiveProperty = allConfigs.someProperty('name', 'templeton.hive.properties');
  1285. if (!templetonHiveProperty && this.get('content.serviceName') === 'WEBHCAT') {
  1286. configs.pushObject({
  1287. "name": "templeton.hive.properties",
  1288. "templateName": ["hivemetastore_host"],
  1289. "foreignKey": null,
  1290. "value": "hive.metastore.local=false,hive.metastore.uris=thrift://<templateName[0]>:9083,hive.metastore.sasl.enabled=yes,hive.metastore.execute.setugi=true,hive.metastore.warehouse.dir=/apps/hive/warehouse",
  1291. "filename": "webhcat-site.xml"
  1292. });
  1293. }
  1294. },
  1295. /**
  1296. * return global config value
  1297. * @param templateName
  1298. * @param expression
  1299. * @return {Object}
  1300. * example: <code>{
  1301. * value: '...',
  1302. * overrides: {
  1303. * 'value1': [h1, h2],
  1304. * 'value2': [h3]
  1305. * }
  1306. * }</code>
  1307. */
  1308. getGlobConfigValueWithOverrides: function (templateName, expression) {
  1309. var express = expression.match(/<(.*?)>/g);
  1310. var value = expression;
  1311. var overrideHostToValue = {};
  1312. if (express != null) {
  1313. express.forEach(function (_express) {
  1314. var index = parseInt(_express.match(/\[([\d]*)(?=\])/)[1]);
  1315. var globalObj = this.get('globalConfigs').findProperty('name', templateName[index]);
  1316. if (globalObj) {
  1317. var globOverride = globalObj.overrides;
  1318. if (globOverride != null) {
  1319. for (var ov in globOverride) {
  1320. globOverride[ov].forEach(function (host) {
  1321. var replacedVal = (host in overrideHostToValue) ? overrideHostToValue[host] : expression;
  1322. overrideHostToValue[host] = replacedVal.replace(_express, ov);
  1323. }, this);
  1324. }
  1325. }
  1326. value = expression.replace(_express, globalObj.value);
  1327. } else {
  1328. value = null;
  1329. }
  1330. }, this);
  1331. }
  1332. return this.getValueWithOverrides(value, overrideHostToValue)
  1333. },
  1334. getValueWithOverrides: function (value, overrideHostToValue) {
  1335. var valueWithOverrides = {
  1336. value: value,
  1337. overrides: {}
  1338. };
  1339. if (!jQuery.isEmptyObject(overrideHostToValue)) {
  1340. for (var host in overrideHostToValue) {
  1341. var hostVal = overrideHostToValue[host];
  1342. if (!(hostVal in valueWithOverrides.overrides)) {
  1343. valueWithOverrides.overrides[hostVal] = [];
  1344. }
  1345. valueWithOverrides.overrides[hostVal].push(host);
  1346. }
  1347. }
  1348. return valueWithOverrides;
  1349. },
  1350. /**
  1351. * Saves cluster level configurations for all necessary sites.
  1352. * PUT calls are made to /api/v1/clusters/clusterName for each site.
  1353. * @return {Boolean}
  1354. * @method doPUTClusterConfigurations
  1355. */
  1356. doPUTClusterConfigurations: function () {
  1357. this.set('saveConfigsFlag', true);
  1358. var serviceConfigTags = this.get('serviceConfigTags');
  1359. this.setNewTagNames(serviceConfigTags);
  1360. var siteNameToServerDataMap = {};
  1361. this.set('putClusterConfigsCallsNumber', serviceConfigTags.length);
  1362. serviceConfigTags.forEach(function (_serviceTags) {
  1363. var configs = this.createConfigObject(_serviceTags.siteName, _serviceTags.newTagName);
  1364. if (configs) {
  1365. this.doPUTClusterConfiguration(_serviceTags.siteName, configs);
  1366. siteNameToServerDataMap[_serviceTags.siteName] = configs;
  1367. } else {
  1368. if (this.decrementProperty('putClusterConfigsCallsNumber') === 0) {
  1369. this.onDoPUTClusterConfigurations();
  1370. }
  1371. }
  1372. }, this);
  1373. this.set("savedSiteNameToServerServiceConfigDataMap", siteNameToServerDataMap);
  1374. },
  1375. /**
  1376. * create different config object depending on siteName
  1377. * @param {String} siteName
  1378. * @param {String} tagName
  1379. * @returns {Object|null}
  1380. * @method createConfigObject
  1381. */
  1382. createConfigObject: function (siteName, tagName) {
  1383. console.log("TRACE: Inside " + siteName);
  1384. var configObject;
  1385. switch (siteName) {
  1386. case 'global':
  1387. configObject = this.createGlobalSiteObj(tagName, this.get('globalConfigs'));
  1388. break;
  1389. case 'core-site':
  1390. if (this.get('content.serviceName') === 'HDFS' || this.get('content.serviceName') === 'GLUSTERFS') {
  1391. configObject = this.createCoreSiteObj(tagName);
  1392. } else {
  1393. return null;
  1394. }
  1395. break;
  1396. default:
  1397. var filename = (App.config.get('filenameExceptions').contains(siteName)) ? siteName : siteName + '.xml';
  1398. if (filename === 'mapred-queue-acls.xml' && !App.supports.capacitySchedulerUi) {
  1399. return null;
  1400. }
  1401. return this.createSiteObj(siteName, tagName, this.get('uiConfigs').filterProperty('filename', filename));
  1402. }
  1403. return configObject;
  1404. },
  1405. /**
  1406. * load existen properties and compare them with current if there are
  1407. * differences - trigger doPUTClusterConfigurationSite to save new properties
  1408. * @param {String} siteName
  1409. * @param {Object} newConfig
  1410. * @method doPUTClusterConfiguration
  1411. */
  1412. doPUTClusterConfiguration: function (siteName, newConfig) {
  1413. var oldConfig = App.router.get('configurationController').getConfigsByTags([
  1414. {siteName: siteName, tagName: this.loadedClusterSiteToTagMap[siteName]}
  1415. ]);
  1416. oldConfig = oldConfig[0] || {};
  1417. var oldProperties = oldConfig.properties || {};
  1418. var oldAttributes = oldConfig["properties_attributes"] || {};
  1419. var newProperties = newConfig.properties || {};
  1420. var newAttributes = newConfig["properties_attributes"] || {};
  1421. if (this.isAttributesChanged(oldAttributes, newAttributes) || this.isConfigChanged(oldProperties, newProperties)) {
  1422. this.doPUTClusterConfigurationSite(newConfig);
  1423. } else {
  1424. if (this.decrementProperty('putClusterConfigsCallsNumber') === 0) {
  1425. this.onDoPUTClusterConfigurations();
  1426. }
  1427. }
  1428. },
  1429. /**
  1430. * Compares the loaded config values with the saving config values.
  1431. * @param {Object} loadedConfig -
  1432. * loadedConfig: {
  1433. * configName1: "configValue1",
  1434. * configName2: "configValue2"
  1435. * }
  1436. * @param {Object} savingConfig
  1437. * savingConfig: {
  1438. * configName1: "configValue1",
  1439. * configName2: "configValue2"
  1440. * }
  1441. * @returns {boolean}
  1442. * @method isConfigChanged
  1443. */
  1444. isConfigChanged: function (loadedConfig, savingConfig) {
  1445. if (loadedConfig != null && savingConfig != null) {
  1446. var seenLoadKeys = [];
  1447. for (var loadKey in loadedConfig) {
  1448. if (!loadedConfig.hasOwnProperty(loadKey)) continue;
  1449. seenLoadKeys.push(loadKey);
  1450. var loadValue = loadedConfig[loadKey];
  1451. var saveValue = savingConfig[loadKey];
  1452. if ("boolean" == typeof(saveValue)) {
  1453. saveValue = saveValue.toString();
  1454. }
  1455. if (saveValue == null) {
  1456. saveValue = "null";
  1457. }
  1458. if (loadValue !== saveValue) {
  1459. return true;
  1460. }
  1461. }
  1462. for (var saveKey in savingConfig) {
  1463. if (seenLoadKeys.indexOf(saveKey) < 0) {
  1464. return true;
  1465. }
  1466. }
  1467. }
  1468. return false;
  1469. },
  1470. /**
  1471. * Compares the loaded config properties attributes with the saving config properties attributes.
  1472. * @param {Object} oldAttributes -
  1473. * oldAttributes: {
  1474. * supports: {
  1475. * final: {
  1476. * "configValue1" : "true",
  1477. * "configValue2" : "true"
  1478. * }
  1479. * }
  1480. * }
  1481. * @param {Object} newAttributes
  1482. * newAttributes: {
  1483. * supports: {
  1484. * final: {
  1485. * "configValue1" : "true",
  1486. * "configValue2" : "true"
  1487. * }
  1488. * }
  1489. * }
  1490. * @returns {boolean}
  1491. * @method isConfigChanged
  1492. */
  1493. isAttributesChanged: function (oldAttributes, newAttributes) {
  1494. oldAttributes = oldAttributes.final || {};
  1495. newAttributes = newAttributes.final || {};
  1496. var key;
  1497. for (key in oldAttributes) {
  1498. if (oldAttributes.hasOwnProperty(key)
  1499. && (!newAttributes.hasOwnProperty(key) || newAttributes[key] !== oldAttributes[key])) {
  1500. return true;
  1501. }
  1502. }
  1503. for (key in newAttributes) {
  1504. if (newAttributes.hasOwnProperty(key)
  1505. && (!oldAttributes.hasOwnProperty(key) || newAttributes[key] !== oldAttributes[key])) {
  1506. return true;
  1507. }
  1508. }
  1509. return false;
  1510. },
  1511. /**
  1512. * Saves configuration of a particular site. The provided data
  1513. * contains the site name and tag to be used.
  1514. * @param {Object} data
  1515. * @method doPUTClusterConfigurationSite
  1516. */
  1517. doPUTClusterConfigurationSite: function (data) {
  1518. App.ajax.send({
  1519. name: 'config.cluster_configuration.put',
  1520. sender: this,
  1521. data: {
  1522. data: JSON.stringify({
  1523. Clusters: {
  1524. desired_config: data
  1525. }
  1526. }),
  1527. cluster: App.router.getClusterName()
  1528. },
  1529. success: 'doPUTClusterConfigurationSiteSuccessCallback',
  1530. error: 'doPUTClusterConfigurationSiteErrorCallback'
  1531. });
  1532. },
  1533. doPUTClusterConfigurationSiteSuccessCallback: function () {
  1534. if (this.decrementProperty('putClusterConfigsCallsNumber') === 0) {
  1535. this.onDoPUTClusterConfigurations();
  1536. }
  1537. },
  1538. doPUTClusterConfigurationSiteErrorCallback: function () {
  1539. this.set('saveConfigsFlag', false);
  1540. this.doPUTClusterConfigurationSiteSuccessCallback();
  1541. },
  1542. /**
  1543. * add newTagName property to each config in serviceConfigs
  1544. * @param serviceConfigs
  1545. */
  1546. setNewTagNames: function (serviceConfigs) {
  1547. var time = (new Date).getTime();
  1548. serviceConfigs.forEach(function (_serviceConfigs) {
  1549. _serviceConfigs.newTagName = 'version' + time;
  1550. }, this);
  1551. },
  1552. /**
  1553. * Save "final" attribute for properties
  1554. * @param {Array} properties - array of properties
  1555. * @returns {Object|null}
  1556. * */
  1557. getConfigAttributes: function(properties) {
  1558. var attributes = {
  1559. final: {}
  1560. };
  1561. var finalAttributes = attributes.final;
  1562. var hasAttributes = false;
  1563. properties.forEach(function (property) {
  1564. if (property.isRequiredByAgent !== false && property.isFinal) {
  1565. hasAttributes = true;
  1566. finalAttributes[property.name] = "true";
  1567. }
  1568. });
  1569. if (hasAttributes) {
  1570. return attributes;
  1571. }
  1572. return null;
  1573. },
  1574. /**
  1575. * create global site object
  1576. * @param {String} tagName
  1577. * @param {Array} globalConfigs array of config objects
  1578. * @return {{"type": String, "tag": String, "properties": Object}}
  1579. * @method createGlobalSiteObj
  1580. */
  1581. createGlobalSiteObj: function (tagName, globalConfigs) {
  1582. var heapsizeException = ['hadoop_heapsize', 'yarn_heapsize', 'nodemanager_heapsize', 'resourcemanager_heapsize', 'apptimelineserver_heapsize', 'jobhistory_heapsize'];
  1583. var globalSiteProperties = {};
  1584. globalConfigs.forEach(function (_globalSiteObj) {
  1585. // do not pass any globalConfigs whose name ends with _host or _hosts
  1586. if (_globalSiteObj.isRequiredByAgent !== false) {
  1587. // append "m" to JVM memory options except for hadoop_heapsize
  1588. if (/_heapsize|_newsize|_maxnewsize$/.test(_globalSiteObj.name) && !heapsizeException.contains(_globalSiteObj.name)) {
  1589. _globalSiteObj.value += "m";
  1590. }
  1591. globalSiteProperties[_globalSiteObj.name] = App.config.escapeXMLCharacters(_globalSiteObj.value);
  1592. //this.recordHostOverride(_globalSiteObj, 'global', tagName, this);
  1593. //console.log("TRACE: name of the global property is: " + _globalSiteObj.name);
  1594. //console.log("TRACE: value of the global property is: " + _globalSiteObj.value);
  1595. }
  1596. }, this);
  1597. var result = {"type": "global", "tag": tagName, "properties": globalSiteProperties};
  1598. var attributes = this.getConfigAttributes(globalConfigs);
  1599. if (attributes) {
  1600. result['properties_attributes'] = attributes;
  1601. }
  1602. return result;
  1603. },
  1604. /**
  1605. * create core site object
  1606. * @param tagName
  1607. * @return {{"type": String, "tag": String, "properties": Object}}
  1608. * @method createCoreSiteObj
  1609. */
  1610. createCoreSiteObj: function (tagName) {
  1611. var coreSiteObj = this.get('uiConfigs').filterProperty('filename', 'core-site.xml');
  1612. var coreSiteProperties = {};
  1613. coreSiteObj.forEach(function (_coreSiteObj) {
  1614. coreSiteProperties[_coreSiteObj.name] = App.config.escapeXMLCharacters(_coreSiteObj.value);
  1615. //this.recordHostOverride(_coreSiteObj, 'core-site', tagName, this);
  1616. }, this);
  1617. var result = {"type": "core-site", "tag": tagName, "properties": coreSiteProperties};
  1618. var attributes = this.getConfigAttributes(coreSiteObj);
  1619. if (attributes) {
  1620. result['properties_attributes'] = attributes;
  1621. }
  1622. return result;
  1623. },
  1624. /**
  1625. * create site object
  1626. * @param siteName
  1627. * @param tagName
  1628. * @param siteObj
  1629. * @return {Object}
  1630. */
  1631. createSiteObj: function (siteName, tagName, siteObj) {
  1632. var siteProperties = {};
  1633. siteObj.forEach(function (_siteObj) {
  1634. switch (siteName) {
  1635. case 'falcon-startup.properties':
  1636. case 'falcon-runtime.properties':
  1637. case 'pig-properties':
  1638. siteProperties[_siteObj.name] = _siteObj.value;
  1639. break;
  1640. default:
  1641. siteProperties[_siteObj.name] = this.setServerConfigValue(_siteObj.name, _siteObj.value);
  1642. }
  1643. }, this);
  1644. var result = {"type": siteName, "tag": tagName, "properties": siteProperties};
  1645. var attributes = this.getConfigAttributes(siteObj);
  1646. if (attributes) {
  1647. result['properties_attributes'] = attributes;
  1648. }
  1649. return result;
  1650. },
  1651. /**
  1652. * This method will be moved to config's decorators class.
  1653. *
  1654. * For now, provide handling for special properties that need
  1655. * be specified in special format required for server.
  1656. *
  1657. * @param configName {String} - name of config property
  1658. * @param value {Mixed} - value of config property
  1659. *
  1660. * @return {String} - formated value
  1661. */
  1662. setServerConfigValue: function (configName, value) {
  1663. switch (configName) {
  1664. case 'storm.zookeeper.servers':
  1665. return JSON.stringify(value).replace(/"/g, "'");
  1666. break;
  1667. case 'content':
  1668. return value;
  1669. break;
  1670. default:
  1671. return App.config.escapeXMLCharacters(value);
  1672. }
  1673. },
  1674. /**
  1675. * Array of Objects
  1676. * {
  1677. * hostProperty - hostName property name for current component
  1678. * componentName - master componentName
  1679. * serviceName - serviceName of component
  1680. * serviceUseThis - services that use hostname property of component(componentName)
  1681. * m(multiple) - true if can be more than one components installed on cluster
  1682. * }
  1683. */
  1684. hostComponentsmapping: [
  1685. {
  1686. hostProperty: 'namenode_host',
  1687. componentName: 'NAMENODE',
  1688. serviceName: 'HDFS',
  1689. serviceUseThis: [],
  1690. m: true
  1691. },
  1692. {
  1693. hostProperty: 'snamenode_host',
  1694. componentName: 'SECONDARY_NAMENODE',
  1695. serviceName: 'HDFS',
  1696. serviceUseThis: []
  1697. },
  1698. {
  1699. hostProperty: 'jobtracker_host',
  1700. componentName: 'JOBTRACKER',
  1701. serviceName: 'MAPREDUCE',
  1702. serviceUseThis: []
  1703. },
  1704. {
  1705. hostProperty: 'jobtracker_host',
  1706. componentName: 'JOBTRACKER',
  1707. serviceName: 'MAPREDUCE2',
  1708. serviceUseThis: []
  1709. },
  1710. {
  1711. hostProperty: 'hs_host',
  1712. componentName: 'HISTORYSERVER',
  1713. serviceName: 'MAPREDUCE2',
  1714. serviceUseThis: ['YARN']
  1715. },
  1716. {
  1717. hostProperty: 'ats_host',
  1718. componentName: 'APP_TIMELINE_SERVER',
  1719. serviceName: 'YARN',
  1720. serviceUseThis: []
  1721. },
  1722. {
  1723. hostProperty: 'rm_host',
  1724. componentName: 'RESOURCEMANAGER',
  1725. serviceName: 'YARN',
  1726. serviceUseThis: []
  1727. },
  1728. {
  1729. hostProperty: 'hivemetastore_host',
  1730. componentName: 'HIVE_SERVER',
  1731. serviceName: 'HIVE',
  1732. serviceUseThis: ['WEBHCAT']
  1733. },
  1734. {
  1735. hostProperty: 'oozieserver_host',
  1736. componentName: 'OOZIE_SERVER',
  1737. serviceName: 'OOZIE',
  1738. serviceUseThis: []
  1739. },
  1740. {
  1741. hostProperty: 'hbasemaster_host',
  1742. componentName: 'HBASE_MASTER',
  1743. serviceName: 'HBASE',
  1744. serviceUseThis: [],
  1745. m: true
  1746. },
  1747. {
  1748. hostProperty: 'hueserver_host',
  1749. componentName: 'HUE_SERVER',
  1750. serviceName: 'HUE',
  1751. serviceUseThis: []
  1752. },
  1753. {
  1754. hostProperty: 'webhcatserver_host',
  1755. componentName: 'WEBHCAT_SERVER',
  1756. serviceName: 'WEBHCAT',
  1757. serviceUseThis: [],
  1758. m: true
  1759. },
  1760. {
  1761. hostProperty: 'zookeeperserver_hosts',
  1762. componentName: 'ZOOKEEPER_SERVER',
  1763. serviceName: 'ZOOKEEPER',
  1764. serviceUseThis: ['HBASE', 'WEBHCAT'],
  1765. m: true
  1766. },
  1767. {
  1768. hostProperty: 'stormuiserver_host',
  1769. componentName: 'STORM_UI_SERVER',
  1770. serviceName: 'STORM',
  1771. serviceUseThis: []
  1772. },
  1773. {
  1774. hostProperty: 'drpcserver_host',
  1775. componentName: 'DRPC_SERVER',
  1776. serviceName: 'STORM',
  1777. serviceUseThis: []
  1778. },
  1779. {
  1780. hostProperty: 'storm_rest_api_host',
  1781. componentName: 'STORM_REST_API',
  1782. serviceName: 'STORM',
  1783. serviceUseThis: []
  1784. },
  1785. {
  1786. hostProperty: 'supervisor_hosts',
  1787. componentName: 'SUPERVISOR',
  1788. serviceName: 'STORM',
  1789. serviceUseThis: [],
  1790. m: true
  1791. }
  1792. ],
  1793. /**
  1794. * Adds host name of master component to global config;
  1795. * @method addHostNamesToGlobalConfig
  1796. */
  1797. addHostNamesToGlobalConfig: function () {
  1798. var serviceName = this.get('content.serviceName');
  1799. var globalConfigs = this.get('globalConfigs');
  1800. //namenode_host is required to derive "fs.default.name" a property of core-site
  1801. try {
  1802. this.setHostForService('HDFS', 'NAMENODE', 'namenode_host', true);
  1803. } catch (err) {
  1804. console.log("No NameNode Host available. This is expected if you're using GLUSTERFS rather than HDFS.");
  1805. }
  1806. var hostProperties = this.get('hostComponentsmapping').filter(function (h) {
  1807. return h.serviceUseThis.contains(serviceName) || h.serviceName == serviceName;
  1808. });
  1809. hostProperties.forEach(function (h) {
  1810. this.setHostForService(h.serviceName, h.componentName, h.hostProperty, h.m);
  1811. }, this);
  1812. if (serviceName === 'HIVE') {
  1813. var hiveDb = globalConfigs.findProperty('name', 'hive_database').value;
  1814. if (['Existing MySQL Database', 'Existing Oracle Database', 'Existing PostgreSQL Database'].contains(hiveDb)) {
  1815. globalConfigs.findProperty('name', 'hive_hostname').isVisible = true;
  1816. }
  1817. }
  1818. if (serviceName === 'OOZIE') {
  1819. var oozieDb = globalConfigs.findProperty('name', 'oozie_database').value;
  1820. if (['Existing MySQL Database', 'Existing Oracle Database', 'Existing PostgreSQL Database'].contains(oozieDb)) {
  1821. globalConfigs.findProperty('name', 'oozie_hostname').isVisible = true;
  1822. }
  1823. }
  1824. },
  1825. /**
  1826. * set host name(s) property for component
  1827. * @param {String} serviceName - service name of component
  1828. * @param {String} componentName - component name whic host we want to know
  1829. * @param {String} hostProperty - name of host property for current component
  1830. * @param {Boolean} multiple - true if can be more than one component
  1831. * @method setHostForService
  1832. */
  1833. setHostForService: function (serviceName, componentName, hostProperty, multiple) {
  1834. var globalConfigs = this.get('globalConfigs');
  1835. var serviceConfigs = this.get('serviceConfigs').findProperty('serviceName', serviceName).get('configs');
  1836. var hostConfig = serviceConfigs.findProperty('name', hostProperty);
  1837. if (hostConfig) {
  1838. hostConfig.defaultValue = this.getMasterComponentHostValue(componentName, multiple);
  1839. globalConfigs.push(hostConfig);
  1840. }
  1841. },
  1842. /**
  1843. * get hostName of component
  1844. * @param {String} componentName
  1845. * @param {Boolean} multiple - true if can be more than one component installed on cluster
  1846. * @return {String|Array|Boolean} hostName|hostNames|false if missing component
  1847. * @method getMasterComponentHostValue
  1848. */
  1849. getMasterComponentHostValue: function (componentName, multiple) {
  1850. var components = this.get('content.hostComponents').filterProperty('componentName', componentName);
  1851. if (components.length > 0) {
  1852. return multiple ? components.mapProperty('hostName') : components[0].get('hostName');
  1853. }
  1854. return false;
  1855. },
  1856. /**
  1857. * Provides service component name and display-name information for
  1858. * the current selected service.
  1859. * @return {Em.Array} validComponents - array of valid components
  1860. * @method getCurrentServiceComponents
  1861. */
  1862. getCurrentServiceComponents: function () {
  1863. var components = this.get('content.hostComponents');
  1864. var validComponents = Ember.A([]);
  1865. var seenComponents = {};
  1866. components.forEach(function (component) {
  1867. var cn = component.get('componentName');
  1868. var cdn = component.get('displayName');
  1869. if (!seenComponents[cn]) {
  1870. validComponents.push(Ember.Object.create({
  1871. componentName: cn,
  1872. displayName: cdn,
  1873. selected: false
  1874. }));
  1875. seenComponents[cn] = cn;
  1876. }
  1877. });
  1878. return validComponents;
  1879. }.property('content'),
  1880. /**
  1881. * trigger loadStep
  1882. * @method loadStep
  1883. */
  1884. doCancel: function () {
  1885. this.loadStep();
  1886. },
  1887. /**
  1888. * trigger restartAllServiceHostComponents(batchUtils) if confirmed in popup
  1889. * @method restartAllStaleConfigComponents
  1890. * @return App.showConfirmationFeedBackPopup
  1891. */
  1892. restartAllStaleConfigComponents: function () {
  1893. var self = this;
  1894. var serviceDisplayName = this.get('content.displayName');
  1895. var bodyMessage = Em.Object.create({
  1896. confirmMsg: Em.I18n.t('services.service.restartAll.confirmMsg').format(serviceDisplayName),
  1897. confirmButton: Em.I18n.t('services.service.restartAll.confirmButton'),
  1898. additionalWarningMsg: this.get('content.passiveState') === 'OFF' ? Em.I18n.t('services.service.restartAll.warningMsg.turnOnMM').format(serviceDisplayName) : null
  1899. });
  1900. return App.showConfirmationFeedBackPopup(function (query) {
  1901. var selectedService = self.get('content.id');
  1902. batchUtils.restartAllServiceHostComponents(selectedService, true, query);
  1903. }, bodyMessage);
  1904. },
  1905. /**
  1906. * trigger launchHostComponentRollingRestart(batchUtils)
  1907. * @method rollingRestartStaleConfigSlaveComponents
  1908. */
  1909. rollingRestartStaleConfigSlaveComponents: function (componentName) {
  1910. batchUtils.launchHostComponentRollingRestart(componentName.context, this.get('content.displayName'), this.get('content.passiveState') === "ON", true);
  1911. },
  1912. /**
  1913. * trigger showItemsShouldBeRestarted popup with hosts that requires resetart
  1914. * @method showHostsShouldBeRestarted
  1915. */
  1916. showHostsShouldBeRestarted: function () {
  1917. var hosts = [];
  1918. for (var hostName in this.get('content.restartRequiredHostsAndComponents')) {
  1919. hosts.push(hostName);
  1920. }
  1921. var hostsText = hosts.length == 1 ? Em.I18n.t('common.host') : Em.I18n.t('common.hosts');
  1922. hosts = hosts.join(', ');
  1923. this.showItemsShouldBeRestarted(hosts, Em.I18n.t('service.service.config.restartService.shouldBeRestarted').format(hostsText));
  1924. },
  1925. /**
  1926. * trigger showItemsShouldBeRestarted popup with components that requires resetart
  1927. * @method showComponentsShouldBeRestarted
  1928. */
  1929. showComponentsShouldBeRestarted: function () {
  1930. var rhc = this.get('content.restartRequiredHostsAndComponents');
  1931. var hostsComponets = [];
  1932. var componentsObject = {};
  1933. for (var hostName in rhc) {
  1934. rhc[hostName].forEach(function (hostComponent) {
  1935. hostsComponets.push(hostComponent);
  1936. if (componentsObject[hostComponent] != undefined) {
  1937. componentsObject[hostComponent]++;
  1938. } else {
  1939. componentsObject[hostComponent] = 1;
  1940. }
  1941. })
  1942. }
  1943. var componentsList = [];
  1944. for (var obj in componentsObject) {
  1945. var componentDisplayName = (componentsObject[obj] > 1) ? obj + 's' : obj;
  1946. componentsList.push(componentsObject[obj] + ' ' + componentDisplayName);
  1947. }
  1948. var componentsText = componentsList.length == 1 ? Em.I18n.t('common.component') : Em.I18n.t('common.components');
  1949. hostsComponets = componentsList.join(', ');
  1950. this.showItemsShouldBeRestarted(hostsComponets, Em.I18n.t('service.service.config.restartService.shouldBeRestarted').format(componentsText));
  1951. },
  1952. showItemsShouldBeRestarted: function (content, header) {
  1953. App.ModalPopup.show({
  1954. content: content,
  1955. header: header,
  1956. bodyClass: Em.View.extend({
  1957. templateName: require('templates/common/selectable_popup'),
  1958. textareaVisible: false,
  1959. textTrigger: function () {
  1960. this.set('textareaVisible', !this.get('textareaVisible'));
  1961. },
  1962. putContentToTextarea: function () {
  1963. var content = this.get('parentView.content');
  1964. if (this.get('textareaVisible')) {
  1965. var wrapper = $(".task-detail-log-maintext");
  1966. $('.task-detail-log-clipboard').html(content).width(wrapper.width()).height(wrapper.height());
  1967. Em.run.next(function () {
  1968. $('.task-detail-log-clipboard').select();
  1969. });
  1970. }
  1971. }.observes('textareaVisible')
  1972. }),
  1973. secondary: null
  1974. });
  1975. },
  1976. /**
  1977. * add new overridden property to config property object
  1978. * @param {object} serviceConfigProperty - config property object
  1979. * @method addOverrideProperty
  1980. */
  1981. addOverrideProperty: function (serviceConfigProperty) {
  1982. var overrides = serviceConfigProperty.get('overrides');
  1983. if (!overrides) {
  1984. overrides = [];
  1985. serviceConfigProperty.set('overrides', overrides);
  1986. }
  1987. // create new override with new value
  1988. var newSCP = App.ServiceConfigProperty.create(serviceConfigProperty);
  1989. newSCP.set('value', '');
  1990. newSCP.set('isOriginalSCP', false); // indicated this is overridden value,
  1991. newSCP.set('parentSCP', serviceConfigProperty);
  1992. newSCP.set('isEditable', true);
  1993. console.debug("createOverrideProperty(): Added:", newSCP, " to main-property:", serviceConfigProperty);
  1994. overrides.pushObject(newSCP);
  1995. },
  1996. /**
  1997. * trigger manageConfigurationGroups
  1998. * @method manageConfigurationGroup
  1999. */
  2000. manageConfigurationGroup: function () {
  2001. this.manageConfigurationGroups();
  2002. },
  2003. manageConfigurationGroups: function (controller) {
  2004. var serviceData = (controller && controller.get('selectedService')) || this.get('content');
  2005. var serviceName = serviceData.get('serviceName');
  2006. var displayName = serviceData.get('displayName');
  2007. App.router.get('manageConfigGroupsController').set('isInstaller', !!controller);
  2008. App.router.get('manageConfigGroupsController').set('serviceName', serviceName);
  2009. if (controller) {
  2010. App.router.get('manageConfigGroupsController').set('isAddService', controller.get('content.controllerName') == 'addServiceController');
  2011. }
  2012. return App.ModalPopup.show({
  2013. header: Em.I18n.t('services.service.config_groups_popup.header').format(displayName),
  2014. bodyClass: App.MainServiceManageConfigGroupView.extend({
  2015. serviceName: serviceName,
  2016. displayName: displayName,
  2017. controllerBinding: 'App.router.manageConfigGroupsController'
  2018. }),
  2019. classNames: ['sixty-percent-width-modal', 'manage-configuration-group-popup'],
  2020. primary: Em.I18n.t('common.save'),
  2021. onPrimary: function () {
  2022. var modifiedConfigGroups = this.get('subViewController.hostsModifiedConfigGroups');
  2023. // Save modified config-groups
  2024. if (!!controller) {
  2025. controller.set('selectedService.configGroups', App.router.get('manageConfigGroupsController.configGroups'));
  2026. controller.selectedServiceObserver();
  2027. if (controller.get('name') == "wizardStep7Controller") {
  2028. if (controller.get('selectedService.selected') === false && modifiedConfigGroups.toDelete.length > 0) {
  2029. controller.setGroupsToDelete(modifiedConfigGroups.toDelete);
  2030. }
  2031. App.config.persistWizardStep7ConfigGroups();
  2032. this.updateConfigGroupOnServicePage();
  2033. }
  2034. this.hide();
  2035. return;
  2036. }
  2037. console.log("manageConfigurationGroups(): Saving modified config-groups: ", modifiedConfigGroups);
  2038. var self = this;
  2039. var errors = [];
  2040. var deleteQueriesCounter = modifiedConfigGroups.toClearHosts.length + modifiedConfigGroups.toDelete.length;
  2041. var createQueriesCounter = modifiedConfigGroups.toSetHosts.length + modifiedConfigGroups.toCreate.length;
  2042. var deleteQueriesRun = false;
  2043. var createQueriesRun = false;
  2044. var runNextQuery = function () {
  2045. if (!deleteQueriesRun && deleteQueriesCounter > 0) {
  2046. deleteQueriesRun = true;
  2047. modifiedConfigGroups.toClearHosts.forEach(function (cg) {
  2048. App.config.clearConfigurationGroupHosts(cg, finishFunction, finishFunction);
  2049. }, this);
  2050. modifiedConfigGroups.toDelete.forEach(function (cg) {
  2051. App.config.deleteConfigGroup(cg, finishFunction, finishFunction);
  2052. }, this);
  2053. } else if (!createQueriesRun && deleteQueriesCounter < 1) {
  2054. createQueriesRun = true;
  2055. modifiedConfigGroups.toSetHosts.forEach(function (cg) {
  2056. App.config.updateConfigurationGroup(cg, finishFunction, finishFunction);
  2057. }, this);
  2058. modifiedConfigGroups.toCreate.forEach(function (cg) {
  2059. App.config.postNewConfigurationGroup(cg, finishFunction);
  2060. }, this);
  2061. }
  2062. };
  2063. var finishFunction = function (xhr, text, errorThrown) {
  2064. if (xhr && errorThrown) {
  2065. var error = xhr.status + "(" + errorThrown + ") ";
  2066. try {
  2067. var json = $.parseJSON(xhr.responseText);
  2068. error += json.message;
  2069. } catch (err) {
  2070. }
  2071. console.error('Error updating Config Group:', error);
  2072. errors.push(error);
  2073. }
  2074. if (createQueriesRun) {
  2075. createQueriesCounter--;
  2076. } else {
  2077. deleteQueriesCounter--;
  2078. }
  2079. if (deleteQueriesCounter + createQueriesCounter < 1) {
  2080. if (errors.length > 0) {
  2081. console.log(errors);
  2082. self.get('subViewController').set('errorMessage', errors.join(". "));
  2083. } else {
  2084. self.updateConfigGroupOnServicePage();
  2085. self.hide();
  2086. }
  2087. } else {
  2088. runNextQuery();
  2089. }
  2090. };
  2091. runNextQuery();
  2092. },
  2093. onSecondary: function () {
  2094. this.hide();
  2095. },
  2096. onClose: function () {
  2097. this.hide();
  2098. },
  2099. subViewController: function () {
  2100. return App.router.get('manageConfigGroupsController');
  2101. }.property('App.router.manageConfigGroupsController'),
  2102. updateConfigGroupOnServicePage: function () {
  2103. var subViewController = this.get('subViewController');
  2104. var selectedConfigGroup = subViewController.get('selectedConfigGroup');
  2105. var managedConfigGroups = subViewController.get('configGroups');
  2106. if (!controller) {
  2107. controller = App.router.get('mainServiceInfoConfigsController');
  2108. controller.set('configGroups', managedConfigGroups);
  2109. } else {
  2110. controller.set('selectedService.configGroups', managedConfigGroups);
  2111. }
  2112. //check whether selectedConfigGroup was selected
  2113. if (selectedConfigGroup && controller.get('configGroups').someProperty('name', selectedConfigGroup.get('name'))) {
  2114. controller.set('selectedConfigGroup', selectedConfigGroup);
  2115. } else {
  2116. controller.set('selectedConfigGroup', managedConfigGroups.findProperty('isDefault', true));
  2117. }
  2118. },
  2119. updateButtons: function () {
  2120. var modified = this.get('subViewController.isHostsModified');
  2121. this.set('disablePrimary', !modified);
  2122. }.observes('subViewController.isHostsModified'),
  2123. secondary: Em.I18n.t('common.cancel'),
  2124. didInsertElement: Em.K
  2125. });
  2126. },
  2127. /**
  2128. * If user chabges cfg group if some configs was changed popup with propose to save changes must be shown
  2129. * @param {object} event - triggered event for selecting another config-group
  2130. * @method selectConfigGroup
  2131. */
  2132. selectConfigGroup: function (event) {
  2133. if (!this.get('isInit')) {
  2134. if (this.hasUnsavedChanges()) {
  2135. this.showSavePopup(null, event);
  2136. return;
  2137. }
  2138. }
  2139. this.set('selectedConfigGroup', event.context);
  2140. },
  2141. /**
  2142. * Are some unsaved changes available
  2143. * @returns {boolean}
  2144. */
  2145. hasUnsavedChanges: function () {
  2146. return this.get('hash') != this.getHash();
  2147. },
  2148. /**
  2149. * If some configs are changed and user navigates away or select another config-group, show this popup with propose to save changes
  2150. * @param {String} path
  2151. * @param {object} event - triggered event for selecting another config-group
  2152. * @method showSavePopup
  2153. */
  2154. showSavePopup: function (path, event) {
  2155. var self = this;
  2156. return App.ModalPopup.show({
  2157. header: Em.I18n.t('common.warning'),
  2158. body: Em.I18n.t('services.service.config.exitPopup.body'),
  2159. footerClass: Ember.View.extend({
  2160. templateName: require('templates/main/service/info/save_popup_footer'),
  2161. isSaveDisabled: function () {
  2162. return self.get('isSubmitDisabled');
  2163. }.property()
  2164. }),
  2165. primary: Em.I18n.t('common.save'),
  2166. secondary: Em.I18n.t('common.cancel'),
  2167. onSave: function () {
  2168. self.restartServicePopup();
  2169. this.hide();
  2170. },
  2171. onDiscard: function () {
  2172. if (path) {
  2173. self.set('forceTransition', true);
  2174. App.router.route(path);
  2175. } else if (event) {
  2176. // Prevent multiple popups
  2177. self.set('hash', self.getHash());
  2178. self.selectConfigGroup(event);
  2179. }
  2180. this.hide();
  2181. },
  2182. onCancel: function () {
  2183. this.hide();
  2184. }
  2185. });
  2186. }
  2187. });