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/12/22 15:48:35 UTC

ambari git commit: AMBARI-14465. When the JDBC URL for Oracle contains a non-standard port, some changes cannot be made via Smart Configs UI for Hive

Repository: ambari
Updated Branches:
  refs/heads/branch-2.2 8d7951e2e -> 3125fcfc3


AMBARI-14465. When the JDBC URL for Oracle contains a non-standard port, some changes cannot be made via Smart Configs UI for Hive


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

Branch: refs/heads/branch-2.2
Commit: 3125fcfc3f1ff45006493202cb2d0dd47a2f6950
Parents: 8d7951e
Author: Alex Antonenko <hi...@gmail.com>
Authored: Tue Dec 22 16:28:06 2015 +0200
Committer: Alex Antonenko <hi...@gmail.com>
Committed: Tue Dec 22 16:48:31 2015 +0200

----------------------------------------------------------------------
 ambari-web/app/utils/configs/database.js       | 154 ++++++++++++++++----
 ambari-web/test/utils/configs/database_test.js | 113 +++++++++++---
 2 files changed, 218 insertions(+), 49 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/3125fcfc/ambari-web/app/utils/configs/database.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/configs/database.js b/ambari-web/app/utils/configs/database.js
index 82ad7bb..d421b9a 100644
--- a/ambari-web/app/utils/configs/database.js
+++ b/ambari-web/app/utils/configs/database.js
@@ -18,6 +18,14 @@
 
 var validators = require('utils/validator');
 var stringUtils = require('utils/string_utils');
+
+/**
+ * @typedef {parsedJDBCUrl}
+ * @type {object}
+ * @property {string} dbType alias name by type of database @see utils/configs/database.DB_UI_TYPE_ALIAS
+ * @property {string} location parsed host name
+ */
+
 /**
  * Helper methods to process database values and properties
  * @module utils/configs/database
@@ -64,6 +72,15 @@ module.exports = {
     sqla: 'jdbc:sqlanywhere:host={0};database={1}'
   },
 
+  DB_UI_TYPE_ALIAS: {
+    mysql: 'mysql',
+    sqlserver: 'mssql',
+    postgresql: 'postgres',
+    derby: 'derby',
+    oracle: 'oracle',
+    sqlanywhere: 'sqla'
+  },
+
   /**
    * Setup database related properties.
    *
@@ -99,10 +116,6 @@ module.exports = {
     });
   },
 
-  isValidHostname: function(value) {
-    return validators.isHostname(value) || validators.isIpAddress(value);
-  },
-
   /**
    * Add UI specific property to serviceConfigObject if it does not exist, and update value for existed property.
    * This code affects properties related to `_host` and `_database` which are hardcoded on UI.
@@ -142,22 +155,58 @@ module.exports = {
   },
 
   /**
-   * Get database location from jdbc url value.
+   * Get database location from jdbc url value
    *
    * @method getDBLocationFromJDBC
    * @param {string} jdbcUrl - url to parse
-   * @returns {string|null} 
+   * @returns {string|null}
    */
   getDBLocationFromJDBC: function(jdbcUrl) {
-    var self = this;
-    var matches = Em.keys(this.DB_JDBC_PATTERNS).map(function(key) {
-      var reg = new RegExp(self.DB_JDBC_PATTERNS[key].format('(.*)', '(.*)'));
-      return jdbcUrl.match(reg);
-    }).compact();
+    var dbProvider = this.getJDBCProviderName(jdbcUrl),
+        protocol = this._makeProtocol(dbProvider),
+        pattern = /^\/\//,
+        url;
+    if (!this.isSupportedProvider(dbProvider)) {
+      return '';
+    }
+    if (dbProvider === 'derby') {
+      return this.getDerbyPath(jdbcUrl);
+    }
+    url = "http://" + jdbcUrl.replace(protocol, '').replace(pattern, '');
+    if (dbProvider === 'sqlserver') {
+      url = url.split(';')[0];
+    }
+    if (dbProvider === 'oracle') {
+      var matches = jdbcUrl.replace(protocol, '').match(/@(?:\/?\/?)(.+)/);
+      if (matches.length) {
+        var result = Em.getWithDefault(matches, '1', '').split(':')[0];
+        return result === '{0}' ? '' : result;
+      }
+      return '';
+    }
+    if (dbProvider === 'sqlanywhere') {
+      url = url.split(';').map(function(i) {
+        return /host=/.test(i) ? i.replace('host=', '').replace('http://', '') : null;
+      }).compact()[0];
+      return this.getHostNameByUrl('http://' + url);
+    }
+    url = url.split(':').slice(0, 2).join(':');
+    return this.getHostNameByUrl(url);
+  },
+
+
+  /**
+   * Return derby database path by jdbcUrl
+   *
+   * @param {string} jdbcUrl
+   * @return {string} database path
+   */
+  getDerbyPath: function(jdbcUrl) {
+    var matches = jdbcUrl.match(new RegExp(this.DB_JDBC_PATTERNS['derby'].format('(.*)', '(.*)')));
     if (matches.length) {
-      var dbLocation = Em.get(matches, '0.1');
+      var dbLocation = Em.getWithDefault(matches, '1', '');
       if (dbLocation.startsWith('${')) {
-        return Em.getWithDefault(matches, '0.0', '').match(/\${[^}]+}/)[0];
+        return Em.getWithDefault(matches, '0', '').match(/\${[^}]+}/)[0];
       }
       return dbLocation != '{0}' ? dbLocation : null;
     } else {
@@ -165,27 +214,74 @@ module.exports = {
     }
   },
 
+  /**
+   * Returns host name by url input
+   *
+   * @param {string} url
+   * @returns {string} host name
+   */
+  getHostNameByUrl: function(url) {
+    var link = document.createElement('a');
+    link.href = url;
+    var hostName = link.hostname;
+    link = null;
+    return hostName;
+  },
+
+  _makeProtocol: function(dbProvider) {
+    var protocol = 'jdbc:' + dbProvider + ':';
+    if (dbProvider === 'oracle') {
+      return protocol + 'thin:';
+    }
+    return protocol;
+  },
+
+  /**
+   * Returns provider name from jdbcUrl
+   *
+   * @param {string} jdbcUrl
+   * @returns {string} provider name e.g. `jdbc:some_provider:another-opt//additional` -> `some_provider`
+   */
+  getJDBCProviderName: function(jdbcUrl) {
+    return jdbcUrl.split(':')[1];
+  },
+
+  /**
+   * Returns true when provider supported by UI.
+   *
+   * @returns {boolean}
+   */
+  isSupportedProvider: function(dbProvider) {
+    return !!(this.DB_UI_TYPE_ALIAS[dbProvider]);
+  },
+
+  /**
+   * Determines alias value (DB_UI_TYPE_ALIAS attribute value) by provider name
+   *
+   * @param {string} dbProvider provider name parsed from jdbcUrl e,g. from `jdbc:mysql://` -> `mysql`
+   * @returns {string} alias value used on UI.
+   */
+  getJDBCAlias: function(dbProvider) {
+    return this.DB_UI_TYPE_ALIAS[dbProvider];
+  },
+
+  /**
+   * Returns parsed info from jdbcUrl connection string
+   *
+   * @param {string} jdbcUrl
+   * @returns {parsedJDBCUrl}
+   */
   parseJdbcUrl: function(jdbcUrl) {
-    var self = this;
     var result = {
       dbType: null,
-      location: null,
-      databaseName: null
+      location: null
     };
-    var dbName;
-
-    result.dbType = Em.keys(this.DB_JDBC_PATTERNS).filter(function(key) {
-      var scheme = self.DB_JDBC_PATTERNS[key].match(/^jdbc:(\w+):/)[1];
-      return new RegExp('jdbc:' + scheme).test(jdbcUrl);
-    })[0];
-
-    result.location = this.getDBLocationFromJDBC(jdbcUrl);
-    if (!jdbcUrl.endsWith('{1}')) {
-      dbName = jdbcUrl.replace(new RegExp(this.DB_JDBC_PATTERNS[result.dbType].format(stringUtils.escapeRegExp(result.location),'')), '');
-      if (dbName) {
-        result.databaseName = dbName.split(/[;|?]/)[0];
-      }
+    if (jdbcUrl === '') {
+      return result;
     }
+    result.dbType = this.getJDBCAlias(this.getJDBCProviderName(jdbcUrl)) || null;
+    result.location = this.getDBLocationFromJDBC(jdbcUrl);
     return result;
   }
+
 };

http://git-wip-us.apache.org/repos/asf/ambari/blob/3125fcfc/ambari-web/test/utils/configs/database_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/utils/configs/database_test.js b/ambari-web/test/utils/configs/database_test.js
index 85ed35c..e5f9d26 100644
--- a/ambari-web/test/utils/configs/database_test.js
+++ b/ambari-web/test/utils/configs/database_test.js
@@ -43,6 +43,10 @@ describe('Database Utils', function() {
         e: '127.0.0.1'
       },
       {
+        jdbcUrl: 'jdbc:sqlserver://127.0.0.1:3030;databaseName=some-db;integratedSecurity=true',
+        e: '127.0.0.1'
+      },
+      {
         jdbcUrl: 'jdbc:oracle:thin:@//localhost.com:1521/someDb',
         e: 'localhost.com'
       },
@@ -51,8 +55,16 @@ describe('Database Utils', function() {
         e: 'ec2-52-5-27-33.compute-1.amazonaws.com'
       },
       {
+        jdbcUrl: 'jdbc:oracle:thin:@ec2-52-5-27-33.compute-1.amazonaws.com:3301:ORCL',
+        e: 'ec2-52-5-27-33.compute-1.amazonaws.com'
+      },
+      {
         jdbcUrl: 'jdbc:oracle:thin:@//{0}:1521/{1}',
-        e: null
+        e: ""
+      },
+      {
+        jdbcUrl: 'jdbc:oracl:thin:@//some.com:1521/some-db',
+        e: ""
       }
     ].forEach(function(test) {
       it('when jdbc url is ' + test.jdbcUrl + ' host name is ' + test.e, function() {
@@ -67,77 +79,138 @@ describe('Database Utils', function() {
         jdbcUrl: 'jdbc:mysql://localhost/somedb',
         e: {
           dbType: 'mysql',
-          location: 'localhost',
-          databaseName: 'somedb'
+          location: 'localhost'
         }
       },
       {
         jdbcUrl: 'jdbc:postgresql://some.hostname.com:5432/somedb',
         e: {
           dbType: 'postgres',
-          location: 'some.hostname.com',
-          databaseName: 'somedb'
+          location: 'some.hostname.com'
+        }
+      },
+      {
+        jdbcUrl: 'jdbc:postgresql://some.hostname.com:1111/somedb',
+        e: {
+          dbType: 'postgres',
+          location: 'some.hostname.com'
         }
       },
       {
         jdbcUrl: 'jdbc:derby:/some/dir/another_dir/somedb',
         e: {
           dbType: 'derby',
-          location: '/some/dir/another_dir',
-          databaseName: 'somedb'
+          location: '/some/dir/another_dir'
         }
       },
       {
         jdbcUrl: 'jdbc:derby:${oozie-env/data-dir}/${oozie-env/database_name}-db',
         e: {
           dbType: 'derby',
-          location: '${oozie-env/data-dir}',
-          databaseName: '${oozie-env/database_name}-db'
+          location: '${oozie-env/data-dir}'
         }
       },
       {
         jdbcUrl: 'jdbc:derby:${oozie.data.dir}/${oozie.db.schema.name}-db;create=true',
         e: {
           dbType: 'derby',
-          location: '${oozie.data.dir}',
-          databaseName: '${oozie.db.schema.name}-db'
+          location: '${oozie.data.dir}'
         }
       },
       {
         jdbcUrl: 'jdbc:sqlserver://127.0.0.1;databaseName=some-db;integratedSecurity=true',
         e: {
           dbType: 'mssql',
-          location: '127.0.0.1',
-          databaseName: 'some-db'
+          location: '127.0.0.1'
+        }
+      },
+      {
+        jdbcUrl: 'jdbc:sqlserver://127.0.0.1:3011;databaseName=some-db;integratedSecurity=true',
+        e: {
+          dbType: 'mssql',
+          location: '127.0.0.1'
         }
       },
       {
         jdbcUrl: 'jdbc:oracle:thin:@//localhost.com:1521/someDb',
         e: {
           dbType: 'oracle',
-          location: 'localhost.com',
-          databaseName: 'someDb'
+          location: 'localhost.com'
         }
       },
       {
         jdbcUrl: 'jdbc:oracle:thin:@localhost.com:1521:someDb',
         e: {
           dbType: 'oracle',
-          location: 'localhost.com',
-          databaseName: 'someDb'
+          location: 'localhost.com'
         }
       },
       {
         jdbcUrl: 'jdbc:oracle:thin:@//{0}:1521/{1}',
         e: {
           dbType: 'oracle',
-          location: null,
-          databaseName: null
+          location: ""
+        }
+      },
+      {
+        jdbcUrl: 'jdbc:oracle:thin:@//localhost:3301/somedb',
+        e: {
+          dbType: 'oracle',
+          location: 'localhost'
+        }
+      },
+      {
+        jdbcUrl: 'jdbc:oracle:thin:@localhost:3302/somedb',
+        e: {
+          dbType: 'oracle',
+          location: 'localhost'
+        }
+      },
+      {
+        jdbcUrl: 'jdbc:sqlanywhere:host=some.com;database=somedb',
+        e: {
+          dbType: 'sqla',
+          location: 'some.com'
+        }
+      },
+      {
+        jdbcUrl: 'jdbc:sqlanywhere:host=some.com:333;database=somedb',
+        e: {
+          dbType: 'sqla',
+          location: 'some.com'
+        }
+      },
+      {
+        jdbcUrl: 'jdbc:sqlanywhere:database=somedb;host=some.com:333',
+        e: {
+          dbType: 'sqla',
+          location: 'some.com'
+        }
+      },
+      {
+        jdbcUrl: 'jdbc:sqlanywhere:database=somedb;host=some2.com:333;someadditional=some_param',
+        e: {
+          dbType: 'sqla',
+          location: 'some2.com'
+        }
+      },
+      {
+        jdbcUrl: 'jdbc:oracle:thin:scott/tiger@myhost:1521:orcl',
+        e: {
+          dbType: 'oracle',
+          location: 'myhost'
+        }
+      },
+      {
+        jdbcUrl: 'jdbc:custom:custom/@@@',
+        e: {
+          dbType: null,
+          location: ''
         }
       }
     ].forEach(function(test) {
       it('when jdbc url is ' + test.jdbcUrl + ' result is ' + JSON.stringify(test.e), function() {
-        expect(dbUtils.parseJdbcUrl(test.jdbcUrl)).to.be.eql(test.e);
+        expect(dbUtils.parseJdbcUrl(test.jdbcUrl)).to.be.deep.eql(test.e);
       });
     });
   });