configs.js 78 KB

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