You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ab...@apache.org on 2015/03/27 11:34:37 UTC
ambari git commit: AMBARI-10230 Support config-dependency changes
when they cross services. (ababiichuk)
Repository: ambari
Updated Branches:
refs/heads/trunk fb763311e -> 9f87c98dc
AMBARI-10230 Support config-dependency changes when they cross services. (ababiichuk)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/9f87c98d
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/9f87c98d
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/9f87c98d
Branch: refs/heads/trunk
Commit: 9f87c98dcf352f2bae671556e74e06798ee0a5a6
Parents: fb76331
Author: aBabiichuk <ab...@cybervisiontech.com>
Authored: Fri Mar 27 12:31:25 2015 +0200
Committer: aBabiichuk <ab...@cybervisiontech.com>
Committed: Fri Mar 27 12:31:25 2015 +0200
----------------------------------------------------------------------
.../controllers/main/service/info/configs.js | 338 +++++------
ambari-web/app/messages.js | 3 +
.../mixins/common/configs/enhanced_configs.js | 586 ++++++++++++++++---
ambari-web/app/mixins/common/serverValidator.js | 77 ---
.../modal_popups/dependent_configs_list.hbs | 8 +-
.../common/modal_popups/select_groups_popup.hbs | 32 +
ambari-web/app/views.js | 1 +
.../dependent_configs_list_popup.js | 12 +-
.../common/modal_popups/select_groups_popup.js | 77 +++
.../main/service/info/config_test.js | 43 --
.../common/configs/enhanced_configs_test.js | 19 +-
11 files changed, 764 insertions(+), 432 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/9f87c98d/ambari-web/app/controllers/main/service/info/configs.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/info/configs.js b/ambari-web/app/controllers/main/service/info/configs.js
index b126798..19179a0 100644
--- a/ambari-web/app/controllers/main/service/info/configs.js
+++ b/ambari-web/app/controllers/main/service/info/configs.js
@@ -38,6 +38,10 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM
requestInProgress: null,
selectedServiceConfigTypes: [],
selectedServiceSupportsFinal: [],
+
+ /**
+ * config groups for current service
+ */
configGroups: [],
allConfigs: [],
uiConfigs: [],
@@ -65,19 +69,6 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM
}.property('selectedVersion', 'content.serviceName', 'dataIsLoaded'),
/**
- * array that contains config properties that were changed and
- * belongs to not current service
- * @returns {*|Array}
- */
- unsavedDependentConfigs: function() {
- return App.ConfigProperty.find().filter(function(cp) {
- return cp.get('stackConfigProperty.serviceName') !== this.get('content.serviceName')
- && this.get('dependentFileNames').contains(cp.get('fileName'))
- && cp.get('isNotDefaultValue');
- }, this);
- },
-
- /**
* @type {boolean}
*/
canEdit: function () {
@@ -252,8 +243,6 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM
*/
isInit: true,
- restartHosts: Em.A(),
-
/**
* On load function
*/
@@ -261,10 +250,12 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM
console.log("TRACE: Loading configure for service");
var self = this;
if (App.get('supports.enhancedConfigs')) {
- App.config.loadConfigTheme(this.get('content.serviceName')).then(function() {
- self.loadDependentConfigs().done(function () {
- App.themesMapper.generateAdvancedTabs([self.get('content.serviceName')]);
- });
+ App.config.loadConfigTheme(this.get('content.serviceName')).always(function() {
+ self.setDependentServices(self.get('content.serviceName'));
+ App.themesMapper.generateAdvancedTabs([self.get('content.serviceName')]);
+ if (self.get('dependentServiceNames.length') > 0) {
+ App.config.loadConfigCurrentVersions(self.get('dependentServiceNames'));
+ }
});
}
this.clearStep();
@@ -333,73 +324,6 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM
},
/**
- * this method defines dependent file names for configs
- * and load them to model
- * @method loadDependentConfigs
- */
- loadDependentConfigs: function() {
- /**
- * filter out configs for current service with
- * <code>propertyDependedBy<code>
- * @type {Array}
- */
- var serviceStackProperties = App.StackConfigProperty.find().filter(function(stackProperty) {
- return stackProperty.get('serviceName') === this.get('content.serviceName') && stackProperty.get('propertyDependedBy.length') > 0
- }, this);
-
- /**
- * defines what fileNames should UI load
- */
- serviceStackProperties.forEach(function(serviceStackProperty) {
- this.calculateDependentFileNames(serviceStackProperty);
- }, this);
-
- var serviceConfigsToLoad = this.getServiceNamesForConfigs();
-
- /**
- * load serviceConfigVersion
- * by serviceName that has dependent properties
- */
- if (serviceConfigsToLoad.length > 0) {
- return App.config.loadConfigCurrentVersions(serviceConfigsToLoad);
- }
- },
-
- /**
- * get required fileNames that has dependencies
- * @returns {string[]}
- */
- getServiceNamesForConfigs: function() {
- return App.StackService.find().filter(function(s) {
- for (var i = 0; i < this.get('dependentFileNames.length'); i++) {
- if (Object.keys(s.get('configTypes')).contains(App.config.getConfigTagFromFileName(this.get('dependentFileNames')[i])))
- return true;
- }
- return false;
- }, this).mapProperty('serviceName').concat(this.get('content.serviceName'));
- },
-
- /**
- * dependent file names for configs
- */
- dependentFileNames: [],
-
- /**
- * defines file names for configs
- * @param {App.StackConfigProperty} stackProperty
- */
- calculateDependentFileNames: function(stackProperty) {
- if (stackProperty.get('propertyDependedBy.length') > 0) {
- stackProperty.get('propertyDependedBy').forEach(function(dependent) {
- if (!this.get('dependentFileNames').contains(dependent.type)) {
- this.get('dependentFileNames').push(dependent.type);
- }
- this.calculateDependentFileNames(App.StackConfigProperty.find(dependent.name + "_" + dependent.type));
- }, this);
- }
- },
-
- /**
* get service config versions of current service
*/
loadServiceConfigVersions: function () {
@@ -526,6 +450,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM
/**
* load config groups of service
+ * and dependent services
*/
loadServiceTagsAndGroups: function () {
this.trackRequest(App.ajax.send({
@@ -533,7 +458,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM
sender: this,
data: {
serviceName: this.get('content.serviceName'),
- urlParams: "&config_groups/ConfigGroup/tag=" + this.get('content.serviceName')
+ urlParams: "&config_groups/ConfigGroup/tag.in(" + [this.get('content.serviceName')].concat(this.get('dependentServiceNames')).join(',')+ ')'
},
success: 'loadServiceConfigsSuccess'
}));
@@ -543,20 +468,6 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM
this.setConfigGroups(data, opt, params);
},
- setConfigTags: function (data, opt, params) {
- var serviceConfigsDef = this.get('serviceConfigs').findProperty('serviceName', this.get('content.serviceName'));
- var siteToTagMap = {};
- var configTypesRendered = Object.keys(serviceConfigsDef.get('configTypesRendered'));
- configTypesRendered.forEach(function (siteName) {
- if (data.Clusters.desired_configs[siteName]) {
- siteToTagMap[siteName] = data.Clusters.desired_configs[siteName].tag;
- } else {
- siteToTagMap[siteName] = 'version1';
- }
- }, this);
- this.loadedClusterSiteToTagMap = siteToTagMap;
- },
-
setConfigGroups: function (data, opt, params) {
var serviceName = this.get('content.serviceName');
var displayName = this.get('content.displayName');
@@ -594,9 +505,50 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM
selectedConfigGroup = newConfigGroup;
}
configGroups.push(newConfigGroup);
+ } else if (this.get('dependentServiceNames').contains(item.tag)) {
+ /**
+ * Load config groups for services that has dependent properties.
+ * If user change properties that have dependencies in not default config group
+ * user should pick to which config group Ambari should save these properties
+ * @type {App.ConfigGroup}
+ */
+ var newDependentConfigGroup = App.ConfigGroup.create({
+ id: item.id,
+ name: item.group_name,
+ description: item.description,
+ isDefault: false,
+ parentConfigGroup: null,
+ service: App.Service.find().findProperty('serviceName', item.tag),
+ hosts: item.hosts.mapProperty('host_name')
+ });
+ if (!this.get('dependentConfigGroups').findProperty('name', item.group_name)) {
+ this.get('dependentConfigGroups').push(newDependentConfigGroup);
+ }
}
}, this);
}
+ this.get('dependentServiceNames').forEach(function(serviceName) {
+ if (serviceName !== this.get('content.serviceName')) {
+ var service = App.Service.find().findProperty('serviceName', serviceName);
+ /**
+ * default groups for dependent services
+ * @type {App.ConfigGroup}
+ */
+ var defaultConfigGroup = App.ConfigGroup.create({
+ name: service.get('displayName') + " Default",
+ description: "Default cluster level " + serviceName + " configuration",
+ isDefault: true,
+ hosts: [],
+ parentConfigGroup: null,
+ service: service,
+ serviceName: serviceName,
+ configSiteTags: []
+ });
+ if (!this.get('dependentConfigGroups').findProperty('name', defaultConfigGroup.get('name'))) {
+ this.get('dependentConfigGroups').push(defaultConfigGroup);
+ }
+ }
+ }, this);
this.set('configGroups', configGroups);
var defaultConfigGroup = App.ConfigGroup.create({
name: displayName + " Default",
@@ -1202,7 +1154,6 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM
}
return newSCP;
},
-
/**
* tells controller in saving configs was started
* for now just changes flag <code>saveInProgress<code> to true
@@ -1237,27 +1188,11 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM
showWarningPopupsBeforeSave: function() {
var displayName = this.get('content.displayName');
if (this.isDirChanged()) {
- App.showConfirmationPopup(this.showDependenciesAndSave.bind(this),
+ App.showConfirmationPopup(this.restartServicePopup.bind(this),
Em.I18n.t('services.service.config.confirmDirectoryChange').format(displayName),
this.completeSave.bind(this)
);
} else {
- this.showDependenciesAndSave();
- }
- },
-
- /**
- * if there are some dependent configs in different services
- * this popup will be shown with info about this configs
- * @method showDependenciesAndSave
- */
- showDependenciesAndSave: function() {
- var dependentConfigs = this.unsavedDependentConfigs();
- if (dependentConfigs.length > 0) {
- App.showDependentConfigsPopup(dependentConfigs,
- this.restartServicePopup.bind(this),
- this.completeSave.bind(this));
- } else {
this.restartServicePopup();
}
},
@@ -1303,51 +1238,39 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM
configs = App.config.textareaIntoFileConfigs(configs, 'capacity-scheduler.xml');
}
- if (App.get('supports.enhancedConfigs')) {
- if (this.get('content.serviceName') === 'HIVE') {
- this.setHiveHostName(configs);
- } else if (this.get('content.serviceName') === 'OOZIE') {
- this.setOozieHostName(configs);
- }
-
- this.loadConfigsToModel(configs, self.get('selectedVersion'));
+ /**
+ * generates list of properties that was changed
+ * @type {Array}
+ */
+ var modifiedConfigs = configs
+ // 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 configs.filterProperty('filename', fileName);
+ });
- this.saveEnhancedConfigs();
+ if (!!modifiedConfigs.length) {
+ // concatenate results
+ modifiedConfigs = modifiedConfigs.reduce(function (current, prev) {
+ return current.concat(prev);
+ });
+ }
+ // save modified original configs that have no group
+ this.saveSiteConfigs(modifiedConfigs.filter(function (config) {
+ return !config.get('group');
+ }));
- } else {
- /**
- * generates list of properties that was changed
- * @type {Array}
- */
- var modifiedConfigs = configs
- // 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 configs.filterProperty('filename', fileName);
- });
+ /**
+ * First we put cluster configurations, which automatically creates /configurations
+ * resources. Next we update host level overrides.
+ */
+ this.doPUTClusterConfigurations();
- if (!!modifiedConfigs.length) {
- // concatenate results
- modifiedConfigs = modifiedConfigs.reduce(function (current, prev) {
- return current.concat(prev);
- });
- }
- // save modified original configs that have no group
- this.saveSiteConfigs(modifiedConfigs.filter(function (config) {
- return !config.get('group');
- }));
-
- /**
- * First we put cluster configurations, which automatically creates /configurations
- * resources. Next we update host level overrides.
- */
- this.doPUTClusterConfigurations();
- }
} else {
var overridenConfigs = [];
var groupHosts = [];
@@ -1356,33 +1279,33 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM
});
// find custom original properties that assigned to selected config group
overridenConfigs = overridenConfigs.concat(configs.filterProperty('group')
- .filter(function(config) { return config.get('group.name') == self.get('selectedConfigGroup.name'); }));
-
- if (App.get('supports.enhancedConfigs')) {
-
- this.loadConfigsToModel(overridenConfigs, this.get('selectedVersion'));
-
- this.saveEnhancedConfigsAndGroup(this.get('selectedConfigGroup'));
+ .filter(function (config) {
+ return config.get('group.name') == self.get('selectedConfigGroup.name');
+ }));
- } else {
- this.formatConfigValues(overridenConfigs);
- selectedConfigGroup.get('hosts').forEach(function (hostName) {
- groupHosts.push({"host_name": hostName});
- });
+ this.formatConfigValues(overridenConfigs);
+ selectedConfigGroup.get('hosts').forEach(function (hostName) {
+ groupHosts.push({"host_name": hostName});
+ });
- this.putConfigGroupChanges({
- ConfigGroup: {
- "id": selectedConfigGroup.get('id'),
- "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.buildGroupDesiredConfigs(overridenConfigs)
- }
- }, true);
- }
+ /**
+ * if there are some changes in dependent configs
+ * need to save these config to in separate request
+ */
+ this.saveDependentGroups();
+
+ this.putConfigGroupChanges({
+ ConfigGroup: {
+ "id": selectedConfigGroup.get('id'),
+ "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.buildGroupDesiredConfigs(overridenConfigs)
+ }
+ }, true);
}
},
@@ -1658,7 +1581,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM
if (showPopup) {
ajaxOptions.success = "putConfigGroupChangesSuccess";
}
- App.ajax.send(ajaxOptions);
+ return App.ajax.send(ajaxOptions);
},
putConfigGroupChangesSuccess: function () {
@@ -2021,7 +1944,9 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM
* adding config tags for dependentConfigs
*/
for (var i = 0; i < this.get('dependentFileNames.length'); i++) {
- serviceConfigTags.pushObject({siteName: this.get('dependentFileNames')[i]});
+ if (!serviceConfigTags.findProperty('siteName', this.get('dependentFileNames')[i])) {
+ serviceConfigTags.pushObject({siteName: this.get('dependentFileNames')[i]});
+ }
}
this.setNewTagNames(serviceConfigTags);
var siteNameToServerDataMap = {};
@@ -2035,7 +1960,29 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM
}, this);
configsToSave = this.filterChangedConfiguration(configsToSave);
if (configsToSave.length > 0) {
- this.doPUTClusterConfigurationSites(configsToSave);
+ var data = [];
+ data.pushObject(JSON.stringify({
+ Clusters: {
+ desired_config: configsToSave
+ }
+ }));
+ if (App.get('supports.enhancedConfigs')) {
+ /**
+ * adding configs that were changed for dependent services
+ * if there are such configs
+ */
+ this.get('dependentServiceNames').forEach(function(serviceName) {
+ var dependentConfigsToSave = this.getDependentConfigObject(serviceName);
+ if (dependentConfigsToSave.length > 0) {
+ data.pushObject(JSON.stringify({
+ Clusters: {
+ desired_config: dependentConfigsToSave
+ }
+ }));
+ }
+ }, this);
+ }
+ this.doPUTClusterConfigurationSites(data);
} else {
this.onDoPUTClusterConfigurations();
}
@@ -2183,15 +2130,15 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM
/**
* Saves configuration of set of sites. The provided data
* contains the site name and tag to be used.
- * @param {Object} sites
+ * @param {Object[]} services
* @method doPUTClusterConfigurationSites
*/
- doPUTClusterConfigurationSites: function (sites) {
+ doPUTClusterConfigurationSites: function (services) {
App.ajax.send({
- name: 'common.service.configurations',
+ name: 'common.across.services.configurations',
sender: this,
data: {
- desired_config: sites
+ data: '[' + services.toString() + ']'
},
success: 'doPUTClusterConfigurationSiteSuccessCallback',
error: 'doPUTClusterConfigurationSiteErrorCallback'
@@ -2640,9 +2587,10 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM
* add new overridden property to config property object
* @param {object} serviceConfigProperty - config property object
* @param {App.ConfigGroup} group - config group for new property
+ * @param {String} value
* @method addOverrideProperty
*/
- addOverrideProperty: function (serviceConfigProperty, group) {
+ addOverrideProperty: function (serviceConfigProperty, group, value) {
var overrides = serviceConfigProperty.get('overrides');
if (!overrides) {
overrides = [];
@@ -2650,7 +2598,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM
}
// create new override with new value
var newSCP = App.ServiceConfigProperty.create(serviceConfigProperty);
- newSCP.set('value', '');
+ newSCP.set('value', value || '');
newSCP.set('isOriginalSCP', false); // indicated this is overridden value,
newSCP.set('parentSCP', serviceConfigProperty);
newSCP.set('isEditable', true);
http://git-wip-us.apache.org/repos/asf/ambari/blob/9f87c98d/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index 50d62f0..42a0aaa 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -255,6 +255,7 @@ Em.I18n.translations = {
'common.minutes': "Minutes",
'common.seconds': "Seconds",
'common.milliseconds': "Milliseconds",
+ 'common.configGroup': 'Config Group',
'models.alert_instance.tiggered.verbose': "Occured on {0} <br> Checked on {1}",
'models.alert_definition.triggered.verbose': "Occured on {0}",
@@ -344,6 +345,8 @@ Em.I18n.translations = {
'popup.dependent.configs.table.currentValue': 'Current value',
'popup.dependent.configs.table.recommendedValue': 'Recommended value',
+ 'popup.dependent.configs.select.config.group': 'Please select to which config group would you like to save dependent properties',
+
'login.header':'Sign in',
'login.username':'Username',
'login.loginButton':'Sign in',
http://git-wip-us.apache.org/repos/asf/ambari/blob/9f87c98d/ambari-web/app/mixins/common/configs/enhanced_configs.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/common/configs/enhanced_configs.js b/ambari-web/app/mixins/common/configs/enhanced_configs.js
index a661ddb..61c2a2e 100644
--- a/ambari-web/app/mixins/common/configs/enhanced_configs.js
+++ b/ambari-web/app/mixins/common/configs/enhanced_configs.js
@@ -17,127 +17,131 @@
*/
var App = require('app');
+var blueprintUtils = require('utils/blueprint');
App.EnhancedConfigsMixin = Em.Mixin.create({
- modifiedFileNames: [],
-
/**
- * merge step configs from model
- * for default config group properties should be list
- * of changed properties
- * @param properties
- * @param currentVersionNumber
+ * values for dependent configs
+ * @type {Object[]}
+ * ex:
+ * {
+ * saveRecommended: {boolean}, //by default is true (checkbox binding)
+ * fileName: {string}, //file name without '.xml'
+ * propertyName: {string},
+ * configGroup: {string},
+ * value: {string},
+ * serviceName: {string},
+ * recommendedValue: {string}
+ * }
+ * @private
*/
- loadConfigsToModel: function(properties, currentVersionNumber) {
- var serviceName = this.get('content.serviceName');
- if (properties && properties.length) {
- properties.forEach(function(p) {
- var configFromModel = App.ConfigProperty.find(p.get('name') + '_' + App.config.getConfigTagFromFileName(p.get('filename')) + '_' + currentVersionNumber);
- if (configFromModel && configFromModel.get('name')) {
- configFromModel.setProperties({
- 'value': p.get('value'),
- 'isFinal': p.get('isFinal'),
- 'defaultValue': p.get('defaultValue'),
- 'defaultIsFinal': p.get('defaultIsFinal'),
- 'isRequiredByAgent': p.get('isRequiredByAgent'),
- 'isNotSaved': p.get('isNotSaved')
- });
- } else {
- App.store.load(App.ConfigProperty, {
- id: p.get('name') + '_' + App.config.getConfigTagFromFileName(p.get('filename')) + '_' + currentVersionNumber,
- name: p.get('name'),
- file_name: p.get('filename'),
- value: p.get('value'),
- is_final: p.get('isFinal'),
- default_value: p.get('defaultValue'),
- default_is_final: p.get('defaultIsFinal'),
- is_required_by_agent: p.get('isRequiredByAgent'),
- is_not_saved: p.get('isNotSaved'),
- is_required: false,
- config_version_id: serviceName + '_' + currentVersionNumber
- })
- }
- });
- }
- },
+ _dependentConfigValues: [],
/**
- * generates data and save configs for default group
- * @method saveEnhancedConfigs
+ * dependent file names for configs
+ * @type {string[]}
*/
- saveEnhancedConfigs: function() {
+ dependentFileNames: [],
- var fileNamesToSave = this.getFileNamesToSave(this.get('modifiedFileNames'));
+ /**
+ * dependent service names for configs
+ * @type {string[]}
+ */
+ dependentServiceNames: [],
- var configsToSave = this.getConfigsToSave(fileNamesToSave);
+ /**
+ * config groups for dependent services
+ * @type {App.ConfigGroup[]}
+ */
+ dependentConfigGroups: [],
- var desired_configs = this.generateDesiredConfigsJSON(configsToSave, fileNamesToSave, this.get('serviceConfigNote'));
+ /**
+ * contains config group name that need to be saved
+ * {
+ * serviceName: configGroupName
+ * }
+ * @type {Object}
+ */
+ groupsToSave: {},
- this.doPUTClusterConfigurationSites(desired_configs);
- },
+ /***********************************METHODS THAT WORKS WITH MODEL ********************************************/
/**
- * generates data and save configs for not default group
- * @param selectedConfigGroup
- * @method saveEnhancedConfigsAndGroup
+ * generates desired_config objects for default config group
+ * @returns {Object}
+ * @method getDependentConfigObject
*/
- saveEnhancedConfigsAndGroup: function(selectedConfigGroup) {
- //TODO update for dependent configs
- var serviceConfigVersion = App.ConfigVersion.find().findProperty('groupName', selectedConfigGroup.get('name'));
+ getDependentConfigObject: function(serviceName) {
- var overridenConfigs = App.ConfigProperty.find().filter(function(cp) {
- return cp.get('configVersion.groupId') === selectedConfigGroup.get('id') || cp.get('isNotDefaultValue');
- });
+ var fileNamesToSave = this._getFileNamesToSave(serviceName);
- var hostNames = serviceConfigVersion.get('hosts').map(function(hostName) {
- return {
- "host_name": hostName
- }
- });
+ var configsToSave = this._getConfigsToSave(fileNamesToSave);
- var fileNamesToSave = overridenConfigs.mapProperty('fileName').uniq();
-
- this.putConfigGroupChanges({
- ConfigGroup: {
- "id": selectedConfigGroup.get('id'),
- "cluster_name": App.get('clusterName'),
- "group_name": selectedConfigGroup.get('name'),
- "tag": selectedConfigGroup.get('service.id'),
- "description": selectedConfigGroup.get('description'),
- "hosts": hostNames,
- "service_config_version_note": this.get('serviceConfigNote'),
- "desired_configs": this.generateDesiredConfigsJSON(overridenConfigs, fileNamesToSave, null, true)
- }
- }, true);
+ return this.generateDesiredConfigsJSON(configsToSave, fileNamesToSave, this.get('serviceConfigNote'));
},
/**
- * get file names that need to be saved
- * @param {Array} modifiedFileNames
- * @returns {Ember.Enumerable}
+ * generates data and save configs for not default groups only
+ * that uses configs from model App.ConfigProperty
+ * @param serviceName
+ * @param configGroup
+ * @method saveEnhancedConfigsAndGroup
*/
- getFileNamesToSave: function(modifiedFileNames) {
- return App.ConfigProperty.find().filter(function(cp) {
- return cp.get('isNotDefaultValue') || cp.get('isNotSaved');
- }, this).mapProperty('fileName').concat(modifiedFileNames).uniq();
+ saveModelConfigsWithGroup: function(serviceName, configGroup) {
+ /**
+ * for now we are saving configs from model only for dependent services
+ * so excluding situation in current service is trying to be saved
+ * this is temporary solution
+ */
+ if (this.get('content.serviceName') !== serviceName) {
+
+ var configsToSave = App.ConfigProperty.find().filter(function(cp) {
+ return cp.get('configVersion.groupName') == configGroup.get('name') || cp.get('isNotSaved');
+ });
+ if (configsToSave.length > 0) {
+ var hostNames = configGroup.get('hosts').map(function(hostName) {
+ return {
+ "host_name": hostName
+ }
+ });
+
+ var fileNamesToSave = configsToSave.mapProperty('fileName').uniq();
+
+ this.putConfigGroupChanges({
+ ConfigGroup: {
+ "id": configGroup.get('id'),
+ "cluster_name": App.get('clusterName'),
+ "group_name": configGroup.get('name'),
+ "tag": configGroup.get('service.id'),
+ "description": configGroup.get('description'),
+ "hosts": hostNames,
+ "service_config_version_note": this.get('serviceConfigNote'),
+ "desired_configs": this.generateDesiredConfigsJSON(configsToSave, fileNamesToSave, null, true)
+ }
+ })
+ }
+ }
},
/**
- * get configs that need to be saved, for default group
- * @param fileNamesToSave
- * @returns {App.ConfigProperty[]}
+ * save configs from model to default config group
+ * @param serviceName
*/
- getConfigsToSave: function(fileNamesToSave) {
- if (Em.isArray(fileNamesToSave) && fileNamesToSave.length) {
- return App.ConfigProperty.find().filter(function(cp) {
- return (fileNamesToSave.contains(cp.get('fileName')) && cp.get('isOriginalSCP')) || cp.get('isNotSaved');
- });
- } else {
- return Em.A([]);
+ saveModelConfigs: function(serviceName) {
+ var desired_configs = this.getDependentConfigObject(serviceName);
+ if (desired_configs.length > 0) {
+ var data = [JSON.stringify({
+ Clusters: {
+ desired_config: desired_configs
+ }
+ })];
+ this.doPUTClusterConfigurationSites(data);
}
},
+ /********************************METHODS THAT GENERATES JSON TO SAVE *****************************************/
+
/**
* generating common JSON object for desired configs
* @param configsToSave
@@ -250,13 +254,403 @@ App.EnhancedConfigsMixin = Em.Mixin.create({
}
},
+ /******************************METHODS THAT WORKS WITH DEPENDENT CONFIGS *************************************/
+
+ /**
+ * clear values for dependent configs
+ * @method clearDependentConfigs
+ * @private
+ */
+ clearDependentConfigs: function() {
+ this.set('groupsToSave', {});
+ this.set('_dependentConfigValues', []);
+ },
+
+ onConfigGroupChangeForEnhanced: function() {
+ this.clearDependentConfigs();
+ }.observes('selectedConfigGroup'),
+
+
+ /**
+ * saves properties for dependent service to config group based on <code>groupsToSave<code>
+ */
+ saveDependentGroups: function() {
+ if (App.get('supports.enhancedConfigs') && this.get('dependentServiceNames.length') && Object.keys(this.get('groupsToSave')).length > 0) {
+
+ this.get('dependentServiceNames').forEach(function(serviceName) {
+ if (this.get('groupsToSave')[serviceName]) {
+ if (this.get('groupsToSave')[serviceName].contains('Default')) {
+ this.saveModelConfigs(serviceName);
+ } else {
+ this.saveModelConfigsWithGroup(serviceName, this.get('dependentConfigGroups').findProperty('name', this.get('groupsToSave')[serviceName]));
+ }
+ }
+ }, this);
+
+ }
+ },
+
+
+ /**
+ * runs <code>setDependentServicesAndFileNames<code>
+ * for stack properties for current service
+ * @method loadDependentConfigs
+ */
+ setDependentServices: function(serviceName) {
+ App.StackConfigProperty.find().forEach(function(stackProperty) {
+ if (stackProperty.get('serviceName') === serviceName && stackProperty.get('propertyDependedBy.length') > 0) {
+ this._setDependentServicesAndFileNames(stackProperty);
+ }
+ }, this);
+ },
+
/**
- * overriden in controller
+ * get service for current config type
+ * @param {String} configType - config fileName without xml
+ * @return App.StackService
*/
- doPUTClusterConfigurationSites: Em.K,
+ getServiceByConfigType: function(configType) {
+ return App.StackService.find().find(function(s) {
+ return Object.keys(s.get('configTypes')).contains(configType);
+ });
+ },
+
+ /**
+ * show popup to select config group for dependent services
+ * to which dependent configs will ve saved
+ * @method showSelectGroupsPopup
+ */
+ showSelectGroupsPopup: function(callback) {
+ var servicesWithConfigGroups = [];
+ this.get('dependentServiceNames').forEach(function(serviceName) {
+ if (serviceName !== this.get('content.serviceName')) {
+ if (!this.get('groupsToSave')[serviceName]) {
+ var groups = this.get('dependentConfigGroups').filterProperty('service.serviceName', serviceName).mapProperty('name').uniq();
+ servicesWithConfigGroups.push({
+ serviceName: serviceName,
+ configGroupNames: groups
+ })
+ }
+ }
+ }, this);
+ if (servicesWithConfigGroups.length > 0) {
+ App.showSelectGroupsPopup(servicesWithConfigGroups, this.get('groupsToSave'), callback);
+ } else {
+ callback();
+ }
+ },
+
+
+ /**
+ * sends request to get values for dependent configs
+ * @param changedConfigs
+ * @returns {$.ajax|null}
+ */
+ getRecommendationsForDependencies: function(changedConfigs) {
+ if (Em.isArray(changedConfigs) && changedConfigs.length > 0) {
+ var recommendations = this.get('hostGroups');
+ var configs = this._getConfigsByGroup(this.get('stepConfigs'));
+ recommendations.blueprint.configurations = blueprintUtils.buildConfigsJSON(this.get('services'), configs);
+
+ var dataToSend = {
+ recommend: 'configurations',
+ hosts: this.get('hostNames'),
+ services: this.get('serviceNames'),
+ recommendations: recommendations
+ };
+ /** TODO uncomment when be will be ready
+ if (App.get('supports.enhancedConfigs')) {
+ dataToSend.recommend = 'configuration-dependencies';
+ dataToSend.changed_configurations = changedConfigs;
+ }
+ **/
+ return App.ajax.send({
+ name: 'config.recommendations',
+ sender: this,
+ data: {
+ stackVersionUrl: App.get('stackVersionURL'),
+ dataToSend: dataToSend
+ },
+ success: 'dependenciesSuccess',
+ error: 'dependenciesError'
+ });
+ } else {
+ return null;
+ }
+ },
/**
- * overriden in controller
+ * shows popup with results for recommended value
+ * if case properties that was changes belongs to not default group
+ * user should pick to what config group from dependent service dependent properties will be saved
+ * @param data
+ * @method dependenciesSuccess
*/
- putConfigGroupChanges: Em.K
+ dependenciesSuccess: function (data) {
+ var self = this;
+ if (!this.get('selectedConfigGroup.isDefault')) {
+ self.showSelectGroupsPopup(function () {
+ self._saveRecommendedValues(data);
+ if (self.get('_dependentConfigValues.length') > 0) {
+ App.showDependentConfigsPopup(self.get('_dependentConfigValues'), function () {
+ self._saveDependentConfigs();
+ });
+ }
+ });
+ } else {
+ self._saveRecommendedValues(data);
+ if (self.get('_dependentConfigValues.length') > 0) {
+ App.showDependentConfigsPopup(self.get('_dependentConfigValues'), function () {
+ self._saveDependentConfigs();
+ });
+ }
+ }
+ },
+
+ /**
+ *
+ * @param jqXHR
+ * @param ajaxOptions
+ * @param error
+ * @param opt
+ */
+ dependenciesError: function(jqXHR, ajaxOptions, error, opt) {
+ App.ajax.defaultErrorHandler(jqXHR, opt.url, opt.method, jqXHR.status);
+ },
+
+
+ /**
+ * defines file names for configs and set them to <code>dependentFileNames<code> and
+ * defines service names for configs and set them to <code>dependentServiceNames<code>
+ * @param {App.StackConfigProperty} stackProperty
+ * @private
+ */
+ _setDependentServicesAndFileNames: function(stackProperty) {
+ if (stackProperty.get('propertyDependedBy.length') > 0) {
+ stackProperty.get('propertyDependedBy').forEach(function(dependent) {
+ var tag = App.config.getConfigTagFromFileName(dependent.type);
+ /** setting dependent fileNames (without '.xml') **/
+ if (!this.get('dependentFileNames').contains(tag)) {
+ this.get('dependentFileNames').push(tag);
+ }
+ /** setting dependent serviceNames (without current serviceName) **/
+ var dependentProperty = App.StackConfigProperty.find(dependent.name + "_" + tag);
+ if (dependentProperty) {
+ if (!this.get('dependentServiceNames').contains(dependentProperty.get('serviceName')) && dependentProperty.get('serviceName') !== this.get('content.serviceName')) {
+ this.get('dependentServiceNames').push(dependentProperty.get('serviceName'));
+ }
+ this._setDependentServicesAndFileNames(dependentProperty);
+ }
+ }, this);
+ }
+ },
+
+ /**
+ * get file names that need to be saved
+ * used for default config group
+ * @param {String} serviceName
+ * @returns {Ember.Enumerable}
+ * @private
+ */
+ _getFileNamesToSave: function(serviceName) {
+ return App.ConfigProperty.find().filter(function(cp) {
+ return cp.get('isNotDefaultValue') && cp.get('stackConfigProperty.serviceName') === serviceName;
+ }, this).mapProperty('fileName').uniq();
+ },
+
+ /**
+ * get configs that need to be saved, for default group
+ * @param fileNamesToSave
+ * @returns {App.ConfigProperty[]}
+ * @private
+ */
+ _getConfigsToSave: function(fileNamesToSave) {
+ if (Em.isArray(fileNamesToSave) && fileNamesToSave.length) {
+ return App.ConfigProperty.find().filter(function(cp) {
+ return fileNamesToSave.contains(cp.get('fileName')) && cp.get('configVersion.isCurrent');
+ });
+ } else {
+ return Em.A([]);
+ }
+ },
+
+ /**
+ * save values that are stored in <code>_dependentConfigValues<code>
+ * for current service to step configs
+ * for dependent services to model
+ * @private
+ */
+ _saveDependentConfigs: function() {
+ var self = this;
+ this.get('_dependentConfigValues').forEach(function(dependentConfig) {
+ if (Em.get(dependentConfig, 'saveRecommended')) { // if saveRecommended is false leave properties as is
+ if (Em.get(dependentConfig, 'serviceName') === self.get('content.serviceName')) { //for current service save dependent properties to step configs
+ self.get('stepConfigs').objectAt(0).get('configs').forEach(function(stepConfig) {
+ if (stepConfig.get('filename') === App.config.getOriginalFileName(Em.get(dependentConfig, 'fileName'))
+ && stepConfig.get('name') === Em.get(dependentConfig, 'propertyName')) {
+ if (self.get('selectedConfigGroup.isDefault')) {
+ stepConfig.set('value', Em.get(dependentConfig, 'recommendedValue'))
+ } else {
+ if (!stepConfig.get('overrides')) {
+ stepConfig.set('overrides', Em.A([]));
+ }
+ var overridenConfig = stepConfig.get('overrides').findProperty('isEditable');
+ if (overridenConfig) {
+ overridenConfig.set('value', Em.get(dependentConfig, 'recommendedValue'));
+ } else {
+ self.addOverrideProperty(stepConfig, self.get('selectedConfigGroup'), Em.get(dependentConfig, 'recommendedValue'));
+ }
+ }
+ }
+ })
+ } else { //for not current service save dependent properties to model
+
+ App.ConfigProperty.find().forEach(function(cp) {
+ if (cp.get('name') === Em.get(dependentConfig, 'propertyName')
+ && cp.get('fileName') === App.config.getOriginalFileName(Em.get(dependentConfig, 'fileName'))) {
+
+ if (self.get('selectedConfigGroup.isDefault') || Em.get(dependentConfig, 'configGroup').contains('Default')) {
+ if (cp.get('isOriginalSCP')) {
+ cp.set('value', Em.get(dependentConfig, 'recommendedValue'))
+ }
+ } else {
+ if (cp.get('configVersion.groupName') === self.get('groupsToSave')[dependentConfig.serviceName]) {
+ cp.set('value', Em.get(dependentConfig, 'recommendedValue'));
+ } else {
+ App.store.load(App.ConfigProperty, {
+ id: Em.get(dependentConfig, 'propertyName') + '_' + Em.get(dependentConfig, 'fileName') + '_',
+ name: Em.get(dependentConfig, 'propertyName'),
+ value: Em.get(dependentConfig, 'recommendedValue'),
+ file_name: App.config.getOriginalFileName(Em.get(dependentConfig, 'fileName')),
+ is_not_saved: true
+ })
+ }
+ }
+
+ }
+ });
+ }
+ }
+ });
+ },
+
+ /**
+ * get array of config objects for current service depends on config group
+ * for default group - it will be current stepConfigs
+ * for not default group - overriden property in case there is such property in group
+ * otherwise - property from default group
+ * @param stepConfigs
+ * @returns {App.ServiceConfigProperty[]}
+ * @private
+ */
+ _getConfigsByGroup: function(stepConfigs) {
+ var configsToSend = [];
+ if (this.get('selectedConfigGroup.isDefault')) {
+ return stepConfigs;
+ } else {
+ stepConfigs.forEach(function(stepConfig) {
+ if (stepConfig.get('overrides')) {
+ var conf = stepConfig.get('overrides').findProperty('group.name', this.get('selectedConfigGroup.name'));
+ if (conf) {
+ configsToSend.pushObject(conf);
+ } else {
+ configsToSend.pushObject(stepConfig);
+ }
+ } else {
+ configsToSend.pushObject(stepConfig);
+ }
+ }, this)
+ }
+ return configsToSend;
+ },
+
+ /**
+ * saves values from response for dependent configs to <code>_dependentConfigValues<code>
+ * @param data
+ * @method saveRecommendedValues
+ * @private
+ */
+ _saveRecommendedValues: function(data) {
+ Em.assert('invalid data', data && data.resources[0] && Em.get(data.resources[0], 'recommendations.blueprint.configurations'));
+ var configs = data.resources[0].recommendations.blueprint.configurations;
+ for (var key in configs) {
+ for (var propertyName in configs[key].properties) {
+ var service = this.getServiceByConfigType(key);
+ var value = this._getCurrentValue(service.get('serviceName'), key, propertyName, this.get('selectedConfigGroup'));
+ if (!Em.isNone(value)) {
+ var dependentProperty = this.get('_dependentConfigValues').findProperty('propertyName', propertyName);
+ if (dependentProperty) {
+ if (value != configs[key].properties[propertyName]) {
+ Em.set(dependentProperty, 'value', value);
+ Em.set(dependentProperty, 'recommendedValue', configs[key].properties[propertyName]);
+ } else {
+ this.get('_dependentConfigValues').removeObject(dependentProperty);
+ }
+ } else {
+ var configGroup = this.get('selectedConfigGroup.isDefault') ?
+ service.get('serviceName') + ' Default' : this.get('groupsToSave')[service.get('serviceName')] || this.get('selectedConfigGroup.name');
+ if (value != configs[key].properties[propertyName]) {
+ this.get('_dependentConfigValues').pushObject({
+ saveRecommended: true,
+ fileName: key,
+ propertyName: propertyName,
+ configGroup: configGroup,
+ value: value,
+ serviceName: service.get('serviceName'),
+ recommendedValue: configs[key].properties[propertyName]
+ });
+ }
+ }
+ }
+ }
+ }
+ },
+
+ /**
+ * get current value for property by serviceName, tag and ConfigGroup
+ * @param serviceName
+ * @param tag
+ * @param propertyName
+ * @param configGroup
+ * @returns {null|Object}
+ * @private
+ */
+ _getCurrentValue: function(serviceName, tag, propertyName, configGroup) {
+ if (serviceName == this.get('content.serviceName')) {
+ var stepConfig = this.get('stepConfigs').objectAt(0).get('configs').find(function(stepConfig) {
+ return (stepConfig.get('filename') === App.config.getOriginalFileName(tag) && stepConfig.get('name') === propertyName);
+ });
+ if (stepConfig) {
+ if (configGroup.get('isDefault') || Em.isNone(stepConfig.get('overrides'))) {
+ return stepConfig.get('value');
+ } else {
+ var overridenConfig = stepConfig.get('overrides').findProperty('isEditable');
+ if (overridenConfig) {
+ return overridenConfig.get('value');
+ } else {
+ return stepConfig.get('value');
+ }
+ }
+ }
+ } else {
+ var currentDefaultProperties = App.ConfigProperty.find().filter(function(cp) {
+ return cp.get('configVersion.isCurrent') && cp.get('configVersion.isDefault');
+ });
+ if (!this.get('selectedConfigGroup.isDefault') && (!this.get('groupsToSave')[serviceName] || !this.get('groupsToSave')[serviceName].contains('Default'))) {
+ var currentProperties = App.ConfigProperty.find().filter(function(cp) {
+ return cp.get('configVersion.isCurrent') && cp.get('configVersion.groupName') === this.get('groupsToSave')[serviceName];
+ }, this);
+ var modelConfig = currentProperties.findProperty('name', propertyName);
+ if (modelConfig) {
+ return modelConfig.get('value');
+ }
+ }
+
+ var modelDefaultConfig = currentDefaultProperties.findProperty('name', propertyName);
+ if (modelDefaultConfig) {
+ return modelDefaultConfig.get('value');
+ }
+ }
+ return null;
+ }
});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/9f87c98d/ambari-web/app/mixins/common/serverValidator.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/common/serverValidator.js b/ambari-web/app/mixins/common/serverValidator.js
index 4c89182..d6eeef3 100644
--- a/ambari-web/app/mixins/common/serverValidator.js
+++ b/ambari-web/app/mixins/common/serverValidator.js
@@ -135,83 +135,6 @@ App.ServerValidatorMixin = Em.Mixin.create({
},
/**
- *
- * @param changedConfigs
- * @returns {$.ajax|null}
- */
- getRecommendationsForDependencies: function(changedConfigs) {
- if (Em.isArray(changedConfigs) && changedConfigs.length > 0) {
- var recommendations = this.get('hostGroups');
- recommendations.blueprint.configurations = blueprintUtils.buildConfigsJSON(this.get('services'), this.get('stepConfigs'));
-
- var dataToSend = {
- recommend: 'configurations',
- hosts: this.get('hostNames'),
- services: this.get('serviceNames'),
- recommendations: recommendations
- };
- /** TODO uncomment when be will be ready
- if (App.get('supports.enhancedConfigs')) {
- dataToSend.recommend = 'configuration-dependencies';
- dataToSend.changed_configurations = changedConfigs;
- }
- **/
- return App.ajax.send({
- name: 'config.recommendations',
- sender: this,
- data: {
- stackVersionUrl: App.get('stackVersionURL'),
- dataToSend: dataToSend
- },
- success: 'dependenciesSuccess',
- error: 'dependenciesError'
- });
- } else {
- return null;
- }
- },
-
- /**
- *
- * @param data
- */
- dependenciesSuccess: function(data) {
- Em.assert('invalid data', data && data.resources[0] && Em.get(data.resources[0], 'recommendations.blueprint.configurations'));
- var configs = data.resources[0].recommendations.blueprint.configurations;
-
- this.loadConfigsToModel(this.get('stepConfigs')[0].get('configs'), this.get('selectedVersion'));
-
- var currentProperties = App.ConfigProperty.find().filterProperty('configVersion.isCurrent').filterProperty('configVersion.groupId', -1);
- for (var key in configs) {
- for (var propertyName in configs[key].properties) {
- var property = currentProperties.findProperty('name', propertyName)
- if (property) {
- property.set('recommendedValue', configs[key].properties[propertyName]);
- }
- }
- }
-
- var configsToShow = currentProperties.filter(function(p) {
- return p.get('recommendedValue') && p.get('recommendedValue') !== p.get('value');
- });
-
- if (configsToShow.length > 0) {
- App.showDependentConfigsPopup(configsToShow);
- }
- },
-
- /**
- *
- * @param jqXHR
- * @param ajaxOptions
- * @param error
- * @param opt
- */
- dependenciesError: function(jqXHR, ajaxOptions, error, opt) {
- App.ajax.defaultErrorHandler(jqXHR, opt.url, opt.method, jqXHR.status);
- },
-
- /**
* @method loadRecommendationsSuccess
* success callback after loading recommendations
* (used only during install)
http://git-wip-us.apache.org/repos/asf/ambari/blob/9f87c98d/ambari-web/app/templates/common/modal_popups/dependent_configs_list.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/common/modal_popups/dependent_configs_list.hbs b/ambari-web/app/templates/common/modal_popups/dependent_configs_list.hbs
index 926c5ea..3c02de9 100644
--- a/ambari-web/app/templates/common/modal_popups/dependent_configs_list.hbs
+++ b/ambari-web/app/templates/common/modal_popups/dependent_configs_list.hbs
@@ -25,8 +25,9 @@
<tr>
<th>{{t popup.dependent.configs.table.saveProperty}}</th>
<th>{{t common.property}}</th>
- <th>{{t common.fileName}}</th>
<th>{{t common.service}}</th>
+ <th>{{t common.configGroup}}</th>
+ <th>{{t common.fileName}}</th>
<th>{{t popup.dependent.configs.table.currentValue}}</th>
<th>{{t popup.dependent.configs.table.recommendedValue}}</th>
</tr>
@@ -35,9 +36,10 @@
{{#each config in view.parentView.configs}}
<tr>
<td>{{view Em.Checkbox checkedBinding="config.saveRecommended"}}</td>
- <td>{{config.name}}</td>
+ <td>{{config.propertyName}}</td>
+ <td>{{config.serviceName}}</td>
+ <td>{{config.configGroup}}</td>
<td>{{config.fileName}}</td>
- <td>{{config.stackConfigProperty.serviceName}}</td>
<td>{{config.value}}</td>
<td>{{config.recommendedValue}}</td>
</tr>
http://git-wip-us.apache.org/repos/asf/ambari/blob/9f87c98d/ambari-web/app/templates/common/modal_popups/select_groups_popup.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/common/modal_popups/select_groups_popup.hbs b/ambari-web/app/templates/common/modal_popups/select_groups_popup.hbs
new file mode 100644
index 0000000..09ee681
--- /dev/null
+++ b/ambari-web/app/templates/common/modal_popups/select_groups_popup.hbs
@@ -0,0 +1,32 @@
+{{!
+* 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.
+}}
+
+<div class="alert alert-warning">
+ {{t popup.dependent.configs.select.config.group}}
+</div>
+<form class="form-horizontal">
+{{#each service in view.parentView.dependentServices}}
+ <div class="form-group">
+ <label class="col-sm-2 control-label">{{service.serviceName}} </label>
+ <div class="col-sm-8">
+ {{view App.selectConfigGroupForService contentBinding="service.configGroupNames" serviceNameBinding="service.serviceName" groupsToSaveBinding="groupsToSave"}}
+ </div>
+ </div>
+{{/each}}
+</form>
+
http://git-wip-us.apache.org/repos/asf/ambari/blob/9f87c98d/ambari-web/app/views.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views.js b/ambari-web/app/views.js
index 8d099b1..b19b535 100644
--- a/ambari-web/app/views.js
+++ b/ambari-web/app/views.js
@@ -34,6 +34,7 @@ require('views/common/modal_popups/reload_popup');
require('views/common/modal_popups/cluster_check_popup');
require('views/common/modal_popups/invalid_KDC_popup');
require('views/common/modal_popups/dependent_configs_list_popup');
+require('views/common/modal_popups/select_groups_popup');
require('views/common/editable_list');
require('views/common/rolling_restart_view');
require('views/common/select_custom_date_view');
http://git-wip-us.apache.org/repos/asf/ambari/blob/9f87c98d/ambari-web/app/views/common/modal_popups/dependent_configs_list_popup.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/modal_popups/dependent_configs_list_popup.js b/ambari-web/app/views/common/modal_popups/dependent_configs_list_popup.js
index 73ed1f6..4c221ba 100644
--- a/ambari-web/app/views/common/modal_popups/dependent_configs_list_popup.js
+++ b/ambari-web/app/views/common/modal_popups/dependent_configs_list_popup.js
@@ -32,7 +32,7 @@ App.showDependentConfigsPopup = function (configs, callback, secondaryCallback)
primary: Em.I18n.t('common.save'),
secondary: Em.I18n.t('common.cancel'),
header: Em.I18n.t('popup.dependent.configs.header'),
- classNames: ['full-width-modal'],
+ classNames: ['sixty-percent-width-modal','modal-full-width'],
configs: configs,
bodyClass: Em.View.extend({
templateName: require('templates/common/modal_popups/dependent_configs_list')
@@ -42,21 +42,13 @@ App.showDependentConfigsPopup = function (configs, callback, secondaryCallback)
}.property('controller.stepConfigs.@each'),
onPrimary: function () {
this.hide();
- configs.filterProperty('saveRecommended', true).forEach(function(c) {
- c.set('value', c.get('recommendedValue'));
- var stepConfig = this.get('stepConfigs').find(function(stepConf) {
- return stepConf.get('name') === c.get('name') && stepConf.get('filename') === c.get('fileName');
- });
- if (stepConfig) {
- stepConfig.set('value', c.get('recommendedValue'));
- }
- }, this);
if (callback) {
callback();
}
},
onSecondary: function() {
this.hide();
+ configs.setEach('saveRecommended', false);
if(secondaryCallback) {
secondaryCallback();
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/9f87c98d/ambari-web/app/views/common/modal_popups/select_groups_popup.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/modal_popups/select_groups_popup.js b/ambari-web/app/views/common/modal_popups/select_groups_popup.js
new file mode 100644
index 0000000..0448cdf
--- /dev/null
+++ b/ambari-web/app/views/common/modal_popups/select_groups_popup.js
@@ -0,0 +1,77 @@
+/**
+ * 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');
+
+/**
+ * Show confirmation popup
+ * @param {[Object]} servicesWithGroups
+ * @param {Object} groupsToSave
+ * @param {function} [callback=null]
+ * @param {function} [secondaryCallback=null]
+ * we use this parameter to defer saving configs before we make some decisions.
+ * @return {App.ModalPopup}
+ */
+App.showSelectGroupsPopup = function (servicesWithGroups, groupsToSave, callback, secondaryCallback) {
+ return App.ModalPopup.show({
+ encodeBody: false,
+ primary: Em.I18n.t('common.save'),
+ secondary: Em.I18n.t('common.cancel'),
+ header: Em.I18n.t('popup.dependent.configs.header'),
+ dependentServices: servicesWithGroups,
+ groupsToSave: groupsToSave,
+ bodyClass: Em.View.extend({
+ templateName: require('templates/common/modal_popups/select_groups_popup')
+ }),
+
+ onPrimary: function () {
+ this._super();
+ if (callback) {
+ callback();
+ }
+ },
+
+ onSecondary: function() {
+ this._super();
+ if(secondaryCallback) {
+ secondaryCallback();
+ }
+ }
+ });
+};
+
+App.selectConfigGroupForService = Ember.Select.extend({
+
+ /**
+ * set Default group by default
+ */
+ didInsertElement: function() {
+ var defaultVersion = this.get('content').find(function(cg) {
+ return cg.contains('Default');
+ });
+ this.set('value', defaultVersion);
+ },
+
+ /**
+ *
+ */
+ onChangeValue: function() {
+ var groupsToSave = this.get('groupsToSave');
+ groupsToSave[this.get('serviceName')] = this.get('value');
+ }.observes('value')
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/9f87c98d/ambari-web/test/controllers/main/service/info/config_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/service/info/config_test.js b/ambari-web/test/controllers/main/service/info/config_test.js
index 9de9f39..9614e3a 100644
--- a/ambari-web/test/controllers/main/service/info/config_test.js
+++ b/ambari-web/test/controllers/main/service/info/config_test.js
@@ -1315,47 +1315,4 @@ describe("App.MainServiceInfoConfigsController", function () {
});
});
- describe('#calculateDependentFileNames()', function() {
-
- beforeEach(function() {
- mainServiceInfoConfigsController.set('dependentFileNames', []);
- App.resetDsStoreTypeMap(App.StackConfigProperty);
- App.StackConfigProperty.createRecord({id: 'name1_site1', propertyDependedBy: [{
- type: 'site2',
- name: 'name2'
- }]});
- App.StackConfigProperty.createRecord({id: 'name2_site2', propertyDependedBy: [{
- type: 'site3',
- name: 'name3'
- },
- {
- type: 'site4',
- name: 'name4'
- }]
- });
- App.StackConfigProperty.createRecord({id: 'name3_site3', propertyDependedBy: []});
- App.StackConfigProperty.createRecord({id: 'name4_site4', propertyDependedBy: []});
- });
-
- it('adds all file names that need to be loaded to dependentFileNames', function() {
- mainServiceInfoConfigsController.calculateDependentFileNames(App.StackConfigProperty.find('name1_site1'));
- expect(mainServiceInfoConfigsController.get('dependentFileNames').toArray()).to.eql(["site2", "site3", "site4"]);
- });
- });
-
- describe('#getServiceNamesForConfigs()', function() {
- it('returns serviceNames which configs need to be loaded', function() {
- mainServiceInfoConfigsController.set('content', {});
- mainServiceInfoConfigsController.set('content.serviceName', 'currentService');
- mainServiceInfoConfigsController.set('dependentFileNames', ['site1', 'site2']);
- App.resetDsStoreTypeMap(App.StackService);
- App.StackService.createRecord({id: 'service1', serviceName: 'service1', configTypes: {'site1':'site1'}});
- App.StackService.createRecord({id: 'service2', serviceName: 'service2', configTypes: {'site1':'site1', 'site2': 'site2'}});
- App.StackService.createRecord({id: 'service3', serviceName: 'service3', configTypes: {'site3':'site3'}});
- expect(mainServiceInfoConfigsController.getServiceNamesForConfigs()).to.eql(['service1', 'service2', 'currentService']);
- });
-
-
- });
-
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/9f87c98d/ambari-web/test/mixins/common/configs/enhanced_configs_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/mixins/common/configs/enhanced_configs_test.js b/ambari-web/test/mixins/common/configs/enhanced_configs_test.js
index eacfea5..babbd3b 100644
--- a/ambari-web/test/mixins/common/configs/enhanced_configs_test.js
+++ b/ambari-web/test/mixins/common/configs/enhanced_configs_test.js
@@ -22,22 +22,25 @@ describe('App.EnhancedConfigsMixin', function() {
var mixinObject = Em.Controller.extend(App.EnhancedConfigsMixin, {});
var instanceObject = mixinObject.create({});
- describe('#getFileNamesToSave()', function() {
+ var stackProperty
+ describe('#_getFileNamesToSave()', function() {
beforeEach(function() {
App.resetDsStoreTypeMap(App.ConfigProperty);
+ App.resetDsStoreTypeMap(App.StackConfigProperty);
+ stackProperty = App.ConfigProperty.createRecord({id: '1', serviceName: 'service1'});
});
it('returns file names that was changed', function() {
- App.ConfigProperty.createRecord({id: 'p1_c1', value:'1', defaultValue: '2', fileName: 'file1'});
- App.ConfigProperty.createRecord({id: 'p2_c1', value:'1', defaultValue: '1', fileName: 'file2'});
- expect(instanceObject.getFileNamesToSave(['file3'])).to.eql(['file1','file3'])
+ App.ConfigProperty.createRecord({id: 'p1_c1', value:'1', defaultValue: '2', fileName: 'file1', stackConfigProperty: stackProperty});
+ App.ConfigProperty.createRecord({id: 'p2_c1', value:'1', defaultValue: '1', fileName: 'file2', stackConfigProperty: stackProperty});
+ expect(instanceObject._getFileNamesToSave('service1')).to.eql(['file1'])
});
- it('returns file names that was changed by adding property', function() {
- App.ConfigProperty.createRecord({id: 'p1_c1', value:'1', defaultValue: '1', fileName: 'file1', isNotSaved: false});
- App.ConfigProperty.createRecord({id: 'p2_c1', value:'1', defaultValue: '1', fileName: 'file2', isNotSaved: true});
- expect(instanceObject.getFileNamesToSave(['file3'])).to.eql(['file2','file3'])
+ it('returns file names that was changed for current service', function() {
+ App.ConfigProperty.createRecord({id: 'p1_c1', value:'7', defaultValue: '1', fileName: 'file1', stackConfigProperty: stackProperty});
+ App.ConfigProperty.createRecord({id: 'p2_c1', value:'8', defaultValue: '1', fileName: 'file2'});
+ expect(instanceObject._getFileNamesToSave('service1')).to.eql(['file1'])
});
});