123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384 |
- /**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var App = require('app');
- var blueprintUtils = require('utils/blueprint');
- App.EnhancedConfigsMixin = Em.Mixin.create(App.ConfigWithOverrideRecommendationParser, {
- /**
- * this value is used for observing
- * whether recommendations for dependent properties was received from server
- * @type {number}
- */
- recommendationTimeStamp: null,
- /**
- * this property is used to force update min/max values
- * for not default config groups
- * @type {boolean}
- */
- forceUpdateBoundaries: false,
- /**
- * object with loaded recommendations
- *
- * @type {Object}
- */
- recommendationsConfigs: null,
- /**
- * flag is true when Ambari changes some of the dependent properties
- * @type {boolean}
- */
- hasChangedDependencies: Em.computed.and('isControllerSupportsEnhancedConfigs', 'changedProperties.length'),
- /**
- * defines is block with changed dependent configs should be shown
- * rely on controller
- * @type {boolean}
- */
- isControllerSupportsEnhancedConfigs: Em.computed.existsIn('name', ['wizardStep7Controller','mainServiceInfoConfigsController']),
- dependenciesGroupMessage: Em.I18n.t('popup.dependent.configs.dependencies.for.groups'),
- /**
- * message fro alert box for dependent configs
- * @type {string}
- */
- dependenciesMessage: function() {
- var changedProperties = this.get('changedProperties').filterProperty('saveRecommended');
- var changedServices = changedProperties.mapProperty('serviceName').uniq();
- var cfgLenSuffix = changedProperties.length === 1 ? 'singular' : 'plural';
- var sLenSuffix = changedServices.length === 1 ? 'singular' : 'plural';
- return Em.I18n.t('popup.dependent.configs.dependencies.config.' + cfgLenSuffix).format(changedProperties.length)
- + Em.I18n.t('popup.dependent.configs.dependencies.service.' + sLenSuffix).format(changedServices.length);
- }.property('changedProperties.length'),
- /**
- * dependent properties that was changed by Ambari
- * @type {Object[]}
- */
- changedProperties: function() {
- return this.get('recommendations').filter(function(dp) {
- return (this.get('selectedConfigGroup.isDefault') && Em.get(dp, 'configGroup').contains('Default'))
- || [this.get('selectedConfigGroup.name'), this.get('selectedConfigGroup.dependentConfigGroups') && this.get('selectedConfigGroup.dependentConfigGroups')[Em.get(dp, 'serviceName')]].contains(Em.get(dp, 'configGroup'));
- }, this);
- }.property('recommendations.@each.saveRecommended', 'recommendations.@each.recommendedValue', 'selectedConfigGroup'),
- /**
- * defines if change dependent group message should be shown
- * @type {boolean}
- */
- showSelectGroupsPopup: Em.computed.and('!selectedConfigGroup.isDefault', 'selectedService.dependentServiceNames.length'),
- /**
- * set default values for dependentGroups
- * @method setDependentGroups
- */
- setDependentGroups: function () {
- if (this.get('selectedConfigGroup') && this.get('isControllerSupportsEnhancedConfigs') && !this.get('selectedConfigGroup.isDefault') && this.get('selectedService.dependentServiceNames.length')) {
- this.get('selectedService.dependentServiceNames').forEach(function (serviceName) {
- if (!this.get('selectedConfigGroup.dependentConfigGroups')[serviceName]) {
- var stepConfig = this.get('stepConfigs').findProperty('serviceName', serviceName);
- if (stepConfig) {
- stepConfig.get('configGroups').filterProperty('isDefault', false).forEach(function (configGroup) {
- this.get('selectedService.configGroups').filterProperty('isDefault', false).forEach(function (currentServiceGroup) {
- if (currentServiceGroup.get('dependentConfigGroups')[serviceName] != configGroup.get('name')) {
- var dependentGroups = $.extend({},this.get('selectedConfigGroup.dependentConfigGroups'));
- dependentGroups[serviceName] = configGroup.get('name');
- this.set('selectedConfigGroup.dependentConfigGroups', dependentGroups);
- }
- }, this);
- }, this);
- }
- }
- }, this);
- }
- }.observes('selectedConfigGroup'),
- /******************************METHODS THAT WORKS WITH DEPENDENT CONFIGS *************************************/
- /**
- * get config group object for current service
- * @param serviceName
- * @returns {App.ConfigGroup|null}
- */
- getGroupForService: function(serviceName) {
- if (!this.get('stepConfigs') || this.get('stepConfigs.length') === 0) {
- return null;
- }
- if (this.get('selectedService.serviceName') === serviceName) {
- return this.get('selectedConfigGroup');
- } else {
- var stepConfig = this.get('stepConfigs').findProperty('serviceName', serviceName);
- if (stepConfig) {
- var groups = stepConfig.get('configGroups');
- if (this.get('selectedConfigGroup.isDefault')) {
- return groups.length ? groups.findProperty('isDefault', true) : null;
- } else {
- return groups.length ? groups.findProperty('name', this.get('selectedConfigGroup.dependentConfigGroups')[serviceName]) : null;
- }
- } else {
- return null;
- }
- }
- },
- clearRecommendationsInfo: function() {
- this.set('recommendationsConfigs', null);
- },
- /**
- * sends request to get values for dependent configs
- * @param {{type: string, name: string}[]} changedConfigs - list of changed configs to track recommendations
- * @param {Function} [onComplete]
- * @returns {$.ajax|null}
- */
- loadConfigRecommendations: function(changedConfigs, onComplete) {
- var updateDependencies = Em.isArray(changedConfigs) && changedConfigs.length > 0;
- if (updateDependencies || Em.isNone(this.get('recommendationsConfigs'))) {
- var configGroup = this.get('selectedConfigGroup');
- var recommendations = this.get('hostGroups');
- var dataToSend = {
- recommend: updateDependencies ? 'configuration-dependencies' : 'configurations',
- hosts: this.get('hostNames'),
- services: this.get('serviceNames')
- };
- if (updateDependencies) {
- dataToSend.changed_configurations = changedConfigs;
- }
- recommendations.blueprint.configurations = blueprintUtils.buildConfigsJSON(this.get('stepConfigs'));
- if (configGroup && !configGroup.get('isDefault') && configGroup.get('hosts.length') > 0) {
- recommendations.config_groups = [this.buildConfigGroupJSON(this.get('selectedService.configs'), configGroup)];
- } else {
- delete recommendations.config_groups;
- }
- dataToSend.recommendations = recommendations;
- var self = this;
- return App.ajax.send({
- name: 'config.recommendations',
- sender: this,
- data: {
- stackVersionUrl: App.get('stackVersionURL'),
- dataToSend: dataToSend
- },
- success: 'loadRecommendationsSuccess',
- error: 'loadRecommendationsError',
- callback: function() {
- self.set('recommendationTimeStamp', (new Date).getTime());
- if (onComplete) {
- onComplete()
- }
- }
- });
- } else {
- if (onComplete) {
- onComplete()
- }
- return null;
- }
- },
- /**
- * Defines if there is any changes made by user.
- * Check all properties except recommended properties from popup
- *
- * @returns {boolean}
- */
- isConfigHasInitialState: function() {
- return this.get('selectedConfigGroup.isDefault') && !Em.isNone(this.get('recommendationsConfigs'))
- && !this.get('stepConfigs').filter(function(stepConfig) {
- return stepConfig.get('changedConfigProperties').filter(function(c) {
- return !this.get('changedProperties').map(function(changed) {
- return App.config.configId(changed.propertyName, changed.propertyFileName);
- }).contains(App.config.configId(c.get('name'), c.get('filename')));
- }, this).length;
- }, this).length;
- },
- /**
- * generates JSON with config group info to send it for recommendations
- * @param configs
- * @param configGroup
- * @returns {{configurations: Object[], hosts: string[]}}
- */
- buildConfigGroupJSON: function(configs, configGroup) {
- Em.assert('configGroup can\'t be null', configGroup);
- var hosts = configGroup.get('hosts');
- var configurations = {};
- var overrides = configs.forEach(function(cp) {
- var override = cp.get('overrides') && cp.get('overrides').findProperty('group.name', configGroup.get('name'));
- if (override) {
- var tag = App.config.getConfigTagFromFileName(cp.get('filename'));
- if (!configurations[tag]) {
- configurations[tag] = { properties: {} };
- }
- configurations[tag].properties[cp.get('name')] = override.get('value');
- }
- });
- return {
- configurations: [configurations],
- hosts: hosts
- }
- },
- /**
- * shows popup with results for recommended value
- * if case properties that was changes belongs to not default group
- * user should pick to what config group from dependent service dependent properties will be saved
- * @param data
- * @param opt
- * @param params
- * @method dependenciesSuccess
- */
- loadRecommendationsSuccess: function (data, opt, params) {
- this._saveRecommendedValues(data, params.dataToSend.changed_configurations);
- if (this.isConfigHasInitialState()) {
- this.undoRedoRecommended(this.get('recommendations'), false);
- this.clearAllRecommendations();
- }
- this.set("recommendationsConfigs", Em.get(data, "resources.0.recommendations.blueprint.configurations"));
- },
- loadRecommendationsError: Em.K,
- changedDependentGroup: function() {
- var dependentServices = this.get('stepConfigs').filter(function(stepConfig) {
- return this.get('selectedService.dependentServiceNames').contains(stepConfig.get('serviceName'));
- }, this);
- App.showSelectGroupsPopup(this.get('selectedService.serviceName'),
- this.get('selectedService.configGroups').findProperty('name', this.get('selectedConfigGroup.name')),
- dependentServices, this.get('recommendations'))
- },
- /**
- * saves values from response for dependent config properties to <code>recommendations<code>
- * @param data
- * @param [changedConfigs=null]
- * @method saveRecommendedValues
- * @private
- */
- _saveRecommendedValues: function(data, changedConfigs) {
- 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 recommendations = data.resources[0].recommendations;
- if (recommendations['config-groups'] && this.get('selectedConfigGroup') && !this.get('selectedConfigGroup.isDefault')) {
- var configFroGroup = recommendations['config-groups'][0];
- this.get('stepConfigs').forEach(function(stepConfig) {
- var configGroup = this.getGroupForService(stepConfig.get('serviceName'));
- if (configGroup) {
- this.updateOverridesByRecommendations(configFroGroup.configurations, stepConfig.get('configs'), changedConfigs, configGroup);
- this.updateOverridesByRecommendations(configFroGroup.dependent_configurations, stepConfig.get('configs'), changedConfigs, configGroup);
- this.toggleProperty('forceUpdateBoundaries');
- }
- }, this);
- } else {
- var configObject = recommendations.blueprint.configurations;
- this.get('stepConfigs').forEach(function(stepConfig) {
- this.updateConfigsByRecommendations(configObject, stepConfig.get('configs'), changedConfigs);
- }, this);
- this.addByRecommendations(configObject, changedConfigs);
- }
- this.cleanUpRecommendations();
- },
- /**
- * method to show popup with dependent configs
- * @method showChangedDependentConfigs
- */
- showChangedDependentConfigs: function(event, callback, secondary) {
- var self = this;
- var recommendations = event ? this.get('changedProperties') : this.get('recommendations');
- if (recommendations.length > 0) {
- App.showDependentConfigsPopup(recommendations, function() {
- self.onSaveRecommendedPopup(recommendations);
- if (callback) callback();
- }, secondary);
- } else {
- if (callback) callback();
- }
- },
- /**
- * update configs when toggle checkbox on dependent configs popup
- */
- onSaveRecommendedPopup: function(recommendations) {
- var propertiesToUpdate = recommendations.filter(function(c) {
- return Em.get(c, 'saveRecommendedDefault') != Em.get(c, 'saveRecommended');
- }),
- propertiesToUndo = propertiesToUpdate.filterProperty('saveRecommended', false),
- propertiesToRedo = propertiesToUpdate.filterProperty('saveRecommended', true);
- this.undoRedoRecommended(propertiesToUndo, false);
- this.undoRedoRecommended(propertiesToRedo, true);
- this.set('recommendationTimeStamp', (new Date).getTime());
- },
- /**
- * 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, 'initialValue') : Em.get(p, 'recommendedValue');
- var recommended = redo ? Em.get(p, 'recommendedValue') : Em.get(p, 'initialValue');
- 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') == App.config.getOriginalFileName(Em.get(p, 'propertyFileName'));
- });
- var selectedGroup = App.ServiceConfigGroup.find().filterProperty('serviceName', Em.get(p, 'serviceName')).findProperty('name', Em.get(p, 'configGroup'));
- if (selectedGroup.get('isDefault')) {
- if (Em.isNone(recommended)) {
- stepConfig.get('configs').removeObject(config);
- } else if (Em.isNone(initial)) {
- this._addConfigByRecommendation(stepConfig.get('configs'), Em.get(p, 'propertyName'), Em.get(p, 'propertyFileName'), recommended);
- } else {
- Em.set(config, 'value', recommended);
- }
- } else {
- if (Em.isNone(recommended)) {
- config.get('overrides').removeObject(config.getOverride(selectedGroup.get('name')));
- } else if (Em.isNone(initial)) {
- this._addConfigOverrideRecommendation(config, recommended, null, selectedGroup);
- } else {
- var override = config.getOverride(selectedGroup.get('name'));
- if (override) {
- override.set('value', recommended);
- }
- }
- }
- }, this);
- },
- /**
- * disable saving recommended value for current config
- * @param config
- * @param {boolean} saveRecommended
- * @method removeCurrentFromDependentList
- */
- removeCurrentFromDependentList: function (config, saveRecommended) {
- var recommendation = this.getRecommendation(config.get('name'), config.get('filename'), config.get('group.name'));
- if (recommendation) this.saveRecommendation(recommendation, saveRecommended);
- }
- });
|