configs.js 94 KB

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