Repository: ambari Updated Branches: refs/heads/trunk c37394ad0 -> 4541b382a
AMBARI-10291. Comparing config revisions should support enhanced configs (onechiporenko) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/4541b382 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/4541b382 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/4541b382 Branch: refs/heads/trunk Commit: 4541b382a634452224626473748f24da209962a2 Parents: c37394a Author: Oleg Nechiporenko <[email protected]> Authored: Tue Mar 31 15:01:16 2015 +0300 Committer: Oleg Nechiporenko <[email protected]> Committed: Tue Mar 31 15:01:16 2015 +0300 ---------------------------------------------------------------------- .../controllers/main/service/info/configs.js | 625 ++++++++----------- ambari-web/app/mixins.js | 1 + .../service/configs/preload_requests_chain.js | 374 +++++++++++ .../slider_config_widget_comparison.hbs | 34 + .../configs/widgets/slider_config_widget.hbs | 19 + ambari-web/app/views.js | 1 + .../configs/service_config_layout_tab_view.js | 22 +- .../slider_config_widget_comparison_view.js | 24 + .../configs/widgets/config_widget_view.js | 17 +- .../main/service/info/config_test.js | 4 +- .../configs/widgets/config_widget_view_test.js | 33 +- 11 files changed, 769 insertions(+), 385 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/4541b382/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 8c5d8ed..881d7ff 100644 --- a/ambari-web/app/controllers/main/service/info/configs.js +++ b/ambari-web/app/controllers/main/service/info/configs.js @@ -21,49 +21,94 @@ require('controllers/wizard/slave_component_groups_controller'); var batchUtils = require('utils/batch_scheduled_requests'); var lazyLoading = require('utils/lazy_loading'); -App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorMixin, App.EnhancedConfigsMixin, App.ConfigOverridable, { +App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorMixin, App.EnhancedConfigsMixin, App.ConfigOverridable, App.PreloadRequestsChainMixin, { + name: 'mainServiceInfoConfigsController', + isHostsConfigsPage: false, + forceTransition: false, + isRecommendedLoaded: true, + dataIsLoaded: false, + stepConfigs: [], //contains all field properties that are viewed in this service + selectedService: null, + serviceConfigTags: null, + selectedConfigGroup: null, + configTypesInfo: { items: [], supportsFinal: [] }, + requestInProgress: null, + selectedServiceConfigTypes: [], + selectedServiceSupportsFinal: [], /** * config groups for current service */ configGroups: [], + allConfigs: [], + uiConfigs: [], + saveInProgress: false, + saveConfigsFlag: true, + isCompareMode: false, + compareServiceVersion: null, + preSelectedConfigVersion: null, - // contain Service Config Property, when user proceed from Select Config Group dialog + + /** + * contain Service Config Property, when user proceed from Select Config Group dialog + */ overrideToAdd: null, - //version of default config group, configs of which currently applied + + /** + * version of default config group, configs of which currently applied + */ currentDefaultVersion: null, - //version selected to view + + /** + * version selected to view + */ selectedVersion: null, - // file names of changed configs + + /** + * file names of changed configs + * @type {string[]} + */ modifiedFileNames: [], - // note passed on configs save + + /** + * note passed on configs save + * @type {string} + */ serviceConfigVersionNote: '', + versionLoaded: false, - // current cluster-env version + + /** + * current cluster-env version + * @type {string} + */ clusterEnvTagVersion: '', + /** + * @type {boolean} + */ isCurrentSelected: function () { return App.ServiceConfigVersion.find(this.get('content.serviceName') + "_" + this.get('selectedVersion')).get('isCurrent'); }.property('selectedVersion', 'content.serviceName', 'dataIsLoaded'), @@ -82,6 +127,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM configMapping: function () { return App.config.get('configMapping'); }.property('App.config.configMapping'), + configs: function () { return App.config.get('preDefinedSiteProperties'); }.property('App.config.preDefinedSiteProperties'), @@ -89,11 +135,14 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM secureConfigs: require('data/HDP2/secure_mapping'), showConfigHistoryFeature: true, + /** * Map, which contains relation between group and site * to upload overridden properties + * @type {object} */ loadedGroupToOverrideSiteToTagMap: {}, + /** * During page load time the cluster level site to tag * mapping is stored here. @@ -106,10 +155,19 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM */ loadedClusterSiteToTagMap: {}, + /** + * Determines if Save-button should be disabled + * Disabled if some configs have invalid values or save-process currently in progress + * @type {boolean} + */ isSubmitDisabled: function () { return (!(this.get('stepConfigs').everyProperty('errorCount', 0)) || this.get('saveInProgress')); }.property('[email protected]', 'saveInProgress'), + /** + * Determines if some config value is changed + * @type {boolean} + */ isPropertiesChanged: function(){ return this.get('stepConfigs').someProperty('isPropertiesChanged', true); }.property('[email protected]'), @@ -118,11 +176,13 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM /** * Filter text will be located here + * @type {string} */ filter: '', /** * List of filters for config properties to populate filter combobox + * @type {{attributeName: string, attributeValue: boolean, caption: string}[]} */ propertyFilters: [ { @@ -155,11 +215,13 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM /** * List of heapsize properties not to be parsed + * @type {string[]} */ heapsizeException: ['hadoop_heapsize', 'yarn_heapsize', 'nodemanager_heapsize', 'resourcemanager_heapsize', 'apptimelineserver_heapsize', 'jobhistory_heapsize'], /** * Regular expression for heapsize properties detection + * @type {regexp} */ heapsizeRegExp: /_heapsize|_newsize|_maxnewsize|_permsize|_maxpermsize$/, @@ -185,9 +247,10 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM /** * indicate whether service config version belongs to default config group - * @method isVersionDefault - * @param version + * @param {object} version * @return {Boolean} + * @private + * @method isVersionDefault */ isVersionDefault: function(version) { return (App.ServiceConfigVersion.find(this.get('content.serviceName') + "_" + version).get('groupId') == -1); @@ -195,7 +258,8 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM /** * register request to view to track his progress - * @param request + * @param {$.ajax} request + * @method trackRequest */ trackRequest: function (request) { this.set('requestInProgress', request); @@ -231,6 +295,9 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM } }, + /** + * @type {object[]} + */ serviceConfigProperties: function () { return App.db.getServiceConfigProperties(); }.property('content'), @@ -238,13 +305,13 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM /** * "Finger-print" of the <code>stepConfigs</code>. Filled after first configGroup selecting * Used to determine if some changes were made (when user navigates away from this page) - * {String} + * @type {String|null} */ hash: null, /** * Is this initial config group changing - * {Boolean} + * @type {Boolean} */ isInit: true, @@ -255,6 +322,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM loadStep: function () { console.log("TRACE: Loading configure for service"); var self = this; + this.clearStep(); if (App.get('supports.enhancedConfigs')) { App.config.loadConfigTheme(this.get('content.serviceName')).always(function() { self.setDependentServices(self.get('content.serviceName')); @@ -264,30 +332,15 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM } }); } - this.clearStep(); this.loadClusterEnvSite(); }, /** - * load all tag versions of cluster-env site - * @returns {$.ajax} + * Generate "finger-print" for current <code>stepConfigs[0]</code> + * Used to determine, if user has some unsaved changes (comparing with <code>hash</code>) + * @returns {string|null} + * @method getHash */ - loadClusterEnvSite: function () { - var self = this; - return App.ajax.send({ - name: 'config.cluster_env_site', - sender: self, - success: 'loadClusterEnvSiteSuccess' - }); - }, - - loadClusterEnvSiteSuccess: function (data) { - // find the latest tag version - var maxVersion = Math.max.apply(this, data.items.mapProperty('version')); - this.set('clusterEnvTagVersion', data.items.findProperty('version', maxVersion).tag); - this.loadServiceConfigs(); - }, - getHash: function () { if (!this.get('stepConfigs')[0]) { return null; @@ -306,278 +359,9 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM }, /** - * Loads service configurations - */ - loadServiceConfigs: function () { - var advancedConfigs = []; - var self = this; - var serviceName = this.get('content.serviceName'); - - var stackService = App.StackService.find().findProperty('serviceName', serviceName); - if (stackService) { - self.set('configTypesInfo', App.config.getConfigTypesInfoFromService(stackService)); - } - - this.trackRequest(App.config.loadAdvancedConfig(serviceName, function (properties, xhr) { - if (xhr.statusText === 'abort') return; - advancedConfigs.pushObjects(properties); - self.set('advancedConfigs', advancedConfigs); - self.trackRequest(App.config.loadClusterConfig(function(clusterProperties) { - self.get('advancedConfigs').pushObjects(clusterProperties); - self.trackRequest(self.loadServiceConfigVersions()); - })); - })); - }, - - /** - * get service config versions of current service - */ - loadServiceConfigVersions: function () { - return App.ajax.send({ - name: 'service.serviceConfigVersions.get', - data: { - serviceName: this.get('content.serviceName') - }, - sender: this, - success: 'loadServiceConfigVersionsSuccess', - error: 'loadServiceConfigVersionsError' - }) - }, - - /** - * load service config versions to model - * set currentDefaultVersion - * @param data - * @param opt - * @param params + * Update configs on the page after <code>selectedConfigGroup</code> is changed + * @method onConfigGroupChange */ - loadServiceConfigVersionsSuccess: function (data, opt, params) { - App.serviceConfigVersionsMapper.map(data); - this.set('currentDefaultVersion', data.items.filterProperty('group_id', -1).findProperty('is_current').service_config_version); - if (this.get('preSelectedConfigVersion')) { - this.loadSelectedVersion(this.get('preSelectedConfigVersion.version')); - } else { - this.loadSelectedVersion(); - } - }, - - /** - * error callback of loadServiceConfigVersions() - * override defaultCallback - * @param request - * @param ajaxOptions - * @param error - * @param opt - * @param params - */ - loadServiceConfigVersionsError: Em.K, - - /** - * get selected service config version - * In case selected version is undefined then take currentDefaultVersion - * @param version - * @param switchToGroup - */ - loadSelectedVersion: function (version, switchToGroup) { - var self = this; - this.set('versionLoaded', false); - version = version || this.get('currentDefaultVersion'); - //version of non-default group require properties from current version of default group to correctly display page - var versions = (this.isVersionDefault(version)) ? [version] : [this.get('currentDefaultVersion'), version]; - switchToGroup = (this.isVersionDefault(version) && !switchToGroup) ? this.get('configGroups').findProperty('isDefault') : switchToGroup; - - if (self.get('dataIsLoaded') && switchToGroup) { - this.set('selectedConfigGroup', switchToGroup); - } - - this.trackRequest(App.ajax.send({ - name: 'service.serviceConfigVersions.get.multiple', - sender: this, - data: { - serviceName: this.get('content.serviceName'), - serviceConfigVersions: versions - }, - success: 'loadSelectedVersionSuccess' - }).complete(function (xhr) { - if (xhr.statusText === 'abort') return; - if (self.get('dataIsLoaded')) { - self.onConfigGroupChange(); - } else { - self.loadServiceTagsAndGroups(); - } - })); - }, - - /** - * set cluster to site tag map - * @param data - * @param opt - * @param params - */ - loadSelectedVersionSuccess: function (data, opt, params) { - var serviceConfigsDef = this.get('serviceConfigs').findProperty('serviceName', this.get('content.serviceName')); - var siteToTagMap = {}; - var configTypesRendered = Object.keys(serviceConfigsDef.get('configTypesRendered')); - var selectedVersion = params.serviceConfigVersions.length > 1 ? params.serviceConfigVersions[1] : params.serviceConfigVersions[0]; - var configurations = []; - - - configTypesRendered.forEach(function (siteName) { - data.items.forEach(function (item) { - if (item.group_id == -1) { - configurations = item.configurations; - if (item.configurations.someProperty('type', siteName)) { - siteToTagMap[siteName] = item.configurations.findProperty('type', siteName).tag; - } else { - siteToTagMap[siteName] = 'version1'; - } - } else { - //set config tags of non-default config group to load overrides from selected version - this.loadedGroupToOverrideSiteToTagMap[item.group_name] = {}; - item.configurations.forEach(function (config) { - this.loadedGroupToOverrideSiteToTagMap[item.group_name][config.type] = config.tag; - }, this) - } - }, this) - }, this); - - App.router.get('configurationController').saveToDB(configurations); - - // add cluster-env tag - siteToTagMap['cluster-env'] = this.get('clusterEnvTagVersion'); - - this.loadedClusterSiteToTagMap = siteToTagMap; - this.set('selectedVersion', selectedVersion); - //reset map if selected current version of default group - if (this.get('isCurrentSelected') && selectedVersion === this.get('currentDefaultVersion')) { - this.loadedGroupToOverrideSiteToTagMap = {}; - } - }, - - /** - * load config groups of service - * and dependent services - */ - loadServiceTagsAndGroups: function () { - this.trackRequest(App.ajax.send({ - name: 'config.tags_and_groups', - sender: this, - data: { - serviceName: this.get('content.serviceName'), - urlParams: "&config_groups/ConfigGroup/tag.in(" + [this.get('content.serviceName')].concat(this.get('dependentServiceNames')).join(',')+ ')' - }, - success: 'loadServiceConfigsSuccess' - })); - }, - - loadServiceConfigsSuccess: function (data, opt, params) { - this.setConfigGroups(data, opt, params); - }, - - setConfigGroups: function (data, opt, params) { - var serviceName = this.get('content.serviceName'); - var displayName = this.get('content.displayName'); - var selectedConfigGroup; - var defaultHosts = App.get('allHostNames'); - - //parse loaded config groups - var configGroups = []; - if (data && data.config_groups && data.config_groups.length) { - data.config_groups.forEach(function (item) { - item = item.ConfigGroup; - if (item.tag === this.get('content.serviceName')) { - var groupHosts = item.hosts.mapProperty('host_name'); - var newConfigGroup = 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: groupHosts, - configSiteTags: [] - }); - for (var i = 0; i < groupHosts.length; i++) { - defaultHosts = defaultHosts.without(groupHosts[i]); - } - item.desired_configs.forEach(function (config) { - newConfigGroup.configSiteTags.push(App.ConfigSiteTag.create({ - site: config.type, - tag: config.tag - })); - }, this); - // select default selected group for hosts page - if (!selectedConfigGroup && this.get('isHostsConfigsPage') && newConfigGroup.get('hosts').contains(this.get('host.hostName')) && this.get('content.serviceName') === item.tag) { - 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", - description: "Default cluster level " + serviceName + " configuration", - isDefault: true, - hosts: defaultHosts, - parentConfigGroup: null, - service: this.get('content'), - serviceName: serviceName, - configSiteTags: [] - }); - if (!selectedConfigGroup) { - selectedConfigGroup = configGroups.findProperty('name', this.get('preSelectedConfigVersion.groupName')) || defaultConfigGroup; - } - - this.get('configGroups').sort(function (configGroupA, configGroupB) { - return (configGroupA.name > configGroupB.name); - }); - this.get('configGroups').unshift(defaultConfigGroup); - this.set('selectedConfigGroup', selectedConfigGroup); - this.set('preSelectedConfigVersion', null); - }, - onConfigGroupChange: function () { var self = this; this.get('stepConfigs').clear(); @@ -629,6 +413,8 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM * load version configs for comparison * @param allConfigs * @return {object} + * @private + * @method loadCompareVersionConfigs */ loadCompareVersionConfigs: function (allConfigs) { var dfd = $.Deferred(); @@ -663,6 +449,8 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM * attach analogical config to each property for comparison * @param allConfigs * @param json + * @private + * @method initCompareConfig */ initCompareConfig: function(allConfigs, json) { var serviceVersionMap = {}; @@ -732,13 +520,14 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM } }, - /** * set compare properties to service config of non-default group * @param serviceConfig * @param serviceVersionMap * @param compareVersion * @param selectedVersion + * @private + * @method setCompareConfigs */ setCompareConfigs: function (serviceConfig, serviceVersionMap, compareVersion, selectedVersion) { var compareConfig = serviceVersionMap[compareVersion][serviceConfig.name + '-' + App.config.getConfigTagFromFileName(serviceConfig.filename)]; @@ -767,9 +556,11 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM * @param serviceConfig * @param compareServiceVersion * @return {object} + * @private + * @method getMockComparisonConfig */ getMockComparisonConfig: function (serviceConfig, compareServiceVersion) { - var compareObject = $.extend(true, {isComparison: true}, serviceConfig); + var compareObject = $.extend(true, {isComparison: false}, serviceConfig); compareObject.isEditable = false; compareObject.serviceVersion = App.ServiceConfigVersion.find(this.get('content.serviceName') + "_" + compareServiceVersion); @@ -785,9 +576,11 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM * @param serviceConfig * @param compareConfig * @return {object} + * @private + * @method getComparisonConfig */ getComparisonConfig: function (serviceConfig, compareConfig) { - var compareObject = $.extend(true, {isComparison: true}, serviceConfig); + var compareObject = $.extend(true, {isComparison: false, isOriginalSCP: false}, serviceConfig); compareObject.isEditable = false; if (compareConfig) { @@ -799,6 +592,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM compareObject = App.ServiceConfigProperty.create(compareObject); compareObject.set('isFinal', compareConfig.isFinal); compareObject.set('value', App.config.formatOverrideValue(serviceConfig, compareConfig.value)); + compareObject.set('compareConfigs', null); this.setSupportsFinal(compareObject); } return compareObject; @@ -808,6 +602,8 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM * set compare properties to service config of default group * @param serviceConfig * @param compareConfig + * @private + * @method setCompareDefaultGroupConfig */ setCompareDefaultGroupConfig: function (serviceConfig, compareConfig) { var compareObject = {}; @@ -832,6 +628,8 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM * @param originalConfig * @param compareConfig * @return {Boolean} + * @private + * @method hasCompareDiffs */ hasCompareDiffs: function (originalConfig, compareConfig) { return (originalConfig.value !== compareConfig.value) || (!!originalConfig.isFinal !== (compareConfig.isFinal == true)); @@ -843,6 +641,8 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM * @param serviceName * @param filename * @return {Object} + * @private + * @method getMockConfig */ getMockConfig: function (name, serviceName, filename) { var undefinedConfig = { @@ -872,6 +672,8 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM * get configs of chosen version from server to compare * @param compareServiceVersions * @return {$.ajax} + * @private + * @method getCompareVersionConfigs */ getCompareVersionConfigs: function (compareServiceVersions) { this.set('versionLoaded', false); @@ -886,11 +688,21 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM }); }, + /** + * @param serviceConfig + * @private + * @method checkDatabaseProperties + */ checkDatabaseProperties: function (serviceConfig) { this.hideHiveDatabaseProperties(serviceConfig.configs); this.hideOozieDatabaseProperties(serviceConfig.configs); }, + /** + * @param configs + * @private + * @method hideHiveDatabaseProperties + */ hideHiveDatabaseProperties: function (configs) { if (!['HIVE'].contains(this.get('content.serviceName'))) return; var property = configs.findProperty('name', 'hive_hostname'); @@ -911,6 +723,11 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM } }, + /** + * @param configs + * @private + * @method hideOozieDatabaseProperties + */ hideOozieDatabaseProperties: function (configs) { if (!['OOZIE'].contains(this.get('content.serviceName'))) return; var property = configs.findProperty('name', 'oozie_hostname'); @@ -931,6 +748,11 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM } }, + /** + * @param allConfigs + * @private + * @method onLoadOverrides + */ onLoadOverrides: function (allConfigs) { var serviceName = this.get('content.serviceName'); var advancedConfigs = this.get('advancedConfigs'); @@ -978,6 +800,8 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM * ] * * set tagnames for configuration of the *-site.xml + * @private + * @method setServiceConfigTags */ setServiceConfigTags: function (desiredConfigsSiteTags) { console.debug("setServiceConfigTags(): Trying to set ", desiredConfigsSiteTags); @@ -996,6 +820,8 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM /** * check whether the config property is a security related knob * @param serviceConfig + * @private + * @method checkForSecureConfig */ checkForSecureConfig: function (serviceConfig) { serviceConfig.get('configs').forEach(function (_config) { @@ -1028,6 +854,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM * @param {Object} _serviceConfigProperty - config object * @param {Boolean} defaultGroupSelected - true if selected cfg group is default * @returns {Ember.Object|null} + * @private * @method createConfigProperty */ createConfigProperty: function (_serviceConfigProperty, defaultGroupSelected) { @@ -1051,6 +878,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM * hide properties from Advanced ranger category that match pattern * if property with dependentConfigPattern is false otherwise don't hide * @param serviceConfig + * @private * @method setVisibilityForRangerProperties */ setVisibilityForRangerProperties: function(serviceConfig) { @@ -1067,11 +895,11 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM } } }, - /** /** * trigger addOverrideProperty * @param {Object} componentConfig + * @private * @method checkOverrideProperty */ checkOverrideProperty: function (componentConfig) { @@ -1092,6 +920,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM * if default cfg group and not on the host config page * @param {Ember.Object} serviceConfigProperty * @param {Boolean} defaultGroupSelected + * @private * @method setEditability */ setEditability: function (serviceConfigProperty, defaultGroupSelected) { @@ -1107,6 +936,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM /** * set supportsFinal property of config for admin * @param {Ember.Object} serviceConfigProperty + * @private * @method setSupportsFinal */ setSupportsFinal: function (serviceConfigProperty) { @@ -1124,6 +954,8 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM * @param _serviceConfigProperty * @param serviceConfigProperty * @param defaultGroupSelected + * @private + * @method setValuesForOverrides */ setValuesForOverrides: function (overrides, _serviceConfigProperty, serviceConfigProperty, defaultGroupSelected) { if (Em.isNone(overrides)) return; @@ -1150,6 +982,8 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM * @param serviceConfigProperty * @param defaultGroupSelected * @returns {*} + * @private + * @method createNewSCP */ createNewSCP: function (override, _serviceConfigProperty, serviceConfigProperty, defaultGroupSelected) { var newSCP = App.ServiceConfigProperty.create(_serviceConfigProperty, { @@ -1166,9 +1000,12 @@ 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 + * @private + * @method startSave */ startSave: function() { this.set("saveInProgress", true); @@ -1177,6 +1014,8 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM /** * tells controller that save has been finished * for now just changes flag <code>saveInProgress<code> to true + * @private + * @method completeSave */ completeSave: function() { this.set("saveInProgress", false); @@ -1196,15 +1035,17 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM /** * show some warning popups before user save configs * @method showWarningPopupsBeforeSave + * @private + * @method showWarningPopupsBeforeSave */ showWarningPopupsBeforeSave: function() { var self = this; if (this.isDirChanged()) { App.showConfirmationPopup(function() { - self.showChangedDependentConfigs(null, function() { - self.restartServicePopup(); - }); - }, + self.showChangedDependentConfigs(null, function() { + self.restartServicePopup(); + }); + }, Em.I18n.t('services.service.config.confirmDirectoryChange').format(self.get('content.displayName')), this.completeSave.bind(this) ); @@ -1217,6 +1058,8 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM /** * Runs config validation before save + * @private + * @method restartServicePopup */ restartServicePopup: function () { this.serverSideValidation() @@ -1227,6 +1070,8 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM /** * Define if user has changed some dir properties * @return {Boolean} + * @private + * @method isDirChanged */ isDirChanged: function () { var dirChanged = false; @@ -1235,9 +1080,9 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM if (serviceName === 'HDFS') { var hdfsConfigs = this.get('stepConfigs').findProperty('serviceName', 'HDFS').get('configs'); if ((hdfsConfigs.findProperty('name', 'dfs.namenode.name.dir') && hdfsConfigs.findProperty('name', 'dfs.namenode.name.dir').get('isNotDefaultValue')) || - (hdfsConfigs.findProperty('name', 'dfs.namenode.checkpoint.dir') && hdfsConfigs.findProperty('name', 'dfs.namenode.checkpoint.dir').get('isNotDefaultValue')) || - (hdfsConfigs.findProperty('name', 'dfs.datanode.data.dir') && hdfsConfigs.findProperty('name', 'dfs.datanode.data.dir').get('isNotDefaultValue'))) { - dirChanged = true; + (hdfsConfigs.findProperty('name', 'dfs.namenode.checkpoint.dir') && hdfsConfigs.findProperty('name', 'dfs.namenode.checkpoint.dir').get('isNotDefaultValue')) || + (hdfsConfigs.findProperty('name', 'dfs.datanode.data.dir') && hdfsConfigs.findProperty('name', 'dfs.datanode.data.dir').get('isNotDefaultValue'))) { + dirChanged = true; } } return dirChanged; @@ -1245,6 +1090,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM /** * Save changed configs and config groups + * @method saveConfigs */ saveConfigs: function () { var selectedConfigGroup = this.get('selectedConfigGroup'); @@ -1328,17 +1174,19 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM }, /** - * On save configs handler. Open save configs popup with appropriate message. + * On save configs handler. Open save configs popup with appropriate message + * @private + * @method onDoPUTClusterConfigurations */ onDoPUTClusterConfigurations: function () { var header, message, messageClass, value, status = 'unknown', urlParams = '', - result = { - flag: this.get('saveConfigsFlag'), - message: null, - value: null - }, - extendedModel = App.Service.extendedModel[this.get('content.serviceName')], - currentService = extendedModel ? App[extendedModel].find(this.get('content.serviceName')) : App.Service.find(this.get('content.serviceName')); + result = { + flag: this.get('saveConfigsFlag'), + message: null, + value: null + }, + extendedModel = App.Service.extendedModel[this.get('content.serviceName')], + currentService = extendedModel ? App[extendedModel].find(this.get('content.serviceName')) : App.Service.find(this.get('content.serviceName')); if (!result.flag) { result.message = Em.I18n.t('services.service.config.failSaveConfig'); @@ -1372,8 +1220,9 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM /** * Show save configs popup - * @method showSaveConfigsPopup * @return {App.ModalPopup} + * @private + * @method showSaveConfigsPopup */ showSaveConfigsPopup: function (header, flag, message, messageClass, value, status, urlParams) { var self = this; @@ -1437,7 +1286,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM * </code> * @return {object} */ - setComponents = function (item, components) { + setComponents = function (item, components) { item.host_components.forEach(function (c) { var name = c.HostRoles.host_name; if (!components[name]) { @@ -1451,7 +1300,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM * Map result of <code>setComponents</code> to array * @return {{name: string, components: string}[]} */ - setHosts = function (components) { + setHosts = function (components) { var hosts = []; Em.keys(components).forEach(function (key) { hosts.push({ @@ -1558,6 +1407,8 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM * @param configs * @param timeTag * @return {Array} + * @private + * @method buildGroupDesiredConfigs */ buildGroupDesiredConfigs: function (configs, timeTag) { var sites = []; @@ -1586,6 +1437,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM * show result popup if <code>showPopup</code> is true * @param data {Object} * @param showPopup {Boolean} + * @method putConfigGroupChanges */ putConfigGroupChanges: function (data, showPopup) { var ajaxOptions = { @@ -1602,6 +1454,10 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM return App.ajax.send(ajaxOptions); }, + /** + * @private + * @method putConfigGroupChangesSuccess + */ putConfigGroupChangesSuccess: function () { this.set('saveConfigsFlag', true); this.onDoPUTClusterConfigurations(); @@ -1610,6 +1466,8 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM /** * set hive hostnames in configs * @param configs + * @private + * @method setHiveHostName */ setHiveHostName: function (configs) { var dbHostPropertyName = null; @@ -1712,6 +1570,8 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM /** * set oozie hostnames in configs * @param configs + * @private + * @method setOozieHostName */ setOozieHostName: function (configs) { var dbHostPropertyName = null; @@ -1834,6 +1694,8 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM /** * save site configs * @param configs + * @private + * @method saveSiteConfigs */ saveSiteConfigs: function (configs) { //storedConfigs contains custom configs as well @@ -1845,6 +1707,12 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM this.set('uiConfigs', configs.concat(allUiConfigs)); }, + /** + * Reprecent boolean value as string (true => 'true', false => 'false') and trim other values + * @param serviceConfigProperties + * @private + * @method formatConfigValues + */ formatConfigValues: function (serviceConfigProperties) { serviceConfigProperties.forEach(function (_config) { if (typeof _config.get('value') === "boolean") _config.set('value', _config.value.toString()); @@ -1856,6 +1724,8 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM * return configs from the UI side * @param configMapping array with configs * @return {Array} + * @private + * @method loadUiSideConfigs */ loadUiSideConfigs: function (configMapping) { var uiConfig = []; @@ -1876,7 +1746,11 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM return uiConfig; }, - + /** + * @param configs + * @private + * @method addDynamicProperties + */ addDynamicProperties: function (configs) { var allConfigs = this.get('stepConfigs').findProperty('serviceName', this.get('content.serviceName')).get('configs'); var templetonHiveProperty = allConfigs.someProperty('name', 'templeton.hive.properties'); @@ -1904,6 +1778,8 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM * 'value2': [h3] * } * }</code> + * @private + * @method getGlobConfigValueWithOverrides */ getGlobConfigValueWithOverrides: function (templateName, expression, name) { var express = expression.match(/<(.*?)>/g); @@ -1932,6 +1808,13 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM return this.getValueWithOverrides(value, overrideHostToValue) }, + /** + * @param value + * @param overrideHostToValue + * @returns {{value: *, overrides: {}}} + * @private + * @method getValueWithOverrides + */ getValueWithOverrides: function (value, overrideHostToValue) { var valueWithOverrides = { value: value, @@ -1950,9 +1833,9 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM }, /** - * Saves cluster level configurations for all necessary sites. - * PUT calls are made to /api/v1/clusters/clusterName for each site. - * @return {Boolean} + * Saves cluster level configurations for all necessary sites + * PUT calls are made to /api/v1/clusters/clusterName for each site + * @private * @method doPUTClusterConfigurations */ doPUTClusterConfigurations: function () { @@ -2011,6 +1894,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM * @param {String} siteName * @param {String} tagName * @returns {Object|null} + * @private * @method createConfigObject */ createConfigObject: function (siteName, tagName) { @@ -2030,7 +1914,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM return null; } configObject = this.createSiteObj(siteName, tagName, this.get('uiConfigs').filterProperty('filename', filename)); - break; + break; } configObject.service_config_version_note = this.get('serviceConfigVersionNote'); return configObject; @@ -2039,6 +1923,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM /** * filter out unchanged configurations * @param {Array} configsToSave + * @private * @method filterChangedConfiguration */ filterChangedConfiguration: function (configsToSave) { @@ -2073,6 +1958,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM * configName2: "configValue2" * } * @returns {boolean} + * @private * @method isConfigChanged */ isConfigChanged: function (loadedConfig, savingConfig) { @@ -2123,6 +2009,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM * } * } * @returns {boolean} + * @private * @method isAttributesChanged */ isAttributesChanged: function (oldAttributes, newAttributes) { @@ -2149,10 +2036,11 @@ 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[]} services + * @return {$.ajax} * @method doPUTClusterConfigurationSites */ doPUTClusterConfigurationSites: function (services) { - App.ajax.send({ + return App.ajax.send({ name: 'common.across.services.configurations', sender: this, data: { @@ -2163,10 +2051,18 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM }); }, + /** + * @private + * @method doPUTClusterConfigurationSiteSuccessCallback + */ doPUTClusterConfigurationSiteSuccessCallback: function () { this.onDoPUTClusterConfigurations(); }, + /** + * @private + * @method doPUTClusterConfigurationSiteErrorCallback + */ doPUTClusterConfigurationSiteErrorCallback: function () { this.set('saveConfigsFlag', false); this.doPUTClusterConfigurationSiteSuccessCallback(); @@ -2175,6 +2071,8 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM /** * add newTagName property to each config in serviceConfigs * @param serviceConfigs + * @private + * @method setNewTagNames */ setNewTagNames: function (serviceConfigs) { var time = (new Date).getTime(); @@ -2187,7 +2085,8 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM * Save "final" attribute for properties * @param {Array} properties - array of properties * @returns {Object|null} - * */ + * @method getConfigAttributes + */ getConfigAttributes: function(properties) { var attributes = { final: {} @@ -2209,7 +2108,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM /** * create core site object * @param tagName - * @return {{"type": String, "tag": String, "properties": Object}} + * @return {{type: string, tag: string, properties: object}} * @method createCoreSiteObj */ createCoreSiteObj: function (tagName) { @@ -2229,10 +2128,11 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM /** * create site object - * @param siteName - * @param tagName - * @param siteObj + * @param {string} siteName + * @param {string} tagName + * @param {object[]} siteObj * @return {Object} + * @method createSiteObj */ createSiteObj: function (siteName, tagName, siteObj) { var heapsizeException = this.get('heapsizeException'); @@ -2263,6 +2163,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM } return result; }, + /** * This method will be moved to config's decorators class. * @@ -2270,9 +2171,10 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM * be specified in special format required for server. * * @param configName {String} - name of config property - * @param value {Mixed} - value of config property + * @param value {*} - value of config property * - * @return {String} - formated value + * @return {String} - formatted value + * @method setServerConfigValue */ setServerConfigValue: function (configName, value) { switch (configName) { @@ -2405,7 +2307,8 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM ], /** - * Adds host name of master component to config; + * Adds host name of master component to config + * @private * @method addHostNamesToGlobalConfig */ addHostNamesToConfig: function () { @@ -2438,12 +2341,14 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM } } }, + /** * set host name(s) property for component * @param {String} serviceName - service name of component * @param {String} componentName - component name which host we want to know * @param {String} hostProperty - name of host property for current component * @param {Boolean} multiple - true if can be more than one component + * @private * @method setHostForService */ setHostForService: function (serviceName, componentName, hostProperty, multiple) { @@ -2461,6 +2366,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM * @param {String} componentName * @param {Boolean} multiple - true if can be more than one component installed on cluster * @return {String|Array|Boolean} hostName|hostNames|false if missing component + * @private * @method getMasterComponentHostValue */ getMasterComponentHostValue: function (componentName, multiple) { @@ -2470,21 +2376,21 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM } return false; }, + /** * Provides service component name and display-name information for * the current selected service. - * @return {Em.Array} validComponents - array of valid components - * @method getCurrentServiceComponents + * @type {Em.Array} validComponents - array of valid components */ getCurrentServiceComponents: function () { var components = this.get('content.hostComponents'); - var validComponents = Ember.A([]); + var validComponents = Em.A([]); var seenComponents = {}; components.forEach(function (component) { var cn = component.get('componentName'); var cdn = component.get('displayName'); if (!seenComponents[cn]) { - validComponents.push(Ember.Object.create({ + validComponents.push(Em.Object.create({ componentName: cn, displayName: cdn, selected: false @@ -2496,7 +2402,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM }.property('content'), /** - * trigger loadStep + * Trigger loadStep * @method loadStep */ doCancel: function () { @@ -2532,8 +2438,8 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM }, /** - * trigger showItemsShouldBeRestarted popup with hosts that requires resetart - * @param event + * trigger showItemsShouldBeRestarted popup with hosts that requires restart + * @param {{context: object}} event * @method showHostsShouldBeRestarted */ showHostsShouldBeRestarted: function (event) { @@ -2548,8 +2454,8 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM }, /** - * trigger showItemsShouldBeRestarted popup with components that requires resetart - * @param event + * trigger showItemsShouldBeRestarted popup with components that requires restart + * @param {{context: object}} event * @method showComponentsShouldBeRestarted */ showComponentsShouldBeRestarted: function (event) { @@ -2576,6 +2482,13 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM this.showItemsShouldBeRestarted(hostsComponets, Em.I18n.t('service.service.config.restartService.shouldBeRestarted').format(componentsText)); }, + /** + * Show popup with selectable (@see App.SelectablePopupBodyView) list of items + * @param {string} content string with comma-separated list of hostNames or componentNames + * @param {string} header popup header + * @returns {App.ModalPopup} + * @method showItemsShouldBeRestarted + */ showItemsShouldBeRestarted: function (content, header) { return App.ModalPopup.show({ content: content, @@ -2621,6 +2534,13 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM this.manageConfigurationGroups(); }, + /** + * Show popup with config groups + * User may edit/create/delete them + * @param controller + * @returns {App.ModalPopup} + * @method manageConfigurationGroups + */ manageConfigurationGroups: function (controller) { var configsController = this; var serviceData = (controller && controller.get('selectedService')) || this.get('content'); @@ -2712,12 +2632,6 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM }; runNextQuery(); }, - onSecondary: function () { - this.hide(); - }, - onClose: function () { - this.hide(); - }, subViewController: function () { return App.router.get('manageConfigGroupsController'); }.property('App.router.manageConfigGroupsController'), @@ -2747,7 +2661,6 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM var modified = this.get('subViewController.isHostsModified'); this.set('disablePrimary', !modified); }.observes('subViewController.isHostsModified'), - secondary: Em.I18n.t('common.cancel'), didInsertElement: Em.K }); }, @@ -2772,6 +2685,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM } callback(); }, + /** * switch view to selected group * @param event @@ -2792,6 +2706,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM /** * Are some unsaved changes available * @returns {boolean} + * @method hasUnsavedChanges */ hasUnsavedChanges: function () { return this.get('hash') != this.getHash(); @@ -2801,6 +2716,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM * If some configs are changed and user navigates away or select another config-group, show this popup with propose to save changes * @param {String} path * @param {object} callback - callback with action to change configs view(change group or version) + * @return {App.ModalPopup} * @method showSavePopup */ showSavePopup: function (path, callback) { @@ -2845,4 +2761,5 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM } }); } + }); http://git-wip-us.apache.org/repos/asf/ambari/blob/4541b382/ambari-web/app/mixins.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/mixins.js b/ambari-web/app/mixins.js index 045333f..260ecae 100644 --- a/ambari-web/app/mixins.js +++ b/ambari-web/app/mixins.js @@ -28,6 +28,7 @@ require('mixins/common/table_server_view_mixin'); require('mixins/common/table_server_mixin'); require('mixins/main/host/details/host_components/decommissionable'); require('mixins/main/service/configs/config_overridable'); +require('mixins/main/service/configs/preload_requests_chain'); require('mixins/routers/redirections'); require('mixins/wizard/wizardProgressPageController'); require('mixins/wizard/wizardDeployProgressController'); http://git-wip-us.apache.org/repos/asf/ambari/blob/4541b382/ambari-web/app/mixins/main/service/configs/preload_requests_chain.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/mixins/main/service/configs/preload_requests_chain.js b/ambari-web/app/mixins/main/service/configs/preload_requests_chain.js new file mode 100644 index 0000000..b40b567 --- /dev/null +++ b/ambari-web/app/mixins/main/service/configs/preload_requests_chain.js @@ -0,0 +1,374 @@ +/** + * 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'); + +/** + * Mixin with chain of the methods for initial configs loading + * Used in the service configs controller + * Entry point - <code>loadClusterEnvSite</code> + * Chain: + * - loadClusterEnvSite + * |- (on success callback) + * loadServiceConfigs + * |- App.config.loadAdvancedConfig + * | - (on complete callback) + * loadServiceConfigVersions + * |- (on success callback) + * loadSelectedVersion + * |- (on complete callback) + * loadServiceTagsAndGroups + * @type {Ember.Mixin} + */ +App.PreloadRequestsChainMixin = Em.Mixin.create({ + + /** + * @type {Function} + */ + trackRequest: Em.required(Function), + + /** + * @type {Function} + */ + isVersionDefault: Em.required(Function), + + /** + * load all tag versions of cluster-env site + * @returns {$.ajax} + * @method loadClusterEnvSite + */ + loadClusterEnvSite: function () { + return App.ajax.send({ + name: 'config.cluster_env_site', + sender: this, + success: 'loadClusterEnvSiteSuccess' + }); + }, + + /** + * Success-callback for loadClusterEnvSite + * @param data + * @private + * @method loadClusterEnvSiteSuccess + */ + loadClusterEnvSiteSuccess: function (data) { + // find the latest tag version + var maxVersion = Math.max.apply(this, data.items.mapProperty('version')); + this.set('clusterEnvTagVersion', data.items.findProperty('version', maxVersion).tag); + this.loadServiceConfigs(); + }, + + /** + * Loads service configurations + * @private + * @method loadServiceConfigs + */ + loadServiceConfigs: function () { + var advancedConfigs = []; + var self = this; + var serviceName = this.get('content.serviceName'); + + var stackService = App.StackService.find().findProperty('serviceName', serviceName); + if (stackService) { + self.set('configTypesInfo', App.config.getConfigTypesInfoFromService(stackService)); + } + + this.trackRequest(App.config.loadAdvancedConfig(serviceName, function (properties, xhr) { + if (xhr.statusText === 'abort') return; + advancedConfigs.pushObjects(properties); + self.set('advancedConfigs', advancedConfigs); + self.trackRequest(App.config.loadClusterConfig(function(clusterProperties) { + self.get('advancedConfigs').pushObjects(clusterProperties); + self.trackRequest(self.loadServiceConfigVersions()); + })); + })); + }, + + /** + * get service config versions of current service + * @return {$.ajax} + * @private + * @method loadServiceConfigVersions + */ + loadServiceConfigVersions: function () { + return App.ajax.send({ + name: 'service.serviceConfigVersions.get', + data: { + serviceName: this.get('content.serviceName') + }, + sender: this, + success: 'loadServiceConfigVersionsSuccess', + error: 'loadServiceConfigVersionsError' + }) + }, + + /** + * success callback for loadServiceConfigVersions + * load service config versions to model + * set currentDefaultVersion + * @param data + * @param opt + * @param params + * @private + * @method loadServiceConfigVersionsSuccess + */ + loadServiceConfigVersionsSuccess: function (data, opt, params) { + App.serviceConfigVersionsMapper.map(data); + this.set('currentDefaultVersion', data.items.filterProperty('group_id', -1).findProperty('is_current').service_config_version); + if (this.get('preSelectedConfigVersion')) { + this.loadSelectedVersion(this.get('preSelectedConfigVersion.version')); + } else { + this.loadSelectedVersion(); + } + }, + + /** + * error callback of loadServiceConfigVersions() + * override defaultCallback + * @private + * @method loadServiceConfigVersionsError + */ + loadServiceConfigVersionsError: Em.K, + + /** + * get selected service config version + * In case selected version is undefined then take currentDefaultVersion + * @param version + * @param switchToGroup + * @method loadSelectedVersion + */ + loadSelectedVersion: function (version, switchToGroup) { + var self = this; + this.set('versionLoaded', false); + version = version || this.get('currentDefaultVersion'); + //version of non-default group require properties from current version of default group to correctly display page + var versions = (this.isVersionDefault(version)) ? [version] : [this.get('currentDefaultVersion'), version]; + switchToGroup = (this.isVersionDefault(version) && !switchToGroup) ? this.get('configGroups').findProperty('isDefault') : switchToGroup; + + if (self.get('dataIsLoaded') && switchToGroup) { + this.set('selectedConfigGroup', switchToGroup); + } + + this.trackRequest(App.ajax.send({ + name: 'service.serviceConfigVersions.get.multiple', + sender: this, + data: { + serviceName: this.get('content.serviceName'), + serviceConfigVersions: versions + }, + success: 'loadSelectedVersionSuccess' + }).complete(function (xhr) { + if (xhr.statusText === 'abort') return; + if (self.get('dataIsLoaded')) { + self.onConfigGroupChange(); + } else { + self.loadServiceTagsAndGroups(); + } + })); + }, + + /** + * load config groups of service + * and dependent services + * @private + * @method loadServiceTagsAndGroups + */ + loadServiceTagsAndGroups: function () { + this.trackRequest(App.ajax.send({ + name: 'config.tags_and_groups', + sender: this, + data: { + serviceName: this.get('content.serviceName'), + urlParams: "&config_groups/ConfigGroup/tag.in(" + [this.get('content.serviceName')].concat(this.get('dependentServiceNames')).join(',')+ ')' + }, + success: 'loadServiceConfigsSuccess' + })); + }, + + /** + * set cluster to site tag map + * @param data + * @param opt + * @param params + * @private + * @method loadSelectedVersionSuccess + */ + loadSelectedVersionSuccess: function (data, opt, params) { + var serviceConfigsDef = this.get('serviceConfigs').findProperty('serviceName', this.get('content.serviceName')); + var siteToTagMap = {}; + var configTypesRendered = Object.keys(serviceConfigsDef.get('configTypesRendered')); + var selectedVersion = params.serviceConfigVersions.length > 1 ? params.serviceConfigVersions[1] : params.serviceConfigVersions[0]; + var configurations = []; + + + configTypesRendered.forEach(function (siteName) { + data.items.forEach(function (item) { + if (item.group_id == -1) { + configurations = item.configurations; + if (item.configurations.someProperty('type', siteName)) { + siteToTagMap[siteName] = item.configurations.findProperty('type', siteName).tag; + } else { + siteToTagMap[siteName] = 'version1'; + } + } else { + //set config tags of non-default config group to load overrides from selected version + this.loadedGroupToOverrideSiteToTagMap[item.group_name] = {}; + item.configurations.forEach(function (config) { + this.loadedGroupToOverrideSiteToTagMap[item.group_name][config.type] = config.tag; + }, this) + } + }, this) + }, this); + + App.router.get('configurationController').saveToDB(configurations); + + // add cluster-env tag + siteToTagMap['cluster-env'] = this.get('clusterEnvTagVersion'); + + this.loadedClusterSiteToTagMap = siteToTagMap; + this.set('selectedVersion', selectedVersion); + //reset map if selected current version of default group + if (this.get('isCurrentSelected') && selectedVersion === this.get('currentDefaultVersion')) { + this.loadedGroupToOverrideSiteToTagMap = {}; + } + }, + + /** + * Success-callback for loadServiceTagsAndGroups + * @param {object} data + * @param {object} opt + * @param {object} params + * @private + * @method loadServiceConfigsSuccess + */ + loadServiceConfigsSuccess: function (data, opt, params) { + this.setConfigGroups(data, opt, params); + }, + + /** + * @param {object} data + * @param {object} opt + * @param {object} params + * @private + * @method setConfigGroups + */ + setConfigGroups: function (data, opt, params) { + var serviceName = this.get('content.serviceName'); + var displayName = this.get('content.displayName'); + var selectedConfigGroup; + var defaultHosts = App.get('allHostNames'); + + //parse loaded config groups + var configGroups = []; + if (data && data.config_groups && data.config_groups.length) { + data.config_groups.forEach(function (item) { + item = item.ConfigGroup; + if (item.tag === this.get('content.serviceName')) { + var groupHosts = item.hosts.mapProperty('host_name'); + var newConfigGroup = 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: groupHosts, + configSiteTags: [] + }); + for (var i = 0; i < groupHosts.length; i++) { + defaultHosts = defaultHosts.without(groupHosts[i]); + } + item.desired_configs.forEach(function (config) { + newConfigGroup.configSiteTags.push(App.ConfigSiteTag.create({ + site: config.type, + tag: config.tag + })); + }, this); + // select default selected group for hosts page + if (!selectedConfigGroup && this.get('isHostsConfigsPage') && newConfigGroup.get('hosts').contains(this.get('host.hostName')) && this.get('content.serviceName') === item.tag) { + 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", + description: "Default cluster level " + serviceName + " configuration", + isDefault: true, + hosts: defaultHosts, + parentConfigGroup: null, + service: this.get('content'), + serviceName: serviceName, + configSiteTags: [] + }); + if (!selectedConfigGroup) { + selectedConfigGroup = configGroups.findProperty('name', this.get('preSelectedConfigVersion.groupName')) || defaultConfigGroup; + } + + this.get('configGroups').sort(function (configGroupA, configGroupB) { + return (configGroupA.name > configGroupB.name); + }); + this.get('configGroups').unshift(defaultConfigGroup); + this.set('selectedConfigGroup', selectedConfigGroup); + this.set('preSelectedConfigVersion', null); + } + +}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/4541b382/ambari-web/app/templates/common/configs/widgets/comparison/slider_config_widget_comparison.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/common/configs/widgets/comparison/slider_config_widget_comparison.hbs b/ambari-web/app/templates/common/configs/widgets/comparison/slider_config_widget_comparison.hbs new file mode 100644 index 0000000..dbe8203 --- /dev/null +++ b/ambari-web/app/templates/common/configs/widgets/comparison/slider_config_widget_comparison.hbs @@ -0,0 +1,34 @@ +{{! +* 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. +}} + +{{#each compareConfig in view.serviceConfigProperty.compareConfigs}} + <div {{bindAttr class=":control-group :overrideField"}}> + {{view App.SliderConfigWidgetView configBinding="compareConfig" categoryConfigsAllBinding="view.parentView.categoryConfigsAll"}} + <span class="label label-info">{{compareConfig.serviceVersion.versionText}}</span> + {{#if compareConfig.serviceVersion.isCurrent}} + <span class="label label-success">{{t common.current}}</span> + {{/if}} + {{#unless compareConfig.isMock}} + {{#if compareConfig.supportsFinal}} + <a disabled="disabled" {{bindAttr class=":btn :btn-small :btn-final compareConfig.isFinal:active compareConfig.hideFinalIcon:hidden" }}> + <i class="icon-lock"></i> + </a> + {{/if}} + {{/unless}} + </div> +{{/each}} http://git-wip-us.apache.org/repos/asf/ambari/blob/4541b382/ambari-web/app/templates/common/configs/widgets/slider_config_widget.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/common/configs/widgets/slider_config_widget.hbs b/ambari-web/app/templates/common/configs/widgets/slider_config_widget.hbs index 36e3989..537c349 100644 --- a/ambari-web/app/templates/common/configs/widgets/slider_config_widget.hbs +++ b/ambari-web/app/templates/common/configs/widgets/slider_config_widget.hbs @@ -48,11 +48,30 @@ <div class="ui-slider-wrapper"> {{view Ember.TextField valueBinding="view.config.value" class="input-mini slider-input"}} </div> + + {{#if view.isComparison}} + {{#if controller.selectedConfigGroup.isDefault}} + <span + class="label label-info">{{t dashboard.configHistory.table.version.prefix}}{{controller.selectedVersion}}</span> + {{#if controller.isCurrentSelected}} + <span class="label label-success">{{t common.current}}</span> + {{/if}} + {{else}} + <span class="label label-info">{{t common.default}} + {{t services.service.config.configHistory.configGroup}}</span> + {{/if}} + {{/if}} + {{#if view.isOriginalSCP}} {{view App.SliderConfigWidgetOverrideView serviceConfigPropertyBinding="view.config" isDefaultGroupSelectedBinding="controller.selectedConfigGroup.isDefault" }} {{/if}} + + {{#if view.isComparison}} + {{view App.SliderConfigWidgetComparisonView serviceConfigPropertyBinding="view.config"}} + {{/if}} + <div class="clearfix"></div> </div> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/4541b382/ambari-web/app/views.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views.js b/ambari-web/app/views.js index c7b8824..6a29279 100644 --- a/ambari-web/app/views.js +++ b/ambari-web/app/views.js @@ -66,6 +66,7 @@ require('views/common/configs/widgets/string_config_widget_view'); require('views/common/configs/widgets/time_interval_spinner_view'); require('views/common/configs/widgets/toggle_config_widget_view'); require('views/common/configs/widgets/overrides/slider_config_widget_override_view'); +require('views/common/configs/widgets/comparison/slider_config_widget_comparison_view'); require('views/common/configs/service_config_layout_tab_view'); require('views/common/filter_combobox'); require('views/common/filter_combo_cleanable'); http://git-wip-us.apache.org/repos/asf/ambari/blob/4541b382/ambari-web/app/views/common/configs/service_config_layout_tab_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/common/configs/service_config_layout_tab_view.js b/ambari-web/app/views/common/configs/service_config_layout_tab_view.js index d1b9121..a48dba9 100644 --- a/ambari-web/app/views/common/configs/service_config_layout_tab_view.js +++ b/ambari-web/app/views/common/configs/service_config_layout_tab_view.js @@ -79,11 +79,23 @@ App.ServiceConfigLayoutTabView = Em.View.extend(App.ConfigOverridable, { Em.assert('Unknown config widget view for config ' + configProperty.get('id') + ' with type ' + configWidgetType, widget); configProperty.set('widget', widget); configProperty.set('stackConfigProperty', config); - if (configProperty.get('overrides')) - configProperty.get('overrides').forEach(function (override) { - override.set('widget', widget); - override.set('stackConfigProperty', config); - }); + if (configProperty.get('overrides')) { + configProperty.get('overrides').forEach(function (override) { + override.setProperties({ + widget: widget, + stackConfigProperty: config + }); + }); + } + if (configProperty.get('compareConfigs')) { + configProperty.get('compareConfigs').forEach(function (compareConfig) { + compareConfig.setProperties({ + widget: widget, + isComparison: false, + stackConfigProperty: config + }); + }); + } }); }); }); http://git-wip-us.apache.org/repos/asf/ambari/blob/4541b382/ambari-web/app/views/common/configs/widgets/comparison/slider_config_widget_comparison_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/common/configs/widgets/comparison/slider_config_widget_comparison_view.js b/ambari-web/app/views/common/configs/widgets/comparison/slider_config_widget_comparison_view.js new file mode 100644 index 0000000..440b884 --- /dev/null +++ b/ambari-web/app/views/common/configs/widgets/comparison/slider_config_widget_comparison_view.js @@ -0,0 +1,24 @@ +/** + * 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'); + +App.SliderConfigWidgetComparisonView = App.ServiceConfigView.SCPComparisonRowsView.extend({ + + templateName: require('templates/common/configs/widgets/comparison/slider_config_widget_comparison') + +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/4541b382/ambari-web/app/views/common/configs/widgets/config_widget_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/common/configs/widgets/config_widget_view.js b/ambari-web/app/views/common/configs/widgets/config_widget_view.js index 9fbb04d..3a9844f 100644 --- a/ambari-web/app/views/common/configs/widgets/config_widget_view.js +++ b/ambari-web/app/views/common/configs/widgets/config_widget_view.js @@ -38,6 +38,14 @@ App.ConfigWidgetView = Em.View.extend(App.SupportsDependentConfigs, { isOriginalSCPBinding: 'config.isOriginalSCP', /** + * Alias to <code>config.isComparison</code> + * Should be used in the templates + * Don't use original <code>config.isComparison</code> in the widget-templates!!! + * @type {boolean} + */ + isComparisonBinding: 'config.isComparison', + + /** * Config name to display. * @type {String} */ @@ -63,11 +71,6 @@ App.ConfigWidgetView = Em.View.extend(App.SupportsDependentConfigs, { }.property('config.value'), /** - * @type {boolean} - */ - isComparison: false, - - /** * Reset config-value to its default * @method restoreValue */ @@ -82,8 +85,8 @@ App.ConfigWidgetView = Em.View.extend(App.SupportsDependentConfigs, { overrideAllowed: function () { var config = this.get('config'); if (!config) return false; - return config.get('isOriginalSCP') && config.get('isPropertyOverridable') && !this.get('isComparison'); - }.property('config.isOriginalSCP', 'config.isPropertyOverridable', 'isComparison'), + return config.get('isOriginalSCP') && config.get('isPropertyOverridable') && !this.get('config.isComparison'); + }.property('config.isOriginalSCP', 'config.isPropertyOverridable', 'config.isComparison'), /** * Determines if undo is allowed for <code>config</code> http://git-wip-us.apache.org/repos/asf/ambari/blob/4541b382/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 e8a6e83..47acdcd 100644 --- a/ambari-web/test/controllers/main/service/info/config_test.js +++ b/ambari-web/test/controllers/main/service/info/config_test.js @@ -600,9 +600,9 @@ describe("App.MainServiceInfoConfigsController", function () { App.ajax.send.restore(); App.router.getClusterName.restore(); }); - it("ajax request to put clsuter cfg", function () { + it("ajax request to put cluster cfg", function () { mainServiceInfoConfigsController.set('stepConfigs', sc); - expect(mainServiceInfoConfigsController.doPUTClusterConfigurationSites([])).to.equal(mainServiceInfoConfigsController.get("doPUTClusterConfigurationSiteResult")); + expect(mainServiceInfoConfigsController.doPUTClusterConfigurationSites([])); expect(App.ajax.send.calledOnce).to.be.true; }); it('values should be parsed', function () { http://git-wip-us.apache.org/repos/asf/ambari/blob/4541b382/ambari-web/test/views/common/configs/widgets/config_widget_view_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/common/configs/widgets/config_widget_view_test.js b/ambari-web/test/views/common/configs/widgets/config_widget_view_test.js index 8df0090..ad85aaf 100644 --- a/ambari-web/test/views/common/configs/widgets/config_widget_view_test.js +++ b/ambari-web/test/views/common/configs/widgets/config_widget_view_test.js @@ -78,71 +78,70 @@ describe('App.ConfigWidgetView', function () { { cfg: { isOriginalSCP: false, - isPropertyOverridable: false + isPropertyOverridable: false, + isComparison: false }, - isComparison: false, e: false }, { cfg: { isOriginalSCP: true, - isPropertyOverridable: false + isPropertyOverridable: false, + isComparison: false }, - isComparison: false, e: false }, { cfg: { isOriginalSCP: false, - isPropertyOverridable: true + isPropertyOverridable: true, + isComparison: false }, - isComparison: false, e: false }, { cfg: { isOriginalSCP: true, - isPropertyOverridable: true + isPropertyOverridable: true, + isComparison: false }, - isComparison: false, e: true }, { cfg: { isOriginalSCP: false, - isPropertyOverridable: false + isPropertyOverridable: false, + isComparison: true }, - isComparison: true, e: false }, { cfg: { isOriginalSCP: true, - isPropertyOverridable: false + isPropertyOverridable: false, + isComparison: true }, - isComparison: true, e: false }, { cfg: { isOriginalSCP: false, - isPropertyOverridable: true + isPropertyOverridable: true, + isComparison: true }, - isComparison: true, e: false }, { cfg: { isOriginalSCP: true, - isPropertyOverridable: true + isPropertyOverridable: true, + isComparison: true }, - isComparison: true, e: false } ]).forEach(function (test, index) { it('test #' + index, function () { view.get('config').setProperties(test.cfg); - view.set('isComparison', test.isComparison); expect(view.get('overrideAllowed')).to.equal(test.e); }); });
