You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by al...@apache.org on 2015/08/19 16:58:16 UTC

ambari git commit: AMBARI-12818. Properties autotrimming works incorrectly (alexantonenko)

Repository: ambari
Updated Branches:
  refs/heads/branch-2.1 598318148 -> 18c605145


AMBARI-12818. Properties autotrimming works incorrectly (alexantonenko)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/18c60514
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/18c60514
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/18c60514

Branch: refs/heads/branch-2.1
Commit: 18c605145503f7ae12da0a27be5d8475a926b911
Parents: 5983181
Author: Alex Antonenko <hi...@gmail.com>
Authored: Wed Aug 19 17:49:11 2015 +0300
Committer: Alex Antonenko <hi...@gmail.com>
Committed: Wed Aug 19 17:53:26 2015 +0300

----------------------------------------------------------------------
 .../mappers/service_config_version_mapper.js    | 14 +++++++++++-
 ambari-web/app/messages.js                      |  1 +
 .../app/mixins/common/configs/configs_loader.js | 11 +++++++---
 .../configs/objects/service_config_property.js  | 15 +++++++++++++
 ambari-web/app/utils/config.js                  |  9 ++++++++
 ambari-web/app/utils/validator.js               | 23 ++++++++++++++++++--
 ambari-web/test/utils/validator_test.js         |  9 +++++---
 7 files changed, 73 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/18c60514/ambari-web/app/mappers/service_config_version_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/service_config_version_mapper.js b/ambari-web/app/mappers/service_config_version_mapper.js
index 0ae9879..23dcdcb 100644
--- a/ambari-web/app/mappers/service_config_version_mapper.js
+++ b/ambari-web/app/mappers/service_config_version_mapper.js
@@ -51,7 +51,7 @@ App.serviceConfigVersionsMapper = App.QuickDataMapper.create({
 
       json.items.forEach(function (item, index) {
         var parsedItem = this.parseIt(item, this.get('config'));
-        parsedItem.id = parsedItem.service_name + '_' + parsedItem.version;
+        parsedItem.id = this.makeId(parsedItem.service_name, parsedItem.version);
         parsedItem.is_requested = true;
         itemIds[parsedItem.id] = true;
         parsedItem.index = index;
@@ -99,5 +99,17 @@ App.serviceConfigVersionsMapper = App.QuickDataMapper.create({
       App.store.loadMany(this.get('model'), result);
       console.timeEnd('App.serviceConfigVersionsMapper');
     }
+  },
+
+  /**
+   * Conventional method to generate id for instances of <code>App.ServiceConfigVersion</code> model.
+   *
+   * @param {String} serviceName
+   * @param {Number|String} version
+   * @returns {String}
+   */
+  makeId: function(serviceName, version) {
+    return serviceName + '_' + version;
   }
+
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/18c60514/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index 9549cc7..67af475 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -906,6 +906,7 @@ Em.I18n.translations = {
   'form.validator.alertGroupName':'Invalid Alert Group Name. Only alphanumerics, hyphens, spaces and underscores are allowed.',
   'form.validator.alertGroupPlaceHolder':'Alert Group Name',
   'form.validator.configKey.specific':'"{0}" is invalid Key. Only alphanumerics, hyphens, underscores, asterisks and periods are allowed.',
+  'form.validator.error.trailingSpaces': 'Cannot contain trailing whitespace',
 
   'alerts.add.header': 'Create Alert Definition',
   'alerts.add.step1.header': 'Choose Type',

http://git-wip-us.apache.org/repos/asf/ambari/blob/18c60514/ambari-web/app/mixins/common/configs/configs_loader.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/common/configs/configs_loader.js b/ambari-web/app/mixins/common/configs/configs_loader.js
index 5546f6b..3d2fd17 100644
--- a/ambari-web/app/mixins/common/configs/configs_loader.js
+++ b/ambari-web/app/mixins/common/configs/configs_loader.js
@@ -68,17 +68,22 @@ App.ConfigsLoader = Em.Mixin.create(App.GroupsMappingMixin, {
     }
     this.set('allVersionsLoaded', true);
     if (this.get('preSelectedConfigVersion')) {
+      var preSelectedId = App.serviceConfigVersionsMapper.makeId(this.get('preSelectedConfigVersion.serviceName'), this.get('preSelectedConfigVersion.version'));
+      var defaultConfigVersion = App.ServiceConfigVersion.find(App.serviceConfigVersionsMapper.makeId(this.get('content.serviceName'), this.get('currentDefaultVersion')));
+      var preSelectedVersion = App.ServiceConfigVersion.find().someProperty('id', preSelectedId) ? this.get('preSelectedConfigVersion') : defaultConfigVersion;
+
       this.set('selectedVersion', this.get('preSelectedConfigVersion.version'));
       /** handling redirecting from config history page **/
       var self = this;
       this.loadConfigGroups(this.get('servicesToLoad')).done(function() {
         var selectedGroup = App.ServiceConfigGroup.find().find(function(g) {
-          return g.get('serviceName') == self.get('preSelectedConfigVersion.serviceName')
-            && (g.get('name') == self.get('preSelectedConfigVersion.groupName') || (self.get('preSelectedConfigVersion.groupName') == 'default' && g.get('isDefault')));
+          return g.get('serviceName') == preSelectedVersion.get('serviceName')
+            && (g.get('name') == preSelectedVersion.get('groupName') || (preSelectedVersion.get('groupName') == 'default' && g.get('isDefault')));
         });
         self.set('selectedConfigGroup', selectedGroup);
-        self.loadSelectedVersion(self.get('preSelectedConfigVersion.version'), selectedGroup);
+        self.loadSelectedVersion(preSelectedVersion.get('version'), selectedGroup);
         self.set('preSelectedConfigVersion', null);
+        preSelectedVersion = null;
       });
     } else {
       this.set('selectedVersion', this.get('currentDefaultVersion'));

http://git-wip-us.apache.org/repos/asf/ambari/blob/18c60514/ambari-web/app/models/configs/objects/service_config_property.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/configs/objects/service_config_property.js b/ambari-web/app/models/configs/objects/service_config_property.js
index 3495e08..b961d3f 100644
--- a/ambari-web/app/models/configs/objects/service_config_property.js
+++ b/ambari-web/app/models/configs/objects/service_config_property.js
@@ -417,6 +417,12 @@ App.ServiceConfigProperty = Em.Object.extend({
             if (!validator.isAllowedDir(value)) {
               this.set('errorMessage', 'Can\'t start with "home(s)"');
               isError = true;
+            } else {
+              // Invalidate values which end with spaces.
+              if (value !== ' ' && validator.isNotTrimmedRight(value)) {
+                this.set('errorMessage', Em.I18n.t('form.validator.error.trailingSpaces'));
+                isError = true;
+              }
             }
           }
           break;
@@ -445,6 +451,8 @@ App.ServiceConfigProperty = Em.Object.extend({
             }
           }
           break;
+        case 'multiLine':
+        case 'content':
         case 'advanced':
           if(this.get('name')=='javax.jdo.option.ConnectionURL' || this.get('name')=='oozie.service.JPAService.jdbc.url') {
             if (validator.isConfigValueLink(value)) {
@@ -453,6 +461,13 @@ App.ServiceConfigProperty = Em.Object.extend({
               this.set('errorMessage', Em.I18n.t('host.trimspacesValidation'));
               isError = true;
             }
+          } else {
+            // Avoid single space values which is work around for validate empty properties.
+            // Invalidate values which end with spaces.
+            if (value !== ' ' && validator.isNotTrimmedRight(value)) {
+              this.set('errorMessage', Em.I18n.t('form.validator.error.trailingSpaces'));
+              isError = true;
+            }
           }
           break;
         case 'password':

http://git-wip-us.apache.org/repos/asf/ambari/blob/18c60514/ambari-web/app/utils/config.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/config.js b/ambari-web/app/utils/config.js
index ff20568..325615c 100644
--- a/ambari-web/app/utils/config.js
+++ b/ambari-web/app/utils/config.js
@@ -492,6 +492,11 @@ App.config = Em.Object.create({
         displayType = Em.get(serviceConfigProperty, 'displayType') || Em.get(serviceConfigProperty, 'valueAttributes.type'),
         category = Em.get(serviceConfigProperty, 'category');
     switch (displayType) {
+      case 'content':
+      case 'advanced':
+      case 'multiLine':
+        return this.trimProperty({ displayType: displayType, value: value });
+        break;
       case 'directories':
         if (['DataNode', 'NameNode'].contains(category)) {
           return value.split(',').sort().join(',');//TODO check if this code is used
@@ -607,6 +612,10 @@ App.config = Em.Object.create({
 
         if (['directory' ,'directories'].contains(configData.displayType) && configData.defaultDirectory) {
           configData.value = configData.defaultDirectory;
+        } else if (advanced && advanced.get('id')) {
+          var configValue = this.formatPropertyValue(advanced, advanced.get('value'));
+          // for property which value is single/multiple spaces set single space as well
+          configData.value = configData.recommendedValue = /^\s+$/.test("" + configValue) ? " " : configValue;
         }
 
         mergedConfigs.push(configData);

http://git-wip-us.apache.org/repos/asf/ambari/blob/18c60514/ambari-web/app/utils/validator.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/validator.js b/ambari-web/app/utils/validator.js
index 4dd967b..f6cb451 100644
--- a/ambari-web/app/utils/validator.js
+++ b/ambari-web/app/utils/validator.js
@@ -49,7 +49,10 @@ module.exports = {
     var floatRegex = /^\/[0-9a-z]*/;
     var winRegex = /^[a-z]:\\[0-9a-zA-Z]*/;
     var winUrlRegex = /^file:\/\/\/[a-zA-Z]:\/[0-9a-zA-Z]*/;
-    var dirs = value.replace(/,/g,' ').trim().split(new RegExp("\\s+", "g"));
+    var dirs = value.split(',');
+    if (dirs.some(function(i) { return i.startsWith(' '); })) {
+      return false;
+    }
     for(var i = 0; i < dirs.length; i++){
       if(!floatRegex.test(dirs[i]) && !winRegex.test(dirs[i]) && !winUrlRegex.test(dirs[i])){
         return false;
@@ -76,7 +79,10 @@ module.exports = {
     var dirRegex = /^(\[[0-9a-zA-Z]+\])?(\/[0-9a-z]*)/;
     var winRegex = /^(\[[0-9a-zA-Z]+\])?[a-zA-Z]:\\[0-9a-zA-Z]*/;
     var winUrlRegex = /^(\[[0-9a-zA-Z]+\])?file:\/\/\/[a-zA-Z]:\/[0-9a-zA-Z]*/;
-    var dirs = value.replace(/,/g,' ').trim().split(new RegExp("\\s+", "g"));
+    var dirs = value.split(',');
+    if (dirs.some(function (i) {return i.startsWith(' '); })) {
+      return false;
+    }
     for(var i = 0; i < dirs.length; i++){
       if(!dirRegex.test(dirs[i]) && !winRegex.test(dirs[i]) && !winUrlRegex.test(dirs[i])){
         return false;
@@ -129,6 +135,19 @@ module.exports = {
     var regex = /(^\s+|\s+$)/;
     return regex.test(value);
   },
+
+  /**
+   * Check if string ends with spaces.
+   * For multiline content only last line will be checked.
+   *
+   * @method isNotTrimmedLeft
+   * @param {String} value
+   * @returns {Boolean} - <code>true</code> if ends with spaces
+   */
+  isNotTrimmedRight: function(value) {
+    return /\s+$/.test(("" + value).split(/\n/).slice(-1)[0]);
+  },
+
   /**
    * validate domain name with port
    * @param value

http://git-wip-us.apache.org/repos/asf/ambari/blob/18c60514/ambari-web/test/utils/validator_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/utils/validator_test.js b/ambari-web/test/utils/validator_test.js
index af1749e..021bd47 100644
--- a/ambari-web/test/utils/validator_test.js
+++ b/ambari-web/test/utils/validator_test.js
@@ -283,8 +283,10 @@ describe('validator', function () {
   describe('#isValidDir(value)', function() {
     var tests = [
       {m:'"dir" - invalid',i:'dir',e:false},
+      {m:'" /dir" - invalid',i:' /dir',e:false},
       {m:'"/dir" - valid',i:'/dir',e:true},
       {m:'"/dir1,dir2" - invalid',i:'/dir1,dir2',e:false},
+      {m:'"/dir1, /dir2" - invalid',i:'/dir1,dir2',e:false},
       {m:'"/dir1,/dir2" - valid',i:'/dir1,/dir2',e:true},
       {m:'"/123" - valid',i:'/111',e:true},
       {m:'"/abc" - valid',i:'/abc',e:true},
@@ -317,6 +319,8 @@ describe('validator', function () {
       {m:'"/dir" - valid',i:'/dir',e:true},
       {m:'"/dir1,dir2" - invalid',i:'/dir1,dir2',e:false},
       {m:'"/dir1,/dir2" - valid',i:'/dir1,/dir2',e:true},
+      {m:'" /dir1,/dir2" - valid',i:' /dir1,/dir2',e:false},
+      {m:'"/dir1, /dir2" - valid',i:' /dir1,/dir2',e:false},
       {m:'"/123" - valid',i:'/111',e:true},
       {m:'"/abc" - valid',i:'/abc',e:true},
       {m:'"/1a2b3c" - valid',i:'/1a2b3c',e:true},
@@ -325,9 +329,8 @@ describe('validator', function () {
       {m:'"[] /1a2b3c" - invalid',i:'[] /1a2b3c',e:false},
       {m:'"[ssd] /1a2b3c" - invalid',i:'[ssd] /1a2b3c',e:false},
       {m:'"[/1a2b3c]" - invalid',i:'[/1a2b3c]',e:false},
-      {m:'"[s]ss /sd" - invalid',i:'[s]ss /sd',e:false}
-
-
+      {m:'"[s]ss /sd" - invalid',i:'[s]ss /sd',e:false},
+      {m:'" [s]ss/sd" - invalid',i:' [s]ss/sd',e:false}
     ];
     tests.forEach(function(test) {
       it(test.m + ' ', function () {