config.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. var App = require('app');
  19. var serviceComponents = {};
  20. var configGroupsByTag = [];
  21. var globalPropertyToServicesMap = null;
  22. App.config = Em.Object.create({
  23. preDefinedServiceConfigs: require('data/service_configs'),
  24. configMapping: require('data/config_mapping'),
  25. preDefinedConfigProperties: require('data/config_properties').configProperties,
  26. preDefinedCustomConfigs: require('data/custom_configs'),
  27. //categories which contain custom configs
  28. categoriesWithCustom: ['CapacityScheduler'],
  29. //configs with these filenames go to appropriate category not in Advanced
  30. customFileNames: function() {
  31. if (App.supports.capacitySchedulerUi) {
  32. return ['capacity-scheduler.xml', 'mapred-queue-acls.xml'];
  33. } else {
  34. return [];
  35. }
  36. }.property(''),
  37. /**
  38. * Cache of loaded configurations. This is useful in not loading
  39. * same configuration multiple times. It is populated in multiple
  40. * places.
  41. *
  42. * Example:
  43. * {
  44. * 'global_version1': {...},
  45. * 'global_version2': {...},
  46. * 'hdfs-site_version3': {...},
  47. * }
  48. */
  49. loadedConfigurationsCache: {},
  50. /**
  51. * Array of global "service/desired_tag/actual_tag" strings which
  52. * indicate different configurations. We cache these so that
  53. * we dont have to recalculate if two tags are difference.
  54. */
  55. differentGlobalTagsCache:[],
  56. identifyCategory: function(config){
  57. var category = null;
  58. var serviceConfigMetaData = this.get('preDefinedServiceConfigs').findProperty('serviceName', config.serviceName);
  59. if (serviceConfigMetaData) {
  60. serviceConfigMetaData.configCategories.forEach(function (_category) {
  61. if (_category.siteFileNames && Array.isArray(_category.siteFileNames) && _category.siteFileNames.contains(config.filename)) {
  62. category = _category;
  63. }
  64. });
  65. category = (category == null) ? serviceConfigMetaData.configCategories.findProperty('siteFileName', config.filename) : category;
  66. }
  67. return category;
  68. },
  69. /**
  70. * return:
  71. * configs,
  72. * globalConfigs,
  73. * mappingConfigs
  74. *
  75. * @param configGroups
  76. * @param advancedConfigs
  77. * @param tags
  78. * @param serviceName
  79. * @return {object}
  80. */
  81. mergePreDefinedWithLoaded: function (configGroups, advancedConfigs, tags, serviceName) {
  82. var configs = [];
  83. var globalConfigs = [];
  84. var preDefinedConfigs = this.get('preDefinedConfigProperties');
  85. var mappingConfigs = [];
  86. tags.forEach(function (_tag) {
  87. var isAdvanced = null;
  88. var properties = configGroups.filter(function (serviceConfigProperties) {
  89. return _tag.tagName === serviceConfigProperties.tag && _tag.siteName === serviceConfigProperties.type;
  90. });
  91. properties = (properties.length) ? properties = properties.objectAt(0).properties : {};
  92. for (var index in properties) {
  93. var configsPropertyDef = preDefinedConfigs.findProperty('name', index) || null;
  94. var serviceConfigObj = {
  95. name: index,
  96. value: properties[index],
  97. defaultValue: properties[index],
  98. filename: _tag.siteName + ".xml",
  99. isUserProperty: false,
  100. isOverridable: true
  101. };
  102. if (configsPropertyDef) {
  103. serviceConfigObj.displayType = configsPropertyDef.displayType;
  104. serviceConfigObj.isRequired = (configsPropertyDef.isRequired !== undefined) ? configsPropertyDef.isRequired : true;
  105. serviceConfigObj.isReconfigurable = (configsPropertyDef.isReconfigurable !== undefined) ? configsPropertyDef.isReconfigurable : true;
  106. serviceConfigObj.isVisible = (configsPropertyDef.isVisible !== undefined) ? configsPropertyDef.isVisible : true;
  107. serviceConfigObj.unit = (configsPropertyDef.unit !== undefined) ? configsPropertyDef.unit : undefined;
  108. serviceConfigObj.description = (configsPropertyDef.description !== undefined) ? configsPropertyDef.description : undefined;
  109. serviceConfigObj.isOverridable = configsPropertyDef.isOverridable === undefined ? true : configsPropertyDef.isOverridable;
  110. }
  111. if (_tag.siteName === 'global') {
  112. if (configsPropertyDef) {
  113. if (configsPropertyDef.displayType === 'int') {
  114. if (/\d+m$/.test(properties[index])) {
  115. serviceConfigObj.value = properties[index].slice(0, properties[index].length - 1);
  116. serviceConfigObj.defaultValue = serviceConfigObj.value;
  117. }
  118. }
  119. if (configsPropertyDef.displayType === 'checkbox') {
  120. switch (properties[index]) {
  121. case 'true' :
  122. serviceConfigObj.value = true;
  123. serviceConfigObj.defaultValue = true;
  124. break;
  125. case 'false' :
  126. serviceConfigObj.value = false;
  127. serviceConfigObj.defaultValue = false;
  128. break;
  129. }
  130. }
  131. }
  132. serviceConfigObj.id = 'puppet var';
  133. serviceConfigObj.serviceName = configsPropertyDef ? configsPropertyDef.serviceName : null;
  134. serviceConfigObj.displayName = configsPropertyDef ? configsPropertyDef.displayName : null;
  135. serviceConfigObj.category = configsPropertyDef ? configsPropertyDef.category : null;
  136. serviceConfigObj.options = configsPropertyDef ? configsPropertyDef.options : null;
  137. globalConfigs.push(serviceConfigObj);
  138. } else if (!this.get('configMapping').computed().someProperty('name', index)) {
  139. isAdvanced = advancedConfigs.someProperty('name', index);
  140. serviceConfigObj.id = 'site property';
  141. serviceConfigObj.displayType = 'advanced';
  142. serviceConfigObj.displayName = configsPropertyDef ? configsPropertyDef.displayName : index;
  143. serviceConfigObj.serviceName = serviceName;
  144. if (!isAdvanced || this.get('customFileNames').contains(serviceConfigObj.filename)) {
  145. var categoryMetaData = this.identifyCategory(serviceConfigObj);
  146. if (categoryMetaData != null) {
  147. serviceConfigObj.category = categoryMetaData.get('name');
  148. if(!isAdvanced) serviceConfigObj.isUserProperty = true;
  149. }
  150. } else {
  151. serviceConfigObj.category = 'Advanced';
  152. serviceConfigObj.filename = isAdvanced && advancedConfigs.findProperty('name', index).filename;
  153. }
  154. configs.push(serviceConfigObj);
  155. } else {
  156. mappingConfigs.push(serviceConfigObj);
  157. }
  158. }
  159. }, this);
  160. return {
  161. configs: configs,
  162. globalConfigs: globalConfigs,
  163. mappingConfigs: mappingConfigs
  164. }
  165. },
  166. /**
  167. * merge stored configs with pre-defined
  168. * @param storedConfigs
  169. * @param advancedConfigs
  170. * @return {*}
  171. */
  172. mergePreDefinedWithStored: function (storedConfigs, advancedConfigs) {
  173. var mergedConfigs = [];
  174. var preDefinedConfigs = $.extend(true, [], this.get('preDefinedConfigProperties'));
  175. var preDefinedNames = [];
  176. var storedNames = [];
  177. var names = [];
  178. var categoryMetaData = null;
  179. storedConfigs = (storedConfigs) ? storedConfigs : [];
  180. preDefinedNames = this.get('preDefinedConfigProperties').mapProperty('name');
  181. storedNames = storedConfigs.mapProperty('name');
  182. names = preDefinedNames.concat(storedNames).uniq();
  183. names.forEach(function (name) {
  184. var stored = storedConfigs.findProperty('name', name);
  185. var preDefined = preDefinedConfigs.findProperty('name', name);
  186. var configData = {};
  187. var configCategory = 'Advanced';
  188. var isAdvanced = advancedConfigs.someProperty('name', name);
  189. if (preDefined && stored) {
  190. configData = preDefined;
  191. configData.value = stored.value;
  192. configData.overrides = stored.overrides;
  193. if (isAdvanced) {
  194. configData.category = (configData.category === undefined) ? configCategory : configData.category;
  195. }
  196. } else if (!preDefined && stored) {
  197. configData = {
  198. id: stored.id,
  199. name: stored.name,
  200. displayName: stored.name,
  201. serviceName: stored.serviceName,
  202. value: stored.value,
  203. defaultValue: stored.defaultValue,
  204. displayType: "advanced",
  205. filename: stored.filename,
  206. category: configCategory,
  207. isUserProperty: stored.isUserProperty === true,
  208. isOverridable: true,
  209. overrides: stored.overrides
  210. }
  211. if (!isAdvanced || this.get('customFileNames').contains(configData.filename)) {
  212. var categoryMetaData = this.identifyCategory(configData);
  213. if (categoryMetaData != null) {
  214. configData.category = categoryMetaData.get('name');
  215. if(!isAdvanced) configData.isUserProperty = true;
  216. }
  217. }
  218. } else if (preDefined && !stored) {
  219. configData = preDefined;
  220. if (isAdvanced) {
  221. configData.category = (configData.category === undefined) ? configCategory : configData.category;
  222. }
  223. }
  224. mergedConfigs.push(configData);
  225. }, this);
  226. return mergedConfigs;
  227. },
  228. /**
  229. * look over advanced configs and add missing configs to serviceConfigs
  230. * filter fetched configs by service if passed
  231. * @param serviceConfigs
  232. * @param advancedConfigs
  233. * @param serviceName
  234. */
  235. addAdvancedConfigs: function (serviceConfigs, advancedConfigs, serviceName) {
  236. serviceConfigs = (serviceName) ? serviceConfigs.filterProperty('serviceName', serviceName) : serviceConfigs;
  237. advancedConfigs.forEach(function (_config) {
  238. var configCategory = 'Advanced';
  239. var categoryMetaData = null;
  240. if (_config) {
  241. if (this.get('configMapping').computed().someProperty('name', _config.name)) {
  242. } else if (!(serviceConfigs.someProperty('name', _config.name))) {
  243. if(this.get('customFileNames').contains(_config.filename)){
  244. categoryMetaData = this.identifyCategory(_config);
  245. if (categoryMetaData != null) {
  246. configCategory = categoryMetaData.get('name');
  247. }
  248. }
  249. _config.id = "site property";
  250. _config.category = configCategory;
  251. _config.displayName = _config.name;
  252. _config.defaultValue = _config.value;
  253. // make all advanced configs optional and populated by default
  254. /*
  255. * if (/\${.*}/.test(_config.value) || (service.serviceName !==
  256. * 'OOZIE' && service.serviceName !== 'HBASE')) { _config.isRequired =
  257. * false; _config.value = ''; } else if
  258. * (/^\s+$/.test(_config.value)) { _config.isRequired = false; }
  259. */
  260. _config.isRequired = false;
  261. _config.isVisible = true;
  262. _config.displayType = 'advanced';
  263. serviceConfigs.push(_config);
  264. }
  265. }
  266. }, this);
  267. },
  268. /**
  269. * Render a custom conf-site box for entering properties that will be written in *-site.xml files of the services
  270. */
  271. addCustomConfigs: function (configs) {
  272. var preDefinedCustomConfigs = $.extend(true, [], this.get('preDefinedCustomConfigs'));
  273. var stored = configs.filter(function (_config) {
  274. if (this.get('categoriesWithCustom').contains(_config.category)) return true;
  275. }, this);
  276. var queueProperties = stored.filter(function (_config) {
  277. if ((_config.name.indexOf('mapred.capacity-scheduler.queue.') !== -1) ||
  278. (/mapred.queue.[a-z]([\_\-a-z0-9]{0,50}).acl-administer-jobs/i.test(_config.name)) ||
  279. (/mapred.queue.[a-z]([\_\-a-z0-9]{0,50}).acl-submit-job/i.test(_config.name))) {
  280. return true;
  281. }
  282. });
  283. if (queueProperties.length) {
  284. queueProperties.setEach('isQueue', true);
  285. } else {
  286. queueProperties = preDefinedCustomConfigs.filterProperty('isQueue');
  287. queueProperties.forEach(function (customConfig) {
  288. this.setDefaultQueue(customConfig, 'default');
  289. configs.push(customConfig);
  290. }, this);
  291. }
  292. },
  293. /**
  294. * set values to properties of queue
  295. * @param customConfig
  296. * @param queueName
  297. */
  298. setDefaultQueue: function (customConfig, queueName) {
  299. customConfig.name = customConfig.name.replace(/<queue-name>/, queueName);
  300. //default values of queue
  301. switch (customConfig.name) {
  302. case 'mapred.capacity-scheduler.queue.' + queueName + '.capacity':
  303. customConfig.value = '100';
  304. break;
  305. case 'mapred.capacity-scheduler.queue.' + queueName + '.maximum-capacity':
  306. customConfig.value = '100';
  307. break;
  308. case 'mapred.capacity-scheduler.queue.' + queueName + '.minimum-user-limit-percent':
  309. customConfig.value = '100';
  310. break;
  311. case 'mapred.capacity-scheduler.queue.' + queueName + '.user-limit-factor':
  312. customConfig.value = '1';
  313. break;
  314. case 'mapred.capacity-scheduler.queue.' + queueName + '.maximum-initialized-active-tasks':
  315. customConfig.value = '200000';
  316. break;
  317. case 'mapred.capacity-scheduler.queue.' + queueName + '.maximum-initialized-active-tasks-per-user':
  318. customConfig.value = '100000';
  319. break;
  320. case 'mapred.capacity-scheduler.queue.' + queueName + '.init-accept-jobs-factor':
  321. customConfig.value = '10';
  322. break;
  323. case 'mapred.capacity-scheduler.queue.' + queueName + '.supports-priority':
  324. customConfig.value = 'false';
  325. break;
  326. case 'mapred.queue.' + queueName + '.acl-submit-job':
  327. customConfig.value = '*';
  328. break;
  329. case 'mapred.queue.' + queueName + '.acl-administer-jobs':
  330. customConfig.value = '*';
  331. break;
  332. }
  333. },
  334. /**
  335. * render configs, distribute them by service
  336. * and wrap each in ServiceConfigProperty object
  337. * @param configs
  338. * @param allInstalledServiceNames
  339. * @param selectedServiceNames
  340. * @return {Array}
  341. */
  342. renderConfigs: function (configs, allInstalledServiceNames, selectedServiceNames) {
  343. var renderedServiceConfigs = [];
  344. var localDB = {
  345. hosts: App.db.getHosts(),
  346. masterComponentHosts: App.db.getMasterComponentHosts(),
  347. slaveComponentHosts: App.db.getSlaveComponentHosts()
  348. };
  349. var services = [];
  350. this.get('preDefinedServiceConfigs').forEach(function (serviceConfig) {
  351. if (allInstalledServiceNames.contains(serviceConfig.serviceName) || serviceConfig.serviceName === 'MISC') {
  352. console.log('pushing ' + serviceConfig.serviceName, serviceConfig);
  353. if (selectedServiceNames.contains(serviceConfig.serviceName) || serviceConfig.serviceName === 'MISC') {
  354. serviceConfig.showConfig = true;
  355. }
  356. services.push(serviceConfig);
  357. }
  358. });
  359. services.forEach(function (service) {
  360. var serviceConfig = {};
  361. var configsByService = [];
  362. var serviceConfigs = configs.filterProperty('serviceName', service.serviceName);
  363. serviceConfigs.forEach(function (_config) {
  364. var serviceConfigProperty = {};
  365. _config.isOverridable = (_config.isOverridable === undefined) ? true : _config.isOverridable;
  366. serviceConfigProperty = App.ServiceConfigProperty.create(_config);
  367. this.updateHostOverrides(serviceConfigProperty, _config);
  368. serviceConfigProperty.initialValue(localDB);
  369. serviceConfigProperty.validate();
  370. configsByService.pushObject(serviceConfigProperty);
  371. }, this);
  372. serviceConfig = this.createServiceConfig(service.serviceName);
  373. serviceConfig.set('showConfig', service.showConfig);
  374. serviceConfig.set('configs', configsByService);
  375. renderedServiceConfigs.push(serviceConfig);
  376. }, this);
  377. return renderedServiceConfigs;
  378. },
  379. /**
  380. * create new child configs from overrides, attach them to parent config
  381. * override - value of config, related to particular host(s)
  382. * @param configProperty
  383. * @param storedConfigProperty
  384. */
  385. updateHostOverrides: function (configProperty, storedConfigProperty) {
  386. if (storedConfigProperty.overrides != null && storedConfigProperty.overrides.length > 0) {
  387. var overrides = [];
  388. storedConfigProperty.overrides.forEach(function (overrideEntry) {
  389. // create new override with new value
  390. var newSCP = App.ServiceConfigProperty.create(configProperty);
  391. newSCP.set('value', overrideEntry.value);
  392. newSCP.set('isOriginalSCP', false); // indicated this is overridden value,
  393. newSCP.set('parentSCP', configProperty);
  394. var hostsArray = Ember.A([]);
  395. overrideEntry.hosts.forEach(function (host) {
  396. hostsArray.push(host);
  397. });
  398. newSCP.set('selectedHostOptions', hostsArray);
  399. overrides.pushObject(newSCP);
  400. });
  401. configProperty.set('overrides', overrides);
  402. }
  403. },
  404. /**
  405. * create new ServiceConfig object by service name
  406. * @param serviceName
  407. */
  408. createServiceConfig: function (serviceName) {
  409. var preDefinedServiceConfig = App.config.preDefinedServiceConfigs.findProperty('serviceName', serviceName);
  410. var serviceConfig = App.ServiceConfig.create({
  411. filename: preDefinedServiceConfig.filename,
  412. serviceName: preDefinedServiceConfig.serviceName,
  413. displayName: preDefinedServiceConfig.displayName,
  414. configCategories: preDefinedServiceConfig.configCategories,
  415. configs: []
  416. });
  417. serviceConfig.configCategories.filterProperty('isCustomView', true).forEach(function (category) {
  418. switch (category.name) {
  419. case 'CapacityScheduler':
  420. category.set('customView', App.ServiceConfigCapacityScheduler);
  421. break;
  422. }
  423. }, this);
  424. return serviceConfig;
  425. },
  426. /**
  427. * GETs all cluster level sites in one call.
  428. *
  429. * @return Array of all site configs
  430. */
  431. loadConfigsByTags: function (tags) {
  432. var urlParams = [];
  433. tags.forEach(function (_tag) {
  434. urlParams.push('(type=' + _tag.siteName + '&tag=' + _tag.tagName + ')');
  435. });
  436. var params = urlParams.join('|');
  437. App.ajax.send({
  438. name: 'config.on-site',
  439. sender: this,
  440. data: {
  441. params: params
  442. },
  443. success: 'loadConfigsByTagsSuccess'
  444. });
  445. return configGroupsByTag;
  446. },
  447. loadConfigsByTagsSuccess: function (data) {
  448. if (data.items) {
  449. configGroupsByTag = [];
  450. data.items.forEach(function (item) {
  451. this.loadedConfigurationsCache[item.type + "_" + item.tag] = item.properties;
  452. configGroupsByTag.push(item);
  453. }, this);
  454. }
  455. },
  456. /**
  457. * Generate serviceProperties save it to localDB
  458. * called form stepController step6WizardController
  459. *
  460. * @param serviceName
  461. * @return {*}
  462. */
  463. loadAdvancedConfig: function (serviceName) {
  464. App.ajax.send({
  465. name: 'config.advanced',
  466. sender: this,
  467. data: {
  468. serviceName: serviceName,
  469. stack2VersionUrl: App.get('stack2VersionURL')
  470. },
  471. success: 'loadAdvancedConfigSuccess'
  472. });
  473. return serviceComponents[serviceName];
  474. //TODO clean serviceComponents
  475. },
  476. loadAdvancedConfigSuccess: function (data, opt, params) {
  477. console.log("TRACE: In success function for the loadAdvancedConfig; url is ", opt.url);
  478. var properties = [];
  479. if (data.items.length) {
  480. data.items.forEach(function (item) {
  481. item = item.StackConfigurations;
  482. properties.push({
  483. serviceName: item.service_name,
  484. name: item.property_name,
  485. value: item.property_value,
  486. description: item.property_description,
  487. filename: item.filename || item.type
  488. });
  489. }, this);
  490. serviceComponents[data.items[0].StackConfigurations.service_name] = properties;
  491. }
  492. },
  493. /**
  494. * Determine the map which shows which services
  495. * each global property effects.
  496. *
  497. * @return {*}
  498. * Example:
  499. * {
  500. * 'hive_pid_dir': ['HIVE'],
  501. * ...
  502. * }
  503. */
  504. loadGlobalPropertyToServicesMap: function () {
  505. if (globalPropertyToServicesMap == null) {
  506. App.ajax.send({
  507. name: 'config.advanced.global',
  508. sender: this,
  509. data: {
  510. stack2VersionUrl: App.get('stack2VersionURL')
  511. },
  512. success: 'loadGlobalPropertyToServicesMapSuccess'
  513. });
  514. }
  515. return globalPropertyToServicesMap;
  516. },
  517. loadGlobalPropertyToServicesMapSuccess: function (data) {
  518. globalPropertyToServicesMap = {};
  519. if(data.items!=null){
  520. data.items.forEach(function(service){
  521. service.configurations.forEach(function(config){
  522. if("global.xml" === config.StackConfigurations.type){
  523. if(!(config.StackConfigurations.property_name in globalPropertyToServicesMap)){
  524. globalPropertyToServicesMap[config.StackConfigurations.property_name] = [];
  525. }
  526. globalPropertyToServicesMap[config.StackConfigurations.property_name].push(service.StackServices.service_name);
  527. }
  528. });
  529. });
  530. }
  531. },
  532. /**
  533. * When global configuration changes, not all services are effected
  534. * by all properties. This method determines if a given service
  535. * is effected by the difference in desired and actual configs.
  536. *
  537. * This method might make a call to server to determine the actual
  538. * key/value pairs involved.
  539. */
  540. isServiceEffectedByGlobalChange: function (service, desiredTag, actualTag) {
  541. var effected = false;
  542. if (service != null && desiredTag != null && actualTag != null) {
  543. if(this.differentGlobalTagsCache.indexOf(service+"/"+desiredTag+"/"+actualTag) < 0){
  544. this.loadGlobalPropertyToServicesMap();
  545. var desiredConfigs = this.loadedConfigurationsCache['global_' + desiredTag];
  546. var actualConfigs = this.loadedConfigurationsCache['global_' + actualTag];
  547. var requestTags = [];
  548. if (!desiredConfigs) {
  549. requestTags.push({
  550. siteName: 'global',
  551. tagName: desiredTag
  552. });
  553. }
  554. if (!actualConfigs) {
  555. requestTags.push({
  556. siteName: 'global',
  557. tagName: actualTag
  558. });
  559. }
  560. if (requestTags.length > 0) {
  561. this.loadConfigsByTags(requestTags);
  562. desiredConfigs = this.loadedConfigurationsCache['global_' + desiredTag];
  563. actualConfigs = this.loadedConfigurationsCache['global_' + actualTag];
  564. }
  565. if (desiredConfigs != null && actualConfigs != null) {
  566. for ( var property in desiredConfigs) {
  567. if (!effected) {
  568. var dpv = desiredConfigs[property];
  569. var apv = actualConfigs[property];
  570. if (dpv !== apv && globalPropertyToServicesMap[property] != null) {
  571. effected = globalPropertyToServicesMap[property].indexOf(service) > -1;
  572. if(effected){
  573. this.differentGlobalTagsCache.push(service+"/"+desiredTag+"/"+actualTag);
  574. }
  575. }
  576. }
  577. }
  578. }
  579. }else{
  580. effected = true; // We already know they are different
  581. }
  582. }
  583. return effected;
  584. },
  585. /**
  586. * Hosts can override service configurations per property. This method GETs
  587. * the overriden configurations and sets only the changed properties into
  588. * the 'overrides' of serviceConfig.
  589. *
  590. *
  591. */
  592. loadServiceConfigHostsOverrides: function (serviceConfigs, loadedHostToOverrideSiteToTagMap) {
  593. var configKeyToConfigMap = {};
  594. serviceConfigs.forEach(function (item) {
  595. configKeyToConfigMap[item.name] = item;
  596. });
  597. var typeTagToHostMap = {};
  598. var urlParams = [];
  599. for (var hostname in loadedHostToOverrideSiteToTagMap) {
  600. var overrideTypeTags = loadedHostToOverrideSiteToTagMap[hostname];
  601. for (var type in overrideTypeTags) {
  602. var tag = overrideTypeTags[type];
  603. typeTagToHostMap[type + "///" + tag] = hostname;
  604. urlParams.push('(type=' + type + '&tag=' + tag + ')');
  605. }
  606. }
  607. var params = urlParams.join('|');
  608. if(urlParams.length){
  609. App.ajax.send({
  610. name: 'config.host_overrides',
  611. sender: this,
  612. data: {
  613. params: params,
  614. configKeyToConfigMap: configKeyToConfigMap,
  615. typeTagToHostMap: typeTagToHostMap
  616. },
  617. success: 'loadServiceConfigHostsOverridesSuccess'
  618. });
  619. }
  620. },
  621. loadServiceConfigHostsOverridesSuccess: function (data, opt, params) {
  622. console.debug("loadServiceConfigHostsOverrides: Data=", data);
  623. data.items.forEach(function (config) {
  624. App.config.loadedConfigurationsCache[config.type + "_" + config.tag] = config.properties;
  625. var hostname = params.typeTagToHostMap[config.type + "///" + config.tag];
  626. var properties = config.properties;
  627. for (var prop in properties) {
  628. var serviceConfig = params.configKeyToConfigMap[prop];
  629. var hostOverrideValue = properties[prop];
  630. if (serviceConfig && serviceConfig.displayType === 'int') {
  631. if (/\d+m$/.test(hostOverrideValue)) {
  632. hostOverrideValue = hostOverrideValue.slice(0, hostOverrideValue.length - 1);
  633. }
  634. } else if (serviceConfig && serviceConfig.displayType === 'checkbox') {
  635. switch (hostOverrideValue) {
  636. case 'true':
  637. hostOverrideValue = true;
  638. break;
  639. case 'false':
  640. hostOverrideValue = false;
  641. break;
  642. }
  643. }
  644. if (serviceConfig) {
  645. // Value of this property is different for this host.
  646. var overrides = 'overrides';
  647. if (!(overrides in serviceConfig)) {
  648. serviceConfig.overrides = {};
  649. }
  650. if (!(hostOverrideValue in serviceConfig.overrides)) {
  651. serviceConfig.overrides[hostOverrideValue] = [];
  652. }
  653. console.log("loadServiceConfigHostsOverrides(): [" + hostname + "] OVERRODE(" + serviceConfig.name + "): " + serviceConfig.value + " -> " + hostOverrideValue);
  654. serviceConfig.overrides[hostOverrideValue].push(hostname);
  655. }
  656. }
  657. });
  658. console.log("loadServiceConfigHostsOverrides(): Finished loading.");
  659. }
  660. });