示例#1
0
class PythonToYaml(object):
    """
    A class that converts a Python dictionary into Yaml and writes the output to a file.
    """
    _class_name = 'PythonToYaml'
    # 4 spaces
    _indent_unit = '    '
    _requires_quotes_chars_regex = '[:{}\[\],&*#?|<>=!%@`-]'

    def __init__(self, dictionary):
        # Fix error handling for None
        self._dictionary = dictionary
        self._logger = PlatformLogger('wlsdeploy.yaml')
        self._hyphenate_lists = False
        return

    def write_to_yaml_file(self, file_name):
        """
        Convert the Python dictionary to Yaml and write it to the specified file.
        :param file_name: the file name to which to write the Yaml output
        :return: The canonical java.io.File object for the Yaml File
        :raises: YamlException: if an error occurs while converting the dictionary to Yaml or writing to the file
        """
        _method_name = 'writeToYamlFile'

        self._logger.entering(file_name,
                              class_name=self._class_name,
                              method_name=_method_name)
        try:
            yaml_file = JFileUtils.validateWritableFile(file_name)
        except JIllegalArgumentException, iae:
            yaml_ex = exception_helper.create_yaml_exception(
                'WLSDPLY-18009',
                file_name,
                iae.getLocalizedMessage(),
                error=iae)
            self._logger.throwing(class_name=self._class_name,
                                  method_name=_method_name,
                                  error=yaml_ex)
            raise yaml_ex

        fos = None
        writer = None
        try:
            fos = JFileOutputStream(yaml_file, False)
            writer = JPrintWriter(fos, True)
            self._write_dictionary_to_yaml_file(self._dictionary, writer)

        except JFileNotFoundException, fnfe:
            yaml_ex = exception_helper.create_yaml_exception(
                'WLSDPLY-18010',
                file_name,
                fnfe.getLocalizedMessage(),
                error=fnfe)
            self._logger.throwing(class_name=self._class_name,
                                  method_name=_method_name,
                                  error=yaml_ex)
            self._close_streams(fos, writer)
            raise yaml_ex
class ApplicationsVersionHelper(object):
    _EXTENSION_INDEX = 0
    _SPEC_INDEX = 1
    _IMPL_INDEX = 2

    _APP_VERSION_MANIFEST_KEY = 'Weblogic-Application-Version'

    def __init__(self, model_context, archive_helper):
        self._class_name = 'ApplicationsVersionHelper'
        self.model_context = model_context
        self.archive_helper = archive_helper
        self.logger = PlatformLogger('wlsdeploy.deploy')

    def get_library_versioned_name(self, source_path, model_name, from_archive=False):
        """
        Get the proper name of the deployable library that WLST requires in the target domain.  This method is
        primarily needed for shared libraries in the Oracle Home where the implementation version may have
        changed.  Rather than requiring the modeller to have to know/adjust the shared library name, we extract
        the information from the target domain's archive file (e.g., war file) and compute the correct name.
        :param source_path: the SourcePath value of the shared library
        :param model_name: the model name of the library
        :param from_archive: if True, use the manifest from the archive, otherwise from the file system
        :return: the updated shared library name for the target environment
        :raises: DeployException: if an error occurs
        """
        _method_name = 'get_library_versioned_name'

        self.logger.entering(source_path, model_name, class_name=self._class_name, method_name=_method_name)

        old_name_tuple = deployer_utils.get_library_name_components(model_name)
        try:
            versioned_name = old_name_tuple[self._EXTENSION_INDEX]
            manifest = self.__get_manifest(source_path, from_archive)
            if manifest is not None:
                attributes = manifest.getMainAttributes()

                extension_name = attributes.getValue(EXTENSION_NAME)
                if not string_utils.is_empty(extension_name):
                    versioned_name = extension_name

                specification_version = attributes.getValue(SPECIFICATION_VERSION)
                if not string_utils.is_empty(specification_version):
                    versioned_name += '#' + specification_version

                    # Cannot specify an impl version without a spec version
                    implementation_version = attributes.getValue(IMPLEMENTATION_VERSION)
                    if not string_utils.is_empty(implementation_version):
                        versioned_name += '@' + implementation_version

                self.logger.info('WLSDPLY-09324', model_name, versioned_name,
                                 class_name=self._class_name, method_name=_method_name)

        except (IOException, FileNotFoundException, ZipException, IllegalStateException), e:
            ex = exception_helper.create_deploy_exception('WLSDPLY-09325', model_name, source_path, str(e), 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=versioned_name)
        return versioned_name
示例#3
0
class PythonToJson(object):
    """
    This class writes a Python dictionary out in a JSON format.
    """
    _class_name = 'PythonToJson'
    # 4 spaces of indent
    _indent_unit = '    '

    def __init__(self, dictionary):
        # Fix error handling for None
        self._dictionary = dictionary
        self._logger = PlatformLogger('wlsdeploy.json')
        return

    def write_to_json_file(self, file_name):
        """
        Convert the Python dictionary to JSON and write it to the specified file.
        :param file_name:  the name of the file
        :return: the java.io.File object of the JSON file
        """
        _method_name = 'writeToJsonFile'

        self._logger.entering(file_name,
                              class_name=self._class_name,
                              method_name=_method_name)
        try:
            json_file = JFileUtils.validateWritableFile(file_name)
        except JIllegalArgumentException, iae:
            json_ex = exception_helper.create_json_exception(
                'WLSDPLY-18015',
                file_name,
                iae.getLocalizedMessage(),
                error=iae)
            self._logger.throwing(class_name=self._class_name,
                                  method_name=_method_name,
                                  error=json_ex)
            raise json_ex

        fos = None
        writer = None
        try:
            fos = JFileOutputStream(json_file, False)
            writer = JPrintWriter(fos, True)
            self._write_dictionary_to_json_file(self._dictionary, writer)

        except JFileNotFoundException, fnfe:
            json_ex = exception_helper.create_json_exception(
                'WLSDPLY-18010',
                file_name,
                fnfe.getLocalizedMessage(),
                error=fnfe)
            self._logger.throwing(class_name=self._class_name,
                                  method_name=_method_name,
                                  error=json_ex)
            self._close_streams(fos, writer)
            raise json_ex
示例#4
0
class CommandLineArgUtil(object):
    """
    Class that handles command-line argument parsing and common validation.
    """
    _class_name = 'CommandLineArgUtil'

    HELP_SWITCH = '-help'
    ORACLE_HOME_SWITCH = '-oracle_home'
    JAVA_HOME_SWITCH = '-java_home'
    DOMAIN_HOME_SWITCH = '-domain_home'
    DOMAIN_PARENT_SWITCH = '-domain_parent'
    DOMAIN_TYPE_SWITCH = '-domain_type'
    # never used by the tools but used by shell scripts
    WLST_PATH_SWITCH = '-wlst_path'
    ADMIN_URL_SWITCH = '-admin_url'
    ADMIN_USER_SWITCH = '-admin_user'
    # phony arg used as a key to store the password
    ADMIN_PASS_SWITCH = '-admin_pass'
    ARCHIVE_FILE_SWITCH = '-archive_file'
    MODEL_FILE_SWITCH = '-model_file'
    PREVIOUS_MODEL_FILE_SWITCH = '-prev_model_file'
    VARIABLE_FILE_SWITCH = '-variable_file'
    PRINT_USAGE_SWITCH = '-print_usage'
    RCU_DB_SWITCH = '-rcu_db'
    RCU_PREFIX_SWITCH = '-rcu_prefix'
    # phony arg used as a key to store the password
    RCU_SYS_PASS_SWITCH = '-rcu_sys_pass'
    # phony arg used as a key to store the password
    RCU_SCHEMA_PASS_SWITCH = '-rcu_schema_pass'
    # phony arg used as a key to store the encryption passphrase
    PASSPHRASE_SWITCH = '-passphrase'
    ENCRYPT_MANUAL_SWITCH = '-manual'
    # phony arg used as a key to store the password
    ONE_PASS_SWITCH = '-password'
    USE_ENCRYPTION_SWITCH = '-use_encryption'
    RUN_RCU_SWITCH = '-run_rcu'
    TARGET_VERSION_SWITCH = '-target_version'
    TARGET_MODE_SWITCH = '-target_mode'
    ATTRIBUTES_ONLY_SWITCH = '-attributes_only'
    FOLDERS_ONLY_SWITCH = '-folders_only'
    RECURSIVE_SWITCH = '-recursive'
    # overrides for the variable injector
    VARIABLE_INJECTOR_FILE_SWITCH = '-variable_injector_file'
    VARIABLE_KEYWORDS_FILE_SWITCH = '-variable_keywords_file'
    VARIABLE_PROPERTIES_FILE_SWITCH = '-variable_properties_file'

    # a slot to stash the parsed domain typedef dictionary
    DOMAIN_TYPEDEF = 'domain_typedef'
    # a slot to stash the archive file object
    ARCHIVE_FILE = 'archive_file'

    HELP_EXIT_CODE = 100
    USAGE_ERROR_EXIT_CODE = 99
    ARG_VALIDATION_ERROR_EXIT_CODE = 98
    PROG_ERROR_EXIT_CODE = 2
    PROG_WARNING_EXIT_CODE = 1
    PROG_OK_EXIT_CODE = 0

    def __init__(self, program_name, required_args, optional_args):
        self._program_name = program_name
        self._logger = PlatformLogger('wlsdeploy.util')

        self._required_args = list(required_args)
        self._optional_args = list(optional_args)

        #
        # Add args that all tools should accept.
        #
        self._optional_args.append(self.HELP_SWITCH)
        self._optional_args.append(self.WLST_PATH_SWITCH)

        self._required_result = {}
        self._optional_result = {}
        return

    def process_args(self, args, for_domain_create=False):
        """
        This method parses the command-line arguments and returns dictionaries of the required and optional args.

        :param args: sys.argv
        :param for_domain_create: true if validating for domain creation
        :return: the required and optional argument dictionaries
        :raises CLAException: if argument processing encounters a usage or validation exception
        """

        method_name = 'process_args'

        self._logger.entering(args,
                              class_name=self._class_name,
                              method_name=method_name)
        #
        # reset the result fields in case the object was reused
        #
        self._required_result = {}
        self._optional_result = {}

        args_len = len(args)
        if args_len == 1:
            ex = exception_helper.create_cla_exception('Dummy Key')
            ex.setExitCode(self.HELP_EXIT_CODE)
            raise ex

        idx = 1
        while idx < args_len:
            key = args[idx]
            self._logger.fine('WLSDPLY-01600',
                              key,
                              class_name=self._class_name,
                              method_name=method_name)
            if self.is_help_key(key):
                ex = exception_helper.create_cla_exception('Dummy Key')
                ex.setExitCode(self.HELP_EXIT_CODE)
                raise ex
            elif self.is_oracle_home_key(key):
                idx += 1
                if idx < args_len:
                    full_path = self._validate_oracle_home_arg(args[idx])
                    self._add_arg(key, full_path, True)
                else:
                    ex = self._get_out_of_args_exception(key)
                    self._logger.throwing(ex,
                                          class_name=self._class_name,
                                          method_name=method_name)
                    raise ex
            elif self.is_java_home_key(key):
                idx += 1
                if idx < args_len:
                    full_path = self._validate_java_home_arg(args[idx])
                    self._add_arg(key, full_path, True)
                else:
                    ex = self._get_out_of_args_exception(key)
                    self._logger.throwing(ex,
                                          class_name=self._class_name,
                                          method_name=method_name)
                    raise ex
            elif self.is_domain_home_key(key):
                idx += 1
                if idx < args_len:
                    if for_domain_create:
                        full_path = self._validate_domain_home_arg_for_create(
                            args[idx])
                    else:
                        full_path = self._validate_domain_home_arg(args[idx])
                    self._add_arg(key, full_path, True)
                else:
                    ex = self._get_out_of_args_exception(key)
                    self._logger.throwing(ex,
                                          class_name=self._class_name,
                                          method_name=method_name)
                    raise ex
            elif self.is_domain_parent_key(key):
                idx += 1
                if idx < args_len:
                    full_path = self._validate_domain_parent_arg(args[idx])
                    self._add_arg(key, full_path, True)
                else:
                    ex = self._get_out_of_args_exception(key)
                    self._logger.throwing(ex,
                                          class_name=self._class_name,
                                          method_name=method_name)
                    raise ex
            elif self.is_domain_type_key(key):
                idx += 1
                if idx < args_len:
                    self._validate_domain_type_arg(args[idx])
                    self._add_arg(key, args[idx])
                else:
                    ex = self._get_out_of_args_exception(key)
                    self._logger.throwing(ex,
                                          class_name=self._class_name,
                                          method_name=method_name)
                    raise ex
            elif self.is_wlst_path_key(key):
                idx += 1
                if idx < args_len:
                    full_path = self._validate_wlst_path_arg(args[idx])
                    self._add_arg(key, full_path, True)
                else:
                    ex = self._get_out_of_args_exception(key)
                    self._logger.throwing(ex,
                                          class_name=self._class_name,
                                          method_name=method_name)
                    raise ex
            elif self.is_admin_url_key(key):
                idx += 1
                if idx < args_len:
                    self._validate_admin_url_arg(args[idx])
                    self._add_arg(key, args[idx])
                else:
                    ex = self._get_out_of_args_exception(key)
                    self._logger.throwing(ex,
                                          class_name=self._class_name,
                                          method_name=method_name)
                    raise ex
            elif self.is_admin_user_key(key):
                idx += 1
                if idx < args_len:
                    self._validate_admin_user_arg(args[idx])
                    self._add_arg(key, args[idx])
                else:
                    ex = self._get_out_of_args_exception(key)
                    self._logger.throwing(ex,
                                          class_name=self._class_name,
                                          method_name=method_name)
                    raise ex
            elif self.is_admin_pass_key(key):
                idx += 1
                if idx < args_len:
                    self._validate_admin_pass_arg(args[idx])
                    self._add_arg(key, args[idx])
                else:
                    ex = self._get_out_of_args_exception(key)
                    self._logger.throwing(ex,
                                          class_name=self._class_name,
                                          method_name=method_name)
                    raise ex
            elif self.is_archive_file_key(key):
                idx += 1
                if idx < args_len:
                    full_path = self._validate_archive_file_arg(args[idx])
                    self._add_arg(key, full_path, True)
                else:
                    ex = self._get_out_of_args_exception(key)
                    self._logger.throwing(ex,
                                          class_name=self._class_name,
                                          method_name=method_name)
                    raise ex
            elif self.is_model_file_key(key):
                idx += 1
                if idx < args_len:
                    full_path = self._validate_model_file_arg(args[idx])
                    self._add_arg(key, full_path, True)
                else:
                    ex = self._get_out_of_args_exception(key)
                    self._logger.throwing(ex,
                                          class_name=self._class_name,
                                          method_name=method_name)
                    raise ex
            elif self.is_previous_model_file_key(key):
                idx += 1
                if idx < args_len:
                    full_path = self._validate_previous_model_file_arg(
                        args[idx])
                    self._add_arg(key, full_path, True)
                else:
                    ex = self._get_out_of_args_exception(key)
                    self._logger.throwing(ex,
                                          class_name=self._class_name,
                                          method_name=method_name)
                    raise ex
            elif self.is_print_usage_key(key):
                idx += 1
                if idx < args_len:
                    context = self._validate_print_usage_arg(args[idx])
                    self._add_arg(key, context)
                else:
                    ex = self._get_out_of_args_exception(key)
                    self._logger.throwing(ex,
                                          class_name=self._class_name,
                                          method_name=method_name)
                    raise ex
            elif self.is_variable_file_key(key):
                idx += 1
                if idx < args_len:
                    full_path = self._validate_variable_file_arg(args[idx])
                    self._add_arg(key, full_path, True)
                else:
                    ex = self._get_out_of_args_exception(key)
                    self._logger.throwing(ex,
                                          class_name=self._class_name,
                                          method_name=method_name)
                    raise ex
            elif self.is_rcu_database_key(key):
                idx += 1
                if idx < args_len:
                    self._validate_rcu_database_arg(args[idx])
                    self._add_arg(key, args[idx])
                else:
                    ex = self._get_out_of_args_exception(key)
                    self._logger.throwing(ex,
                                          class_name=self._class_name,
                                          method_name=method_name)
                    raise ex
            elif self.is_rcu_prefix_key(key):
                idx += 1
                if idx < args_len:
                    self._validate_rcu_prefix_arg(args[idx])
                    self._add_arg(key, args[idx])
                else:
                    ex = self._get_out_of_args_exception(key)
                    self._logger.throwing(ex,
                                          class_name=self._class_name,
                                          method_name=method_name)
                    raise ex
            elif self.is_rcu_sys_pass_key(key):
                idx += 1
                if idx < args_len:
                    self._validate_rcu_sys_pass_arg(args[idx])
                    self._add_arg(key, args[idx])
                else:
                    ex = self._get_out_of_args_exception(key)
                    self._logger.throwing(ex,
                                          class_name=self._class_name,
                                          method_name=method_name)
                    raise ex
            elif self.is_rcu_schema_pass_key(key):
                idx += 1
                if idx < args_len:
                    self._validate_rcu_schema_pass_arg(args[idx])
                    self._add_arg(key, args[idx])
                else:
                    ex = self._get_out_of_args_exception(key)
                    self._logger.throwing(ex,
                                          class_name=self._class_name,
                                          method_name=method_name)
                    raise ex
            elif self.is_passphrase_switch(key):
                idx += 1
                if idx < args_len:
                    self._validate_passphrase_arg(args[idx])
                    self._add_arg(key, args[idx])
                else:
                    ex = self._get_out_of_args_exception(key)
                    self._logger.throwing(ex,
                                          class_name=self._class_name,
                                          method_name=method_name)
                    raise ex
            elif self.is_encrypt_manual_switch(key):
                self._add_arg(key, True)
            elif self.is_one_pass_switch(key):
                idx += 1
                if idx < args_len:
                    self._validate_one_pass_arg(args[idx])
                    self._add_arg(key, args[idx])
                else:
                    ex = self._get_out_of_args_exception(key)
                    self._logger.throwing(ex,
                                          class_name=self._class_name,
                                          method_name=method_name)
                    raise ex
            elif self.is_use_encryption_switch(key):
                self._add_arg(key, True)
            elif self.is_run_rcu_switch(key):
                self._add_arg(key, True)
            elif self.is_target_version_switch(key):
                idx += 1
                if idx < args_len:
                    self._validate_target_version_arg(args[idx])
                    self._add_arg(key, args[idx])
                else:
                    ex = self._get_out_of_args_exception(key)
                    self._logger.throwing(ex,
                                          class_name=self._class_name,
                                          method_name=method_name)
                    raise ex
            elif self.is_target_mode_switch(key):
                idx += 1
                if idx < args_len:
                    self._validate_target_mode_arg(args[idx])
                    self._add_arg(key, args[idx])
                else:
                    ex = self._get_out_of_args_exception(key)
                    self._logger.throwing(ex,
                                          class_name=self._class_name,
                                          method_name=method_name)
                    raise ex
            elif self.is_attributes_only_switch(key):
                self._add_arg(key, True)
            elif self.is_folders_only_switch(key):
                self._add_arg(key, True)
            elif self.is_recursive_switch(key):
                self._add_arg(key, True)
            elif self.is_variable_injector_file_key(key):
                idx += 1
                if idx < args_len:
                    full_path = self._validate_variable_injector_file_arg(
                        args[idx])
                    self._add_arg(key, full_path, True)
                else:
                    ex = self._get_out_of_args_exception(key)
                    self._logger.throwing(ex,
                                          class_name=self._class_name,
                                          method_name=method_name)
                    raise ex
            elif self.is_variable_keywords_file_key(key):
                idx += 1
                if idx < args_len:
                    full_path = self._validate_variable_keywords_file_arg(
                        args[idx])
                    self._add_arg(key, full_path, True)
                else:
                    ex = self._get_out_of_args_exception(key)
                    self._logger.throwing(ex,
                                          class_name=self._class_name,
                                          method_name=method_name)
                    raise ex
            elif self.is_variable_properties_file_key(key):
                idx += 1
                if idx < args_len:
                    full_path = self._validate_variable_properties_file_arg(
                        args[idx])
                    self._add_arg(key, full_path, True)
                else:
                    ex = self._get_out_of_args_exception(key)
                    self._logger.throwing(ex,
                                          class_name=self._class_name,
                                          method_name=method_name)
                    raise ex
            else:
                ex = exception_helper.create_cla_exception(
                    'WLSDPLY-01601', self._program_name, key)
                ex.setExitCode(self.USAGE_ERROR_EXIT_CODE)
                self._logger.throwing(ex,
                                      class_name=self._class_name,
                                      method_name=method_name)
                raise ex
            idx += 1

        print_result = {
            'required': self._required_result,
            'optional': self._optional_result
        }
        self._logger.exiting(class_name=self._class_name,
                             method_name=method_name,
                             result=print_result)
        return self._required_result, self._optional_result

    def get_help_key(self):
        return self.HELP_SWITCH

    def is_help_key(self, key):
        return self.HELP_SWITCH == key

    def get_oracle_home_key(self):
        return str(self.ORACLE_HOME_SWITCH)

    def is_oracle_home_key(self, key):
        return self.ORACLE_HOME_SWITCH == key

    def _validate_oracle_home_arg(self, value):
        method_name = '_validate_oracle_home_arg'

        try:
            oh = JFileUtils.validateExistingDirectory(value)
        except JIllegalArgumentException, iae:
            ex = exception_helper.create_cla_exception(
                'WLSDPLY-01602', 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

        oh_name = oh.getAbsolutePath()
        wl_helper = WebLogicHelper(self._logger)
        wl_home_name = wl_helper.get_weblogic_home(oh_name)
        try:
            JFileUtils.validateExistingDirectory(wl_home_name)
        except JIllegalArgumentException, iae:
            ex = exception_helper.create_cla_exception(
                'WLSDPLY-01603',
                wl_home_name,
                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
class CommandLineArgUtil(object):
    """
    Class that handles command-line argument parsing and common validation.
    """
    _class_name = 'CommandLineArgUtil'

    HELP_SWITCH = '-help'
    ORACLE_HOME_SWITCH = '-oracle_home'
    JAVA_HOME_SWITCH = '-java_home'
    DOMAIN_HOME_SWITCH = '-domain_home'
    DOMAIN_PARENT_SWITCH = '-domain_parent'
    DOMAIN_TYPE_SWITCH = '-domain_type'
    # never used by the tools but used by shell scripts
    WLST_PATH_SWITCH = '-wlst_path'
    ADMIN_URL_SWITCH = '-admin_url'
    ADMIN_USER_SWITCH = '-admin_user'
    # phony arg used as a key to store the password
    ADMIN_PASS_SWITCH = '-admin_pass'
    ARCHIVE_FILE_SWITCH = '-archive_file'
    MODEL_FILE_SWITCH = '-model_file'
    OPSS_WALLET_SWITCH = '-opss_wallet'
    OPSS_WALLET_PASSPHRASE = '-opss_wallet_passphrase'
    PREVIOUS_MODEL_FILE_SWITCH = '-prev_model_file'
    VARIABLE_FILE_SWITCH = '-variable_file'
    RCU_DB_SWITCH = '-rcu_db'
    RCU_PREFIX_SWITCH = '-rcu_prefix'
    # phony arg used as a key to store the password
    RCU_SYS_PASS_SWITCH = '-rcu_sys_pass'
    # phony arg used as a key to store the password
    RCU_SCHEMA_PASS_SWITCH = '-rcu_schema_pass'
    # phony arg used as a key to store the encryption passphrase
    PASSPHRASE_SWITCH = '-passphrase'
    ENCRYPT_MANUAL_SWITCH = '-manual'
    # phony arg used as a key to store the password
    ONE_PASS_SWITCH = '-password'
    ROLLBACK_IF_RESTART_REQ_SWITCH = '-rollback_if_require_restart'
    USE_ENCRYPTION_SWITCH = '-use_encryption'
    RUN_RCU_SWITCH = '-run_rcu'
    TARGET_VERSION_SWITCH = '-target_version'
    TARGET_MODE_SWITCH = '-target_mode'
    # phony arg used as a key to store the trailing (non-switched) arguments
    TRAILING_ARGS_SWITCH = '-trailing_arguments'
    ATTRIBUTES_ONLY_SWITCH = '-attributes_only'
    FOLDERS_ONLY_SWITCH = '-folders_only'
    MODEL_SAMPLE_SWITCH = '-model_sample'
    RECURSIVE_SWITCH = '-recursive'
    UPDATE_RCU_SCHEMA_PASS_SWITCH = '-updateRCUSchemaPassword'
    VALIDATION_METHOD = '-method'
    # overrides for the variable injector
    VARIABLE_INJECTOR_FILE_SWITCH = '-variable_injector_file'
    VARIABLE_KEYWORDS_FILE_SWITCH = '-variable_keywords_file'
    VARIABLE_PROPERTIES_FILE_SWITCH = '-variable_properties_file'
    # extractDomainResource output file
    DOMAIN_RESOURCE_FILE_SWITCH = '-domain_resource_file'
    COMPARE_MODEL_OUTPUT_DIR_SWITCH = "-output_dir"

    # arguments that are true if specified, false if not
    BOOLEAN_SWITCHES = [
        ATTRIBUTES_ONLY_SWITCH, ENCRYPT_MANUAL_SWITCH, FOLDERS_ONLY_SWITCH,
        MODEL_SAMPLE_SWITCH, RECURSIVE_SWITCH, ROLLBACK_IF_RESTART_REQ_SWITCH,
        RUN_RCU_SWITCH, UPDATE_RCU_SCHEMA_PASS_SWITCH, USE_ENCRYPTION_SWITCH
    ]

    # a slot to stash the parsed domain typedef dictionary
    DOMAIN_TYPEDEF = 'domain_typedef'
    # a slot to stash the archive file object
    ARCHIVE_FILE = 'archive_file'

    ARCHIVE_FILES_SEPARATOR = ','
    MODEL_FILES_SEPARATOR = ','

    HELP_EXIT_CODE = 100
    USAGE_ERROR_EXIT_CODE = 99
    ARG_VALIDATION_ERROR_EXIT_CODE = 98
    PROG_RESTART_REQUIRED = 103
    PROG_ROLLBACK_IF_RESTART_EXIT_CODE = 104
    PROG_ERROR_EXIT_CODE = 2
    PROG_WARNING_EXIT_CODE = 1
    PROG_OK_EXIT_CODE = 0

    def __init__(self, program_name, required_args, optional_args):
        self._program_name = program_name
        self._logger = PlatformLogger('wlsdeploy.util')

        self._required_args = list(required_args)
        self._optional_args = list(optional_args)
        self._allow_multiple_models = False

        #
        # Add args that all tools should accept.
        #
        self._optional_args.append(self.HELP_SWITCH)
        self._optional_args.append(self.WLST_PATH_SWITCH)

        self._required_result = {}
        self._optional_result = {}
        return

    def set_allow_multiple_models(self, allow_multiple_models):
        """
        This method determines if this instance allows multiple models to be specified for the MODEL_FILE_SWITCH
        argument. By default, multiple models are not allowed.
        :param allow_multiple_models: the flag indicating if multiple models are allowed
        """
        self._allow_multiple_models = allow_multiple_models

    def process_args(self,
                     args,
                     tool_type=TOOL_TYPE_DEFAULT,
                     trailing_arg_count=0):
        """
        This method parses the command-line arguments and returns dictionaries of the required and optional args.

        :param args: sys.argv
        :param tool_type: optional, type of tool for special argument processing
        :param trailing_arg_count: optional, the number of trailing (no switch) arguments
        :return: the required and optional argument dictionaries
        :raises CLAException: if argument processing encounters a usage or validation exception
        """

        method_name = 'process_args'

        self._logger.entering(args,
                              class_name=self._class_name,
                              method_name=method_name)
        #
        # reset the result fields in case the object was reused
        #
        self._required_result = {}
        self._optional_result = {}

        args_len = len(args)
        if args_len == 1:
            ex = exception_helper.create_cla_exception('Dummy Key')
            ex.setExitCode(self.HELP_EXIT_CODE)
            raise ex

        args = self._check_trailing_arguments(args, trailing_arg_count)
        args_len = len(args)

        idx = 1
        while idx < args_len:
            key = args[idx]
            self._logger.fine('WLSDPLY-01600',
                              key,
                              class_name=self._class_name,
                              method_name=method_name)
            if self.is_help_key(key):
                ex = exception_helper.create_cla_exception('Dummy Key')
                ex.setExitCode(self.HELP_EXIT_CODE)
                raise ex
            elif self.is_oracle_home_key(key):
                value, idx = self._get_arg_value(args, idx, key)
                full_path = self._validate_oracle_home_arg(value)
                self._add_arg(key, full_path, True)
            elif self.is_java_home_key(key):
                value, idx = self._get_arg_value(args, idx, key)
                full_path = self._validate_java_home_arg(value)
                self._add_arg(key, full_path, True)
            elif self.is_domain_home_key(key):
                value, idx = self._get_arg_value(args, idx, key)
                if tool_type == TOOL_TYPE_CREATE:
                    full_path = self._validate_domain_home_arg_for_create(
                        value)
                elif tool_type == TOOL_TYPE_EXTRACT:
                    full_path = self._validate_domain_home_arg_for_extract(
                        value)
                else:
                    full_path = self._validate_domain_home_arg(value)
                self._add_arg(key, full_path, True)
            elif self.is_domain_parent_key(key):
                value, idx = self._get_arg_value(args, idx, key)
                full_path = self._validate_domain_parent_arg(value)
                self._add_arg(key, full_path, True)
            elif self.is_domain_type_key(key):
                value, idx = self._get_arg_value(args, idx, key)
                self._validate_domain_type_arg(value)
                self._add_arg(key, value)
            elif self.is_wlst_path_key(key):
                value, idx = self._get_arg_value(args, idx, key)
                full_path = self._validate_wlst_path_arg(value)
                self._add_arg(key, full_path, True)
            elif self.is_admin_url_key(key):
                value, idx = self._get_arg_value(args, idx, key)
                self._validate_admin_url_arg(value)
                self._add_arg(key, value)
            elif self.is_admin_user_key(key):
                value, idx = self._get_arg_value(args, idx, key)
                self._validate_admin_user_arg(value)
                self._add_arg(key, value)
            elif self.is_admin_pass_key(key):
                value, idx = self._get_arg_value(args, idx, key)
                self._validate_admin_pass_arg(value)
                self._add_arg(key, value)
            elif self.is_archive_file_key(key):
                value, idx = self._get_arg_value(args, idx, key)
                full_path = self._validate_archive_file_arg(value)
                self._add_arg(key, full_path, True)
            elif self.is_opss_passphrase_key(key):
                value, idx = self._get_arg_value(args, idx, key)
                self._validate_opss_passphrase_arg(value)
                self._add_arg(key, value)
            elif self.is_opss_wallet_key(key):
                value, idx = self._get_arg_value(args, idx, key)
                full_path = self._validate_opss_wallet_arg(value)
                self._add_arg(key, full_path, True)
            elif self.is_model_file_key(key):
                value, idx = self._get_arg_value(args, idx, key)
                full_path = self._validate_model_file_arg(value)
                self._add_arg(key, full_path, True)
            elif self.is_previous_model_file_key(key):
                value, idx = self._get_arg_value(args, idx, key)
                full_path = self._validate_previous_model_file_arg(value)
                self._add_arg(key, full_path, True)
            elif self.is_validate_method_key(key):
                value, idx = self._get_arg_value(args, idx, key)
                context = self._validate_validate_method_arg(value)
                self._add_arg(key, context)
            elif self.is_variable_file_key(key):
                value, idx = self._get_arg_value(args, idx, key)
                self._add_arg(key, value, True)
            elif self.is_rcu_database_key(key):
                value, idx = self._get_arg_value(args, idx, key)
                self._validate_rcu_database_arg(value)
                self._add_arg(key, value)
            elif self.is_rcu_prefix_key(key):
                value, idx = self._get_arg_value(args, idx, key)
                self._validate_rcu_prefix_arg(value)
                self._add_arg(key, value)
            elif self.is_rcu_sys_pass_key(key):
                value, idx = self._get_arg_value(args, idx, key)
                self._validate_rcu_sys_pass_arg(value)
                self._add_arg(key, value)
            elif self.is_rcu_schema_pass_key(key):
                value, idx = self._get_arg_value(args, idx, key)
                self._validate_rcu_schema_pass_arg(value)
                self._add_arg(key, value)
            elif self.is_passphrase_switch(key):
                value, idx = self._get_arg_value(args, idx, key)
                self._validate_passphrase_arg(value)
                self._add_arg(key, value)
            elif self.is_one_pass_switch(key):
                value, idx = self._get_arg_value(args, idx, key)
                self._validate_one_pass_arg(value)
                self._add_arg(key, value)
            elif self.is_target_version_switch(key):
                value, idx = self._get_arg_value(args, idx, key)
                self._validate_target_version_arg(value)
                self._add_arg(key, value)
            elif self.is_target_mode_switch(key):
                value, idx = self._get_arg_value(args, idx, key)
                self._validate_target_mode_arg(value)
                self._add_arg(key, value)
            elif self.is_variable_injector_file_key(key):
                value, idx = self._get_arg_value(args, idx, key)
                full_path = self._validate_variable_injector_file_arg(value)
                self._add_arg(key, full_path, True)
            elif self.is_variable_keywords_file_key(key):
                value, idx = self._get_arg_value(args, idx, key)
                full_path = self._validate_variable_keywords_file_arg(value)
                self._add_arg(key, full_path, True)
            elif self.is_variable_properties_file_key(key):
                value, idx = self._get_arg_value(args, idx, key)
                full_path = self._validate_variable_properties_file_arg(value)
                self._add_arg(key, full_path, True)
            elif self.is_domain_resource_file_key(key):
                value, idx = self._get_arg_value(args, idx, key)
                full_path = self._validate_domain_resource_file_arg(value)
                self._add_arg(key, full_path, True)
            elif self.is_boolean_switch(key):
                self._add_arg(key, True)
            elif self.is_compare_model_output_dir_switch(key):
                value, idx = self._get_arg_value(args, idx, key)
                full_path = self._validate_compare_model_output_dir_arg(value)
                self._add_arg(key, full_path, True)
            else:
                ex = exception_helper.create_cla_exception(
                    'WLSDPLY-01601', self._program_name, key)
                ex.setExitCode(self.USAGE_ERROR_EXIT_CODE)
                self._logger.throwing(ex,
                                      class_name=self._class_name,
                                      method_name=method_name)
                raise ex
            idx += 1

        print_result = {
            'required': self._required_result,
            'optional': self._optional_result
        }
        self._logger.exiting(class_name=self._class_name,
                             method_name=method_name,
                             result=print_result)
        return self._required_result, self._optional_result

    def _get_arg_value(self, args, index, key):
        """
        Return the value after the specified index in the argument array.
        Throw an exception if the next index is past the end of the arguments.
        :param args: the arguments to be examined
        :param index: the index argument before the value
        :param key: the key of the previous argument, for logging
        :return: the value of the argument, and the next index value
        """
        method_name = '_get_arg_value'
        key = args[index]
        index = index + 1
        if index >= len(args):
            ex = self._get_out_of_args_exception(key)
            self._logger.throwing(ex,
                                  class_name=self._class_name,
                                  method_name=method_name)
            raise ex
        return args[index], index

    def _check_trailing_arguments(self, args, trailing_arg_count):
        """
        Remove any trailing (no switch) arguments from the argument list and add them to the required result.
          example:
            command.sh -oracle_home /oracle file1 file2
            file1 and file2 are trailing arguments

        :param args: the arguments to be examined
        :param trailing_arg_count: the number of trailing arguments that are expected
        :return: the argument list, with the trailing arguments removed
        :raises CLAException: if there are not enough arguments present
        """
        method_name = '_check_trailing_arguments'
        args_len = len(args)

        # verify there are enough arguments for any trailing (no switch) args
        if args_len < trailing_arg_count + 1:
            ex = exception_helper.create_cla_exception('WLSDPLY-01639',
                                                       trailing_arg_count)
            ex.setExitCode(self.ARG_VALIDATION_ERROR_EXIT_CODE)
            self._logger.throwing(ex,
                                  class_name=self._class_name,
                                  method_name=method_name)
            raise ex

        # set required_result['TRAILING_ARGS'] to list of trailing args (such as ['file1', 'file2'])
        trailing_args = []
        for index in range(args_len - trailing_arg_count, args_len):
            arg = args[index]
            trailing_args.append(arg)
        self._required_result[self.TRAILING_ARGS_SWITCH] = trailing_args

        # remove trailing args from the list and return revised list
        return args[0:(args_len - trailing_arg_count)]

    def get_help_key(self):
        return self.HELP_SWITCH

    def is_help_key(self, key):
        return self.HELP_SWITCH == key

    def get_oracle_home_key(self):
        return str(self.ORACLE_HOME_SWITCH)

    def is_oracle_home_key(self, key):
        return self.ORACLE_HOME_SWITCH == key

    def _validate_oracle_home_arg(self, value):
        method_name = '_validate_oracle_home_arg'

        try:
            oh = JFileUtils.validateExistingDirectory(value)
        except JIllegalArgumentException, iae:
            ex = exception_helper.create_cla_exception(
                'WLSDPLY-01602', 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

        oh_name = oh.getAbsolutePath()
        wl_helper = WebLogicHelper(self._logger)
        wl_home_name = wl_helper.get_weblogic_home(oh_name)
        try:
            JFileUtils.validateExistingDirectory(wl_home_name)
        except JIllegalArgumentException, iae:
            ex = exception_helper.create_cla_exception(
                'WLSDPLY-01603',
                wl_home_name,
                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
class OnlineGenerator(GeneratorHelper):
    """
    Generate MBean and attribute information into a dictionary from the online wlst session.
    The data is traversed using the registered mbean information for the online session.
    """

    def __init__(self, model_context, dictionary):
        GeneratorHelper.__init__(self,  model_context, dictionary)
        self.__class_name__ = self.__class__.__name__
        self._domain_home = None
        self.__logger = PlatformLogger('test.aliases.generate', resource_bundle_name='aliastest_rb')
        self.__logger.set_level(Level.FINER)

    def generate(self):
        """
        Generate the mbean dictionary for weblogic in wlst online mode.
        :return: the domain home of the connected session
        """
        _method_name = 'generate'
        self.__logger.entering(class_name=self.__class_name__, method_name=_method_name)
        if generator_wlst.connect(self._helper.admin_user(), self._helper.admin_password(), self._helper.admin_url()):
            try:
                self.__folder_hierarchy(self._dictionary, '/')
            finally:
                generator_wlst.disconnect()
        self.__logger.exiting(class_name=self.__class_name__, method_name=_method_name)
        return

    def __folder_hierarchy(self, mbean_dictionary, mbean_path):
        _method_name = '__folder_hierarchy'
        self.__logger.entering(mbean_path, class_name=self.__class_name__, method_name=_method_name)

        mbean_instance = generator_wlst.get_mbean_proxy(mbean_path)

        mbean_dictionary[all_utils.ATTRIBUTES] = self.__get_attributes(mbean_instance)

        mbean_map = self.__create_any_subfolders()

        info_helper = MBeanInfoHelper(mbean_instance, mbean_path)
        mbean_info_map = info_helper.get_child_mbeans()
        mbean_info_list = mbean_info_map.keys()

        mbi_helper = MBIHelper(mbean_instance, mbean_path)
        mbean_mbi_map = mbi_helper.get_child_mbeans()
        for mbean_type, attribute_helper in mbean_mbi_map.iteritems():
            mbean_name = None
            # mbean_type is the name of the child MBean attribute in the mbean Helper attribute list
            if mbean_type in mbean_map:
                mbean_name = mbean_map[mbean_type]
                del mbean_map[mbean_type]
            if mbean_type in mbean_info_list:
                mbean_info_list.remove(mbean_type)
                self.__logger.finest('Child MBean {0} is in both the MBI information and the MBeanInfo information',
                                   mbean_type, class_name=self.__class_name__, method_name=_method_name)
            else:
                self.__logger.fine('Child MBean {0} is in the MBI information but not the MBeanInfo information',
                                   mbean_type, class_name=self.__class_name__, method_name=_method_name)

            if attribute_helper.is_reference_only():
                mbean_dictionary[mbean_type] = all_utils.dict_obj()
                # This non-attribute might have been added as a folder, which it is not
                mbean_dictionary[mbean_type][all_utils.ONLINE_REFERENCE_ONLY] = all_utils.TRUE
                continue

            if self._is_valid_folder(attribute_helper):
                self.__logger.fine('WLSDPLYST-01115', mbean_type, generator_wlst.current_path(),
                                   class_name=self.__class_name__, method_name=_method_name)
                mbean_dictionary[mbean_type] = all_utils.dict_obj()
                attribute_helper.generate_mbean(mbean_dictionary[mbean_type])
                if mbean_name is None:
                    mbean_name = generator_wlst.get_singleton_name(mbean_type)
                if mbean_name is not None:
                    if mbean_type in generator_wlst.child_mbean_types():
                        mbean_dictionary[mbean_type][all_utils.INSTANCE_TYPE] = all_utils.MULTIPLE
                    else:
                        mbean_dictionary[mbean_type][all_utils.INSTANCE_TYPE] = all_utils.SINGLE
                    bean_dir = mbean_type + '/' + mbean_name
                    if not generator_wlst.cd_mbean(bean_dir):
                        self.__logger.fine('WLSDPLYST-01117', mbean_type, generator_wlst.current_path(), '',
                                           class_name=self.__class_name__, method_name=_method_name)
                        mbean_dictionary[mbean_type][all_utils.RECHECK] = \
                            'cd to mbean and mbean name returned exception'
                        continue

                    self.__folder_hierarchy(mbean_dictionary[mbean_type], generator_wlst.current_path())
                    generator_wlst.cd_mbean('../..')
            else:
                # make this a real message
                self.__logger.warning('Ignore invalid MBean folder {0} containment : {1}, deprecated : {2}',
                                      mbean_type, all_utils.str_bool(attribute_helper.is_containment()),
                                      all_utils.str_bool(attribute_helper.is_deprecated()),
                                      class_name=self.__class_name__, method_name=_method_name)

        if len(mbean_map) > 0:
            mbeans_only = [leftover for leftover in mbean_map if leftover not in mbi_helper.get_all_attributes()]
            if len(mbeans_only) > 0:
                for mbean_type in mbeans_only:
                    # If it is in the attribute list, its a reference
                    if mbi_helper.get_all_attribute(mbean_type).is_attribute_found() is False:
                        self.__logger.fine('MBean {0} was not found in the MBI map but is in the LSC map',
                                           mbean_type, class_name=self.__class_name__, method_name=_method_name)
                        info_attribute_helper = info_helper.get_child_mbean(mbean_type)
                        if info_attribute_helper.is_attribute_found():
                            self.__logger.fine('Child MBean {0} is in the MBeanInfo information but not'
                                               ' the MBI information',
                                               class_name=self.__class_name__, method_name=_method_name)
                        mbean_name = mbean_map[mbean_type]
                        if mbean_name is not None:
                            bean_dir = mbean_type + '/' + mbean_name
                            mbean_dictionary[mbean_type] = all_utils.dict_obj()
                            if generator_wlst.cd_mbean(bean_dir) is False:
                                self.__logger.fine('WLSDPLYST-01117', mbean_type, generator_wlst.current_path(), '',
                                                   class_name=self.__class_name__, method_name=_method_name)
                                mbean_dictionary[mbean_type][all_utils.RECHECK] = \
                                    'cd to mbean and mbean name returned exception'
                                continue

                            self.__folder_hierarchy(mbean_dictionary[mbean_type], generator_wlst.current_path())
                            generator_wlst.cd_mbean('../..')
        self.__logger.exiting(class_name=self.__class_name__, method_name=_method_name)
        return

    def __get_attributes(self, mbean_instance):
        _method_name = '__get_attributes'
        mbean_path = generator_wlst.current_path()
        self.__logger.entering(mbean_instance, mbean_path, class_name=self.__class_name__, method_name=_method_name)
        lsa_map = generator_wlst.lsa_map_modified()
        not_found_mbean_list = list()
        if len(lsa_map) > 0:
            not_found_mbean_list = lsa_map.keys()
            not_found_mbean_list.sort()

        mbean_instance = generator_wlst.get_mbean_proxy(mbean_path)
        operation_list = generator_wlst.ls_operations()
        info_helper = MBeanInfoHelper(mbean_instance, mbean_path)
        mbean_type = info_helper.get_mbean_type()
        mbean_info_map = info_helper.get_attributes()
        mbean_info_list = mbean_info_map.keys()
        self.__logger.finest('MBean {0} LSA map attributes are {1} at location {2} mbean_path',
                             mbean_type, not_found_mbean_list, mbean_path,
                             class_name=self.__class_name__, method_name=_method_name)

        method_helper = MBeanMethodHelper(mbean_instance, mbean_path)
        method_map = method_helper.get_attributes()

        # The main driver must have all attributes in the map
        mbi_helper = MBIHelper(mbean_instance, mbean_path)
        mbean_mbi_map = mbi_helper.get_all_attributes()

        attributes = all_utils.dict_obj()
        for attribute, attribute_helper in mbean_mbi_map.iteritems():
            self.__logger.finer('Processing MBean {0} attribute {1} from MBI map', mbean_type, attribute,
                                class_name=self.__class_name__, method_name=_method_name)
            info_attribute_helper = None
            if attribute in mbean_info_list:
                info_attribute_helper = mbean_info_map[attribute]
                mbean_info_list.remove(attribute)

            method_helper = None
            if attribute in method_map:
                method_helper = method_map[attribute]

            if attribute not in lsa_map:
                if self._is_valid_cmo_attribute(attribute_helper, info_attribute_helper):
                    self.__logger.fine('Adding MBean {0} attribute {1} from location {2} '
                                       'that is in MBI map and not in LSA map', mbean_type, attribute, mbean_path,
                                       class_name=self.__class_name__, method_name=_method_name)
                    holder = all_utils.dict_obj()
                    self.add_default_value(holder, lsa_map, attribute_helper, method_helper)
                    attribute_helper.generate_attribute(holder)
                    attributes[attribute] = all_utils.sort_dict(holder)
            else:
                not_found_mbean_list.remove(attribute)
                if self._is_valid_attribute(attribute, attribute_helper, info_attribute_helper):
                    self.__logger.finer('Adding MBean {0} attribute {1} from location {2} which is in LSA and MBI maps',
                                        mbean_type, attribute, mbean_path,
                                        class_name=self.__class_name__, method_name=_method_name)
                    holder = all_utils.dict_obj()
                    self.add_default_value(holder, lsa_map, attribute_helper, method_helper)
                    attribute_helper.generate_attribute(holder)
                    attributes[attribute] = all_utils.sort_dict(holder)

        for attribute in mbean_info_list:
            self.__logger.finer('Processing MBean {0} attribute {1} from MBeanInfo map',
                                mbean_type, attribute,
                                class_name=self.__class_name__, method_name=_method_name)
            if attribute in not_found_mbean_list:
                not_found_mbean_list.remove(attribute)
            attribute_helper = mbean_info_map[attribute]
            method_helper = None
            if attribute in method_map:
                method_helper = method_map[attribute]
            if self._is_valid_cmo_attribute(attribute_helper, method_helper):
                self.__logger.fine('Adding MBean {0} attribute {1} found in MBeanInfo but not MBI',
                                   mbean_type, attribute,
                                   class_name=self.__class_name__, method_name=_method_name)
                holder = all_utils.dict_obj()
                self.add_default_value(holder, lsa_map, attribute_helper, method_helper)
                attribute_helper.generate_attribute(holder)
                attributes[attribute] = all_utils.sort_dict(holder)

        for lsa_only in not_found_mbean_list:
            self.__logger.finer('Processing MBean {0} attribute {1} from LSA map', mbean_type, lsa_only,
                                class_name=self.__class_name__, method_name=_method_name)
            if lsa_only in operation_list:
                continue

            method_helper = None
            if lsa_only in method_map:
                method_helper = method_map[lsa_only]

            if lsa_only in mbean_info_map:
                attribute_helper = mbean_info_map[lsa_only]
                mbean_info_list.remove(lsa_only)
            elif method_helper is not None:
                attribute_helper = method_helper
            else:
                # Fake one up
                attribute_helper = mbi_helper.get_attribute(lsa_only)
            if self._is_valid_lsa(attribute_helper):
                self.__logger.fine('MBean {0} attribute {1} that is in LSA and not MBI is found in the MBeanInfo : {2}',
                                   mbean_type, lsa_only, Boolean(info_helper.get_attribute(lsa_only) is not None),
                                   class_name=self.__class_name__, method_name=_method_name)
                holder = all_utils.dict_obj()
                # Not all LSA with -rw- really are -rw-. Might need to add in a physical attempt to set
                # if to find attributes without a set method that CAN be set in offline.
                # However, I suspect that if no set method, then cannot RW
                self.add_default_value(holder, lsa_map, attribute_helper, method_helper)
                if attribute_helper.is_attribute_found():
                    self.__logger.finer('MBean {0} attribute {1} in LSA map will generate attribute info '
                                        'from additional helper', mbean_type, lsa_only,
                                        class_name=self.__class_name__, method_name=_method_name)
                    attribute_helper.generate_attribute(holder)
                else:
                    self.__logger.fine('MBean {0} attribute {1} is found only in the LSA map', mbean_type, lsa_only,
                                       class_name=self.__class_name__, method_name=_method_name)
                attributes[lsa_only] = all_utils.sort_dict(holder)

        self.__logger.exiting(class_name=self.__class_name__, method_name=_method_name)
        return all_utils.sort_dict(attributes)

    def __create_any_subfolders(self):
        _method_name = 'create_any_subfolders'
        subfolder_list = all_utils.dict_obj()
        operation_map = generator_wlst.ls_operations()
        # create_by_operation_list = HashSet(operation_map.keySet())
        # for operation in operation_map.keySet():
        #     if operation.startswith(CREATE) and not operation.endswith('FromBuiltin'):
        #         mbean_type = operation[len(CREATE):]
        #         name1, name2 = helper.mbean_name(mbean_type)
        #         if not do_operation(name1, operation) and not do_operation(name2, operation):
        #             create_by_operation_list.remove(operation)

        checklist = generator_wlst.lsc_modified()
        if checklist is None:
            self.__logger.fine('WLSDPLYST-01320', generator_wlst.current_path(), '',
                               class_name=self.__class_name__, method_name=_method_name)
            return subfolder_list

        for check in checklist:
            if check not in operation_map:
                name_list = generator_wlst.ls_mbean_names(check)
                if name_list is None:
                    self.__logger.finer('WLSDPLYST-01121', check, '',
                                       class_name=self.__class_name__, method_name=_method_name)
                    continue
                    # if empty, it returns a str

                if name_list and len(str(name_list).strip()) > 0:
                    subfolder_list[check] = name_list[0]

        child_types = generator_wlst.child_mbean_types()
        if child_types is not None:
            for child_type in child_types:
                if child_type not in subfolder_list:
                    name1, name2 = all_utils.mbean_name(child_type)
                    if generator_wlst.created(child_type, name1) or generator_wlst.created(child_type, name2):
                        name_list = generator_wlst.ls_mbean_names(child_type)
                        if name_list is not None and len(str(name_list).strip()) > 0:
                            subfolder_list[child_type] = name_list[0]

        return subfolder_list
class OdlDeployer(object):
    """
    Handle the ODL validation and configuration.
    """
    __class_name = 'OdlHelper'

    def __init__(self, model, model_context, aliases, wlst_mode):
        self.model = model
        self.model_context = model_context
        self.aliases = aliases

        self.logger = PlatformLogger('wlsdeploy.deploy')
        self.wlst_mode = wlst_mode

    def configure_odl(self, parent_dict, parent_location):
        """
        Apply the ODL configuration section of the model, if present.
        :param parent_dict: the model dictionary that may contains ODL configuration
        :param parent_location: the alias location of the parent dictionary (used for logging paths)
        """
        _method_name = 'configure_odl'
        self.logger.entering(class_name=self.__class_name,
                             method_name=_method_name)

        odl_info = dictionary_utils.get_dictionary_element(
            parent_dict, ODL_CONFIGURATION)
        if len(odl_info):
            typedef = self.model_context.get_domain_typedef()
            if not (typedef.is_jrf_domain_type()
                    or typedef.is_restricted_jrf_domain_type()):
                self.logger.info('WLSDPLY-19709',
                                 class_name=self.__class_name,
                                 method_name=_method_name)
            elif self.wlst_mode == WlstModes.ONLINE:
                self.logger.info('WLSDPLY-19700',
                                 class_name=self.__class_name,
                                 method_name=_method_name)
            else:
                for config in odl_info:
                    self._update_config(config, odl_info[config],
                                        parent_location)

        self.logger.exiting(class_name=self.__class_name,
                            method_name=_method_name)
        return

    def _update_config(self, config_name, config_dictionary, parent_location):
        _method_name = '_update_config'

        config_location = LocationContext(parent_location).append_location(
            ODL_CONFIGURATION)
        token = self.aliases.get_name_token(config_location)
        config_location.add_name_token(token, config_name)

        servers = dictionary_utils.get_element(config_dictionary, _SERVERS)
        if servers is not None:
            servers_list = alias_utils.convert_to_type(
                'list', servers, delimiter=MODEL_LIST_DELIMITER)
            for server in servers_list:
                self.logger.info('WLSDPLY-19708',
                                 ODL_CONFIGURATION,
                                 config_name,
                                 server,
                                 class_name=self.__class_name,
                                 method_name=_method_name)
                self._update_server(server, config_dictionary, config_location)

    def _update_server(self, name, dictionary, config_location):
        _method_name = '_update_server'

        # these imports are local, since they are only present in JRF environments.
        # this method is only called after that check has been made.
        from oracle.core.ojdl.weblogic.ODLConfiguration import CONFIG_DIR
        from oracle.core.ojdl.weblogic.ODLConfiguration import CONFIG_FILE
        from oracle.core.ojdl.logging.config import LoggingConfigurationDocument

        config_dir = File(self.model_context.get_domain_home(), CONFIG_DIR)
        server_dir = File(config_dir, name)
        config_file = File(server_dir, CONFIG_FILE)
        log_template_dir = config_dir.getParentFile()

        try:
            if config_file.exists():
                source_file = config_file
                FileUtils.validateWritableFile(config_file.getPath())
            else:
                # for dynamic servers, the logging config does not exist until the server is started.
                # read the from template file, verify that the server directory is present and writable.
                source_file = File(log_template_dir, LOGGING_TEMPLATE_FILE)
                FileUtils.validateExistingFile(source_file)
                if not server_dir.exists() and not server_dir.mkdirs():
                    ex = exception_helper.create_deploy_exception(
                        'WLSDPLY-19710', server_dir)
                    self.logger.throwing(ex,
                                         class_name=self.__class_name,
                                         method_name=_method_name)
                    raise ex
                FileUtils.validateWritableDirectory(server_dir.getPath())

            document = LoggingConfigurationDocument(
                FileInputStream(source_file))

            # configure AddJvmNumber
            add_jvm_number = dictionary_utils.get_element(
                dictionary, _ADD_JVM_NUMBER)
            if add_jvm_number is not None:
                document.setAddJvmNumber(
                    alias_utils.convert_boolean(add_jvm_number))

            # configure HandlerDefaults
            handler_defaults = dictionary_utils.get_dictionary_element(
                dictionary, _HANDLER_DEFAULTS)
            if handler_defaults is not None:
                for key in handler_defaults:
                    value = handler_defaults[key]
                    document.setHandlerDefault(key, _get_property_text(value))

            # configure Handlers
            # do these before loggers, in case new handlers are assigned to loggers
            existing_handler_names = document.getHandlerNames()
            handlers = dictionary_utils.get_dictionary_element(
                dictionary, _HANDLER)
            if handlers is not None:
                for handler_name in handlers:
                    handler = handlers[handler_name]
                    self._configure_handler(handler_name, handler, document,
                                            existing_handler_names,
                                            config_location)

            # configure Loggers
            existing_logger_names = document.getLoggerNames()
            loggers = dictionary_utils.get_dictionary_element(
                dictionary, _LOGGER)
            if loggers is not None:
                for logger_name in loggers:
                    logger = loggers[logger_name]
                    self._configure_logger(logger_name, logger, document,
                                           existing_logger_names,
                                           config_location)

            document.writeDocument(FileOutputStream(config_file))

        except (ParserConfigurationException, SAXException, IOException,
                IllegalArgumentException), ex:
            self.logger.severe('WLSDPLY-19707',
                               name,
                               ex.getLocalizedMessage(),
                               class_name=self.__class_name,
                               method_name=_method_name)
        return