diff --git a/core/src/main/python/create.py b/core/src/main/python/create.py index dd0b3884fa..985b1e4b80 100644 --- a/core/src/main/python/create.py +++ b/core/src/main/python/create.py @@ -27,6 +27,9 @@ from wlsdeploy.aliases.aliases import Aliases from wlsdeploy.aliases import model_constants +from wlsdeploy.aliases.model_constants import DEFAULT_WLS_DOMAIN_NAME +from wlsdeploy.aliases.model_constants import DOMAIN_NAME +from wlsdeploy.aliases.model_constants import TOPOLOGY from wlsdeploy.aliases.wlst_modes import WlstModes from wlsdeploy.exception import exception_helper from wlsdeploy.exception.expection_types import ExceptionType @@ -37,6 +40,7 @@ from wlsdeploy.tool.create.domain_typedef import CREATE_DOMAIN from wlsdeploy.tool.util import filter_helper from wlsdeploy.tool.util.alias_helper import AliasHelper +from wlsdeploy.tool.util.archive_helper import ArchiveHelper from wlsdeploy.tool.validate.validator import Validator from wlsdeploy.util import cla_helper from wlsdeploy.util import getcreds @@ -289,7 +293,6 @@ def __process_opss_args(optional_arg_map): return - def validate_model(model_dictionary, model_context, aliases): _method_name = 'validate_model' @@ -311,7 +314,9 @@ def validate_model(model_dictionary, model_context, aliases): tool_exit.end(model_context, CommandLineArgUtil.PROG_ERROR_EXIT_CODE) -def validateRCUArgsAndModel(model_context, model, alias_helper): +def validate_rcu_args_and_model(model_context, model, archive_helper, alias_helper): + _method_name = 'validate_rcu_args_and_model' + has_atpdbinfo = 0 domain_info = model[model_constants.DOMAIN_INFO] if domain_info is not None: @@ -321,26 +326,20 @@ def validateRCUArgsAndModel(model_context, model, alias_helper): has_regular_db = rcu_db_info.is_regular_db() has_atpdbinfo = rcu_db_info.has_atpdbinfo() - if model_context.get_archive_file_name() and not has_regular_db: + if archive_helper and not has_regular_db: System.setProperty('oracle.jdbc.fanEnabled', 'false') # 1. If it does not have the oracle.net.tns_admin specified, then extract to domain/atpwallet # 2. If it is plain old regular oracle db, do nothing # 3. If it deos not have tns_admin in the model, then the wallet must be in the archive if not has_tns_admin: - # extract the wallet first - archive_file = WLSDeployArchive(model_context.get_archive_file_name()) - atp_wallet_zipentry = None - if archive_file: - atp_wallet_zipentry = archive_file.getATPWallet() - if atp_wallet_zipentry and model[model_constants.TOPOLOGY]['Name']: - extract_path = atp_helper.extract_walletzip(model, model_context, archive_file, atp_wallet_zipentry) + wallet_path = archive_helper.extract_atp_wallet() + if wallet_path: # update the model to add the tns_admin model[model_constants.DOMAIN_INFO][model_constants.RCU_DB_INFO][ - model_constants.DRIVER_PARAMS_NET_TNS_ADMIN] = extract_path + model_constants.DRIVER_PARAMS_NET_TNS_ADMIN] = wallet_path else: - __logger.severe('WLSDPLY-12411', error=None, - class_name=_class_name, method_name="validateRCUArgsAndModel") + __logger.severe('WLSDPLY-12411', error=None, class_name=_class_name, method_name=_method_name) cla_helper.clean_up_temp_files() tool_exit.end(model_context, CommandLineArgUtil.PROG_ERROR_EXIT_CODE) @@ -355,6 +354,22 @@ def validateRCUArgsAndModel(model_context, model, alias_helper): return has_atpdbinfo +def _get_domain_path(model_context, model): + """ + Returns the domain home path. + :param model_context: the model context + :param model: the model + :return: the domain path + """ + domain_parent = model_context.get_domain_parent_dir() + if domain_parent is None: + return model_context.get_domain_home() + elif TOPOLOGY in model and DOMAIN_NAME in model[TOPOLOGY]: + return domain_parent + os.sep + model[TOPOLOGY][DOMAIN_NAME] + else: + return domain_parent + os.sep + DEFAULT_WLS_DOMAIN_NAME + + def main(args): """ The entry point for the create domain tool. @@ -419,18 +434,20 @@ def main(args): if filter_helper.apply_filters(model, "create"): # if any filters were applied, re-validate the model validate_model(model, model_context, aliases) + try: + archive_helper = None + archive_file_name = model_context.get_archive_file_name() + if archive_file_name: + domain_path = _get_domain_path(model_context, model) + archive_helper = ArchiveHelper(archive_file_name, domain_path, __logger, ExceptionType.CREATE) + + has_atp = validate_rcu_args_and_model(model_context, model, archive_helper, alias_helper) - has_atp = validateRCUArgsAndModel(model_context, model, alias_helper) # check if there is an atpwallet and extract in the domain dir # it is to support non JRF domain but user wants to use ATP database - archive_file_name = model_context.get_archive_file_name() - if not has_atp and archive_file_name and os.path.exists(archive_file_name): - archive_file = WLSDeployArchive(archive_file_name) - if archive_file: - atp_wallet_zipentry = archive_file.getATPWallet() - if atp_wallet_zipentry: - atp_helper.extract_walletzip(model, model_context, archive_file, atp_wallet_zipentry) + if not has_atp and archive_helper: + archive_helper.extract_atp_wallet() creator = DomainCreator(model, model_context, aliases) creator.create() diff --git a/core/src/main/python/deploy.py b/core/src/main/python/deploy.py index 3237d72814..d1468b5454 100644 --- a/core/src/main/python/deploy.py +++ b/core/src/main/python/deploy.py @@ -119,27 +119,6 @@ def __verify_required_args_present(required_arg_map): return -def __validate_archive_file_arg(required_arg_map): - """ - Verify that the archive file exists. - :param required_arg_map: the required arguments map - :return: the archive file name - :raises CLAException: if the archive file is not valid - """ - _method_name = '__validate_archive_file_arg' - - archive_file_name = required_arg_map[CommandLineArgUtil.ARCHIVE_FILE_SWITCH] - try: - FileUtils.validateExistingFile(archive_file_name) - except IllegalArgumentException, iae: - ex = exception_helper.create_cla_exception('WLSDPLY-20014', _program_name, archive_file_name, - iae.getLocalizedMessage(), error=iae) - ex.setExitCode(CommandLineArgUtil.ARG_VALIDATION_ERROR_EXIT_CODE) - __logger.throwing(ex, class_name=_class_name, method_name=_method_name) - raise ex - return archive_file_name - - def __process_model_args(optional_arg_map): """ Determine if the model file was passed separately or requires extraction from the archive. @@ -221,10 +200,10 @@ def __deploy(model, model_context, aliases): ret_code = __deploy_online(model, model_context, aliases) else: ret_code = __deploy_offline(model, model_context, aliases) - return ret_code = + return ret_code - def __deploy_online(model, model_context, aliases): +def __deploy_online(model, model_context, aliases): """ Online deployment orchestration :param model: the model diff --git a/core/src/main/python/update.py b/core/src/main/python/update.py index 89d2ccd3d9..845d5aba4a 100644 --- a/core/src/main/python/update.py +++ b/core/src/main/python/update.py @@ -8,7 +8,6 @@ import sys from java.io import IOException, PrintStream -from java.lang import IllegalArgumentException from java.lang import String, System from oracle.weblogic.deploy.deploy import DeployException @@ -128,27 +127,6 @@ def __verify_required_args_present(required_arg_map): return -def __validate_archive_file_arg(required_arg_map): - """ - Verify that the archive file exists. - :param required_arg_map: the required arguments map - :return: the archive file name - :raises CLAException: if the archive file is not valid - """ - _method_name = '__validate_archive_file_arg' - - archive_file_name = required_arg_map[CommandLineArgUtil.ARCHIVE_FILE_SWITCH] - try: - FileUtils.validateExistingFile(archive_file_name) - except IllegalArgumentException, iae: - ex = exception_helper.create_cla_exception('WLSDPLY-20014', _program_name, archive_file_name, - iae.getLocalizedMessage(), error=iae) - ex.setExitCode(CommandLineArgUtil.ARG_VALIDATION_ERROR_EXIT_CODE) - __logger.throwing(ex, class_name=_class_name, method_name=_method_name) - raise ex - return archive_file_name - - def __process_model_args(optional_arg_map): """ Determine if the model file was passed separately or requires extraction from the archive. diff --git a/core/src/main/python/wlsdeploy/tool/create/atp_helper.py b/core/src/main/python/wlsdeploy/tool/create/atp_helper.py index 6ba0138327..889708f98c 100644 --- a/core/src/main/python/wlsdeploy/tool/create/atp_helper.py +++ b/core/src/main/python/wlsdeploy/tool/create/atp_helper.py @@ -4,12 +4,7 @@ """ - -import os import re -from java.io import File -from oracle.weblogic.deploy.util import FileUtils -from wlsdeploy.aliases import model_constants from xml.dom.minidom import parse @@ -117,18 +112,3 @@ def format_connect_string(connect_string): connect_string = "%s%s%s%s" % (part1, part2, part3, part4) return connect_string - - -def extract_walletzip(model, model_context, archive_file, atp_zipentry): - domain_parent = model_context.get_domain_parent_dir() - if domain_parent is None: - domain_path = model_context.get_domain_home() - else: - domain_path = domain_parent + os.sep + model[model_constants.TOPOLOGY][ - 'Name'] - extract_path = domain_path + os.sep + 'atpwallet' - extract_dir = File(extract_path) - extract_dir.mkdirs() - FileUtils.extractZipFileContent(archive_file, atp_zipentry, extract_path) - return extract_path - # update the model to add the tns_admin diff --git a/core/src/main/python/wlsdeploy/tool/create/creator.py b/core/src/main/python/wlsdeploy/tool/create/creator.py index 0a623a56c2..4ee8a36f1c 100644 --- a/core/src/main/python/wlsdeploy/tool/create/creator.py +++ b/core/src/main/python/wlsdeploy/tool/create/creator.py @@ -366,7 +366,7 @@ def _extract_archive_files(self, location, model_name, model_value): self.files_to_extract_from_archive.append(model_path) else: path = self.alias_helper.get_model_folder_path(location) - archive_file_name = self.model_context.get_archive_file_name + archive_file_name = self.model_context.get_archive_file_name() ex = exception_helper.create_create_exception('WLSDPLY-12121', model_name, path, model_path, archive_file_name) self.logger.throwing(ex, class_name=self.__class_name, method_name=_method_name) diff --git a/core/src/main/python/wlsdeploy/tool/create/domain_creator.py b/core/src/main/python/wlsdeploy/tool/create/domain_creator.py index beb3ad621d..87b37e6319 100644 --- a/core/src/main/python/wlsdeploy/tool/create/domain_creator.py +++ b/core/src/main/python/wlsdeploy/tool/create/domain_creator.py @@ -1172,11 +1172,8 @@ def __configure_opss_secrets(self): domain_info = self._domain_info if OPSS_SECRETS in domain_info: opss_secret_password = domain_info[OPSS_SECRETS] - if self.model_context.get_archive_file_name() and opss_secret_password: - archive_file = WLSDeployArchive(self.model_context.get_archive_file_name()) - extract_path = self._domain_home + os.sep + 'opsswallet' - zip_entry = archive_file.getOPSSWallet(); - FileUtils.extractZipFileContent(archive_file, zip_entry, extract_path) + if self.archive_helper and opss_secret_password: + extract_path = self.archive_helper.extract_opss_wallet() self.wlst_helper.setSharedSecretStoreWithPassword(extract_path, opss_secret_password) else: opss_secret_password = self.model_context.get_opss_wallet_passphrase() diff --git a/core/src/main/python/wlsdeploy/tool/util/archive_helper.py b/core/src/main/python/wlsdeploy/tool/util/archive_helper.py index 896c577b3e..f97b884c14 100644 --- a/core/src/main/python/wlsdeploy/tool/util/archive_helper.py +++ b/core/src/main/python/wlsdeploy/tool/util/archive_helper.py @@ -11,150 +11,196 @@ from oracle.weblogic.deploy.util import WLSDeployArchiveIOException from wlsdeploy.exception import exception_helper +from wlsdeploy.util.cla_utils import CommandLineArgUtil + class ArchiveHelper(object): """ Helper class for working with the archive file. + This class should be the access point for any operation that makes use of multiple archives. """ __class_name = 'ArchiveHelper' - def __init__(self, archive_file_name, domain_home, logger, exception_type): + def __init__(self, archive_files_text, domain_home, logger, exception_type): + """ + :param archive_files_text: a comma-separated list of one or more file names + :param domain_home: the domain home + :param logger: the logger to use + :param exception_type: the exception type for the associated tool + """ _method_name = '__init__' - self.__archive_file_name = archive_file_name - self.__domain_home = File(domain_home) + + # used for logging only, comma-separated text is OK + self.__archive_files_text = archive_files_text + + self.__domain_home = None + if domain_home: + self.__domain_home = File(domain_home) + self.__logger = logger self.__exception_type = exception_type - try: - self.__archive_file = WLSDeployArchive(archive_file_name) - except (IllegalArgumentException, IllegalStateException), e: - ex = exception_helper.create_exception(exception_type, 'WLSDPLY-19300', self.__archive_file_name, - e.getLocalizedMessage(), error=e) - self.__logger.throwing(ex, class_name=self.__class_name, method_name=_method_name) - raise ex + self.__archive_files = [] + file_names = archive_files_text.split(CommandLineArgUtil.ARCHIVE_FILES_SEPARATOR) + for file_name in file_names: + try: + self.__archive_files.append(WLSDeployArchive(file_name)) + except (IllegalArgumentException, IllegalStateException), e: + ex = exception_helper.create_exception(exception_type, 'WLSDPLY-19300', file_name, + e.getLocalizedMessage(), error=e) + self.__logger.throwing(ex, class_name=self.__class_name, method_name=_method_name) + raise ex + return def contains_model(self): """ - Does the archive file contain a model file? + Determine if an archive file contain a model file. Search in reverse order :return: True, if a model file was found, False otherwise :raises: BundleAwareException of the appropriate type: if an error occurs """ _method_name = 'contains_model' - self.__logger.entering(class_name=self.__class_name, method_name=_method_name) - try: - result = self.__archive_file.containsModel() - except WLSDeployArchiveIOException, e: - ex = exception_helper.create_exception(self.__exception_type, "WLSDPLY-19301", - self.__archive_file_name, e.getLocalizedMessage(), error=e) - self.__logger.throwing(ex, class_name=self.__class_name, method_name=_method_name) - raise ex + + result = False + for archive_file in self.__archive_files[::-1]: + try: + result = archive_file.containsModel() + if result: + break + except WLSDeployArchiveIOException, e: + ex = exception_helper.create_exception(self.__exception_type, "WLSDPLY-19301", + self.__archive_files_text, e.getLocalizedMessage(), error=e) + self.__logger.throwing(ex, class_name=self.__class_name, method_name=_method_name) + raise ex + self.__logger.exiting(class_name=self.__class_name, method_name=_method_name, result=result) - return + return result def extract_model(self, program_name): """ - Extract the model from the archive. + Extract the model from an archive. Search in reverse order :param program_name: the program name (for logging purposes) - :return: the temporary directory and the full path to the model file + :return: the temporary directory and the full path to the model file, or None if not found :raises: BundleAwareException of the appropriate type: if an error occurs """ _method_name = 'extract_model' - self.__logger.entering(program_name, class_name=self.__class_name, method_name=_method_name) + try: tmp_model_dir = FileUtils.createTempDirectory(program_name) - tmp_model_file = self.__archive_file.extractModel(tmp_model_dir) + tmp_model_file = None + for archive_file in self.__archive_files[::-1]: + tmp_model_file = archive_file.extractModel(tmp_model_dir) + if tmp_model_file: + break + except (IllegalArgumentException, IllegalStateException, WLSDeployArchiveIOException), archex: - ex = exception_helper.create_cla_exception('WLSDPLY-20010', program_name, self.__archive_file_name, + ex = exception_helper.create_cla_exception('WLSDPLY-20010', program_name, self.__archive_files_text, archex.getLocalizedMessage(), error=archex) self.__logger.throwing(ex, class_name=self.__class_name, method_name=_method_name) raise ex + self.__logger.exiting(class_name=self.__class_name, method_name=_method_name, result=(tmp_model_dir, tmp_model_file)) return tmp_model_dir, tmp_model_file def contains_file(self, path): """ - Does the archive file contain the specified location? + Does an archive file contain the specified location? :param path: the path to test - :return: True, if the path was found in the archive file and is a file, False otherwise + :return: True, if the path was found in an archive file and is a file, False otherwise :raises: BundleAwareException of the appropriate type: if an error occurs """ _method_name = 'contains_file' - self.__logger.entering(path, class_name=self.__class_name, method_name=_method_name) - try: - result = self.__archive_file.containsFile(path) - except (IllegalArgumentException, WLSDeployArchiveIOException), e: - ex = exception_helper.create_exception(self.__exception_type, "WLSDPLY-19302", path, - self.__archive_file_name, e.getLocalizedMessage(), error=e) - self.__logger.throwing(ex, class_name=self.__class_name, method_name=_method_name) - raise ex + + result = False + for archive_file in self.__archive_files: + try: + result = archive_file.containsFile(path) + if result: + break + except (IllegalArgumentException, WLSDeployArchiveIOException), e: + ex = exception_helper.create_exception(self.__exception_type, "WLSDPLY-19302", path, + self.__archive_files_text, e.getLocalizedMessage(), error=e) + self.__logger.throwing(ex, class_name=self.__class_name, method_name=_method_name) + raise ex + self.__logger.exiting(class_name=self.__class_name, method_name=_method_name, result=result) return result def contains_path(self, path): """ - Check that the provided path is a path, not a file, contained inside the archive file + Check that the provided path is a path, not a file, contained inside an archive file :param path: the path to test - :return: True, if the path was found in the archive file and is a path, False otherwise + :return: True, if the path was found in an archive file and is a path, False otherwise :raises: BundleAwareException of the appropriate type: if an error occurs """ _method_name = 'contains_path' - self.__logger.entering(path, class_name=self.__class_name, method_name=_method_name) - try: - result = self.__archive_file.containsPath(path) - except (IllegalArgumentException, WLSDeployArchiveIOException), e: - ex = exception_helper.create_exception(self.__exception_type, "WLSDPLY-19308", path, - self.__archive_file_name, e.getLocalizedMessage(), error=e) - self.__logger.throwing(ex, class_name=self.__class_name, method_name=_method_name) - raise ex + + result = False + for archive_file in self.__archive_files: + try: + result = archive_file.containsPath(path) + if result: + break + except (IllegalArgumentException, WLSDeployArchiveIOException), e: + ex = exception_helper.create_exception(self.__exception_type, "WLSDPLY-19302", path, + archive_file, e.getLocalizedMessage(), error=e) + self.__logger.throwing(ex, class_name=self.__class_name, method_name=_method_name) + raise ex + self.__logger.exiting(class_name=self.__class_name, method_name=_method_name, result=result) return result def contains_file_or_path(self, path): """ - Check that the provided path is a file or path contained inside the archive file + Check that the provided path is a file or path contained inside one of the archive files :param path: the path to test - :return: True, if the path was found in the archive file. False otherwise + :return: True, if the path was found in an archive file. False otherwise :raises: BundleAwareException of the appropriate type: if an error occurs """ _method_name = 'contains_file_or_path' - self.__logger.entering(path, class_name=self.__class_name, method_name=_method_name) - try: - result = self.__archive_file.containsFileOrPath(path) - except (IllegalArgumentException, WLSDeployArchiveIOException), e: - ex = exception_helper.create_exception(self.__exception_type, "WLSDPLY-19309", path, - self.__archive_file_name, e.getLocalizedMessage(), error=e) - self.__logger.throwing(ex, class_name=self.__class_name, method_name=_method_name) - raise ex + + result = False + for archive_file in self.__archive_files: + try: + result = archive_file.containsFileOrPath(path) + if result: + break + except (IllegalArgumentException, WLSDeployArchiveIOException), e: + ex = exception_helper.create_exception(self.__exception_type, "WLSDPLY-19309", path, + self.__archive_files_text, e.getLocalizedMessage(), error=e) + self.__logger.throwing(ex, class_name=self.__class_name, method_name=_method_name) + raise ex + self.__logger.exiting(class_name=self.__class_name, method_name=_method_name, result=result) return result def extract_file(self, path, location=None): """ - Extract the specified file from the archive into the Domain Home directory. + Extract the specified file from the archive into the specified directory, or into Domain Home. :param path: the path into the archive :param location: the location to which to extract the file :return: path to the extracted file :raises: BundleAwareException of the appropriate type: if an error occurs """ _method_name = 'extract_file' - self.__logger.entering(path, class_name=self.__class_name, method_name=_method_name) + try: + archive_file = self._find_archive_for_path(path, True) if location is None: - result = self.__archive_file.extractFile(path, self.__domain_home) + result = archive_file.extractFile(path, self.__domain_home) else: extract_location = FileUtils.getCanonicalFile(File(location)) - result = self.__archive_file.extractFile(path, extract_location, True) + result = archive_file.extractFile(path, extract_location, True) except (IllegalArgumentException, WLSDeployArchiveIOException), e: ex = exception_helper.create_exception(self.__exception_type, "WLSDPLY-19303", path, - self.__archive_file_name, e.getLocalizedMessage(), error=e) + self.__archive_files_text, e.getLocalizedMessage(), error=e) self.__logger.throwing(ex, class_name=self.__class_name, method_name=_method_name) raise ex self.__logger.exiting(class_name=self.__class_name, method_name=_method_name, result=result) @@ -168,13 +214,14 @@ def get_file_hash(self, path): :raises: BundleAwareException of the appropriate type: if an error occurs """ _method_name = 'get_file_hash' - self.__logger.entering(path, class_name=self.__class_name, method_name=_method_name) + try: - result = self.__archive_file.getFileHash(path) + archive_file = self._find_archive_for_path(path, True) + result = archive_file.getFileHash(path) except (IllegalArgumentException, WLSDeployArchiveIOException), e: ex = exception_helper.create_exception(self.__exception_type, "WLSDPLY-19304", path, - self.__archive_file_name, e.getLocalizedMessage(), error=e) + self.__archive_files_text, e.getLocalizedMessage(), error=e) self.__logger.throwing(ex, class_name=self.__class_name, method_name=_method_name) raise ex self.__logger.exiting(class_name=self.__class_name, method_name=_method_name, result=result) @@ -190,17 +237,17 @@ def extract_domain_library(self, lib_path): self.__logger.entering(lib_path, class_name=self.__class_name, method_name=_method_name) try: - domain_libs = self.__archive_file.listDomainLibLibraries() - if lib_path in domain_libs: - self.__archive_file.extractDomainLibLibrary(lib_path, File(self.__domain_home, 'lib')) + archive = self._find_archive_for_path(lib_path) + if archive is not None: + archive.extractDomainLibLibrary(lib_path, File(self.__domain_home, 'lib')) else: ex = exception_helper.create_exception(self.__exception_type, 'WLSDPLY-19305', - lib_path, self.__archive_file_name) + lib_path, self.__archive_files_text) self.__logger.throwing(ex, class_name=self.__class_name, method_name=_method_name) raise ex except (WLSDeployArchiveIOException, IllegalArgumentException), e: ex = exception_helper.create_exception(self.__exception_type, 'WLSDPLY-19306', lib_path, - self.__archive_file_name, e.getLocalizedMessage(), error=e) + self.__archive_files_text, e.getLocalizedMessage(), error=e) self.__logger.throwing(ex, class_name=self.__class_name, method_name=_method_name) raise ex self.__logger.exiting(class_name=self.__class_name, method_name=_method_name) @@ -214,36 +261,112 @@ def extract_classpath_libraries(self): :raises: BundleAwareException of the appropriate type: if an error occurs """ _method_name = 'extract_classpath_libraries' - self.__logger.entering(class_name=self.__class_name, method_name=_method_name) - try: - cp_libs = self.__archive_file.listClasspathLibraries() - if cp_libs.size() > 0: - self.__archive_file.extractClasspathLibraries(self.__domain_home) - except (WLSDeployArchiveIOException, IllegalArgumentException), e: - ex = exception_helper.create_exception(self.__exception_type, 'WLSDPLY-19307', self.__archive_file_name, - self.__domain_home.getAbsolutePath(), e.getLocalizedMessage(), - error=e) - self.__logger.throwing(ex, class_name=self.__class_name, method_name=_method_name) - raise ex - self.__logger.exiting(class_name=self.__class_name, method_name=_method_name, result=cp_libs.size()) - return cp_libs.size() + + count = 0 + for archive_file in self.__archive_files: + try: + cp_libs = archive_file.listClasspathLibraries() + if cp_libs.size() > 0: + archive_file.extractClasspathLibraries(self.__domain_home) + count += cp_libs.size() + except (WLSDeployArchiveIOException, IllegalArgumentException), e: + ex = exception_helper.create_exception(self.__exception_type, 'WLSDPLY-19307', + self.__archive_files_text, self.__domain_home.getAbsolutePath(), + e.getLocalizedMessage(), error=e) + self.__logger.throwing(ex, class_name=self.__class_name, method_name=_method_name) + raise ex + + self.__logger.exiting(class_name=self.__class_name, method_name=_method_name, result=count) + return count def get_archive_entries(self): """ - Get the entries in the archive. + Get the entries from all the archives. :return: a list of archive entries :raises: BundleAwareException of the appropriate type: if an error occurs """ _method_name = 'get_archive_entries' + self.__logger.entering(class_name=self.__class_name, method_name=_method_name) + all_entries = list() + for archive_file in self.__archive_files: + try: + entries = archive_file.getArchiveEntries() + for entry in entries: + all_entries.append(entry) + except WLSDeployArchiveIOException, e: + ex = exception_helper.create_exception(self.__exception_type, 'WLSDPLY-19308', + self.__archive_files_text, e.getLocalizedMessage(), error=e) + self.__logger.throwing(ex, class_name=self.__class_name, method_name=_method_name) + raise ex + + self.__logger.exiting(class_name=self.__class_name, method_name=_method_name, result=all_entries) + return all_entries + + def extract_atp_wallet(self): + """ + Extract the and unzip the ATP wallet, if present, and return the path to the wallet directory. + :return: the path to the extracted wallet, or None if no wallet was found + :raises: BundleAwareException of the appropriate type: if an error occurs + """ + _method_name = 'extract_atp_wallet' self.__logger.entering(class_name=self.__class_name, method_name=_method_name) - try: - entries = self.__archive_file.getArchiveEntries() - except WLSDeployArchiveIOException, e: - ex = exception_helper.create_exception(self.__exception_type, 'WLSDPLY-19308', self.__archive_file_name, - e.getLocalizedMessage(), error=e) + + wallet_path = None + for archive_file in self.__archive_files[::-1]: + atp_wallet_zipentry = archive_file.getATPWallet() + if atp_wallet_zipentry: + wallet_dir = File(self.__domain_home, 'atpwallet') + wallet_dir.mkdirs() + wallet_path = wallet_dir.getPath() + FileUtils.extractZipFileContent(archive_file, atp_wallet_zipentry, wallet_path) + break + + self.__logger.exiting(class_name=self.__class_name, method_name=_method_name, result=wallet_path) + return wallet_path + + def extract_opss_wallet(self): + """ + Extract the and unzip the OPSS wallet, if present, and return the path to the wallet directory. + :return: the path to the extracted wallet, or None if no wallet was found + :raises: BundleAwareException of the appropriate type: if an error occurs + """ + _method_name = 'extract_opss_wallet' + self.__logger.entering(class_name=self.__class_name, method_name=_method_name) + + wallet_path = None + for archive_file in self.__archive_files[::-1]: + atp_wallet_zipentry = archive_file.getOPSSWallet() + if atp_wallet_zipentry: + wallet_dir = File(self.__domain_home, 'opsswallet') + wallet_dir.mkdirs() + wallet_path = wallet_dir.getPath() + FileUtils.extractZipFileContent(archive_file, atp_wallet_zipentry, wallet_path) + break + + self.__logger.exiting(class_name=self.__class_name, method_name=_method_name, result=wallet_path) + return wallet_path + + def _find_archive_for_path(self, path, required=False): + """ + Find the archive file containing the specified path. + Search from the end of the list, as later entries override previous ones. + :param path: the path to find + :param required: if True, throw an exception if path is not found + :return: the archive containing the path, or None + :raises: WLSDeployArchiveIOException if required is True, and path not found + """ + _method_name = '_find_archive_for_path' + + for archive_file in self.__archive_files[::-1]: + if archive_file.containsFileOrPath(path): + return archive_file + + if required: + args = [path, self.__archive_files_text] + ex = WLSDeployArchiveIOException("WLSDPLY-01403", args) self.__logger.throwing(ex, class_name=self.__class_name, method_name=_method_name) raise ex - self.__logger.exiting(class_name=self.__class_name, method_name=_method_name, result=entries) - return entries + + return None diff --git a/core/src/main/python/wlsdeploy/util/cla_helper.py b/core/src/main/python/wlsdeploy/util/cla_helper.py index 27064ef551..f35beaac1a 100644 --- a/core/src/main/python/wlsdeploy/util/cla_helper.py +++ b/core/src/main/python/wlsdeploy/util/cla_helper.py @@ -4,12 +4,13 @@ Utility CLS methods shared by multiple tools. """ -from java.lang import IllegalArgumentException, IllegalStateException -from oracle.weblogic.deploy.util import FileUtils, WLSDeployArchive, WLSDeployArchiveIOException +from java.lang import IllegalArgumentException +from oracle.weblogic.deploy.util import FileUtils from wlsdeploy.exception import exception_helper from wlsdeploy.logging.platform_logger import PlatformLogger from wlsdeploy.tool.deploy import deployer_utils +from wlsdeploy.tool.util.archive_helper import ArchiveHelper from wlsdeploy.util import cla_utils from wlsdeploy.util import variables from wlsdeploy.util.cla_utils import CommandLineArgUtil @@ -34,15 +35,17 @@ def validate_optional_archive(program_name, optional_arg_map): if CommandLineArgUtil.ARCHIVE_FILE_SWITCH in optional_arg_map: archive_file_name = optional_arg_map[CommandLineArgUtil.ARCHIVE_FILE_SWITCH] + archive_files = cla_utils.get_archive_files(archive_file_name) - try: - FileUtils.validateExistingFile(archive_file_name) - except IllegalArgumentException, iae: - ex = exception_helper.create_cla_exception('WLSDPLY-20014', program_name, archive_file_name, - iae.getLocalizedMessage(), error=iae) - ex.setExitCode(CommandLineArgUtil.ARG_VALIDATION_ERROR_EXIT_CODE) - __logger.throwing(ex, class_name=_class_name, method_name=_method_name) - raise ex + for archive_file in archive_files: + try: + FileUtils.validateExistingFile(archive_file) + except IllegalArgumentException, iae: + ex = exception_helper.create_cla_exception('WLSDPLY-20014', program_name, archive_file_name, + iae.getLocalizedMessage(), error=iae) + ex.setExitCode(CommandLineArgUtil.ARG_VALIDATION_ERROR_EXIT_CODE) + __logger.throwing(ex, class_name=_class_name, method_name=_method_name) + raise ex def validate_model_present(program_name, optional_arg_map): @@ -51,6 +54,7 @@ def validate_model_present(program_name, optional_arg_map): If the model is in the archive, extract it to the temporary model location, and set that file as the MODEL_FILE_SWITCH argument. The MODEL_FILE_SWITCH value may be specified as multiple comma-separated models. + The ARCHIVE_FILE_SWITCH value may be specified as multiple comma-separated archives. :param program_name: the name of the calling program, for logging :param optional_arg_map: the optional arguments from the command line :raises CLAException: if the specified model is not an existing file, or the model is not found in the archive, @@ -74,28 +78,20 @@ def validate_model_present(program_name, optional_arg_map): raise ex elif CommandLineArgUtil.ARCHIVE_FILE_SWITCH in optional_arg_map: - archive_file_name = optional_arg_map[CommandLineArgUtil.ARCHIVE_FILE_SWITCH] - try: - archive_file = WLSDeployArchive(archive_file_name) - __tmp_model_dir = FileUtils.createTempDirectory(program_name) - tmp_model_raw_file = archive_file.extractModel(__tmp_model_dir) - if not tmp_model_raw_file: - ex = exception_helper.create_cla_exception('WLSDPLY-20026', program_name, archive_file_name, - CommandLineArgUtil.MODEL_FILE_SWITCH) - ex.setExitCode(CommandLineArgUtil.ARG_VALIDATION_ERROR_EXIT_CODE) - __logger.throwing(ex, class_name=_class_name, method_name=_method_name) - raise ex + archive_file = optional_arg_map[CommandLineArgUtil.ARCHIVE_FILE_SWITCH] + archive_helper = ArchiveHelper(archive_file, None, __logger, exception_helper.ExceptionType.CLA) - model_file_name = FileUtils.fixupFileSeparatorsForJython(tmp_model_raw_file.getAbsolutePath()) - except (IllegalArgumentException, IllegalStateException, WLSDeployArchiveIOException), archex: - ex = exception_helper.create_cla_exception('WLSDPLY-20010', program_name, archive_file_name, - archex.getLocalizedMessage(), error=archex) + if archive_helper.contains_model(): + tmp_model_dir, tmp_model_file = archive_helper.extract_model(program_name) + model_file_name = FileUtils.fixupFileSeparatorsForJython(tmp_model_file.getAbsolutePath()) + optional_arg_map[CommandLineArgUtil.MODEL_FILE_SWITCH] = model_file_name + else: + ex = exception_helper.create_cla_exception('WLSDPLY-20026', program_name, archive_file, + CommandLineArgUtil.MODEL_FILE_SWITCH) ex.setExitCode(CommandLineArgUtil.ARG_VALIDATION_ERROR_EXIT_CODE) __logger.throwing(ex, class_name=_class_name, method_name=_method_name) raise ex - optional_arg_map[CommandLineArgUtil.MODEL_FILE_SWITCH] = model_file_name - else: ex = exception_helper.create_cla_exception('WLSDPLY-20015', program_name, CommandLineArgUtil.MODEL_FILE_SWITCH, diff --git a/core/src/main/python/wlsdeploy/util/cla_utils.py b/core/src/main/python/wlsdeploy/util/cla_utils.py index fc3c4c8574..f86adf40cd 100644 --- a/core/src/main/python/wlsdeploy/util/cla_utils.py +++ b/core/src/main/python/wlsdeploy/util/cla_utils.py @@ -76,6 +76,7 @@ class CommandLineArgUtil(object): # a slot to stash the archive file object ARCHIVE_FILE = 'archive_file' + ARCHIVE_FILES_SEPARATOR = ',' MODEL_FILES_SEPARATOR = ',' HELP_EXIT_CODE = 100 @@ -683,14 +684,25 @@ def is_archive_file_key(self, key): def _validate_archive_file_arg(self, value): method_name = '_validate_archive_file_arg' - try: - archive = JFileUtils.validateFileName(value) - except JIllegalArgumentException, iae: - ex = exception_helper.create_cla_exception('WLSDPLY-01616', value, iae.getLocalizedMessage(), error=iae) - ex.setExitCode(self.ARG_VALIDATION_ERROR_EXIT_CODE) - self._logger.throwing(ex, class_name=self._class_name, method_name=method_name) - raise ex - return archive.getAbsolutePath() + result_archive_files = [] # type: list + if self._allow_multiple_models: + archive_files = get_archive_files(value) + else: + archive_files = [value] + + for archive_file in archive_files: + try: + archive_file = JFileUtils.validateFileName(archive_file) + archive_file = archive_file.getAbsolutePath() + result_archive_files.append(archive_file) + except JIllegalArgumentException, iae: + ex = exception_helper.create_cla_exception('WLSDPLY-01616', archive_file, iae.getLocalizedMessage(), + error=iae) + ex.setExitCode(self.ARG_VALIDATION_ERROR_EXIT_CODE) + self._logger.throwing(ex, class_name=self._class_name, method_name=method_name) + raise ex + + return CommandLineArgUtil.ARCHIVE_FILES_SEPARATOR.join(result_archive_files) def get_opss_passphrase_key(self): return self.OPSS_WALLET_PASSPHRASE @@ -1121,3 +1133,13 @@ def get_model_files(model_files_text): :return: a list of model files """ return model_files_text.split(CommandLineArgUtil.MODEL_FILES_SEPARATOR) + + +def get_archive_files(archive_files_text): + """ + Returns a list of archive files from the comma-separated ARCHIVE_FILE_SWITCH value. + Returns a list of one item if there is only one archive in the value. + :param archive_files_text: the value of the ARCHIVE_FILE_SWITCH argument + :return: a list of archive files + """ + return archive_files_text.split(CommandLineArgUtil.ARCHIVE_FILES_SEPARATOR) diff --git a/installer/src/main/bin/createDomain.cmd b/installer/src/main/bin/createDomain.cmd index 0606248323..e500795ed6 100644 --- a/installer/src/main/bin/createDomain.cmd +++ b/installer/src/main/bin/createDomain.cmd @@ -342,7 +342,9 @@ ECHO environment variable. ECHO. ECHO archive_file - the path to the archive file to use. If the -model_file ECHO argument is not specified, the model file in this archive -ECHO will be used. +ECHO will be used. This can also be specified as a +ECHO comma-separated list of archive files. The overlapping contents in +ECHO each archive take precedence over previous archives in the list. ECHO. ECHO model_file - the location of the model file to use. This can also be specified as a ECHO comma-separated list of model locations, where each successive model diff --git a/installer/src/main/bin/createDomain.sh b/installer/src/main/bin/createDomain.sh index 575b858d61..31cc7331f4 100644 --- a/installer/src/main/bin/createDomain.sh +++ b/installer/src/main/bin/createDomain.sh @@ -85,7 +85,9 @@ usage() { echo "" echo " archive_file - the path to the archive file to use. If the -model_file" echo " argument is not specified, the model file in this archive" - echo " will be used." + echo " will be used. This can also be specified as a" + echo " comma-separated list of archive files. The overlapping contents in" + echo " each archive take precedence over previous archives in the list." echo "" echo " model_file - the location of the model file to use. This can also be specified as a" echo " comma-separated list of model locations, where each successive model layers on top" diff --git a/installer/src/main/bin/deployApps.cmd b/installer/src/main/bin/deployApps.cmd index 6158ce52a6..bbded09216 100644 --- a/installer/src/main/bin/deployApps.cmd +++ b/installer/src/main/bin/deployApps.cmd @@ -336,7 +336,11 @@ ECHO oracle_home - the existing Oracle Home directory for the domain ECHO. ECHO domain_home - the domain home directory ECHO. -ECHO archive_file - the path to the archive file to use +ECHO archive_file - the path to the archive file to use. If the -model_file +ECHO argument is not specified, the model file in this archive +ECHO will be used. This can also be specified as a +ECHO comma-separated list of archive files. The overlapping contents in +ECHO each archive take precedence over previous archives in the list. ECHO. ECHO model_file - the location of the model file to use. This can also be specified as a ECHO comma-separated list of model locations, where each successive model diff --git a/installer/src/main/bin/deployApps.sh b/installer/src/main/bin/deployApps.sh index 45878f3cc4..be67a26232 100644 --- a/installer/src/main/bin/deployApps.sh +++ b/installer/src/main/bin/deployApps.sh @@ -66,7 +66,11 @@ usage() { echo "" echo " domain_home - the domain home directory" echo "" - echo " archive_file - the path to the archive file to use" + echo " archive_file - the path to the archive file to use If the -model_file" + echo " argument is not specified, the model file in this archive" + echo " will be used. This can also be specified as a" + echo " comma-separated list of archive files. The overlapping contents in" + echo " each archive take precedence over previous archives in the list." echo "" echo " model_file - the location of the model file to use. This can also be specified as a" echo " comma-separated list of model locations, where each successive model layers" diff --git a/installer/src/main/bin/updateDomain.cmd b/installer/src/main/bin/updateDomain.cmd index 7286b26710..1736a6951c 100644 --- a/installer/src/main/bin/updateDomain.cmd +++ b/installer/src/main/bin/updateDomain.cmd @@ -337,7 +337,11 @@ ECHO oracle_home - the existing Oracle Home directory for the domain ECHO. ECHO domain_home - the domain home directory ECHO. -ECHO archive_file - the path to the archive file to use +ECHO archive_file - the path to the archive file to use. If the -model_file +ECHO argument is not specified, the model file in this archive +ECHO will be used. This can also be specified as a +ECHO comma-separated list of archive files. The overlapping contents in +ECHO each archive take precedence over previous archives in the list. ECHO. ECHO model_file - the location of the model file to use. This can also be specified as a ECHO comma-separated list of model locations, where each successive model diff --git a/installer/src/main/bin/updateDomain.sh b/installer/src/main/bin/updateDomain.sh index e5505b9dc8..a50665d07b 100644 --- a/installer/src/main/bin/updateDomain.sh +++ b/installer/src/main/bin/updateDomain.sh @@ -66,7 +66,11 @@ usage() { echo "" echo " domain_home - the domain home directory" echo "" - echo " archive_file - the path to the archive file to use" + echo " archive_file - the path to the archive file to use. If the -model_file" + echo " argument is not specified, the model file in this archive" + echo " will be used. This can also be specified as a" + echo " comma-separated list of archive files. The overlapping contents in" + echo " each archive take precedence over previous archives in the list." echo "" echo " model_file - the location of the model file to use. This can also be specified as a" echo " comma-separated list of model locations, where each successive model layers" diff --git a/installer/src/main/bin/validateModel.cmd b/installer/src/main/bin/validateModel.cmd index 247b20f467..76fe3d74d2 100644 --- a/installer/src/main/bin/validateModel.cmd +++ b/installer/src/main/bin/validateModel.cmd @@ -369,7 +369,9 @@ ECHO. ECHO archive_file - the path to the archive file to use if not using the ECHO -print_usage functionality. If the archive file is ECHO not provided, validation will only validate the -ECHO artifacts provided. +ECHO artifacts provided. This can also be specified as a +ECHO comma-separated list of archive files. The overlapping contents in +ECHO each archive take precedence over previous archives in the list. ECHO. ECHO target_version - the target version of WebLogic Server the tool ECHO should use to validate the model content. This diff --git a/installer/src/main/bin/validateModel.sh b/installer/src/main/bin/validateModel.sh index 4fb0b752be..ee78e5289f 100644 --- a/installer/src/main/bin/validateModel.sh +++ b/installer/src/main/bin/validateModel.sh @@ -85,7 +85,9 @@ usage() { echo " archive_file - the path to the archive file to use if not using the" echo " -print_usage functionality. If the archive file is" echo " not provided, validation will only validate the" - echo " artifacts provided." + echo " artifacts provided. This can also be specified as a" + echo " comma-separated list of archive files. The overlapping contents in" + echo " each archive take precedence over previous archives in the list." echo "" echo " target_version - the target version of WebLogic Server the tool" echo " should use to validate the model content. This"