configs.js 82 KB

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