Repository: ambari Updated Branches: refs/heads/branch-feature-AMBARI-18456 f0da4fa49 -> 817aed4bd
AMBARI-18469. Fix custom jdbc functionality for ambari-server setup.(vbrodetskyi) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/05e65e29 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/05e65e29 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/05e65e29 Branch: refs/heads/branch-feature-AMBARI-18456 Commit: 05e65e297a09e1498a8ee75fd55d059c00f99976 Parents: 20ce57b Author: Vitaly Brodetskyi <[email protected]> Authored: Wed Sep 28 09:26:32 2016 +0300 Committer: Vitaly Brodetskyi <[email protected]> Committed: Wed Sep 28 09:26:32 2016 +0300 ---------------------------------------------------------------------- .../python/ambari_server/dbConfiguration.py | 52 +++++++-- .../src/test/python/TestAmbariServer.py | 107 +++++++------------ 2 files changed, 79 insertions(+), 80 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/05e65e29/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 ede257f..1d54dce 100644 --- a/ambari-server/src/main/python/ambari_server/dbConfiguration.py +++ b/ambari-server/src/main/python/ambari_server/dbConfiguration.py @@ -19,17 +19,19 @@ limitations under the License. ''' import glob import os +import shutil from ambari_commons import OSConst, OSCheck from ambari_commons.exceptions import FatalException from ambari_commons.logging_utils import get_silent, print_error_msg, print_info_msg, print_warning_msg, set_silent from ambari_commons.os_family_impl import OsFamilyImpl from ambari_commons.str_utils import cbool +from ambari_server.serverClassPath import JDBC_DRIVER_PATH_PROPERTY from ambari_server.serverConfiguration import decrypt_password_for_alias, get_ambari_properties, get_is_secure, \ get_resources_location, get_value_from_properties, is_alias_string, \ JDBC_PASSWORD_PROPERTY, JDBC_RCA_PASSWORD_ALIAS, PRESS_ENTER_MSG, DEFAULT_DBMS_PROPERTY, JDBC_DATABASE_PROPERTY, \ - PERSISTENCE_TYPE_PROPERTY -from ambari_server.userInput import get_validated_string_input + PERSISTENCE_TYPE_PROPERTY, update_properties, configDefaults +from ambari_server.userInput import get_YN_input, get_validated_string_input #Database settings @@ -160,14 +162,46 @@ class DBMSConfig(object): pass def ensure_jdbc_driver_installed(self, properties): - (result, msg) = self._prompt_jdbc_driver_install(properties) - if result == -1: - print_error_msg(msg) - raise FatalException(-1, msg) + server_jdbc_path = properties.get_property(JDBC_DRIVER_PATH_PROPERTY) + if server_jdbc_path and os.path.isfile(server_jdbc_path): + return True + + default_driver_path = self._get_default_driver_path(properties) + if default_driver_path and os.path.isfile(default_driver_path): + ambari_should_use_existing_default_jdbc = get_YN_input("Should ambari use existing default jdbc {0} [y/n] (y)? ".format(default_driver_path), True) + if ambari_should_use_existing_default_jdbc: + properties.process_pair(JDBC_DRIVER_PATH_PROPERTY, default_driver_path) + update_properties(properties) + return True + + path_to_custom_jdbc_driver = get_validated_string_input("Enter full path to custom jdbc driver: ", None, None, None, False, False) + if path_to_custom_jdbc_driver and os.path.isfile(path_to_custom_jdbc_driver): + try: + custom_jdbc_name = os.path.basename(path_to_custom_jdbc_driver) + if not path_to_custom_jdbc_driver == os.path.join(configDefaults.JAVA_SHARE_PATH, custom_jdbc_name): + if os.path.isfile(os.path.join(configDefaults.JAVA_SHARE_PATH, custom_jdbc_name)): + replace_jdbc_in_share_dir = get_YN_input("You already have file {0} in /usr/share/java/. Should it be replaced? [y/n] (y)? ".format(custom_jdbc_name), True) + if replace_jdbc_in_share_dir: + try: + os.remove(os.path.join(configDefaults.JAVA_SHARE_PATH, custom_jdbc_name)) + except Exception, ee: + err = 'ERROR: Could not remove jdbc file. %s' % os.path.join(configDefaults.JAVA_SHARE_PATH, custom_jdbc_name) + raise FatalException(1, err) + shutil.copy(path_to_custom_jdbc_driver, configDefaults.JAVA_SHARE_PATH) + print "Copying {0} to {1}".format(path_to_custom_jdbc_driver, configDefaults.JAVA_SHARE_PATH) + except Exception, e: + err = "Can not copy file {0} to {1} due to: {2} . Please check file " \ + "permissions and free disk space.".format(path_to_custom_jdbc_driver, configDefaults.JAVA_SHARE_PATH, str(e)) + raise FatalException(1, err) + + properties.process_pair(JDBC_DRIVER_PATH_PROPERTY, path_to_custom_jdbc_driver) + update_properties(properties) + return True + else: + print_error_msg("Custom jdbc connector path is unavailable. Please put correct path to jdbc connector.") + + return False - if result != 1: - result = self._install_jdbc_driver(properties, result) - return cbool(result) def change_db_files_owner(self): if self._is_local_database(): http://git-wip-us.apache.org/repos/asf/ambari/blob/05e65e29/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 5746503..ed200b8 100644 --- a/ambari-server/src/test/python/TestAmbariServer.py +++ b/ambari-server/src/test/python/TestAmbariServer.py @@ -125,7 +125,7 @@ with patch.object(platform, "linux_distribution", return_value = MagicMock(retur from ambari_server.userInput import get_YN_input, get_choice_string_input, get_validated_string_input, \ read_password from ambari_server_main import get_ulimit_open_files, ULIMIT_OPEN_FILES_KEY, ULIMIT_OPEN_FILES_DEFAULT - from ambari_server.serverClassPath import ServerClassPath + from ambari_server.serverClassPath import JDBC_DRIVER_PATH_PROPERTY, ServerClassPath from ambari_server.hostUpdate import update_host_names from ambari_server.checkDatabase import check_database from ambari_server import serverConfiguration @@ -6459,7 +6459,12 @@ class TestAmbariServer(TestCase): @patch("os.remove") @patch("os.symlink") @patch("shutil.copy") - def test_ensure_jdbc_drivers_installed(self, shutil_copy_mock, os_symlink_mock, os_remove_mock, lexists_mock, isdir_mock, glob_mock, + @patch("os.path.isfile") + @patch("ambari_server.dbConfiguration.get_YN_input") + @patch("ambari_server.dbConfiguration.update_properties") + @patch("ambari_server.dbConfiguration.get_validated_string_input") + def test_ensure_jdbc_drivers_installed(self, get_valid_str_in_mock, update_properties_mock, getYN_mock, isfile_mock, shutil_copy_mock, + os_symlink_mock, os_remove_mock, lexists_mock, isdir_mock, glob_mock, raw_input_mock, print_warning_msg, print_error_msg_mock, print_error_msg_2_mock, get_ambari_properties_mock, get_ambari_properties_2_mock): out = StringIO.StringIO() @@ -6472,7 +6477,11 @@ class TestAmbariServer(TestCase): print_error_msg_mock.reset_mock() print_warning_msg.reset_mock() raw_input_mock.reset_mock() - + isfile_mock.reset_mock() + os_remove_mock.reset_mock + getYN_mock.reset_mock() + get_valid_str_in_mock.reset_mock() + update_properties_mock.reset_mock() args = MagicMock() del args.database_index @@ -6485,12 +6494,13 @@ class TestAmbariServer(TestCase): return args - # Check positive scenario + # Check scenario when default jdbc was found and used drivers_list = [os.path.join(os.sep,'usr','share','java','ojdbc6.jar')] resources_dir = os.sep + 'tmp' props = Properties() props.process_pair(RESOURCES_DIR_PROPERTY, resources_dir) + props.process_pair(JDBC_DRIVER_PATH_PROPERTY, "/some/test/path/to/oracle.-jdbc.jar") get_ambari_properties_2_mock.return_value = get_ambari_properties_mock.return_value = props factory = DBMSConfigFactory() @@ -6500,94 +6510,49 @@ class TestAmbariServer(TestCase): isdir_mock.return_value = True lexists_mock.return_value = True + isfile_mock.return_value = True + getYN_mock.return_value = True dbms = factory.create(args, props) rcode = dbms.ensure_jdbc_driver_installed(props) - self.assertEquals(os_symlink_mock.call_count, 1) - self.assertEquals(os_symlink_mock.call_args_list[0][0][0], os.path.join(os.sep,'tmp','ojdbc6.jar')) - self.assertEquals(os_symlink_mock.call_args_list[0][0][1], os.path.join(os.sep,'tmp','oracle-jdbc-driver.jar')) + self.assertEquals(update_properties_mock.call_count, 0) self.assertTrue(rcode) - self.assertEquals(shutil_copy_mock.call_count, 1) - self.assertEquals(shutil_copy_mock.call_args_list[0][0][0], drivers_list[0]) - self.assertEquals(shutil_copy_mock.call_args_list[0][0][1], resources_dir) - - # Check negative scenarios - # Silent option, no drivers - set_silent(True) args = reset_mocks() - glob_mock.return_value = [] - - failed = False - - try: - dbms = factory.create(args, props) - rcode = dbms.ensure_jdbc_driver_installed(props) - except FatalException: - failed = True - - self.assertTrue(print_error_msg_mock.called) - self.assertTrue(failed) - - # Non-Silent option, no drivers - set_silent(False) - - args = reset_mocks() - glob_mock.return_value = [] - - failed = False - - try: - dbms = factory.create(args, props) - rcode = dbms.ensure_jdbc_driver_installed(props) - except FatalException: - failed = True - - self.assertTrue(failed) - self.assertTrue(print_error_msg_mock.called) - - # Non-Silent option, no drivers at first ask, present drivers after that - args = reset_mocks() - - glob_mock.side_effect = [[], drivers_list, drivers_list] + isfile_mock.side_effect = [False, True] + getYN_mock.return_value = True dbms = factory.create(args, props) rcode = dbms.ensure_jdbc_driver_installed(props) + self.assertEquals(update_properties_mock.call_count, 1) + self.assertEquals(getYN_mock.call_count, 1) self.assertTrue(rcode) - self.assertEquals(shutil_copy_mock.call_count, 1) - self.assertEquals(shutil_copy_mock.call_args_list[0][0][0], drivers_list[0]) - self.assertEquals(shutil_copy_mock.call_args_list[0][0][1], resources_dir) - # Non-Silent option, no drivers at first ask, no drivers after that + # check scenario when user entered valid jdbc full path args = reset_mocks() - glob_mock.side_effect = [[], []] + isfile_mock.side_effect = [False, False, True, True] + get_valid_str_in_mock.return_value = '/test/full/path/to/oracle_jdbc.jar' - failed = False - - try: - dbms = factory.create(args, props) - rcode = dbms.ensure_jdbc_driver_installed(props) - except FatalException: - failed = True + rcode = dbms.ensure_jdbc_driver_installed(props) - self.assertTrue(failed) - self.assertTrue(print_error_msg_mock.called) + self.assertEquals(update_properties_mock.call_count, 1) + self.assertTrue(rcode) + self.assertEquals(props['server.jdbc.driver.path'], '/test/full/path/to/oracle_jdbc.jar') + self.assertEquals(shutil_copy_mock.call_count, 1) + self.assertEquals(shutil_copy_mock.call_count, 1) + self.assertEquals(os_remove_mock.call_count, 1) - # Failed to copy_files + # check scenario when no default jdbc and user entered incorrect full jdbc path args = reset_mocks() - glob_mock.side_effect = [[], drivers_list, drivers_list] + isfile_mock.side_effect = [False, False, False, False] - try: - dbms = factory.create(args, props) - rcode = dbms.ensure_jdbc_driver_installed(props) - except FatalException: - failed = True + rcode = dbms.ensure_jdbc_driver_installed(props) - self.assertTrue(failed) + self.assertFalse(rcode) + print_error_msg_mock.assert_called_once_with("Custom jdbc connector path is unavailable. Please put correct path to jdbc connector.") - sys.stdout = sys.__stdout__ pass
