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/12/24 12:30:01 UTC
ambari git commit: AMBARI-14483 Improve config recommendations flow.
(ababiichuk)
Repository: ambari
Updated Branches:
refs/heads/trunk 8acfcd892 -> 810d6e82b
AMBARI-14483 Improve config recommendations flow. (ababiichuk)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/810d6e82
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/810d6e82
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/810d6e82
Branch: refs/heads/trunk
Commit: 810d6e82b03726f68b45b9c31cfc37469ea5decb
Parents: 8acfcd8
Author: ababiichuk <ab...@hortonworks.com>
Authored: Wed Dec 23 15:15:05 2015 +0200
Committer: ababiichuk <ab...@hortonworks.com>
Committed: Thu Dec 24 13:15:40 2015 +0200
----------------------------------------------------------------------
.../controllers/main/service/info/configs.js | 6 +-
.../app/controllers/wizard/step7_controller.js | 26 +-
.../mixins/common/configs/enhanced_configs.js | 601 ++++++++-----------
ambari-web/app/mixins/common/serverValidator.js | 6 +-
ambari-web/app/utils/config.js | 16 +-
ambari-web/app/views/common/controls_view.js | 5 +-
.../dependent_configs_list_popup.js | 7 +-
7 files changed, 286 insertions(+), 381 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/810d6e82/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 c59bd91..1eef9a1 100644
--- a/ambari-web/app/controllers/main/service/info/configs.js
+++ b/ambari-web/app/controllers/main/service/info/configs.js
@@ -445,8 +445,8 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
for (var prop in config.properties) {
var fileName = App.config.getOriginalFileName(config.type);
var serviceConfig = allConfigs.filterProperty('name', prop).findProperty('filename', fileName);
+ var value = App.config.formatPropertyValue(serviceConfig, config.properties[prop]);
if (serviceConfig) {
- var value = App.config.formatPropertyValue(serviceConfig, config.properties[prop]);
var isFinal = !!(config.properties_attributes && config.properties_attributes.final && config.properties_attributes.final[prop]);
if (self.get('selectedConfigGroup.isDefault') || configGroup.get('name') == self.get('selectedConfigGroup.name')) {
var overridePlainObject = {
@@ -460,7 +460,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
}
} else {
var isEditable = self.get('canEdit') && configGroup.get('name') == self.get('selectedConfigGroup.name');
- allConfigs.push(App.config.createCustomGroupConfig(prop, config, configGroup, isEditable));
+ allConfigs.push(App.config.createCustomGroupConfig(prop, fileName, value, configGroup, isEditable));
}
}
});
@@ -494,7 +494,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
} else {
App.config.removeRangerConfigs(this.get('stepConfigs'));
}
- this.getRecommendationsForDependencies(null, true, function () {self._onLoadComplete();}, this.get('selectedConfigGroup'));
+ this.getRecommendationsForDependencies(null, true, function () {self._onLoadComplete();});
App.loadTimer.finish('Service Configs Page');
},
http://git-wip-us.apache.org/repos/asf/ambari/blob/810d6e82/ambari-web/app/controllers/wizard/step7_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard/step7_controller.js b/ambari-web/app/controllers/wizard/step7_controller.js
index 608b163..2726236 100644
--- a/ambari-web/app/controllers/wizard/step7_controller.js
+++ b/ambari-web/app/controllers/wizard/step7_controller.js
@@ -485,7 +485,7 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
if (!Em.get(serviceConfig, 'overrides')) Em.set(serviceConfig, 'overrides', []);
serviceConfig.overrides.pushObject({value: hostOverrideValue, group: group, isFinal: hostOverrideIsFinal});
} else {
- params.serviceConfigs.push(App.config.createCustomGroupConfig(prop, config, group));
+ params.serviceConfigs.push(App.config.createCustomGroupConfig(prop, fileName, config.properties[prop], group));
}
}
});
@@ -707,29 +707,15 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
App.config.removeRangerConfigs(self.get('stepConfigs'));
}
this.loadServerSideConfigsRecommendations().always(function() {
- self.updateConfigsRecommendations();
+ if (self.get('wizardController.name') == 'addServiceController') {
+ // for Add Service just remove or add dependent properties and ignore config values changes
+ // for installed services only
+ self.clearDependenciesForInstalledServices(self.get('installedServiceNames'), self.get('stepConfigs'));
+ }
self.completeConfigLoading();
});
},
- /**
- * update dependent configs based on recommendations from
- * stack adviser
- *
- * @method updateConfigsRecommendations
- */
- updateConfigsRecommendations: function() {
- if (this.get('wizardController.name') == 'addServiceController') {
- // for Add Service just remove or add dependent properties and ignore config values changes
- // for installed services only
- this.clearDependenciesForInstalledServices(this.get('installedServiceNames'), this.get('stepConfigs'));
- }
- // * add dependencies based on recommendations
- // * update config values with recommended
- // * remove properties received from recommendations
- this.updateDependentConfigs();
- },
-
completeConfigLoading: function() {
this.clearDependentConfigsByService(App.StackService.find().filterProperty('isSelected').mapProperty('serviceName'));
console.timeEnd('wizard loadStep: ');
http://git-wip-us.apache.org/repos/asf/ambari/blob/810d6e82/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 230493b..7efcf55 100644
--- a/ambari-web/app/mixins/common/configs/enhanced_configs.js
+++ b/ambari-web/app/mixins/common/configs/enhanced_configs.js
@@ -252,14 +252,11 @@ App.EnhancedConfigsMixin = Em.Mixin.create({
* @param {{type: string, name: string}[]} changedConfigs - list of changed configs to track recommendations
* @param {Boolean} initial
* @param {Function} onComplete
- * @param {App.ConfigGroup|null} [configGroup=null]
* @returns {$.ajax|null}
*/
- getRecommendationsForDependencies: function(changedConfigs, initial, onComplete, configGroup) {
+ getRecommendationsForDependencies: function(changedConfigs, initial, onComplete) {
if (Em.isArray(changedConfigs) && changedConfigs.length > 0 || initial) {
- if (!configGroup) {
- configGroup = this.get('selectedConfigGroup');
- }
+ var configGroup = this.get('selectedConfigGroup');
var recommendations = this.get('hostGroups');
delete recommendations.config_groups;
@@ -289,7 +286,7 @@ App.EnhancedConfigsMixin = Em.Mixin.create({
data: {
stackVersionUrl: App.get('stackVersionURL'),
dataToSend: dataToSend,
- selectedConfigGroup: configGroup.get('isDefault') ? null : configGroup.get('name'),
+ notDefaultGroup: configGroup && !configGroup.get('isDefault'),
initial: initial,
clearConfigsOnAddService: clearConfigsOnAddService
},
@@ -382,15 +379,15 @@ App.EnhancedConfigsMixin = Em.Mixin.create({
* @method dependenciesSuccess
*/
dependenciesSuccess: function (data, opt, params) {
- this._saveRecommendedValues(data, params.initial, params.dataToSend.changed_configurations, params.selectedConfigGroup);
+ this._saveRecommendedValues(data, params.initial, params.dataToSend.changed_configurations, params.notDefaultGroup);
this.set("recommendationsConfigs", Em.get(data.resources[0] , "recommendations.blueprint.configurations"));
if (params.clearConfigsOnAddService) {
- this.clearDependenciesForInstalledServices(this.get('installedServiceNames'), this.get('stepConfigs'));
+ if (this.get('wizardController.name') == 'addServiceController') {
+ this.clearDependenciesForInstalledServices(this.get('installedServiceNames'), this.get('stepConfigs'));
+ }
this.clearConfigValues();
}
- if (!params.initial) {
- this.updateDependentConfigs();
- }
+ this.set('recommendationTimeStamp', (new Date).getTime());
},
/**
@@ -398,14 +395,8 @@ App.EnhancedConfigsMixin = Em.Mixin.create({
* @method showChangedDependentConfigs
*/
showChangedDependentConfigs: function(event, callback, secondary) {
- var self = this;
if (this.get('_dependentConfigValues.length') > 0) {
- App.showDependentConfigsPopup(this.get('changedProperties'), function() {
- self.updateDependentConfigs();
- if (callback) {
- callback();
- }
- }, secondary);
+ App.showDependentConfigsPopup(this.get('changedProperties'), this.onSaveRecommendedPopup.bind(this), secondary);
} else {
if (callback) {
callback();
@@ -414,8 +405,46 @@ App.EnhancedConfigsMixin = Em.Mixin.create({
},
/**
- *
+ * run through config properties list (form dependent popup)
+ * and set value to default (undo) or recommended (redo)
+ * this happens when toggle checkbox in popup
+ * @param {Object[]} propertiesToUpdate
+ * @param {boolean} redo
*/
+ undoRedoRecommended: function(propertiesToUpdate, redo) {
+ propertiesToUpdate.forEach(function(p) {
+ var initial = redo ? Em.get(p, 'value') : Em.get(p, 'recommendedValue');
+ var recommended = redo ? Em.get(p, 'recommendedValue') : Em.get(p, 'value');
+ var stepConfig = this.get('stepConfigs').findProperty('serviceName', Em.get(p, 'serviceName'));
+ var config = stepConfig.get('configs').find(function(scp) {
+ return scp.get('name') == Em.get(p, 'propertyName') && scp.get('filename') == Em.get(p, 'fileName');
+ });
+ var selectedGroup = App.ServiceConfigGroup.find().filterProperty('serviceName', Em.get(p, 'serviceName')).findProperty('name', Em.get(p, 'configGroup'));
+ if (Em.isNone(recommended)) {
+ if (selectedGroup.get('isDefault')) {
+ stepConfig.get('configs').removeObject(config);
+ } else {
+ config.get('overrides').removeObject(this._getOverride(config, selectedGroup));
+ }
+ } else if (Em.isNone(initial)) {
+ this._addConfigByRecommendation(stepConfig, selectedGroup, Em.get(p, 'propertyName'), Em.get(p, 'fileName'), Em.get(p, 'serviceName'), recommended, initial, config);
+ } else {
+ Em.set(config, 'value', recommended);
+ }
+ }, this);
+ },
+
+ /**
+ * update configs when toggle checkbox on dependent configs popup
+ * @param propertiesToUndo
+ * @param propertiesToRedo
+ */
+ onSaveRecommendedPopup: function(propertiesToUndo, propertiesToRedo) {
+ this.undoRedoRecommended(propertiesToUndo, false);
+ this.undoRedoRecommended(propertiesToRedo, true);
+ this.set('recommendationTimeStamp', (new Date).getTime());
+ },
+
changedDependentGroup: function() {
var dependentServices = this.get('stepConfigs').filter(function(stepConfig) {
return this.get('selectedService.dependentServiceNames').contains(stepConfig.get('serviceName'));
@@ -442,37 +471,34 @@ App.EnhancedConfigsMixin = Em.Mixin.create({
* @param data
* @param [updateOnlyBoundaries=false]
* @param [changedConfigs=null]
+ * @param notDefaultGroup
+ * @param updateInitial
* @method saveRecommendedValues
* @private
*/
- _saveRecommendedValues: function(data, updateOnlyBoundaries, changedConfigs, selectedConfigGroup) {
+ _saveRecommendedValues: function(data, updateOnlyBoundaries, changedConfigs, notDefaultGroup, updateInitial) {
Em.assert('invalid data - `data.resources[0].recommendations.blueprint.configurations` not defined ', data && data.resources[0] && Em.get(data.resources[0], 'recommendations.blueprint.configurations'));
var configObject = data.resources[0].recommendations.blueprint.configurations;
- if (!selectedConfigGroup) {
- this.parseConfigsByTag(configObject, updateOnlyBoundaries, changedConfigs, selectedConfigGroup);
+ if (!notDefaultGroup) {
+ this.parseConfigsByTag(configObject, changedConfigs, updateInitial, updateOnlyBoundaries);
} else if (data.resources[0].recommendations['config-groups']){
var configFroGroup = data.resources[0].recommendations['config-groups'][0];
- this.parseConfigsByTag(configFroGroup.configurations, updateOnlyBoundaries, changedConfigs, selectedConfigGroup);
- this.parseConfigsByTag(configFroGroup.dependent_configurations, updateOnlyBoundaries, changedConfigs, selectedConfigGroup);
+ this.parseConfigsByTag(configFroGroup.configurations, changedConfigs, updateInitial, updateOnlyBoundaries);
+ this.parseConfigsByTag(configFroGroup.dependent_configurations, changedConfigs, updateInitial, updateOnlyBoundaries);
}
+ this._cleanUpPopupProperties();
},
/**
* saves values from response for dependent configs to <code>_dependentConfigValues<code>
* @param configObject - JSON response from `recommendations` endpoint
- * @param updateOnlyBoundaries
- * @param selectedConfigGroup
* @param {App.ServiceConfigProperty[]} parentConfigs - config properties for which recommendations were received
+ * @param updateInitial
+ * @param updateOnlyBoundaries
* @method saveRecommendedValues
* @private
*/
- parseConfigsByTag: function(configObject, updateOnlyBoundaries, parentConfigs, selectedConfigGroup) {
- var wizardController = this.get('wizardController');
- if (wizardController) {
- var fileNamesToUpdate = wizardController.getDBProperty('fileNamesToUpdate') || [];
- this.set('_fileNamesToUpdate', fileNamesToUpdate);
- }
- var notDefaultGroup = !!selectedConfigGroup;
+ parseConfigsByTag: function(configObject, parentConfigs, updateInitial, updateOnlyBoundaries) {
var parentPropertiesNames = parentConfigs ? parentConfigs.map(function(p) { return App.config.configId(Em.get(p, 'name'), Em.get(p, 'type'))}) : [];
/** get all configs by config group **/
for (var key in configObject) {
@@ -482,7 +508,6 @@ App.EnhancedConfigsMixin = Em.Mixin.create({
var serviceName = service.get('serviceName');
var stepConfig = this.get('stepConfigs').findProperty('serviceName', serviceName);
if (stepConfig) {
- var initialValue;
var configProperties = stepConfig ? stepConfig.get('configs').filterProperty('filename', App.config.getOriginalFileName(key)) : [];
var group = this.getGroupForService(serviceName);
@@ -490,103 +515,24 @@ App.EnhancedConfigsMixin = Em.Mixin.create({
for (var propertyName in configObject[key].properties) {
var cp = configProperties.findProperty('name', propertyName);
- var override = (notDefaultGroup && group && cp && cp.get('overrides')) ? cp.get('overrides').findProperty('group.name', group.get('name')) : null;
- var value = override ? override.get('value') : cp && cp.get('value');
-
- if (this.useInitialValue(serviceName)) {
- initialValue = override ? override.get('initialValue') : cp && cp.get('initialValue');
- } else {
- initialValue = override ? override.get('savedValue') : cp && cp.get('savedValue');
- }
-
- var recommendedValue = configObject[key].properties[propertyName];
-
- var isNewProperty = (!notDefaultGroup && Em.isNone(cp)) || (notDefaultGroup && group && Em.isNone(override));
-
- initialValue = validator.isValidFloat(initialValue) ? parseFloat(initialValue).toString() : initialValue;
- recommendedValue = validator.isValidFloat(recommendedValue) ? parseFloat(recommendedValue).toString() : recommendedValue;
-
- var groupName = group && Em.get(group, 'name');
- var dependentProperty = this.get('_dependentConfigValues').find(function (dcv) {
- return dcv.propertyName === propertyName && dcv.fileName === key && dcv.configGroup === groupName;
- });
-
- if (!updateOnlyBoundaries && !parentPropertiesNames.contains(App.config.configId(propertyName, key)) && initialValue != recommendedValue) { //on first initial request we don't need to change values
- if (dependentProperty) {
- Em.set(dependentProperty, 'value', initialValue);
- Em.set(dependentProperty, 'notDefined', Em.isNone(initialValue));
- Em.set(dependentProperty, 'recommendedValue', recommendedValue);
- Em.set(dependentProperty, 'toDelete', false); // handled in <code>saveRecommendedAttributes</code>
- Em.set(dependentProperty, 'toAdd', isNewProperty);
- Em.set(dependentProperty, 'parentConfigs', dependentProperty.parentConfigs.concat(parentPropertiesNames).uniq());
- } else {
- this.get('_dependentConfigValues').pushObject({
- saveRecommended: true,
- saveRecommendedDefault: true,
- toDelete: false,
- isDeleted: false, // handled in <code>saveRecommendedAttributes</code>
- toAdd: isNewProperty,
- fileName: key,
- propertyName: propertyName,
- configGroup: group ? group.get('name') : "",
- value: initialValue,
- notDefined: Em.isNone(initialValue),
- parentConfigs: parentPropertiesNames,
- serviceName: serviceName,
- allowChangeGroup: !this.get('selectedService.isDefault') && service.get('serviceName') != stepConfig.get('serviceName') && stepConfig.get('configGroups.length') > 1,
- serviceDisplayName: service.get('displayName'),
- recommendedValue: recommendedValue
- });
- }
- }
+ var configPropertyObject = (!group || group.get('isDefault')) ? cp : this._getOverride(cp, group);
- /**
- * saving recommended value to service config properties
- * this value can be used as marker on slider widget
- */
- if (notDefaultGroup) {
- override && override.set('recommendedValue', recommendedValue);
- } else {
- cp && cp.set('recommendedValue', recommendedValue);
+ var recommendedValue = this.getFormattedValue(configObject[key].properties[propertyName]);
+ var popupProperty = this.getPopupProperty(propertyName, key, Em.get(group || {}, 'name'));
+ var initialValue = this._getInitialValue(configObject, popupProperty, serviceName, recommendedValue, updateInitial);
+ if (configPropertyObject) {
+ this._updateConfigByRecommendation(configPropertyObject, recommendedValue, updateInitial, updateOnlyBoundaries);
+ } else if (!updateOnlyBoundaries) {
+ this._addConfigByRecommendation(stepConfig, group, propertyName, key, serviceName, recommendedValue, initialValue, cp);
}
if (!updateOnlyBoundaries) {
- /**
- * clear _dependentPropertyValues from
- * properties that wasn't changed while recommendations
- */
-
- if ((initialValue == recommendedValue) || (Em.isNone(initialValue) && Em.isNone(recommendedValue))) {
- /** if recommended value same as default we shouldn't show it in popup **/
- if (notDefaultGroup) {
- if (override) {
- if (override.get('isNotSaved')) {
- cp.get('overrides').removeObject(override);
- } else {
- override.set('value', initialValue);
- }
- if (dependentProperty) {
- this.get('_dependentConfigValues').removeObject(dependentProperty);
- }
- }
- } else {
- cp.set('value', initialValue);
- if (!this.useInitialValue(serviceName)) {
- cp.set('savedValue', initialValue);
- }
- if (dependentProperty) {
- this.get('_dependentConfigValues').removeObject(dependentProperty);
- }
- }
- }
+ this._updatePopup(popupProperty, propertyName, key, recommendedValue, Em.get(configPropertyObject || {}, 'initialValue'), service, Em.get(group || {},'name') || "Default", parentPropertiesNames);
}
}
}
- this._saveRecommendedAttributes(configObject, parentPropertiesNames, updateOnlyBoundaries, selectedConfigGroup);
- }
- if (wizardController) {
- wizardController.setDBProperty('fileNamesToUpdate', this.get('_fileNamesToUpdate').uniq());
}
+ this.parseConfigAttributes(configObject, parentPropertiesNames, updateOnlyBoundaries);
},
installedServices: function () {
@@ -604,266 +550,233 @@ App.EnhancedConfigsMixin = Em.Mixin.create({
* @param updateOnlyBoundaries
* @private
*/
- _saveRecommendedAttributes: function(configs, parentPropertiesNames, updateOnlyBoundaries, selectedConfigGroup) {
+ parseConfigAttributes: function(configs, parentPropertiesNames, updateOnlyBoundaries) {
var self = this;
- var installedServices = this.get('installedServices');
- var wizardController = this.get('wizardController');
- var fileNamesToUpdate = wizardController ? this.get('_fileNamesToUpdate') : [];
Em.keys(configs).forEach(function (siteName) {
- var fileName = App.config.getOriginalFileName(siteName);
- var service = App.config.get('serviceByConfigTypeMap')[siteName];
- var serviceName = service.get('serviceName');
- var group = self.getGroupForService(serviceName);
- var stepConfig = self.get('stepConfigs').findProperty('serviceName', serviceName);
- var configProperties = stepConfig ? stepConfig.get('configs').filterProperty('filename', App.config.getOriginalFileName(siteName)) : [];
- var properties = configs[siteName].property_attributes || {};
- Em.keys(properties).forEach(function (propertyName) {
- var cp = configProperties.findProperty('name', propertyName);
- var stackProperty = App.configsCollection.getConfigByName(propertyName, siteName);
- var attributes = properties[propertyName] || {};
- Em.keys(attributes).forEach(function (attributeName) {
- if (attributeName == 'delete' && cp) {
- if (!updateOnlyBoundaries) {
- var modifiedFileNames = self.get('modifiedFileNames');
- var groupName = group && Em.get(group,'name');
- var dependentProperty = self.get('_dependentConfigValues').find(function (dcv) {
- return dcv.propertyName === propertyName && dcv.fileName === siteName && dcv.configGroup === groupName;
- });
- if (dependentProperty) {
- Em.set(dependentProperty, 'toDelete', true);
- Em.set(dependentProperty, 'toAdd', false);
- Em.set(dependentProperty, 'recommendedValue', null);
- } else {
- self.get('_dependentConfigValues').pushObject({
- saveRecommended: true,
- saveRecommendedDefault: true,
- value: cp && (self.useInitialValue(serviceName) ? cp.get('initialValue') : cp.get('savedValue')),
- toDelete: true,
- toAdd: false,
- isDeleted: true,
- fileName: siteName,
- propertyName: propertyName,
- configGroup: group ? group.get('name') : "",
- parentConfigs: parentPropertiesNames,
- serviceName: service.get('serviceName'),
- allowChangeGroup: !self.get('selectedService.isDefault') && service.get('serviceName') != stepConfig.get('serviceName') && stepConfig.get('configGroups.length') > 1,
- serviceDisplayName: service.get('displayName'),
- recommendedValue: null
- });
- }
- if (modifiedFileNames && !modifiedFileNames.contains(fileName)) {
- modifiedFileNames.push(fileName);
- } else if (wizardController && installedServices[service.get('serviceName')]) {
- if (!fileNamesToUpdate.contains(fileName)) {
- fileNamesToUpdate.push(fileName);
+ var fileName = App.config.getOriginalFileName(siteName),
+ service = App.config.get('serviceByConfigTypeMap')[siteName];
+ var serviceName = service && service.get('serviceName'),
+ stepConfig = self.get('stepConfigs').findProperty('serviceName', serviceName);
+ if (stepConfig) {
+ var group = self.getGroupForService(serviceName),
+ configProperties = stepConfig ? stepConfig.get('configs').filterProperty('filename', App.config.getOriginalFileName(siteName)) : [],
+ properties = configs[siteName].property_attributes || {};
+ Em.keys(properties).forEach(function (propertyName) {
+ var cp = configProperties.findProperty('name', propertyName);
+ var stackProperty = App.configsCollection.getConfigByName(propertyName, siteName);
+ var configObject = (!group || group.get('isDefault')) ? cp : self._getOverride(cp, group);
+ var configsCollection = !group || group.get('isDefault') ? stepConfig.get('configs') : Em.getWithDefault(cp, 'overrides', []);
+ var dependentProperty = self.getPopupProperty(propertyName, fileName, Em.get(group || {},'name'));
+ var attributes = properties[propertyName] || {};
+ Em.keys(attributes).forEach(function (attributeName) {
+ if (attributeName == 'delete' && configObject) {
+ if (!updateOnlyBoundaries) {
+ self._removeConfigByRecommendation(configObject, configsCollection);
+ self._updatePopup(dependentProperty, propertyName, siteName, null, Em.get(configObject, 'initialValue'), service, Em.get(group || {},'name') || "Default", parentPropertiesNames);
+ }
+ } else if (stackProperty) {
+ var selectedConfigGroup = group && !group.get('isDefault') ? group.get('name') : null;
+ if (selectedConfigGroup) {
+ if (!stackProperty.valueAttributes[selectedConfigGroup]) {
+ /** create not default group object for updating such values as min/max **/
+ Em.set(stackProperty.valueAttributes, selectedConfigGroup, {});
+ }
+ if (stackProperty.valueAttributes[selectedConfigGroup][attributeName] != attributes[attributeName]) {
+ Em.set(stackProperty.valueAttributes[selectedConfigGroup], attributeName, attributes[attributeName]);
+ self.toggleProperty('forceUpdateBoundaries');
+ }
+ } else {
+ Em.set(stackProperty.valueAttributes, attributeName, attributes[attributeName]);
+ }
}
- }
- }
- } else if (stackProperty) {
- if (selectedConfigGroup) {
- if (!stackProperty.valueAttributes[selectedConfigGroup]) {
- /** create not default group object for updating such values as min/max **/
- Em.set(stackProperty.valueAttributes, selectedConfigGroup, {});
- }
- if (stackProperty.valueAttributes[selectedConfigGroup][attributeName] != attributes[attributeName]) {
- Em.set(stackProperty.valueAttributes[selectedConfigGroup], attributeName, attributes[attributeName]);
- self.toggleProperty('forceUpdateBoundaries');
- }
- } else {
- Em.set(stackProperty.valueAttributes, attributeName, attributes[attributeName]);
- }
- }
- });
- });
+ });
+ });
+ }
});
- this.set('_fileNamesToUpdate', fileNamesToUpdate);
},
/**
- * save values that are stored in <code>_dependentConfigValues<code>
- * to step configs
+ * update config based on recommendations
+ * @param config
+ * @param recommendedValue
+ * @param updateInitial
+ * @param updateOnlyBoundaries
+ * @private
*/
- updateDependentConfigs: function() {
- var self = this;
- this.get('stepConfigs').forEach(function(serviceConfigs) {
- var selectedGroup = self.getGroupForService(serviceConfigs.get('serviceName'));
- if (selectedGroup) {
- self._updateRecommendedValues(serviceConfigs, selectedGroup);
-
- self._addRecommendedProperties(serviceConfigs, selectedGroup);
+ _updateConfigByRecommendation: function(config, recommendedValue, updateInitial, updateOnlyBoundaries) {
+ Em.assert('config should be defined', config);
+ Em.set(config, 'recommendedValue', recommendedValue);
+ if (!updateOnlyBoundaries) Em.set(config, 'value', recommendedValue);
+ if (updateInitial && Em.isNone(Em.get(config, 'savedValue'))) Em.set(config, 'initialValue', recommendedValue);
+ },
- self._removeUnRecommendedProperties(serviceConfigs, selectedGroup);
+ /**
+ * remove config based on recommendations
+ * @param config
+ * @param configsCollection
+ * @private
+ */
+ _removeConfigByRecommendation: function(config, configsCollection) {
+ Em.assert('config and configsCollection should be defined', config && configsCollection);
+ configsCollection.removeObject(config);
+ /**
+ * need to update wizard info when removing configs for installed services;
+ */
+ var installedServices = this.get('installedServices'), wizardController = this.get('wizardController'),
+ fileNamesToUpdate = wizardController ? wizardController.getDBProperty('fileNamesToUpdate') || [] : [],
+ fileName = Em.get(config, 'filename'), serviceName = Em.get(config, 'serviceName');
+ var modifiedFileNames = this.get('modifiedFileNames');
+ if (modifiedFileNames && !modifiedFileNames.contains(fileName)) {
+ modifiedFileNames.push(fileName);
+ } else if (wizardController && installedServices[serviceName]) {
+ if (!fileNamesToUpdate.contains(fileName)) {
+ fileNamesToUpdate.push(fileName);
}
- });
- this.set('recommendationTimeStamp', (new Date).getTime());
+ }
+ if (wizardController) {
+ wizardController.setDBProperty('fileNamesToUpdate', fileNamesToUpdate.uniq());
+ }
},
/**
- * add configs that was recommended and wasn't present in stepConfigs
+ * add config based on recommendations
* @param stepConfigs
* @param selectedGroup
+ * @param name
+ * @param fileName
+ * @param serviceName
+ * @param recommendedValue
+ * @param initialValue
+ * @param cp
* @private
*/
- _addRecommendedProperties: function(stepConfigs, selectedGroup) {
- var propertiesToAdd = this.get('_dependentConfigValues').filterProperty('toAdd').filterProperty('serviceName', stepConfigs.get('serviceName')).filterProperty('configGroup', selectedGroup.get('name'));
- if (propertiesToAdd.length > 0) {
- propertiesToAdd.forEach(function(propertyToAdd) {
- if (!selectedGroup || selectedGroup.get('isDefault')) {
- if (Em.get(propertyToAdd, 'isDeleted')) {
- this.get('_dependentConfigValues').removeObject(propertyToAdd);
- }
- var originalFileName = App.config.getOriginalFileName(Em.get(propertyToAdd, 'fileName'));
- var stackProperty = App.configsCollection.getConfigByName(Em.get(propertyToAdd, 'propertyName'), Em.get(propertyToAdd, 'fileName'));
- var addedProperty = App.ServiceConfigProperty.create({
- name: Em.get(propertyToAdd, 'propertyName'),
- displayName: Em.get(propertyToAdd, 'propertyName'),
- value: Em.get(propertyToAdd, 'recommendedValue'),
- recommendedValue: Em.get(propertyToAdd, 'recommendedValue'),
- savedValue: null,
- category: 'Advanced ' + Em.get(propertyToAdd, 'fileName'),
- serviceName: stepConfigs.get('serviceName'),
- filename: originalFileName,
- isNotSaved: !Em.get(propertyToAdd, 'isDeleted'),
- isRequired: stackProperty && stackProperty.isRequired !== false
- });
- if (!Em.get(propertyToAdd, 'isDeleted')) {
- addedProperty.set('initialValue', null);
- }
- stepConfigs.get('configs').pushObject(addedProperty);
- addedProperty.validate();
- } else {
- var cp = stepConfigs.get('configs').filterProperty('name', Em.get(propertyToAdd, 'propertyName')).findProperty('filename', App.config.getOriginalFileName(Em.get(propertyToAdd, 'fileName')));
- if (Em.get(propertyToAdd, 'isDeleted')) {
- this.get('_dependentConfigValues').removeObject(propertyToAdd);
- }
- var overriddenProperty = cp.get('overrides') && cp.get('overrides').findProperty('group.name', selectedGroup.get('name'));
- if (overriddenProperty) {
- overriddenProperty.set('value', Em.get(propertyToAdd, 'recommendedValue'));
- overriddenProperty.set('recommendedValue', Em.get(propertyToAdd, 'recommendedValue'));
- } else {
- var overridePlainObject = {
- "value": Em.get(propertyToAdd, 'recommendedValue'),
- "recommendedValue": Em.get(propertyToAdd, 'recommendedValue'),
- "isNotSaved": !Em.get(propertyToAdd, 'isDeleted'),
- "isEditable": true
- };
- App.config.createOverride(cp, overridePlainObject, selectedGroup);
- }
- }
- Em.setProperties(propertyToAdd, {
- isDeleted: Em.get(propertyToAdd, 'isDeleted'),
- toAdd: false,
- toDelete: false
- });
- }, this);
+ _addConfigByRecommendation: function(stepConfigs, selectedGroup, name, fileName, serviceName, recommendedValue, initialValue, cp) {
+ fileName = App.config.getOriginalFileName(fileName);
+ var coreObject = {
+ "value": recommendedValue,
+ "recommendedValue": recommendedValue,
+ "initialValue": initialValue,
+ "savedValue": !this.useInitialValue(serviceName) && !Em.isNone(initialValue) ? initialValue : null,
+ "isEditable": true
+ };
+ if (!selectedGroup || selectedGroup.get('isDefault')) {
+ var addedProperty = App.configsCollection.getConfigByName(name, fileName) || App.config.createDefaultConfig(name, serviceName, fileName, false, coreObject);
+ var addedPropertyObject = App.ServiceConfigProperty.create(addedProperty);
+ stepConfigs.get('configs').pushObject(addedPropertyObject);
+ addedPropertyObject.validate();
+ } else {
+ if (cp) {
+ var newOverride = App.config.createOverride(cp, coreObject, selectedGroup);
+ selectedGroup.get('properties').pushObject(newOverride);
+ } else {
+ stepConfigs.get('configs').push(App.config.createCustomGroupConfig(name, fileName, recommendedValue, selectedGroup, true, true));
+ }
}
},
/**
- * remove configs that was recommended to delete from stepConfigs
- * @param stepConfigs
- * @param selectedGroup
+ * @param configProperty
+ * @param popupProperty
+ * @param serviceName
+ * @param recommendedValue
+ * @param updateInitial
+ * @returns {*}
* @private
*/
- _removeUnRecommendedProperties: function(stepConfigs, selectedGroup) {
- var propertiesToDelete = this.get('_dependentConfigValues').filterProperty('toDelete').filterProperty('serviceName', stepConfigs.get('serviceName')).filterProperty('configGroup', selectedGroup.get('name'));
- if (propertiesToDelete.length > 0) {
-
- propertiesToDelete.forEach(function(propertyToDelete) {
- var cp = stepConfigs.get('configs').filterProperty('name', Em.get(propertyToDelete, 'propertyName')).findProperty('filename', App.config.getOriginalFileName(Em.get(propertyToDelete, 'fileName')));
- if (cp) {
- if (!selectedGroup || selectedGroup.get('isDefault')) {
- if (cp.get('isNotSaved')) {
- this.get('_dependentConfigValues').removeObject(propertyToDelete);
- }
- stepConfigs.get('configs').removeObject(cp);
- if (!cp.get('isNotSaved')) {
- Em.set(propertyToDelete, 'isDeleted', true);
- }
- } else {
- var overriddenConfig = cp.get('overrides') && cp.get('overrides').findProperty('group.name', selectedGroup.get('name'));
- if (overriddenConfig) {
- if (overriddenConfig.get('isNotSaved')) {
- this.get('_dependentConfigValues').removeObject(propertyToDelete);
- }
- cp.removeObject(overriddenConfig);
- if (!overriddenConfig.get('isNotSaved')) {
- Em.set(propertyToDelete, 'isDeleted', true);
- }
- }
- }
- Em.setProperties(propertyToDelete, {
- toAdd: false,
- toDelete: false
- });
- } else {
- this.get('_dependentConfigValues').removeObject(propertyToDelete);
- }
- }, this);
+ _getInitialValue: function(configProperty, popupProperty, serviceName, recommendedValue, updateInitial) {
+ if (!this.useInitialValue(serviceName)) {
+ return configProperty ? Em.get(configProperty, 'savedValue') : null;
+ } else if (updateInitial) {
+ return recommendedValue;
+ } else {
+ return popupProperty ? popupProperty.value : configProperty ? Em.get(configProperty, 'initialValue') : null;
}
},
/**
- * update config to their recommended values
- * @param stepConfigs
+ * format value for float values
+ * @param value
+ * @returns {*}
+ */
+ getFormattedValue: function(value) {
+ return validator.isValidFloat(value) ? parseFloat(value).toString() : value;
+ },
+
+ /**
+ * just get config override
+ * @param cp
* @param selectedGroup
+ * @returns {*|Object}
* @private
*/
- _updateRecommendedValues: function(stepConfigs, selectedGroup) {
- var propertiesToUpdate = this.get('_dependentConfigValues').filter(function(p) {
- return !Em.get(p, 'toDelete') && !Em.get(p, 'toAdd') && Em.get(p, 'serviceName') == stepConfigs.get('serviceName') && Em.get(p, 'configGroup') == selectedGroup.get('name');
+ _getOverride: function(cp, selectedGroup) {
+ return Em.get(cp, 'overrides.length') && Em.get(cp, 'overrides').findProperty('group.name', Em.get(selectedGroup, 'name'));
+ },
+
+ /**
+ * get property form popup
+ * @param name
+ * @param fileName
+ * @param groupName
+ * @returns {Object}
+ */
+ getPopupProperty: function(name, fileName, groupName) {
+ return this.get('_dependentConfigValues').find(function (dcv) {
+ return dcv.propertyName === name && dcv.fileName === App.config.getOriginalFileName(fileName) && dcv.configGroup === (groupName || "Default");
});
- if (propertiesToUpdate.length > 0) {
- stepConfigs.get('configs').forEach(function (cp) {
- var propertyToUpdate = propertiesToUpdate.filterProperty('propertyName', cp.get('name')).findProperty('fileName', App.config.getConfigTagFromFileName(cp.get('filename')));
- if (propertyToUpdate) {
- var valueToSave = propertyToUpdate.saveRecommended ? propertyToUpdate.recommendedValue : propertyToUpdate.value;
- if (!selectedGroup || selectedGroup.get('isDefault')) {
- if (propertyToUpdate.saveRecommended || cp.get('value') == propertyToUpdate.recommendedValue) {
- cp.set('value', valueToSave);
- }
- cp.set('recommendedValue', propertyToUpdate.recommendedValue);
- } else {
- var overriddenConfig = cp.get('overrides') && cp.get('overrides').findProperty('group.name', selectedGroup.get('name'));
- if (overriddenConfig) {
- if (propertyToUpdate.saveRecommended || overriddenConfig.get('value') == propertyToUpdate.recommendedValue) {
- overriddenConfig.set('value', valueToSave);
- }
- overriddenConfig.set('recommendedValue', propertyToUpdate.recommendedValue);
- }
- }
- }
- }, this);
- }
},
/**
- * On first load on installer and add service <code>initialValue<code> of <code>serviceConfigProperty<code> object
- * that contains value from stack should be overriden by dynamic recommendation.
- * Do this only for not installed services as in this case <code>initialValue<code> is not used.
- * @param configObject
+ * add or update proeprty in popup
+ * @param popupProperty
+ * @param name
+ * @param fileName
+ * @param recommendedValue
+ * @param initialValue
+ * @param service
+ * @param groupName
+ * @param parentPropertiesNames
+ * @private
*/
- updateInitialValue: function(configObject) {
- for (var key in configObject) {
- /** defines main info for file name (service name, config group, config that belongs to filename) **/
- var service = App.config.getServiceByConfigType(key);
- if (App.Service.find().filterProperty('serviceName', service.get('serviceName'))) {
- var stepConfig = this.get('stepConfigs').findProperty('serviceName', service.get('serviceName'));
- if (stepConfig) {
- var configProperties = stepConfig ? stepConfig.get('configs').filterProperty('filename', App.config.getOriginalFileName(key)) : [];
-
- for (var propertyName in configObject[key].properties) {
- var configProperty = configProperties.findProperty('name', propertyName);
- if (configProperty) {
- configProperty.set('initialValue', configObject[key].properties[propertyName]);
- }
- }
- }
- }
+ _updatePopup: function(popupProperty, name, fileName, recommendedValue, initialValue, service, groupName, parentPropertiesNames) {
+ if (popupProperty) {
+ Em.set(popupProperty, 'recommendedValue', recommendedValue);
+ Em.set(popupProperty, 'isDeleted', Em.isNone(recommendedValue));
+ } else {
+ var popupPropertyObject = {
+ saveRecommended: true,
+ saveRecommendedDefault: true,
+ fileName: App.config.getOriginalFileName(fileName),
+ propertyName: name,
+
+ isDeleted: Em.isNone(recommendedValue),
+ notDefined: Em.isNone(initialValue),
+
+ configGroup: groupName,
+ value: initialValue,
+ parentConfigs: parentPropertiesNames,
+ serviceName: service.get('serviceName'),
+ allowChangeGroup: groupName!= "Default" && (service.get('serviceName') != this.get('selectedService.serviceName'))
+ && (App.ServiceConfigGroup.find().filterProperty('serviceName', service.get('serviceName')).length > 1),
+ serviceDisplayName: service.get('displayName'),
+ recommendedValue: recommendedValue
+ };
+ this.get('_dependentConfigValues').pushObject(popupPropertyObject);
}
},
/**
+ * clean properties that have same current and recommended values
+ * @private
+ */
+ _cleanUpPopupProperties: function() {
+ var cleanDependentList = this.get('_dependentConfigValues').filter(function(d) {
+ return !((Em.isNone(d.value) && Em.isNone(d.recommendedValue)) || d.value == d.recommendedValue);
+ }, this);
+ this.set('_dependentConfigValues', cleanDependentList);
+ },
+
+ /**
* Helper method to get property from the <code>stepConfigs</code>
*
* @param {String} name - config property name
http://git-wip-us.apache.org/repos/asf/ambari/blob/810d6e82/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 0306a97..7938729 100644
--- a/ambari-web/app/mixins/common/serverValidator.js
+++ b/ambari-web/app/mixins/common/serverValidator.js
@@ -174,10 +174,9 @@ App.ServerValidatorMixin = Em.Mixin.create({
* @param data
*/
loadRecommendationsSuccess: function(data) {
- this._saveRecommendedValues(data);
- var configObject = data.resources[0].recommendations.blueprint.configurations;
- if (configObject) this.updateInitialValue(configObject);
+ this._saveRecommendedValues(data, false, null, false, true);
this.set("recommendationsConfigs", Em.get(data.resources[0] , "recommendations.blueprint.configurations"));
+ this.set('recommendationTimeStamp', (new Date).getTime());
},
loadRecommendationsError: function(jqXHR, ajaxOptions, error, opt) {
@@ -186,7 +185,6 @@ App.ServerValidatorMixin = Em.Mixin.create({
serverSideValidation: function () {
var deferred = $.Deferred();
- var self = this;
this.set('configValidationFailed', false);
this.set('configValidationGlobalMessage', []);
if (this.get('configValidationFailed')) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/810d6e82/ambari-web/app/utils/config.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/config.js b/ambari-web/app/utils/config.js
index df92ebe..f4c8034 100644
--- a/ambari-web/app/utils/config.js
+++ b/ambari-web/app/utils/config.js
@@ -630,17 +630,19 @@ App.config = Em.Object.create({
* can be created and assigned to non-default config group.
*
* @param {String} propertyName - name of the property
- * @param {Object} config - config info
+ * @param {String} fileName - file name of the property
+ * @param {String} value - config value
* @param {Em.Object} group - config group to set
- * @param {Boolean} isEditable
+ * @param {Boolean} [isEditable]
+ * @param {Boolean} [isInstaller]
* @return {Object}
**/
- createCustomGroupConfig: function (propertyName, config, group, isEditable) {
- var propertyObject = this.createDefaultConfig(propertyName, group.get('service.serviceName'), this.getOriginalFileName(config.type), false, {
- savedValue: config.properties[propertyName],
- value: config.properties[propertyName],
+ createCustomGroupConfig: function (propertyName, fileName, value, group, isEditable, isInstaller) {
+ var propertyObject = this.createDefaultConfig(propertyName, group.get('service.serviceName'), this.getOriginalFileName(fileName), false, {
+ savedValue: isInstaller ? null : value,
+ value: value,
group: group,
- isEditable: isEditable !== false,
+ isEditable: !!isEditable,
isOverridable: false
});
group.set('switchGroupTextShort', Em.I18n.t('services.service.config_groups.switchGroupTextShort').format(group.get('name')));
http://git-wip-us.apache.org/repos/asf/ambari/blob/810d6e82/ambari-web/app/views/common/controls_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/controls_view.js b/ambari-web/app/views/common/controls_view.js
index 2644192..a88be76 100644
--- a/ambari-web/app/views/common/controls_view.js
+++ b/ambari-web/app/views/common/controls_view.js
@@ -114,8 +114,7 @@ App.SupportsDependentConfigs = Ember.Mixin.create({
restoreDependentConfigs: function(parentConfig) {
var controller = this.get('controller');
var dependentConfigs = controller.get('_dependentConfigValues');
- if (controller.updateDependentConfigs) {
- controller.updateDependentConfigs();
+ try {
controller.set('_dependentConfigValues', dependentConfigs.reject(function(item) {
if (item.parentConfigs.contains(parentConfig.get('name'))) {
if (item.parentConfigs.length > 1) {
@@ -131,6 +130,8 @@ App.SupportsDependentConfigs = Ember.Mixin.create({
}
return false;
}));
+ } catch(e) {
+ console.warn('Dependent properties popup was not cleared');
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/810d6e82/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 684598e..334ca75 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
@@ -57,11 +57,16 @@ App.showDependentConfigsPopup = function (configs, primary, secondary) {
}),
onPrimary: function () {
this._super();
+ var propertiesToUpdate = this.get('configs').filter(function(c) {
+ return Em.get(c, 'saveRecommendedDefault') != Em.get(c, 'saveRecommended');
+ }),
+ propertiesToUndo = propertiesToUpdate.filterProperty('saveRecommended', false),
+ propertiesToRedo = propertiesToUpdate.filterProperty('saveRecommended', true);
this.get('configs').forEach(function (c) {
Em.set(c, 'saveRecommendedDefault', Em.get(c, 'saveRecommended'));
});
if (primary) {
- primary();
+ primary(propertiesToUndo, propertiesToRedo);
}
},
onSecondary: function() {