12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160 |
- /**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var App = require('app');
- var dataManipulationUtils = require('utils/data_manipulation');
- var lazyLoading = require('utils/lazy_loading');
- /**
- * this mixin has method to save configs (used in MainServiceInfoConfigsController)
- * all methods are divided into couple groups :
- * 0. HELPERS - some helper methods
- * 1. PRE SAVE CHECKS - warning popups and validations checks
- * 2. PREPARE CONFIGS TO SAVE - filtering and formatting changed configs
- * 2.1 PREPARE DATABASE CONFIGS - modify database properties
- * 2.2 ADD DYNAMIC CONFIGS - !!!NEED INVESTIGATION
- * 3. GENERATING JSON TO SAVE - generating json data
- * 4. AJAX REQUESTS - ajax request
- * 5. AFTER SAVE INFO - after save methods like to show popup with result
- * 6. ADDITIONAL
- */
- App.ConfigsSaverMixin = Em.Mixin.create({
- /**
- * @type {boolean}
- */
- saveConfigsFlag: true,
- /**
- * file names of changed configs
- * @type {string[]}
- */
- modifiedFileNames: [],
- /**
- * List of heapsize properties not to be parsed
- * @type {string[]}
- */
- heapsizeException: ['hadoop_heapsize', 'yarn_heapsize', 'nodemanager_heapsize', 'resourcemanager_heapsize', 'apptimelineserver_heapsize', 'jobhistory_heapsize', 'nfsgateway_heapsize', 'accumulo_master_heapsize', 'accumulo_tserver_heapsize', 'accumulo_monitor_heapsize', 'accumulo_gc_heapsize', 'accumulo_other_heapsize'],
- /**
- * Regular expression for heapsize properties detection
- * @type {regexp}
- */
- heapsizeRegExp: /_heapsize|_newsize|_maxnewsize|_permsize|_maxpermsize$/,
- /**
- * clear info to default
- * @method clearSaveInfo
- */
- clearSaveInfo: function() {
- this.set('modifiedFileNames', []);
- },
- /**
- * method to run saving configs
- * @method saveStepConfigs
- */
- saveStepConfigs: function() {
- if (!this.get("isSubmitDisabled")) {
- this.startSave();
- this.showWarningPopupsBeforeSave();
- }
- },
- /**
- * get config group object for current service
- * @param serviceName
- * @returns {App.ConfigGroup}
- */
- getGroupFromModel: function(serviceName) {
- if (this.get('selectedService.serviceName') === serviceName) {
- return this.get('selectedConfigGroup');
- } else {
- var groups = App.ServiceConfigGroup.find().filterProperty('serviceName', serviceName);
- if (this.get('selectedConfigGroup.isDefault')) {
- return groups.length ? groups.findProperty('isDefault', true) : null;
- } else {
- return groups.length ? groups.findProperty('name', this.get('selectedConfigGroup.dependentConfigGroups')[serviceName]) : null;
- }
- }
- },
- /**
- * Save changed configs and config groups
- * @method saveConfigs
- */
- saveConfigs: function () {
- var selectedConfigGroup = this.get('selectedConfigGroup');
- if (selectedConfigGroup.get('isDefault')) {
- var data = [];
- this.get('stepConfigs').forEach(function(stepConfig) {
- var serviceConfig = this.getServiceConfigToSave(stepConfig.get('serviceName'), stepConfig.get('configs'));
- if (serviceConfig) {
- data.push(serviceConfig);
- }
- }, this);
- if (Em.isArray(data) && data.length) {
- this.putChangedConfigurations(data, true);
- } else {
- this.onDoPUTClusterConfigurations();
- }
- } else {
- this.get('stepConfigs').forEach(function(stepConfig) {
- var serviceName = stepConfig.get('serviceName');
- var configs = stepConfig.get('configs');
- var configGroup = this.getGroupFromModel(serviceName);
- if (configGroup) {
- if (configGroup.get('isDefault')) {
- var configsToSave = this.getServiceConfigToSave(serviceName, configs);
- if (configsToSave) {
- this.putChangedConfigurations([configsToSave], false);
- }
- } else {
- var overridenConfigs = this.getConfigsForGroup(configs, configGroup.get('name'));
- if (Em.isArray(overridenConfigs)) {
- this.saveGroup(overridenConfigs, configGroup, this.get('content.serviceName') === serviceName);
- }
- }
- }
- }, this);
- }
- },
- /*********************************** 0. HELPERS ********************************************/
- /**
- * tells controller in saving configs was started
- * for now just changes flag <code>saveInProgress<code> to true
- * @private
- * @method startSave
- */
- startSave: function() {
- this.set("saveInProgress", true);
- },
- /**
- * tells controller that save has been finished
- * for now just changes flag <code>saveInProgress<code> to true
- * @private
- * @method completeSave
- */
- completeSave: function() {
- this.set("saveInProgress", false);
- },
- /**
- * Are some unsaved changes available
- * @returns {boolean}
- * @method hasUnsavedChanges
- */
- hasUnsavedChanges: function () {
- return !Em.isNone(this.get('hash')) && this.get('hash') != this.getHash();
- },
- /*********************************** 1. PRE SAVE CHECKS ************************************/
- /**
- * show some warning popups before user save configs
- * @private
- * @method showWarningPopupsBeforeSave
- */
- showWarningPopupsBeforeSave: function() {
- var self = this;
- if (this.isDirChanged()) {
- App.showConfirmationPopup(function() {
- self.showChangedDependentConfigs(null, function() {
- self.restartServicePopup();
- });
- },
- Em.I18n.t('services.service.config.confirmDirectoryChange').format(self.get('content.displayName')),
- this.completeSave.bind(this)
- );
- } else {
- self.showChangedDependentConfigs(null, function() {
- self.restartServicePopup();
- }, this.completeSave.bind(this));
- }
- },
- /**
- * Runs config validation before save
- * @private
- * @method restartServicePopup
- */
- restartServicePopup: function () {
- this.serverSideValidation()
- .done(this.saveConfigs.bind(this))
- .fail(this.completeSave.bind(this));
- },
- /**
- * Define if user has changed some dir properties
- * @return {Boolean}
- * @private
- * @method isDirChanged
- */
- isDirChanged: function () {
- var dirChanged = false;
- var serviceName = this.get('content.serviceName');
- if (serviceName === 'HDFS') {
- var hdfsConfigs = this.get('stepConfigs').findProperty('serviceName', 'HDFS').get('configs');
- if ((hdfsConfigs.findProperty('name', 'dfs.namenode.name.dir') && hdfsConfigs.findProperty('name', 'dfs.namenode.name.dir').get('isNotDefaultValue')) ||
- (hdfsConfigs.findProperty('name', 'dfs.namenode.checkpoint.dir') && hdfsConfigs.findProperty('name', 'dfs.namenode.checkpoint.dir').get('isNotDefaultValue')) ||
- (hdfsConfigs.findProperty('name', 'dfs.datanode.data.dir') && hdfsConfigs.findProperty('name', 'dfs.datanode.data.dir').get('isNotDefaultValue'))) {
- dirChanged = true;
- }
- }
- return dirChanged;
- },
- /*********************************** 2. GENERATING DATA TO SAVE ****************************/
- /**
- * get config properties for that fileNames that was changed
- * @param stepConfigs
- * @private
- * @returns {Array}
- */
- getModifiedConfigs: function(stepConfigs) {
- var modifiedConfigs = stepConfigs
- // get only modified and created configs
- .filter(function (config) {
- return config.get('isNotDefaultValue') || config.get('isNotSaved');
- })
- // get file names and add file names that was modified, for example after property removing
- .mapProperty('filename').concat(this.get('modifiedFileNames')).uniq()
- // get configs by filename
- .map(function (fileName) {
- return stepConfigs.filterProperty('filename', fileName);
- });
- if (!!modifiedConfigs.length) {
- // concatenate results
- modifiedConfigs = modifiedConfigs.reduce(function (current, prev) {
- return current.concat(prev);
- });
- }
- return modifiedConfigs;
- },
- /**
- * get configs that belongs to config group
- * @param stepConfigs
- * @private
- * @param configGroupName
- */
- getConfigsForGroup: function(stepConfigs, configGroupName) {
- var overridenConfigs = [];
- stepConfigs.filterProperty('overrides').forEach(function (config) {
- overridenConfigs = overridenConfigs.concat(config.get('overrides'));
- });
- // find custom original properties that assigned to selected config group
- return overridenConfigs.concat(stepConfigs.filterProperty('group')
- .filter(function (config) {
- return config.get('group.name') == configGroupName;
- }));
- },
- /**
- *
- * @param serviceName
- * @param configs
- * @private
- * @returns {*}
- */
- getServiceConfigToSave: function(serviceName, configs) {
- if (serviceName === 'YARN') {
- configs = App.config.textareaIntoFileConfigs(configs, 'capacity-scheduler.xml');
- }
- /**
- * generates list of properties that was changed
- * @type {Array}
- */
- var modifiedConfigs = this.getModifiedConfigs(configs);
- // save modified original configs that have no group
- modifiedConfigs = this.saveSiteConfigs(modifiedConfigs.filter(function (config) {
- return !config.get('group');
- }));
- if (!Em.isArray(modifiedConfigs) || modifiedConfigs.length == 0) return null;
- var fileNamesToSave = modifiedConfigs.mapProperty('filename').concat(this.get('modifiedFileNames')).uniq();
- var configsToSave = this.generateDesiredConfigsJSON(modifiedConfigs, fileNamesToSave, this.get('serviceConfigVersionNote'));
- if (configsToSave.length > 0) {
- return JSON.stringify({
- Clusters: {
- desired_config: configsToSave
- }
- });
- } else {
- return null;
- }
- },
- /**
- * save site configs
- * @param configs
- * @private
- * @method saveSiteConfigs
- */
- saveSiteConfigs: function (configs) {
- configs = this.setHiveHostName(configs);
- configs = this.setOozieHostName(configs);
- this.formatConfigValues(configs);
- return configs;
- },
- /**
- * Represent boolean value as string (true => 'true', false => 'false') and trim other values
- * @param serviceConfigProperties
- * @private
- * @method formatConfigValues
- */
- formatConfigValues: function (serviceConfigProperties) {
- serviceConfigProperties.forEach(function (_config) {
- if (typeof _config.get('value') === "boolean") _config.set('value', _config.value.toString());
- _config.set('value', App.config.trimProperty(_config, true));
- });
- },
- /*********************************** 2.1 PREPARE DATABASE CONFIGS ****************************/
- /**
- * set hive hostnames in configs
- * @param configs
- * @private
- * @method setHiveHostName
- */
- setHiveHostName: function (configs) {
- var dbHostPropertyName = null, configsToRemove = [];
- if (configs.someProperty('name', 'hive_database')) {
- var hiveDb = configs.findProperty('name', 'hive_database');
- switch(hiveDb.value) {
- case 'New MySQL Database':
- case 'New PostgreSQL Database':
- dbHostPropertyName = configs.someProperty('name', 'hive_ambari_host') ? 'hive_ambari_host' : dbHostPropertyName;
- configsToRemove = ['hive_existing_mysql_host', 'hive_existing_mysql_database', 'hive_existing_oracle_host', 'hive_existing_oracle_database', 'hive_existing_postgresql_host', 'hive_existing_postgresql_database', 'hive_existing_mssql_server_database', 'hive_existing_mssql_server_host', 'hive_existing_mssql_server_2_database', 'hive_existing_mssql_server_2_host'];
- break;
- case 'Existing MySQL Database':
- dbHostPropertyName = configs.someProperty('name', 'hive_existing_mysql_host') ? 'hive_existing_mysql_host' : dbHostPropertyName;
- configsToRemove = ['hive_ambari_database', 'hive_existing_oracle_host', 'hive_existing_oracle_database', 'hive_existing_postgresql_host', 'hive_existing_postgresql_database', 'hive_existing_mssql_server_database', 'hive_existing_mssql_server_host', 'hive_existing_mssql_server_2_database', 'hive_existing_mssql_server_2_host'];
- break;
- case 'Existing PostgreSQL Database':
- dbHostPropertyName = configs.someProperty('name', 'hive_existing_postgresql_host') ? 'hive_existing_postgresql_host' : dbHostPropertyName;
- configsToRemove = ['hive_ambari_database', 'hive_existing_mysql_host', 'hive_existing_mysql_database', 'hive_existing_oracle_host', 'hive_existing_oracle_database', 'hive_existing_mssql_server_database', 'hive_existing_mssql_server_host', 'hive_existing_mssql_server_2_database', 'hive_existing_mssql_server_2_host'];
- break;
- case 'Existing Oracle Database':
- dbHostPropertyName = configs.someProperty('name', 'hive_existing_oracle_host') ? 'hive_existing_oracle_host' : dbHostPropertyName;
- configsToRemove = ['hive_ambari_database', 'hive_existing_mysql_host', 'hive_existing_mysql_database', 'hive_existing_postgresql_host', 'hive_existing_postgresql_database', 'hive_existing_mssql_server_database', 'hive_existing_mssql_server_host', 'hive_existing_mssql_server_2_database', 'hive_existing_mssql_server_2_host'];
- break;
- case 'Existing MSSQL Server database with SQL authentication':
- dbHostPropertyName = configs.someProperty('name', 'hive_existing_mssql_server_host') ? 'hive_existing_mssql_server_host' : dbHostPropertyName;
- configsToRemove = ['hive_ambari_database', 'hive_existing_mysql_host', 'hive_existing_mysql_database', 'hive_existing_postgresql_host', 'hive_existing_postgresql_database', 'hive_existing_oracle_host', 'hive_existing_oracle_database', 'hive_existing_mssql_server_2_database', 'hive_existing_mssql_server_2_host'];
- break;
- case 'Existing MSSQL Server database with integrated authentication':
- dbHostPropertyName = configs.someProperty('name', 'hive_existing_mssql_server_2_host') ? 'hive_existing_mssql_server_2_host' : dbHostPropertyName;
- configsToRemove = ['hive_ambari_database', 'hive_existing_mysql_host', 'hive_existing_mysql_database', 'hive_existing_postgresql_host', 'hive_existing_postgresql_database', 'hive_existing_oracle_host', 'hive_existing_oracle_database', 'hive_existing_mssql_server_database', 'hive_existing_mssql_server_host'];
- break;
- }
- configs = dataManipulationUtils.rejectPropertyValues(configs, 'name', configsToRemove);
- }
- if (dbHostPropertyName) {
- var hiveHostNameProperty = App.ServiceConfigProperty.create(App.config.get('preDefinedSiteProperties').findProperty('name', 'hive_hostname'));
- hiveHostNameProperty.set('value', configs.findProperty('name', dbHostPropertyName).get('value'));
- configs.pushObject(hiveHostNameProperty);
- }
- return configs;
- },
- /**
- * set oozie hostnames in configs
- * @param configs
- * @private
- * @method setOozieHostName
- */
- setOozieHostName: function (configs) {
- var dbHostPropertyName = null, configsToRemove = [];
- if (configs.someProperty('name', 'oozie_database')) {
- var oozieDb = configs.findProperty('name', 'oozie_database');
- switch (oozieDb.value) {
- case 'New Derby Database':
- configsToRemove = ['oozie_ambari_database', 'oozie_existing_mysql_host', 'oozie_existing_mysql_database', 'oozie_existing_oracle_host', 'oozie_existing_oracle_database', 'oozie_existing_postgresql_host', 'oozie_existing_postgresql_database', 'oozie_existing_mssql_server_database', 'oozie_existing_mssql_server_host', 'oozie_existing_mssql_server_2_database', 'oozie_existing_mssql_server_2_host'];
- break;
- case 'New MySQL Database':
- var ambariHost = configs.findProperty('name', 'oozie_ambari_host');
- if (ambariHost) {
- ambariHost.name = 'oozie_hostname';
- }
- configsToRemove = ['oozie_existing_mysql_host', 'oozie_existing_mysql_database', 'oozie_existing_oracle_host', 'oozie_existing_oracle_database', 'oozie_derby_database', 'oozie_existing_postgresql_host', 'oozie_existing_postgresql_database', 'oozie_existing_mssql_server_database', 'oozie_existing_mssql_server_host', 'oozie_existing_mssql_server_2_database', 'oozie_existing_mssql_server_2_host'];
- break;
- case 'Existing MySQL Database':
- dbHostPropertyName = configs.someProperty('name', 'oozie_existing_mysql_host') ? 'oozie_existing_mysql_host' : dbHostPropertyName;
- configsToRemove = ['oozie_ambari_database', 'oozie_existing_oracle_host', 'oozie_existing_oracle_database', 'oozie_derby_database', 'oozie_existing_postgresql_host', 'oozie_existing_postgresql_database', 'oozie_existing_mssql_server_database', 'oozie_existing_mssql_server_host', 'oozie_existing_mssql_server_2_database', 'oozie_existing_mssql_server_2_host'];
- break;
- case 'Existing PostgreSQL Database':
- dbHostPropertyName = configs.someProperty('name', 'oozie_existing_postgresql_host') ? 'oozie_existing_postgresql_host' : dbHostPropertyName;
- configsToRemove = ['oozie_ambari_database', 'oozie_existing_mysql_host', 'oozie_existing_mysql_database', 'oozie_existing_oracle_host', 'oozie_existing_oracle_database', 'oozie_existing_mssql_server_database', 'oozie_existing_mssql_server_host', 'oozie_existing_mssql_server_2_database', 'oozie_existing_mssql_server_2_host'];
- break;
- case 'Existing Oracle Database':
- dbHostPropertyName = configs.someProperty('name', 'oozie_existing_oracle_host') ? 'oozie_existing_oracle_host' : dbHostPropertyName;
- configsToRemove = ['oozie_ambari_database', 'oozie_existing_mysql_host', 'oozie_existing_mysql_database', 'oozie_derby_database', 'oozie_existing_mssql_server_database', 'oozie_existing_mssql_server_host', 'oozie_existing_mssql_server_2_database', 'oozie_existing_mssql_server_2_host'];
- break;
- case 'Existing MSSQL Server database with SQL authentication':
- dbHostPropertyName = configs.someProperty('name', 'oozie_existing_mssql_server_host') ? 'oozie_existing_mssql_server_host' : dbHostPropertyName;
- configsToRemove = ['oozie_ambari_database', 'oozie_existing_oracle_host', 'oozie_existing_oracle_database', 'oozie_derby_database', 'oozie_existing_postgresql_host', 'oozie_existing_postgresql_database', 'oozie_existing_mysql_host', 'oozie_existing_mysql_database', 'oozie_existing_mssql_server_2_database', 'oozie_existing_mssql_server_2_host'];
- break;
- case 'Existing MSSQL Server database with integrated authentication':
- dbHostPropertyName = configs.someProperty('name', 'oozie_existing_mssql_server_2_host') ? 'oozie_existing_mssql_server_2_host' : dbHostPropertyName;
- configsToRemove = ['oozie_ambari_database', 'oozie_existing_oracle_host', 'oozie_existing_oracle_database', 'oozie_derby_database', 'oozie_existing_postgresql_host', 'oozie_existing_postgresql_database', 'oozie_existing_mysql_host', 'oozie_existing_mysql_database', 'oozie_existing_mssql_server_database', 'oozie_existing_mssql_server_host'];
- break;
- }
- configs = dataManipulationUtils.rejectPropertyValues(configs, 'name', configsToRemove);
- }
- if (dbHostPropertyName) {
- var oozieHostNameProperty = App.ServiceConfigProperty.create(App.config.get('preDefinedSiteProperties').findProperty('name', 'oozie_hostname'));
- oozieHostNameProperty.set('value', configs.findProperty('name', dbHostPropertyName).get('value'));
- configs.pushObject(oozieHostNameProperty);
- }
- return configs;
- },
- /*********************************** 3. GENERATING JSON TO SAVE *****************************/
- /**
- * generating common JSON object for desired configs
- * @param configsToSave
- * @param fileNamesToSave
- * @param serviceConfigNote
- * @param {boolean} [isNotDefaultGroup=false]
- * @returns {Array}
- */
- generateDesiredConfigsJSON: function(configsToSave, fileNamesToSave, serviceConfigNote, isNotDefaultGroup) {
- var desired_config = [];
- if (Em.isArray(configsToSave) && Em.isArray(fileNamesToSave) && fileNamesToSave.length && configsToSave.length) {
- serviceConfigNote = serviceConfigNote || "";
- var tagVersion = "version" + (new Date).getTime();
- fileNamesToSave.forEach(function(fName) {
- if (this.allowSaveSite(fName)) {
- var properties = configsToSave.filterProperty('filename', fName);
- var type = App.config.getConfigTagFromFileName(fName);
- desired_config.push(this.createDesiredConfig(type, tagVersion, properties, serviceConfigNote, isNotDefaultGroup));
- }
- }, this);
- }
- return desired_config;
- },
- /**
- * for some file names we have a restriction
- * and can't save them, in this this method will return false
- * @param fName
- * @returns {boolean}
- */
- allowSaveSite: function(fName) {
- switch (fName) {
- case 'mapred-queue-acls.xml':
- return false;
- case 'core-site.xml':
- return ['HDFS', 'GLUSTERFS'].contains(this.get('content.serviceName'));
- default :
- return true;
- }
- },
- /**
- * generating common JSON object for desired config
- * @param {string} type - file name without '.xml'
- * @param {string} tagVersion - version + timestamp
- * @param {App.ConfigProperty[]} properties - array of properties from model
- * @param {string} serviceConfigNote
- * @param {boolean} [isNotDefaultGroup=false]
- * @returns {{type: string, tag: string, properties: {}, properties_attributes: {}|undefined, service_config_version_note: string|undefined}}
- */
- createDesiredConfig: function(type, tagVersion, properties, serviceConfigNote, isNotDefaultGroup) {
- Em.assert('type and tagVersion should be defined', type && tagVersion);
- var desired_config = {
- "type": type,
- "tag": tagVersion,
- "properties": {}
- };
- if (!isNotDefaultGroup) {
- desired_config.service_config_version_note = serviceConfigNote || "";
- }
- var attributes = { final: {} };
- if (Em.isArray(properties)) {
- properties.forEach(function(property) {
- if (property.get('isRequiredByAgent')) {
- desired_config.properties[property.get('name')] = this.formatValueBeforeSave(property);
- /**
- * add is final value
- */
- if (property.get('isFinal')) {
- attributes.final[property.get('name')] = "true";
- }
- }
- }, this);
- }
- if (Object.keys(attributes.final).length) {
- desired_config.properties_attributes = attributes;
- }
- return desired_config;
- },
- /**
- * format value before save performs some changing of values
- * according to the rules that includes heapsizeException trimming and some custom rules
- * @param {App.ConfigProperty} property
- * @returns {string}
- */
- formatValueBeforeSave: function(property) {
- var name = property.get('name');
- var value = property.get('value');
- //TODO check for core-site
- if (this.get('heapsizeRegExp').test(name) && !this.get('heapsizeException').contains(name) && !(value).endsWith("m")) {
- return value += "m";
- }
- if (typeof property.get('value') === "boolean") {
- return property.get('value').toString();
- }
- switch (name) {
- case 'storm.zookeeper.servers':
- case 'nimbus.seeds':
- if (Em.isArray(value)) {
- return JSON.stringify(value).replace(/"/g, "'");
- } else {
- return value;
- }
- break;
- default:
- return App.config.trimProperty(property, true);
- }
- },
- /*********************************** 4. AJAX REQUESTS **************************************/
- /**
- * save config group
- * @param overridenConfigs
- * @param selectedConfigGroup
- * @param showPopup
- */
- saveGroup: function(overridenConfigs, selectedConfigGroup, showPopup) {
- var groupHosts = [];
- var fileNamesToSave = overridenConfigs.mapProperty('filename').uniq();
- selectedConfigGroup.get('hosts').forEach(function (hostName) {
- groupHosts.push({"host_name": hostName});
- });
- this.putConfigGroupChanges({
- ConfigGroup: {
- "id": selectedConfigGroup.get('configGroupId'),
- "cluster_name": App.get('clusterName'),
- "group_name": selectedConfigGroup.get('name'),
- "tag": selectedConfigGroup.get('service.id'),
- "description": selectedConfigGroup.get('description'),
- "hosts": groupHosts,
- "service_config_version_note": this.get('serviceConfigVersionNote'),
- "desired_configs": this.generateDesiredConfigsJSON(overridenConfigs, fileNamesToSave, null, true)
- }
- }, showPopup);
- },
- /**
- * persist properties of config groups to server
- * show result popup if <code>showPopup</code> is true
- * @param data {Object}
- * @param showPopup {Boolean}
- * @method putConfigGroupChanges
- */
- putConfigGroupChanges: function (data, showPopup) {
- var ajaxOptions = {
- name: 'config_groups.update_config_group',
- sender: this,
- data: {
- id: data.ConfigGroup.id,
- configGroup: data
- }
- };
- if (showPopup) {
- ajaxOptions.success = "putConfigGroupChangesSuccess";
- }
- return App.ajax.send(ajaxOptions);
- },
- /**
- * Saves configuration of set of sites. The provided data
- * contains the site name and tag to be used.
- * @param {Object[]} services
- * @param {boolean} showPopup
- * @return {$.ajax}
- * @method putChangedConfigurations
- */
- putChangedConfigurations: function (services, showPopup) {
- var ajaxData = {
- name: 'common.across.services.configurations',
- sender: this,
- data: {
- data: '[' + services.toString() + ']'
- },
- error: 'doPUTClusterConfigurationSiteErrorCallback'
- };
- if (showPopup) {
- ajaxData.success = 'doPUTClusterConfigurationSiteSuccessCallback'
- }
- return App.ajax.send(ajaxData);
- },
- /*********************************** 5. AFTER SAVE INFO ************************************/
- /**
- * @private
- * @method putConfigGroupChangesSuccess
- */
- putConfigGroupChangesSuccess: function () {
- this.set('saveConfigsFlag', true);
- this.onDoPUTClusterConfigurations();
- },
- /**
- * @private
- * @method doPUTClusterConfigurationSiteSuccessCallback
- */
- doPUTClusterConfigurationSiteSuccessCallback: function () {
- this.onDoPUTClusterConfigurations();
- },
- /**
- * @private
- * @method doPUTClusterConfigurationSiteErrorCallback
- */
- doPUTClusterConfigurationSiteErrorCallback: function () {
- this.set('saveConfigsFlag', false);
- this.doPUTClusterConfigurationSiteSuccessCallback();
- },
- /**
- * On save configs handler. Open save configs popup with appropriate message
- * and clear config dependencies list.
- * @private
- * @method onDoPUTClusterConfigurations
- */
- onDoPUTClusterConfigurations: function () {
- var header, message, messageClass, value, status = 'unknown', urlParams = '',
- result = {
- flag: this.get('saveConfigsFlag'),
- message: null,
- value: null
- },
- extendedModel = App.Service.extendedModel[this.get('content.serviceName')],
- currentService = extendedModel ? App[extendedModel].find(this.get('content.serviceName')) : App.Service.find(this.get('content.serviceName'));
- if (!result.flag) {
- result.message = Em.I18n.t('services.service.config.failSaveConfig');
- }
- App.router.get('clusterController').updateClusterData();
- App.router.get('updateController').updateComponentConfig(function () {
- });
- var flag = result.flag;
- if (result.flag === true) {
- header = Em.I18n.t('services.service.config.saved');
- message = Em.I18n.t('services.service.config.saved.message');
- messageClass = 'alert alert-success';
- // warn the user if any of the components are in UNKNOWN state
- urlParams += ',ServiceComponentInfo/installed_count,ServiceComponentInfo/total_count';
- if (this.get('content.serviceName') === 'HDFS') {
- urlParams += '&ServiceComponentInfo/service_name.in(HDFS)'
- }
- } else {
- header = Em.I18n.t('common.failure');
- message = result.message;
- messageClass = 'alert alert-error';
- value = result.value;
- }
- if(currentService){
- App.QuickViewLinks.proto().set('content', currentService);
- App.QuickViewLinks.proto().loadTags();
- }
- this.showSaveConfigsPopup(header, flag, message, messageClass, value, status, urlParams);
- this.clearDependentConfigs();
- },
- /**
- * Show save configs popup
- * @return {App.ModalPopup}
- * @private
- * @method showSaveConfigsPopup
- */
- showSaveConfigsPopup: function (header, flag, message, messageClass, value, status, urlParams) {
- var self = this;
- if (flag) {
- this.set('forceTransition', flag);
- self.loadStep();
- }
- return App.ModalPopup.show({
- header: header,
- primary: Em.I18n.t('ok'),
- secondary: null,
- onPrimary: function () {
- this.hide();
- if (!flag) {
- self.completeSave();
- }
- },
- onClose: function () {
- this.hide();
- self.completeSave();
- },
- disablePrimary: true,
- bodyClass: Ember.View.extend({
- flag: flag,
- message: function () {
- return this.get('isLoaded') ? message : Em.I18n.t('services.service.config.saving.message');
- }.property('isLoaded'),
- messageClass: function () {
- return this.get('isLoaded') ? messageClass : 'alert alert-info';
- }.property('isLoaded'),
- setDisablePrimary: function () {
- this.get('parentView').set('disablePrimary', !this.get('isLoaded'));
- }.observes('isLoaded'),
- runningHosts: [],
- runningComponentCount: 0,
- unknownHosts: [],
- unknownComponentCount: 0,
- siteProperties: value,
- isLoaded: false,
- componentsFilterSuccessCallback: function (response) {
- var count = 0,
- view = this,
- lazyLoadHosts = function (dest) {
- lazyLoading.run({
- initSize: 20,
- chunkSize: 50,
- delay: 50,
- destination: dest,
- source: hosts,
- context: view
- });
- },
- /**
- * Map components for their hosts
- * Return format:
- * <code>
- * {
- * host1: [component1, component2, ...],
- * host2: [component3, component4, ...]
- * }
- * </code>
- * @return {object}
- */
- setComponents = function (item, components) {
- item.host_components.forEach(function (c) {
- var name = c.HostRoles.host_name;
- if (!components[name]) {
- components[name] = [];
- }
- components[name].push(App.format.role(item.ServiceComponentInfo.component_name));
- });
- return components;
- },
- /**
- * Map result of <code>setComponents</code> to array
- * @return {{name: string, components: string}[]}
- */
- setHosts = function (components) {
- var hosts = [];
- Em.keys(components).forEach(function (key) {
- hosts.push({
- name: key,
- components: components[key].join(', ')
- });
- });
- return hosts;
- },
- components = {},
- hosts = [];
- switch (status) {
- case 'unknown':
- response.items.filter(function (item) {
- return (item.ServiceComponentInfo.total_count > item.ServiceComponentInfo.started_count + item.ServiceComponentInfo.installed_count);
- }).forEach(function (item) {
- var total = item.ServiceComponentInfo.total_count,
- started = item.ServiceComponentInfo.started_count,
- installed = item.ServiceComponentInfo.installed_count,
- unknown = total - started + installed;
- components = setComponents(item, components);
- count += unknown;
- });
- hosts = setHosts(components);
- this.set('unknownComponentCount', count);
- lazyLoadHosts(this.get('unknownHosts'));
- break;
- case 'started':
- response.items.filterProperty('ServiceComponentInfo.started_count').forEach(function (item) {
- var started = item.ServiceComponentInfo.started_count;
- components = setComponents(item, components);
- count += started;
- hosts = setHosts(components);
- });
- this.set('runningComponentCount', count);
- lazyLoadHosts(this.get('runningHosts'));
- break;
- }
- },
- componentsFilterErrorCallback: function () {
- this.set('isLoaded', true);
- },
- didInsertElement: function () {
- return App.ajax.send({
- name: 'components.filter_by_status',
- sender: this,
- data: {
- clusterName: App.get('clusterName'),
- urlParams: urlParams
- },
- success: 'componentsFilterSuccessCallback',
- error: 'componentsFilterErrorCallback'
- });
- },
- getDisplayMessage: function () {
- var displayMsg = [];
- var siteProperties = this.get('siteProperties');
- if (siteProperties) {
- siteProperties.forEach(function (_siteProperty) {
- var displayProperty = _siteProperty.siteProperty;
- var displayNames = _siteProperty.displayNames;
- if (displayNames && displayNames.length) {
- if (displayNames.length === 1) {
- displayMsg.push(displayProperty + Em.I18n.t('as') + displayNames[0]);
- } else {
- var name;
- displayNames.forEach(function (_name, index) {
- if (index === 0) {
- name = _name;
- } else if (index === siteProperties.length - 1) {
- name = name + Em.I18n.t('and') + _name;
- } else {
- name = name + ', ' + _name;
- }
- }, this);
- displayMsg.push(displayProperty + Em.I18n.t('as') + name);
- }
- } else {
- displayMsg.push(displayProperty);
- }
- }, this);
- }
- return displayMsg;
- }.property('siteProperties'),
- runningHostsMessage: function () {
- return Em.I18n.t('services.service.config.stopService.runningHostComponents').format(this.get('runningComponentCount'), this.get('runningHosts.length'));
- }.property('runningComponentCount', 'runningHosts.length'),
- unknownHostsMessage: function () {
- return Em.I18n.t('services.service.config.stopService.unknownHostComponents').format(this.get('unknownComponentCount'), this.get('unknownHosts.length'));
- }.property('unknownComponentCount', 'unknownHosts.length'),
- templateName: require('templates/main/service/info/configs_save_popup')
- })
- })
- },
- /*********************************** 6. ADDITIONAL *******************************************/
- /**
- * If some configs are changed and user navigates away or select another config-group, show this popup with propose to save changes
- * @param {String} path
- * @param {object} callback - callback with action to change configs view(change group or version)
- * @return {App.ModalPopup}
- * @method showSavePopup
- */
- showSavePopup: function (path, callback) {
- var self = this;
- return App.ModalPopup.show({
- header: Em.I18n.t('common.warning'),
- bodyClass: Em.View.extend({
- templateName: require('templates/common/configs/save_configuration'),
- showSaveWarning: true,
- notesArea: Em.TextArea.extend({
- classNames: ['full-width'],
- placeholder: Em.I18n.t('dashboard.configHistory.info-bar.save.popup.placeholder'),
- onChangeValue: function() {
- this.get('parentView.parentView').set('serviceConfigNote', this.get('value'));
- }.observes('value')
- })
- }),
- footerClass: Ember.View.extend({
- templateName: require('templates/main/service/info/save_popup_footer')
- }),
- primary: Em.I18n.t('common.save'),
- secondary: Em.I18n.t('common.cancel'),
- onSave: function () {
- self.set('serviceConfigVersionNote', this.get('serviceConfigNote'));
- self.saveStepConfigs();
- this.hide();
- },
- onDiscard: function () {
- self.set('preSelectedConfigVersion', null);
- if (path) {
- self.set('forceTransition', true);
- App.router.route(path);
- } else if (callback) {
- // Prevent multiple popups
- self.set('hash', self.getHash());
- callback();
- }
- this.hide();
- },
- onCancel: function () {
- this.hide();
- }
- });
- },
- /**
- * TODO the methods below are not used as the logic was changed
- * check and delete if this methods is not required
- */
- /**
- * filter out unchanged configurations
- * @param {Array} configsToSave
- * @private
- * @method filterChangedConfiguration
- */
- filterChangedConfiguration: function (configsToSave) {
- var changedConfigs = [];
- configsToSave.forEach(function (configSite) {
- var oldConfig = App.router.get('configurationController').getConfigsByTags([
- {siteName: configSite.type, tagName: this.loadedClusterSiteToTagMap[configSite.type]}
- ]);
- oldConfig = oldConfig[0] || {};
- var oldProperties = oldConfig.properties || {};
- var oldAttributes = oldConfig["properties_attributes"] || {};
- var newProperties = configSite.properties || {};
- var newAttributes = configSite["properties_attributes"] || {};
- if (this.isAttributesChanged(oldAttributes, newAttributes) || this.isConfigChanged(oldProperties, newProperties) || this.get('modifiedFileNames').contains(App.config.getOriginalFileName(configSite.type))) {
- changedConfigs.push(configSite);
- }
- }, this);
- return changedConfigs;
- },
- /**
- * Compares the loaded config values with the saving config values.
- * @param {Object} loadedConfig -
- * loadedConfig: {
- * configName1: "configValue1",
- * configName2: "configValue2"
- * }
- * @param {Object} savingConfig
- * savingConfig: {
- * configName1: "configValue1",
- * configName2: "configValue2"
- * }
- * @returns {boolean}
- * @private
- * @method isConfigChanged
- */
- isConfigChanged: function (loadedConfig, savingConfig) {
- if (loadedConfig != null && savingConfig != null) {
- var seenLoadKeys = [];
- for (var loadKey in loadedConfig) {
- if (!loadedConfig.hasOwnProperty(loadKey)) continue;
- seenLoadKeys.push(loadKey);
- var loadValue = loadedConfig[loadKey];
- var saveValue = savingConfig[loadKey];
- if ("boolean" == typeof(saveValue)) {
- saveValue = saveValue.toString();
- }
- if (saveValue == null) {
- saveValue = "null";
- }
- if (loadValue !== saveValue) {
- return true;
- }
- }
- for (var saveKey in savingConfig) {
- if (seenLoadKeys.indexOf(saveKey) < 0) {
- return true;
- }
- }
- }
- return false;
- },
- /**
- * Compares the loaded config properties attributes with the saving config properties attributes.
- * @param {Object} oldAttributes -
- * oldAttributes: {
- * supports: {
- * final: {
- * "configValue1" : "true",
- * "configValue2" : "true"
- * }
- * }
- * }
- * @param {Object} newAttributes
- * newAttributes: {
- * supports: {
- * final: {
- * "configValue1" : "true",
- * "configValue2" : "true"
- * }
- * }
- * }
- * @returns {boolean}
- * @private
- * @method isAttributesChanged
- */
- isAttributesChanged: function (oldAttributes, newAttributes) {
- oldAttributes = oldAttributes.final || {};
- newAttributes = newAttributes.final || {};
- var key;
- for (key in oldAttributes) {
- if (oldAttributes.hasOwnProperty(key)
- && (!newAttributes.hasOwnProperty(key) || newAttributes[key] !== oldAttributes[key])) {
- return true;
- }
- }
- for (key in newAttributes) {
- if (newAttributes.hasOwnProperty(key)
- && (!oldAttributes.hasOwnProperty(key) || newAttributes[key] !== oldAttributes[key])) {
- return true;
- }
- }
- return false;
- },
- /**
- * Save "final" attribute for properties
- * @param {Array} properties - array of properties
- * @returns {Object|null}
- * @method getConfigAttributes
- */
- getConfigAttributes: function(properties) {
- var attributes = {
- final: {}
- };
- var finalAttributes = attributes.final;
- var hasAttributes = false;
- properties.forEach(function (property) {
- if (property.isRequiredByAgent !== false && property.isFinal) {
- hasAttributes = true;
- finalAttributes[property.name] = "true";
- }
- });
- if (hasAttributes) {
- return attributes;
- }
- return null;
- },
- /**
- * create site object
- * @param {string} siteName
- * @param {string} tagName
- * @param {object[]} siteObj
- * @return {Object}
- * @method createSiteObj
- */
- createSiteObj: function (siteName, tagName, siteObj) {
- var heapsizeException = this.get('heapsizeException');
- var heapsizeRegExp = this.get('heapsizeRegExp');
- var siteProperties = {};
- siteObj.forEach(function (_siteObj) {
- var value = _siteObj.value;
- if (_siteObj.isRequiredByAgent == false) return;
- // site object name follow the format *permsize/*heapsize and the value NOT ends with "m"
- if (heapsizeRegExp.test(_siteObj.name) && !heapsizeException.contains(_siteObj.name) && !(_siteObj.value).endsWith("m")) {
- value += "m";
- }
- siteProperties[_siteObj.name] = value;
- switch (siteName) {
- case 'falcon-startup.properties':
- case 'falcon-runtime.properties':
- case 'pig-properties':
- siteProperties[_siteObj.name] = value;
- break;
- default:
- siteProperties[_siteObj.name] = this.setServerConfigValue(_siteObj.name, value);
- }
- }, this);
- var result = {"type": siteName, "tag": tagName, "properties": siteProperties};
- var attributes = this.getConfigAttributes(siteObj);
- if (attributes) {
- result['properties_attributes'] = attributes;
- }
- return result;
- },
- /**
- * This method will be moved to config's decorators class.
- *
- * For now, provide handling for special properties that need
- * be specified in special format required for server.
- *
- * @param configName {String} - name of config property
- * @param value {*} - value of config property
- *
- * @return {String} - formatted value
- * @method setServerConfigValue
- */
- setServerConfigValue: function (configName, value) {
- switch (configName) {
- case 'storm.zookeeper.servers':
- case 'nimbus.seeds':
- if(Em.isArray(value)) {
- return JSON.stringify(value).replace(/"/g, "'");
- } else {
- return value;
- }
- break;
- default:
- return value;
- }
- }
- });
|