You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by jl...@apache.org on 2015/04/13 21:27:32 UTC

ambari git commit: AMBARI-10448: Add Microsoft SQL Server support for Ambari (jluniya)

Repository: ambari
Updated Branches:
  refs/heads/trunk b0d1c232a -> 9c1c722f0


AMBARI-10448: Add Microsoft SQL Server support for Ambari (jluniya)


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

Branch: refs/heads/trunk
Commit: 9c1c722f0339a8257f4d0b1192fef8be4b8faa68
Parents: b0d1c23
Author: Jayush Luniya <jl...@hortonworks.com>
Authored: Mon Apr 13 12:27:26 2015 -0700
Committer: Jayush Luniya <jl...@hortonworks.com>
Committed: Mon Apr 13 12:27:26 2015 -0700

----------------------------------------------------------------------
 .../TestRepositoryResource.py                   |  1 +
 ambari-server/src/main/python/ambari-server.py  |  4 +-
 .../python/ambari_server/dbConfiguration.py     | 26 +++++-----
 .../ambari_server/dbConfiguration_linux.py      | 50 +++++++++++++++++++-
 .../ambari_server/dbConfiguration_windows.py    | 40 ++++++++--------
 .../python/ambari_server/serverConfiguration.py | 11 +++--
 .../src/test/python/TestAmbariServer.py         | 34 +++++++++----
 .../2.0.6/HBASE/test_hbase_service_check.py     |  1 +
 8 files changed, 121 insertions(+), 46 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/9c1c722f/ambari-agent/src/test/python/resource_management/TestRepositoryResource.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/resource_management/TestRepositoryResource.py b/ambari-agent/src/test/python/resource_management/TestRepositoryResource.py
index 0539d25..82a185a 100644
--- a/ambari-agent/src/test/python/resource_management/TestRepositoryResource.py
+++ b/ambari-agent/src/test/python/resource_management/TestRepositoryResource.py
@@ -276,6 +276,7 @@ class TestRepositoryResource(TestCase):
     @patch.object(OSCheck, "is_suse_family")
     @patch.object(OSCheck, "is_ubuntu_family")
     @patch.object(OSCheck, "is_redhat_family")
+    @patch.object(System, "os_family", new='redhat')
     @patch("resource_management.libraries.providers.repository.File")
     def test_remove_repo_redhat(self, file_mock,
                               is_redhat_family, is_ubuntu_family, is_suse_family):

http://git-wip-us.apache.org/repos/asf/ambari/blob/9c1c722f/ambari-server/src/main/python/ambari-server.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/python/ambari-server.py b/ambari-server/src/main/python/ambari-server.py
index 70c4232..f1f005d 100755
--- a/ambari-server/src/main/python/ambari-server.py
+++ b/ambari-server/src/main/python/ambari-server.py
@@ -343,7 +343,7 @@ def init_parser_options(parser):
                     dest="ldap_sync_users")
   parser.add_option('--groups', default=None, help="LDAP sync groups option.  Specifies the path to a CSV file of group names to be synchronized.",
                     dest="ldap_sync_groups")
-  parser.add_option('--database', default=None, help="Database to use embedded|oracle|mysql|postgres", dest="dbms")
+  parser.add_option('--database', default=None, help="Database to use embedded|oracle|mysql|mssql|postgres", dest="dbms")
   parser.add_option('--databasehost', default=None, help="Hostname of database server", dest="database_host")
   parser.add_option('--databaseport', default=None, help="Database port", dest="database_port")
   parser.add_option('--databasename', default=None, help="Database/Service name or ServiceID",
@@ -357,7 +357,7 @@ def init_parser_options(parser):
   parser.add_option('--jdbc-driver', default=None, help="Specifies the path to the JDBC driver JAR file for the " \
                                                         "database type specified with the --jdbc-db option. Used only with --jdbc-db option.",
                     dest="jdbc_driver")
-  parser.add_option('--jdbc-db', default=None, help="Specifies the database type [postgres|mysql|oracle|hsqldb] for the " \
+  parser.add_option('--jdbc-db', default=None, help="Specifies the database type [postgres|mysql|mssql|oracle|hsqldb] for the " \
                                                     "JDBC driver specified with the --jdbc-driver option. Used only with --jdbc-driver option.",
                     dest="jdbc_db")
   parser.add_option('--cluster-name', default=None, help="Cluster name", dest="cluster_name")

http://git-wip-us.apache.org/repos/asf/ambari/blob/9c1c722f/ambari-server/src/main/python/ambari_server/dbConfiguration.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/python/ambari_server/dbConfiguration.py b/ambari-server/src/main/python/ambari_server/dbConfiguration.py
index 5e26096..363e056 100644
--- a/ambari-server/src/main/python/ambari_server/dbConfiguration.py
+++ b/ambari-server/src/main/python/ambari_server/dbConfiguration.py
@@ -39,8 +39,8 @@ SETUP_DB_CONNECT_ATTEMPTS = 3
 
 USERNAME_PATTERN = "^[a-zA-Z_][a-zA-Z0-9_\-]*$"
 PASSWORD_PATTERN = "^[a-zA-Z0-9_-]*$"
-DATABASE_NAMES = ["postgres", "oracle", "mysql"]
-DATABASE_FULL_NAMES = {"oracle": "Oracle", "mysql": "MySQL", "postgres": "PostgreSQL"}
+DATABASE_NAMES = ["postgres", "oracle", "mysql", "mssql"]
+DATABASE_FULL_NAMES = {"oracle": "Oracle", "mysql": "MySQL", "mssql": "Microsoft SQL Server", "postgres": "PostgreSQL"}
 
 AMBARI_DATABASE_NAME = "ambari"
 AMBARI_DATABASE_TITLE = "ambari"
@@ -282,10 +282,10 @@ class DBMSConfigFactory(object):
 @OsFamilyImpl(os_family=OSConst.WINSRV_FAMILY)
 class DBMSConfigFactoryWindows(DBMSConfigFactory):
   def __init__(self):
-    from ambari_server.dbConfiguration_windows import DATABASE_DBMS_SQLSERVER
+    from ambari_server.dbConfiguration_windows import DATABASE_DBMS_MSSQL
 
     self.DBMS_KEYS_LIST = [
-      DATABASE_DBMS_SQLSERVER
+      DATABASE_DBMS_MSSQL
     ]
 
   def select_dbms(self, options):
@@ -300,8 +300,8 @@ class DBMSConfigFactoryWindows(DBMSConfigFactory):
     #   right now in Windows we only support SQL Server, this argument is not yet used.
     # dbId = additional information, that helps distinguish between various database connections, if applicable
     """
-    from ambari_server.dbConfiguration_windows import createSQLServerConfig
-    return createSQLServerConfig(options, properties, STORAGE_TYPE_REMOTE, dbId)
+    from ambari_server.dbConfiguration_windows import createMSSQLConfig
+    return createMSSQLConfig(options, properties, STORAGE_TYPE_REMOTE, dbId)
 
   def get_supported_dbms(self):
     return self.DBMS_KEYS_LIST
@@ -315,13 +315,14 @@ class DBMSConfigFactoryWindows(DBMSConfigFactory):
 @OsFamilyImpl(os_family=OsFamilyImpl.DEFAULT)
 class DBMSConfigFactoryLinux(DBMSConfigFactory):
   def __init__(self):
-    from ambari_server.dbConfiguration_linux import createPGConfig, createOracleConfig, createMySQLConfig
+    from ambari_server.dbConfiguration_linux import createPGConfig, createOracleConfig, createMySQLConfig, createMSSQLConfig
 
     self.DBMS_KEYS_LIST = [
       'embedded',
       'oracle',
       'mysql',
-      'postgres'
+      'postgres',
+      'mssql'
     ]
 
     self.DRIVER_KEYS_LIST = [
@@ -336,7 +337,8 @@ class DBMSConfigFactoryLinux(DBMSConfigFactory):
       DBMSDesc(self.DBMS_KEYS_LIST[3], STORAGE_TYPE_LOCAL, 'PostgreSQL', 'Embedded', createPGConfig),
       DBMSDesc(self.DBMS_KEYS_LIST[1], STORAGE_TYPE_REMOTE, 'Oracle', '', createOracleConfig),
       DBMSDesc(self.DBMS_KEYS_LIST[2], STORAGE_TYPE_REMOTE, 'MySQL', '', createMySQLConfig),
-      DBMSDesc(self.DBMS_KEYS_LIST[3], STORAGE_TYPE_REMOTE, 'PostgreSQL', '', createPGConfig)
+      DBMSDesc(self.DBMS_KEYS_LIST[3], STORAGE_TYPE_REMOTE, 'PostgreSQL', '', createPGConfig),
+      DBMSDesc(self.DBMS_KEYS_LIST[4], STORAGE_TYPE_REMOTE, 'Microsoft SQL Server', '', createMSSQLConfig)
     ]
 
     self.DBMS_DICT = \
@@ -346,6 +348,8 @@ class DBMSConfigFactoryLinux(DBMSConfigFactory):
       self.DBMS_KEYS_LIST[0] + '-' : 0,
       self.DBMS_KEYS_LIST[2] + '-'  : 2,
       self.DBMS_KEYS_LIST[2] + '-' + STORAGE_TYPE_REMOTE : 2,
+      self.DBMS_KEYS_LIST[4] + '-'  : 4,
+      self.DBMS_KEYS_LIST[4] + '-' + STORAGE_TYPE_REMOTE : 4,
       self.DBMS_KEYS_LIST[1] + '-' : 1,
       self.DBMS_KEYS_LIST[1] + '-' + STORAGE_TYPE_REMOTE : 1,
       self.DBMS_KEYS_LIST[3] + '-' : 3,
@@ -403,7 +407,7 @@ class DBMSConfigFactoryLinux(DBMSConfigFactory):
     # Linux implementation of the factory method. The outcome of the derived implementations
     #  is expected to be a subclass of DBMSConfig.
     # properties = property bag that will ultimately define the type of database. Supported types are
-    #   MySQL, Oracle and PostgreSQL.
+    #   MySQL, MSSQL, Oracle and PostgreSQL.
     # dbId = additional information, that helps distinguish between various database connections, if applicable
     """
 
@@ -440,7 +444,7 @@ class DBMSConfigFactoryLinux(DBMSConfigFactory):
     try:
       def_index = self.DBMS_DICT[dbms_name + "-" + persistence_type]
     except KeyError:
-      # Unsupported database type (e.g. local Oracle or MySQL)
+      # Unsupported database type (e.g. local Oracle, MySQL or MSSQL)
       raise FatalException(15, "Invalid database selection: {0} {1}".format(
           getattr(options, "persistence_type", ""), getattr(options, "options.dbms", "")))
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/9c1c722f/ambari-server/src/main/python/ambari_server/dbConfiguration_linux.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/python/ambari_server/dbConfiguration_linux.py b/ambari-server/src/main/python/ambari_server/dbConfiguration_linux.py
index e59f1ed..e85454b 100644
--- a/ambari-server/src/main/python/ambari_server/dbConfiguration_linux.py
+++ b/ambari-server/src/main/python/ambari_server/dbConfiguration_linux.py
@@ -105,7 +105,7 @@ class LinuxDBMSConfig(DBMSConfig):
       if not self._configure_database_name():
         return False
 
-      # Username is common for Oracle/MySQL/Postgres
+      # Username is common for Oracle/MySQL/MSSQL/Postgres
       self.database_username = get_validated_string_input(
           'Username (' + self.database_username + '): ',
           self.database_username,
@@ -868,3 +868,51 @@ class MySQLConfig(LinuxDBMSConfig):
 
 def createMySQLConfig(options, properties, storage_type, dbId):
   return MySQLConfig(options, properties, storage_type)
+
+
+class MSSQLConfig(LinuxDBMSConfig):
+  def __init__(self, options, properties, storage_type):
+    super(MSSQLConfig, self).__init__(options, properties, storage_type)
+
+    #Init the database configuration data here, if any
+    self.dbms = "mssql"
+    self.dbms_full_name = "Microsoft SQL Server"
+    self.driver_class_name = "com.microsoft.sqlserver.jdbc.SQLServerDriver"
+    self.driver_file_name = "sqljdbc4.jar"
+    self.driver_symlink_name = "mssql-jdbc-driver.jar"
+
+    self.database_storage_name = "Database"
+    self.database_port = DBMSConfig._init_member_with_prop_default(options, "database_port",
+                                                                   properties, JDBC_PORT_PROPERTY, "1433")
+
+    self.database_url_pattern = "jdbc:sqlserver://{0}:{1};databaseName={2}"
+    self.database_url_pattern_alt = "jdbc:sqlserver://{0}:{1};databaseName={2}"
+
+    self.JDBC_DRIVER_INSTALL_MSG = 'Before starting Ambari Server, ' \
+                                   'you must copy the {0} JDBC driver JAR file to {1}.'.format(
+      self.dbms_full_name, configDefaults.JAVA_SHARE_PATH)
+
+    self.init_script_file = "/var/lib/ambari-server/resources/Ambari-DDL-SQLServer-CREATE.sql"
+    self.drop_tables_script_file = "/var/lib/ambari-server/resources/Ambari-DDL-SQLServer-DROP.sql"
+    self.client_tool_usage_pattern = ''
+
+  #
+  # Private implementation
+  #
+  def _reset_remote_database(self):
+    super(MSSQLConfig, self)._reset_remote_database()
+
+    raise NonFatalException("Please replace '*' symbols with password before running DDL`s!")
+
+  def _is_jdbc_driver_installed(self, properties):
+    return LinuxDBMSConfig._find_jdbc_driver("*sqljdbc*.jar")
+
+  def _configure_database_name(self):
+    self.database_name = LinuxDBMSConfig._get_validated_db_name(self.database_storage_name, self.database_name)
+    return True
+
+  def _get_remote_script_line(self, scriptFile):
+    return scriptFile
+
+def createMSSQLConfig(options, properties, storage_type, dbId):
+  return MSSQLConfig(options, properties, storage_type)

http://git-wip-us.apache.org/repos/asf/ambari/blob/9c1c722f/ambari-server/src/main/python/ambari_server/dbConfiguration_windows.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/python/ambari_server/dbConfiguration_windows.py b/ambari-server/src/main/python/ambari_server/dbConfiguration_windows.py
index f34caeb..04db2af 100644
--- a/ambari-server/src/main/python/ambari_server/dbConfiguration_windows.py
+++ b/ambari-server/src/main/python/ambari_server/dbConfiguration_windows.py
@@ -40,27 +40,27 @@ from ambari_server.userInput import get_validated_string_input
 
 
 # SQL Server settings
-DATABASE_DBMS_SQLSERVER = "sqlserver"
-DATABASE_DRIVER_NAME_SQLSERVER = "com.microsoft.sqlserver.jdbc.SQLServerDriver"
-DATABASE_SERVER_SQLSERVER_DEFAULT = "localhost\\SQLEXPRESS"
+DATABASE_DBMS_MSSQL = "mssql"
+DATABASE_DRIVER_NAME_MSSQL = "com.microsoft.sqlserver.jdbc.SQLServerDriver"
+DATABASE_SERVER_MSSQL_DEFAULT = "localhost\\SQLEXPRESS"
 
-class SqlServerAuthenticationKeys(DbAuthenticationKeys):
+class MSSQLAuthenticationKeys(DbAuthenticationKeys):
   def __init__(self, i_integrated_auth_key, i_user_name_key, i_password_key, i_password_alias, i_password_filename):
     self.integrated_auth_key = i_integrated_auth_key
     DbAuthenticationKeys.__init__(self, i_user_name_key, i_password_key, i_password_alias, i_password_filename)
 
 #
-# SQL Server configuration and setup
+# Microsoft SQL Server configuration and setup
 #
-class SQLServerConfig(DBMSConfig):
+class MSSQLConfig(DBMSConfig):
   def __init__(self, options, properties, storage_type):
-    super(SQLServerConfig, self).__init__(options, properties, storage_type)
+    super(MSSQLConfig, self).__init__(options, properties, storage_type)
 
     """
     #Just load the defaults. The derived classes will be able to modify them later
     """
-    self.dbms = DATABASE_DBMS_SQLSERVER
-    self.driver_class_name = DATABASE_DRIVER_NAME_SQLSERVER
+    self.dbms = DATABASE_DBMS_MSSQL
+    self.driver_class_name = DATABASE_DRIVER_NAME_MSSQL
 
     self.JDBC_DRIVER_INSTALL_MSG = 'Before starting Ambari Server, you must install the SQL Server JDBC driver.'
 
@@ -72,7 +72,7 @@ class SQLServerConfig(DBMSConfig):
       else:
         self.database_host = compress_backslashes(self.database_host)
     except:
-      self.database_host = DATABASE_SERVER_SQLSERVER_DEFAULT
+      self.database_host = DATABASE_SERVER_MSSQL_DEFAULT
       pass
     self.database_port = DBMSConfig._init_member_with_prop_default(options, "database_port",
                                                                    properties, self.dbPropKeys.port_key, "1433")
@@ -287,10 +287,10 @@ class SQLServerConfig(DBMSConfig):
     os.environ[self.env_var_db_owner] = 'hadoop'
 
     # Don't create the database, assume it already exists. Just clear out the known tables structure
-    SQLServerConfig._execute_db_script(self.database_host, self.drop_tables_script_file)
+    MSSQLConfig._execute_db_script(self.database_host, self.drop_tables_script_file)
 
     # Init DB
-    SQLServerConfig._execute_db_script(self.database_host, self.init_script_file)
+    MSSQLConfig._execute_db_script(self.database_host, self.init_script_file)
     pass
 
   @staticmethod
@@ -305,9 +305,9 @@ class SQLServerConfig(DBMSConfig):
     pass
 
 #
-# SQL Server Ambari database configuration and setup
+# Microsoft SQL Server Ambari database configuration and setup
 #
-class SQLServerAmbariDBConfig(SQLServerConfig):
+class MSSQLAmbariDBConfig(MSSQLConfig):
   def __init__(self, options, properties, storage_type):
     self.dbPropKeys = DbPropKeys(
       JDBC_DATABASE_PROPERTY,
@@ -316,7 +316,7 @@ class SQLServerAmbariDBConfig(SQLServerConfig):
       JDBC_PORT_PROPERTY,
       JDBC_DATABASE_NAME_PROPERTY,
       JDBC_URL_PROPERTY)
-    self.dbAuthKeys = SqlServerAuthenticationKeys(
+    self.dbAuthKeys = MSSQLAuthenticationKeys(
       JDBC_USE_INTEGRATED_AUTH_PROPERTY,
       JDBC_USER_NAME_PROPERTY,
       JDBC_PASSWORD_PROPERTY,
@@ -324,7 +324,7 @@ class SQLServerAmbariDBConfig(SQLServerConfig):
       JDBC_PASSWORD_FILENAME
     )
 
-    super(SQLServerAmbariDBConfig, self).__init__(options, properties, storage_type)
+    super(MSSQLAmbariDBConfig, self).__init__(options, properties, storage_type)
 
     if self.database_name is None or self.database_name is "":
       self.database_name = AMBARI_DATABASE_NAME
@@ -342,14 +342,14 @@ class SQLServerAmbariDBConfig(SQLServerConfig):
         "resources" + os.path.sep + "Ambari-DDL-SQLServer-DROP.sql"))
 
   def _setup_remote_server(self, properties):
-    super(SQLServerAmbariDBConfig, self)._setup_remote_server(properties)
+    super(MSSQLAmbariDBConfig, self)._setup_remote_server(properties)
 
     properties.process_pair(JDBC_RCA_DRIVER_PROPERTY, self.driver_class_name)
     properties.process_pair(JDBC_RCA_HOSTNAME_PROPERTY, ensure_double_backslashes(self.database_host))
     if self.database_port is not None and self.database_port != "":
       properties.process_pair(JDBC_RCA_PORT_PROPERTY, self.database_port)
 
-    authKeys = SqlServerAuthenticationKeys(
+    authKeys = MSSQLAuthenticationKeys(
       JDBC_RCA_USE_INTEGRATED_AUTH_PROPERTY,
       JDBC_RCA_USER_NAME_PROPERTY,
       JDBC_RCA_PASSWORD_FILE_PROPERTY,
@@ -362,5 +362,5 @@ class SQLServerAmbariDBConfig(SQLServerConfig):
     pass
 
 
-def createSQLServerConfig(options, properties, storage_type, dbId):
-  return SQLServerAmbariDBConfig(options, properties, storage_type)
+def createMSSQLConfig(options, properties, storage_type, dbId):
+  return MSSQLAmbariDBConfig(options, properties, storage_type)

http://git-wip-us.apache.org/repos/asf/ambari/blob/9c1c722f/ambari-server/src/main/python/ambari_server/serverConfiguration.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/python/ambari_server/serverConfiguration.py b/ambari-server/src/main/python/ambari_server/serverConfiguration.py
index c8eebbf..c13202c 100644
--- a/ambari-server/src/main/python/ambari_server/serverConfiguration.py
+++ b/ambari-server/src/main/python/ambari_server/serverConfiguration.py
@@ -81,11 +81,11 @@ JDK_NAME_PROPERTY = "jdk.name"
 JCE_NAME_PROPERTY = "jce.name"
 
 # JDBC
-JDBC_PATTERNS = {"oracle": "*ojdbc*.jar", "mysql": "*mysql*.jar"}
+JDBC_PATTERNS = {"oracle": "*ojdbc*.jar", "mysql": "*mysql*.jar", "mssql": "*sqljdbc*.jar"}
 
 #TODO property used incorrectly in local case, it was meant to be dbms name, not postgres database name,
 # has workaround for now, as we don't need dbms name if persistence_type=local
-JDBC_DATABASE_PROPERTY = "server.jdbc.database"                 # E.g., embedded|oracle|mysql|postgres|sqlserver
+JDBC_DATABASE_PROPERTY = "server.jdbc.database"                 # E.g., embedded|oracle|mysql|mssql|postgres
 JDBC_DATABASE_NAME_PROPERTY = "server.jdbc.database_name"       # E.g., ambari. Not used on Windows.
 JDBC_HOSTNAME_PROPERTY = "server.jdbc.hostname"
 JDBC_PORT_PROPERTY = "server.jdbc.port"
@@ -491,6 +491,8 @@ def get_db_type(properties):
       db_type = "oracle"
     elif "mysql" in jdbc_url:
       db_type = "mysql"
+    elif "sqlserver" in jdbc_url:
+      db_type = "mssql"
     elif "derby" in jdbc_url:
       db_type = "derby"
 
@@ -507,7 +509,7 @@ def check_database_name_property(upgrade=False):
     return -1
 
   version = get_ambari_version(properties)
-  if upgrade and (properties[JDBC_DATABASE_PROPERTY] not in ["postgres", "oracle", "mysql", "derby"]
+  if upgrade and (properties[JDBC_DATABASE_PROPERTY] not in ["postgres", "oracle", "mysql", "mssql", "derby"]
                     or properties.has_key(JDBC_RCA_SCHEMA_PROPERTY)):
     # This code exists for historic reasons in which property names changed from Ambari 1.6.1 to 1.7.0
     persistence_type = properties[PERSISTENCE_TYPE_PROPERTY]
@@ -518,7 +520,7 @@ def check_database_name_property(upgrade=False):
 
       # If DB type is missing, attempt to reconstruct it from the JDBC URL
       db_type = properties[JDBC_DATABASE_PROPERTY]
-      if db_type is None or db_type.strip().lower() not in ["postgres", "oracle", "mysql", "derby"]:
+      if db_type is None or db_type.strip().lower() not in ["postgres", "oracle", "mysql", "mssql", "derby"]:
         db_type = get_db_type(properties)
         if db_type:
           write_property(JDBC_DATABASE_PROPERTY, db_type)
@@ -1001,6 +1003,7 @@ def get_share_jars():
   share_jars = ""
   file_list = []
   file_list.extend(glob.glob(configDefaults.JAVA_SHARE_PATH + os.sep + "*mysql*"))
+  file_list.extend(glob.glob(configDefaults.JAVA_SHARE_PATH + os.sep + "*sqljdbc*"))
   file_list.extend(glob.glob(configDefaults.JAVA_SHARE_PATH + os.sep + "*ojdbc*"))
   if len(file_list) > 0:
     share_jars = string.join(file_list, os.pathsep)

http://git-wip-us.apache.org/repos/asf/ambari/blob/9c1c722f/ambari-server/src/test/python/TestAmbariServer.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/TestAmbariServer.py b/ambari-server/src/test/python/TestAmbariServer.py
index 35cd5a5..17e8aea 100644
--- a/ambari-server/src/test/python/TestAmbariServer.py
+++ b/ambari-server/src/test/python/TestAmbariServer.py
@@ -921,7 +921,7 @@ class TestAmbariServer(TestCase):
   @patch("ambari_server.serverConfiguration.print_info_msg")
   def test_get_share_jars(self, printInfoMsg_mock, globMock):
     globMock.return_value = ["one", "two"]
-    expected = "one:two:one:two"
+    expected = "one:two:one:two:one:two"
     result = get_share_jars()
     self.assertEqual(expected, result)
     globMock.return_value = []
@@ -2593,8 +2593,9 @@ MIIFHjCCAwYCCQDpHKOBI+Lt0zANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJV
     oracle_values = [hostname, port, oracle_service, oracle_service_name, user_name]
     mysql_values = [hostname, port, db_name, user_name]
     postgres_external_values = [hostname, port, db_name, postgres_schema, user_name]
+    mssql_values = [hostname, port, db_name, user_name]
 
-    list_of_return_values = postgres_embedded_values + oracle_values + mysql_values + postgres_external_values
+    list_of_return_values = postgres_embedded_values + oracle_values + mysql_values + postgres_external_values + mssql_values
     list_of_return_values = list_of_return_values[::-1]       # Reverse the list since the input will be popped
 
     def side_effect(*args, **kwargs):
@@ -2608,7 +2609,7 @@ MIIFHjCCAwYCCQDpHKOBI+Lt0zANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJV
     os.environ[AMBARI_CONF_VAR] = tempdir
     prop_file = os.path.join(tempdir, "ambari.properties")
 
-    for i in range(0, 4):
+    for i in range(0, 5):
       # Use the expected path of the ambari.properties file to delete it if it exists, and then create a new one
       # during each use case.
       if os.path.exists(prop_file):
@@ -2665,6 +2666,11 @@ MIIFHjCCAwYCCQDpHKOBI+Lt0zANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJV
         self.assertEqual(properties[JDBC_DATABASE_NAME_PROPERTY], db_name)
         self.assertEqual(properties[JDBC_POSTGRES_SCHEMA_PROPERTY], postgres_schema)
         self.assertEqual(properties[PERSISTENCE_TYPE_PROPERTY], "remote")
+      elif i == 4:
+        # MSSQL
+        self.assertEqual(properties[JDBC_DATABASE_PROPERTY], "mssql")
+        self.assertFalse(JDBC_POSTGRES_SCHEMA_PROPERTY in properties.propertyNames())
+        self.assertEqual(properties[PERSISTENCE_TYPE_PROPERTY], "remote")
     pass
 
   @patch.object(os.path, "exists")
@@ -3893,6 +3899,18 @@ MIIFHjCCAwYCCQDpHKOBI+Lt0zANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJV
       fail = True
     self.assertTrue(fail)
 
+    # test getAmbariProperties failed
+    args.jdbc_db = "mssql"
+    get_ambari_properties_mock.return_value = -1
+    fail = False
+
+    try:
+      proceedJDBCProperties(args)
+    except FatalException as e:
+      self.assertEquals("Error getting ambari properties", e.reason)
+      fail = True
+    self.assertTrue(fail)
+
     # test get resource dir param failed
     args.jdbc_db = "oracle"
     p = MagicMock()
@@ -4119,7 +4137,7 @@ MIIFHjCCAwYCCQDpHKOBI+Lt0zANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJV
     get_ambari_properties_mock.return_value = properties
     get_ambari_properties_3_mock.side_effect = get_ambari_properties_2_mock.side_effect = [properties, properties2, properties2]
 
-    isfile_mock.side_effect = [False, True]
+    isfile_mock.side_effect = [False, True, False]
 
     try:
       upgrade(args)
@@ -4325,7 +4343,7 @@ MIIFHjCCAwYCCQDpHKOBI+Lt0zANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJV
       get_ambari_properties_mock.return_value = props
     exists_mock.return_value = True
     lexists_mock.return_value = True
-    isfile_mock.side_effect = [True, False]
+    isfile_mock.side_effect = [True, False, False]
 
     upgrade(args)
     self.assertTrue(os_remove_mock.called)
@@ -5052,7 +5070,7 @@ MIIFHjCCAwYCCQDpHKOBI+Lt0zANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJV
 
     isdir_mock.return_value = True
 
-    isfile_mock.side_effect = [True, False]
+    isfile_mock.side_effect = [True, False, False]
 
     del args.database_index
     del args.persistence_type
@@ -5074,7 +5092,7 @@ MIIFHjCCAwYCCQDpHKOBI+Lt0zANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJV
     get_ambari_properties_mock.reset_mock()
     os_symlink_mock.reset_mock()
 
-    isfile_mock.side_effect = [False, False]
+    isfile_mock.side_effect = [False, False, False]
 
     check_jdbc_drivers(args)
 
@@ -6340,7 +6358,7 @@ MIIFHjCCAwYCCQDpHKOBI+Lt0zANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJV
   @patch("ambari_server.serverConfiguration.get_ambari_version")
   def test_check_database_name_property(self, get_ambari_version_mock, get_ambari_properties_mock, write_property_mock):
     parser = OptionParser()
-    parser.add_option('--database', default=None, help="Database to use embedded|oracle|mysql|postgres", dest="dbms")
+    parser.add_option('--database', default=None, help="Database to use embedded|oracle|mysql|mssql|postgres", dest="dbms")
     args = parser.parse_args()
 
     # negative case

http://git-wip-us.apache.org/repos/asf/ambari/blob/9c1c722f/ambari-server/src/test/python/stacks/2.0.6/HBASE/test_hbase_service_check.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.0.6/HBASE/test_hbase_service_check.py b/ambari-server/src/test/python/stacks/2.0.6/HBASE/test_hbase_service_check.py
index 8470269..f08a31a 100644
--- a/ambari-server/src/test/python/stacks/2.0.6/HBASE/test_hbase_service_check.py
+++ b/ambari-server/src/test/python/stacks/2.0.6/HBASE/test_hbase_service_check.py
@@ -22,6 +22,7 @@ from stacks.utils.RMFTestCase import *
 import datetime
 import  resource_management.libraries.functions
 
+@patch("platform.linux_distribution", new = MagicMock(return_value="Linux"))
 @patch.object(resource_management.libraries.functions, "get_unique_id_and_date", new = MagicMock(return_value=''))
 class TestServiceCheck(RMFTestCase):
   COMMON_SERVICES_PACKAGE_DIR = "HBASE/0.96.0.2.0/package"