浏览代码

AMBARI-6766 Config History: E2E Integration of Compare View. (atkach)

atkach 10 年之前
父节点
当前提交
5a56e80cd5

+ 114 - 33
ambari-web/app/controllers/main/service/info/configs.js

@@ -48,7 +48,12 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
   overrideToAdd: null,
   //latest version of service config versions
   currentVersion: null,
+  //version selected to view
+  selectedVersion: null,
   versionLoaded: false,
+  isCurrentSelected: function () {
+    return this.get('selectedVersion') === this.get('currentVersion');
+  }.property('selectedVersion', 'currentVersion'),
   serviceConfigs: function () {
     return App.config.get('preDefinedServiceConfigs');
   }.property('App.config.preDefinedServiceConfigs'),
@@ -70,6 +75,9 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
     }
   }.property('App.isHadoop2Stack'),
 
+  showConfigHistoryFeature: function() {
+    return (App.supports.configHistory && this.get('selectedConfigGroup.isDefault'));
+  }.property('selectedConfigGroup.isDefault'),
   /**
    * Map, which contains relation between group and site
    * to upload overridden properties
@@ -263,6 +271,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
     var currentVersion = Math.max.apply(this, data.items.mapProperty('serviceconfigversion'));
 
     this.set('currentVersion', currentVersion);
+    data.items.findProperty('serviceconfigversion', currentVersion).is_current = true;
     App.serviceConfigVersionsMapper.map(data);
   },
 
@@ -309,6 +318,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
 
     App.router.get('configurationController').saveToDB(data.items[0].configurations);
     this.loadedClusterSiteToTagMap = siteToTagMap;
+    this.set('selectedVersion', params.serviceConfigVersion);
     this.loadServiceTagsAndGroups();
   },
 
@@ -464,9 +474,13 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
       //STEP 8: add configs as names of host components
       self.addHostNamesToConfig();
       //STEP load configs of version being compared against
-      self.loadCompareVersionConfigs(self.get('allConfigs')).done(function () {
+      self.loadCompareVersionConfigs(self.get('allConfigs')).done(function (isComparison) {
         //STEP 9: Load and add overriden configs of group
-        App.config.loadServiceConfigGroupOverrides(self.get('allConfigs'), self.get('loadedGroupToOverrideSiteToTagMap'), self.get('configGroups'), self.onLoadOverrides, self);
+        if (!isComparison && self.get('isCurrentSelected')) {
+          App.config.loadServiceConfigGroupOverrides(self.get('allConfigs'), self.get('loadedGroupToOverrideSiteToTagMap'), self.get('configGroups'), self.onLoadOverrides, self);
+        } else {
+          self.onLoadOverrides(self.get('allConfigs'));
+        }
       });
     });
   }.observes('selectedConfigGroup'),
@@ -483,55 +497,121 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
 
     if (compareServiceVersion) {
       this.getCompareVersionConfigs(compareServiceVersion).done(function (json) {
-        var serviceVersionMap = {};
-
-        json.items[0].configurations.forEach(function (configuration) {
-          for (var prop in configuration.properties) {
-            serviceVersionMap[prop] = {
-              name: prop,
-              value: configuration.properties[prop],
-              type: configuration.type,
-              tag: configuration.tag,
-              version: configuration.version
-            }
-          }
-        });
-        allConfigs.forEach(function (serviceConfig) {
-          var compareConfig = serviceVersionMap[serviceConfig.name];
-
-          if (compareConfig) {
-            serviceConfig.compareConfig = App.ServiceConfigProperty.create(serviceConfig);
-            serviceConfig.compareConfig.set('value', compareConfig.value);
-            serviceConfig.compareConfig.set('serviceVersion', compareServiceVersion);
-            serviceConfig.isComparison = true;
-          }
-        });
+        self.initCompareConfig(allConfigs, json);
         self.set('compareServiceVersion', null);
-        dfd.resolve();
+        dfd.resolve(true);
       }).fail(function () {
-          dfd.resolve();
+          self.set('compareServiceVersion', null);
+          dfd.resolve(true);
         });
     } else {
       allConfigs.setEach('isComparison', false);
-      dfd.resolve();
+      dfd.resolve(false);
     }
     return dfd.promise();
   },
 
+  /**
+   * attach analogical config to each property for comparison
+   * @param allConfigs
+   * @param json
+   */
+  initCompareConfig: function(allConfigs, json) {
+    var serviceVersionMap = {};
+    var configNamesMap = {};
+    var serviceName = json.items[0].service_name;
+    var compareServiceVersion = this.get('compareServiceVersion');
+
+    allConfigs.mapProperty('name').forEach(function(name) {
+      configNamesMap[name] = true;
+    });
+
+    json.items[0].configurations.forEach(function (configuration) {
+      for (var prop in configuration.properties) {
+        serviceVersionMap[prop] = {
+          name: prop,
+          value: configuration.properties[prop],
+          type: configuration.type,
+          tag: configuration.tag,
+          version: configuration.version
+        };
+        if (Em.isNone(configNamesMap[prop])) {
+          allConfigs.push(this.getMockConfig(prop, serviceName, App.config.getOriginalFileName(configuration.type)));
+        }
+      }
+    }, this);
+
+    allConfigs.forEach(function (serviceConfig) {
+      var compareConfig = serviceVersionMap[serviceConfig.name];
+      var compareObject = $.extend(true, {isComparison: true}, serviceConfig);
+
+      compareObject.serviceVersion = compareServiceVersion;
+      compareObject.isEditable = false;
+
+      if (compareConfig) {
+        if (serviceConfig.isMock) {
+          compareObject.displayType = 'string';
+          compareObject.isMock = false;
+        }
+        serviceConfig.compareConfig = App.ServiceConfigProperty.create(compareObject);
+        serviceConfig.compareConfig.set('value', App.config.formatOverrideValue(serviceConfig, compareConfig.value));
+        serviceConfig.isComparison = true;
+      } else if (serviceConfig.isUserProperty) {
+        compareObject.isMock = true;
+        compareObject.displayType = 'label';
+        serviceConfig.compareConfig = App.ServiceConfigProperty.create(compareObject);
+        serviceConfig.compareConfig.set('value', 'Undefined');
+        serviceConfig.isComparison = true;
+      }
+    }, this);
+  },
+
+  /**
+   * generate mock config object
+   * @param name
+   * @param serviceName
+   * @param filename
+   * @return {Object}
+   */
+  getMockConfig: function (name, serviceName, filename) {
+    var undefinedConfig = {
+      description: name,
+      displayName: name,
+      id: "site property",
+      isOverridable: false,
+      isReconfigurable: false,
+      isRequired: false,
+      isRequiredByAgent: false,
+      isSecureConfig: false,
+      isUserProperty: true,
+      isVisible: true,
+      name: name,
+      filename: filename,
+      serviceName: serviceName,
+      value: "Undefined",
+      isMock: true,
+      displayType: 'label'
+    };
+    undefinedConfig.category = App.config.identifyCategory(undefinedConfig).name;
+    return undefinedConfig;
+  },
+
   /**
    * get configs of chosen version from server to compare
    * @param compareServiceVersion
    * @return {$.ajax}
    */
   getCompareVersionConfigs: function (compareServiceVersion) {
+    this.set('versionLoaded', false);
+
     return App.ajax.send({
-      name: 'service.config.version.get',
+      name: 'service.serviceConfigVersion.get',
       sender: this,
       data: {
-        serviceVersion: compareServiceVersion,
-        url: '/data/configurations/service_version.json'
+        serviceName: this.get('content.serviceName'),
+        serviceConfigVersion: compareServiceVersion.get('version')
       }
-    })
+    });
   },
 
   checkDatabaseProperties: function (serviceConfig) {
@@ -843,7 +923,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
   setEditability: function (serviceConfigProperty, defaultGroupSelected) {
     serviceConfigProperty.set('isEditable', false);
     if (App.get('isAdmin') && defaultGroupSelected && !this.get('isHostsConfigsPage') && !serviceConfigProperty.get('group')) {
-      serviceConfigProperty.set('isEditable', serviceConfigProperty.get('isReconfigurable') && !serviceConfigProperty.get('isComparison'));
+      serviceConfigProperty.set('isEditable', serviceConfigProperty.get('isReconfigurable'));
     } else if (serviceConfigProperty.get('group') && this.get('selectedConfigGroup.name') === serviceConfigProperty.get('group.name')) {
       serviceConfigProperty.set('isEditable', true);
     }
@@ -855,6 +935,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
    * @method setSupportsFinal
    */
   setSupportsFinal: function (serviceConfigProperty) {
+    if (serviceConfigProperty.get('isMock')) return;
     var fileName = serviceConfigProperty.get('filename');
     var matchingConfigType = this.get('configTypesInfo').supportsFinal.find(function(configType) {
       return fileName.startsWith(configType);

+ 1 - 0
ambari-web/app/mappers/service_config_version_mapper.js

@@ -28,6 +28,7 @@ App.serviceConfigVersionsMapper = App.QuickDataMapper.create({
     applied_time: 'appliedtime',
     author: 'user',
     notes: 'notes',
+    is_current: 'is_current',
     index: 'index'
   },
   map: function (json) {

+ 3 - 0
ambari-web/app/models/service_config.js

@@ -154,6 +154,7 @@ App.ServiceConfigProperty = Ember.Object.extend({
   defaultIsFinal: false,
   supportsFinal: false,
   isVisible: true,
+  isMock: false, // mock config created created only to displaying
   isRequiredByAgent: true, // Setting it to true implies property will be stored in configuration
   isSecureConfig: false,
   errorMessage: '',
@@ -689,6 +690,8 @@ App.ServiceConfigProperty = Ember.Object.extend({
         return App.ServiceConfigBigTextArea;
       case 'masterHost':
         return App.ServiceConfigMasterHostView;
+      case 'label':
+        return App.ServiceConfigLabelView;
       case 'masterHosts':
         return App.ServiceConfigMasterHostsView;
       case 'slaveHosts':

+ 1 - 2
ambari-web/app/models/service_config_version.js

@@ -30,6 +30,7 @@ App.ServiceConfigVersion = DS.Model.extend({
   notes: DS.attr('string'),
   service: DS.belongsTo('App.Service'),
   index: DS.attr('number'),
+  isCurrent: DS.attr('boolean'),
   briefNotes: function () {
     var length = this.get('isCurrent') ? 20 : 40;
     return (typeof this.get('notes') === 'string') ? this.get('notes').slice(0, length) : "";
@@ -43,8 +44,6 @@ App.ServiceConfigVersion = DS.Model.extend({
   shortModifiedDate: function () {
     return dateUtil.dateFormat(this.get('appliedTime'), 'MMM DD, YYYY');
   }.property('createTime'),
-  //TODO set isCurrent value from API response
-  isCurrent: false,
   /**
    * determine whether ServiceConfigVersion is requested from server
    */

+ 5 - 3
ambari-web/app/templates/common/configs/compare_property.hbs

@@ -17,10 +17,12 @@
 }}
 
 <div {{bindAttr class=":control-group :overrideField"}}>
-  {{view view.serviceConfigProperty.viewClass serviceConfigBinding="view.serviceConfigProperty.compareConfig"}}
+  {{view view.serviceConfigProperty.compareConfig.viewClass serviceConfigBinding="view.serviceConfigProperty.compareConfig"}}
+  {{#unless view.serviceConfigProperty.compareConfig.isMock}}
     <span>
       <strong><i class="icon-asterisks">&#10037;</i>{{view.serviceConfigProperty.compareConfig.serviceVersion.author}}</strong>&nbsp;
-      {{t dashboard.configHistory.info-bar.authoredOn}}&nbsp;
+        {{t dashboard.configHistory.info-bar.authoredOn}}&nbsp;
       <strong>{{view.serviceConfigProperty.compareConfig.serviceVersion.modifiedDate}}</strong>
-  </span>
+    </span>
+  {{/unless}}
 </div>

+ 5 - 6
ambari-web/app/templates/common/configs/config_history_flow.hbs

@@ -77,12 +77,11 @@
             <strong>{{view.displayedServiceVersion.author}}</strong>&nbsp;{{t dashboard.configHistory.info-bar.authoredOn}}&nbsp;<strong>{{view.displayedServiceVersion.modifiedDate}}</strong>
         </div>
         <div class="pull-right">
-            {{#if view.displayedServiceVersion.isCurrent}}
-                <button class="btn" {{action doCancel target="controller"}}>{{t common.cancel}}</button>
-                <button class="btn btn-success" {{bindAttr disabled="isSubmitDisabled"}} {{action save target="view"}}>{{t common.save}}</button>
-            {{else}}
-                <button class="btn btn-success" {{action revert view.displayedServiceVersion target="view"}} {{bindAttr disabled="view.versionActionsDisabled"}}>{{t dashboard.configHistory.info-bar.revert.button}}</button>
-            {{/if}}
+            <div {{bindAttr class="view.displayedServiceVersion.isCurrent::hidden"}}>
+                <button class="btn" {{action doCancel target="controller"}} {{bindAttr disabled="view.versionActionsDisabled"}}>{{t common.cancel}}</button>
+                <button class="btn btn-success" {{action save target="view"}} {{bindAttr disabled="view.isSaveDisabled"}}>{{t common.save}}</button>
+            </div>
+            <button class="btn btn-success"  {{action revert view.displayedServiceVersion target="view"}} {{bindAttr disabled="view.versionActionsDisabled" class="view.displayedServiceVersion.isCurrent:hidden"}}>{{t dashboard.configHistory.info-bar.revert.button}}</button>
         </div>
     </div>
     <div class="label-wrapper">

+ 2 - 4
ambari-web/app/templates/common/configs/service_config.hbs

@@ -77,10 +77,8 @@
 	</div>
 {{/if}}
 
-{{#if App.supports.configHistory}}
-  {{#if view.showConfigHistoryFlow}}
-    {{view App.ConfigHistoryFlowView serviceBinding="selectedService"}}
-  {{/if}}
+{{#if view.showConfigHistoryFeature}}
+  {{view App.ConfigHistoryFlowView serviceBinding="selectedService"}}
 {{/if}}
 
 {{#if versionLoaded}}

+ 2 - 2
ambari-web/app/templates/main/service/info/configs.hbs

@@ -43,9 +43,9 @@
       {{/if}}
     {{/if}}
     <div class="clearfix"></div>
-    {{view App.ServiceConfigView filterBinding="controller.filter" columnsBinding="controller.filterColumns"}}
+    {{view App.ServiceConfigView filterBinding="controller.filter" columnsBinding="controller.filterColumns" canEditBinding="controller.isCurrentSelected" showConfigHistoryFeatureBinding="controller.showConfigHistoryFeature"}}
     {{#if App.isAdmin}}
-      {{#unless App.supports.configHistory}}
+      {{#unless showConfigHistoryFeature}}
           <p class="pull-right">
               <!--<input class="btn btn-primary" type="button" value="Save" {{!bindAttr disabled="isSubmitDisabled"}} />-->
               <a class="btn" {{action doCancel target="controller"}}>{{t common.cancel}}</a>

+ 2 - 12
ambari-web/app/utils/ajax/ajax.js

@@ -1756,23 +1756,13 @@ var urls = {
       }
     }
   },
-  'service.config.version.get': {
-    //TODO set actual url when API is ready
-    'real': '',
-    'mock': '',
-    format: function(data) {
-      return {
-        url: data.url
-      }
-    }
-  },
   'service.serviceConfigVersions.get': {
     real: '/clusters/{clusterName}/configurations/serviceconfigversions?service_name={serviceName}&fields=serviceconfigversion,user,appliedtime,createtime,service_name&minimal_response=true',
-    mock: ''
+    mock: '/data/configurations/service_versions.json'
   },
   'service.serviceConfigVersion.get': {
     real: '/clusters/{clusterName}/configurations/serviceconfigversions?service_name={serviceName}&serviceconfigversion={serviceConfigVersion}',
-    mock: ''
+    mock: '/data/configurations/service_version.json'
   },
   'service.serviceConfigVersion.revert': {
     'real': '/clusters/{clusterName}',

+ 5 - 7
ambari-web/app/utils/config.js

@@ -929,8 +929,7 @@ App.config = Em.Object.create({
       for (var prop in properties) {
         var fileName = this.getOriginalFileName(config.type);
         var serviceConfig = !!params.configKeyToConfigMap[fileName] ? params.configKeyToConfigMap[fileName][prop] : false;
-        var hostOverrideValue = properties[prop];
-        this.formatOverrideValue(serviceConfig, hostOverrideValue);
+        var hostOverrideValue = this.formatOverrideValue(serviceConfig, properties[prop]);
         if (serviceConfig) {
           // Value of this property is different for this host.
           if (!Em.get(serviceConfig, 'overrides')) Em.set(serviceConfig, 'overrides', []);
@@ -982,18 +981,17 @@ App.config = Em.Object.create({
   formatOverrideValue: function (serviceConfig, hostOverrideValue) {
     if (serviceConfig && serviceConfig.displayType === 'int') {
       if (/\d+m$/.test(hostOverrideValue)) {
-        hostOverrideValue = hostOverrideValue.slice(0, hostOverrideValue.length - 1);
+        return hostOverrideValue.slice(0, hostOverrideValue.length - 1);
       }
     } else if (serviceConfig && serviceConfig.displayType === 'checkbox') {
       switch (hostOverrideValue) {
         case 'true':
-          hostOverrideValue = true;
-          break;
+          return true;
         case 'false':
-          hostOverrideValue = false;
-          break;
+          return false;
       }
     }
+    return hostOverrideValue;
   },
 
   /**

+ 9 - 7
ambari-web/app/views/common/configs/config_history_flow.js

@@ -34,6 +34,10 @@ App.ConfigHistoryFlowView = Em.View.extend({
    */
   showFullList: false,
 
+  isSaveDisabled: function () {
+    return (this.get('controller.isSubmitDisabled') || !this.get('controller.versionLoaded'));
+  }.property('controller.isSubmitDisabled', 'controller.versionLoaded'),
+
   serviceName: function () {
     return this.get('controller.selectedService.serviceName');
   }.property('controller.selectedService.serviceName'),
@@ -96,9 +100,7 @@ App.ConfigHistoryFlowView = Em.View.extend({
     var serviceVersions = this.get('serviceVersions');
     var startIndex = 0;
 
-    serviceVersions.setEach('isCurrent', false);
     serviceVersions.setEach('isDisplayed', false);
-    serviceVersions.findProperty('appliedTime', Math.max.apply(this, serviceVersions.mapProperty('appliedTime'))).set('isCurrent', true);
     serviceVersions.findProperty('isCurrent').set('isDisplayed', true);
 
     if (serviceVersions.length > 0) {
@@ -218,11 +220,11 @@ App.ConfigHistoryFlowView = Em.View.extend({
     this.get('serviceVersions').forEach(function (serviceVersion) {
       serviceVersion.set('isCurrent', serviceVersion.get('version') === version);
     });
-    if (this.get('displayedServiceVersion.version') !== version) {
-      this.switchVersion({context: Em.Object.create({
-        version: version
-      })});
-    }
+    this.set('controller.currentVersion', version);
+
+    this.switchVersion({context: Em.Object.create({
+      version: version
+    })});
   },
 
   /**

+ 1 - 4
ambari-web/app/views/common/configs/services_config.js

@@ -48,10 +48,7 @@ App.ServiceConfigView = Em.View.extend({
         return false;
     }
   }.property('controller.name', 'controller.selectedService'),
-  showConfigHistoryFlow: function() {
-    //TODO change condition to actual
-    return (this.get('controller.name') === 'mainServiceInfoConfigsController' && this.get('controller.selectedConfigGroup.isDefault'))
-  }.property('controller.name', 'controller.selectedConfigGroup.isDefault'),
+  showConfigHistoryFeature: false,
   toggleRestartMessageView: function () {
     this.$('.service-body').toggle('blind', 200);
     this.set('isRestartMessageCollapsed', !this.get('isRestartMessageCollapsed'));

+ 13 - 1
ambari-web/app/views/wizard/controls_view.js

@@ -76,7 +76,7 @@ App.ServiceConfigTextField = Ember.TextField.extend(App.ServiceConfigPopoverSupp
   },
   //Set editDone false for all current category config text field parameter
   focusIn: function (event) {
-    if (!this.get('serviceConfig.isOverridden')) {
+    if (!this.get('serviceConfig.isOverridden') && !this.get('serviceConfig.isComparison')) {
       this.get("parentView.categoryConfigsAll").setEach("editDone", false);
     }
   },
@@ -477,6 +477,18 @@ App.ServiceConfigMasterHostView = Ember.View.extend(App.ServiceConfigHostPopover
 
 });
 
+/**
+ * Show value as plain label in italics
+ * @type {*}
+ */
+App.ServiceConfigLabelView = Ember.View.extend(App.ServiceConfigHostPopoverSupport, {
+
+  classNames: ['master-host', 'span6'],
+  valueBinding: 'serviceConfig.value',
+
+  template: Ember.Handlebars.compile('<i>{{view.value}}</i>')
+});
+
 /**
  * Base component to display Multiple hosts
  * @type {*}