示例#1
0
    def __init__(self,
                 model,
                 model_context,
                 aliases,
                 wlst_mode=WlstModes.OFFLINE):
        Deployer.__init__(self, model, model_context, aliases, wlst_mode)
        self._topology = self.model.get_model_topology()
        self._resources = self.model.get_model_resources()
        self._topology_helper = TopologyHelper(self.aliases,
                                               ExceptionType.DEPLOY,
                                               self.logger)
        self._domain_typedef = self.model_context.get_domain_typedef()

        self._security_provider_creator = SecurityProviderCreator(
            model.get_model(), model_context, aliases, ExceptionType.DEPLOY,
            self.logger)

        self.library_helper = LibraryHelper(self.model, self.model_context,
                                            self.aliases,
                                            model_context.get_domain_home(),
                                            ExceptionType.DEPLOY, self.logger)

        self.target_helper = TargetHelper(self.model, self.model_context,
                                          self.aliases, ExceptionType.DEPLOY,
                                          self.logger)
示例#2
0
class TopologyUpdater(Deployer):
    """
    Deploy relevant resources at the domain level using WLST.  Entry point, deploy()
    """
    _class_name = "TopologyUpdater"

    def __init__(self,
                 model,
                 model_context,
                 aliases,
                 wlst_mode=WlstModes.OFFLINE):
        Deployer.__init__(self, model, model_context, aliases, wlst_mode)
        self._topology = self.model.get_model_topology()
        self._resources = self.model.get_model_resources()
        self._topology_helper = TopologyHelper(self.aliases,
                                               ExceptionType.DEPLOY,
                                               self.logger)
        self._domain_typedef = self.model_context.get_domain_typedef()

        self._security_provider_creator = SecurityProviderCreator(
            model.get_model(), model_context, aliases, ExceptionType.DEPLOY,
            self.logger)

        self.library_helper = LibraryHelper(self.model, self.model_context,
                                            self.aliases,
                                            model_context.get_domain_home(),
                                            ExceptionType.DEPLOY, self.logger)

        self.target_helper = TargetHelper(self.model, self.model_context,
                                          self.aliases, ExceptionType.DEPLOY,
                                          self.logger)

    # Override
    def _add_named_elements(self, type_name, model_nodes, location):
        """
        Override default behavior to create placeholders for referenced Coherence clusters.
        :param type_name: the model folder type
        :param model_nodes: the model dictionary of the specified model folder type
        :param location: the location object to use to create the MBeans
        :raises: DeployException: if an error occurs
        """
        self._topology_helper.check_coherence_cluster_references(
            type_name, model_nodes)
        # continue with regular processing

        Deployer._add_named_elements(self, type_name, model_nodes, location)

    def update(self):
        """
        Deploy resource model elements at the domain level, including multi-tenant elements.
        """
        domain_token = deployer_utils.get_domain_token(self.alias_helper)
        location = LocationContext()
        location.add_name_token(domain_token,
                                self.model_context.get_domain_name())

        # create a list, then remove each element as it is processed
        folder_list = self.alias_helper.get_model_topology_top_level_folder_names(
        )

        # /Security cannot be updated on existing domain
        folder_list.remove(SECURITY)

        self._security_provider_creator.create_security_configuration(location)
        folder_list.remove(SECURITY_CONFIGURATION)

        self._process_section(self._topology, folder_list, MACHINE, location)
        self._process_section(self._topology, folder_list, UNIX_MACHINE,
                              location)

        # avoid circular references between clusters and server templates
        self._topology_helper.create_placeholder_server_templates(
            self._topology)

        self._process_section(self._topology, folder_list, CLUSTER, location)
        self._process_section(self._topology, folder_list, SERVER_TEMPLATE,
                              location)
        self._process_section(self._topology, folder_list, SERVER, location)

        self._process_section(self._topology, folder_list, MIGRATABLE_TARGET,
                              location)

        # process remaining top-level folders. copy list to avoid concurrent update in loop
        remaining = list(folder_list)
        for folder_name in remaining:
            self._process_section(self._topology, folder_list, folder_name,
                                  location)

        server_groups_to_target = self._domain_typedef.get_server_groups_to_target(
        )
        self.target_helper.target_server_groups_to_servers(
            server_groups_to_target)

        # files referenced in attributes are extracted as attributes are processed

        self.library_helper.install_domain_libraries()
        self.library_helper.extract_classpath_libraries()

    def _process_section(self, folder_dict, folder_list, key, location):
        if key in folder_dict:
            nodes = dictionary_utils.get_dictionary_element(folder_dict, key)
            sub_location = LocationContext(location).append_location(key)
            if self.alias_helper.supports_multiple_mbean_instances(
                    sub_location):
                self._add_named_elements(key, nodes, location)
            else:
                self._add_model_elements(key, nodes, location)

            folder_list.remove(key)
示例#3
0
class TopologyUpdater(Deployer):
    """
    Deploy relevant resources at the domain level using WLST.  Entry point, deploy()
    """
    _class_name = "TopologyUpdater"

    def __init__(self,
                 model,
                 model_context,
                 aliases,
                 wlst_mode=WlstModes.OFFLINE):
        Deployer.__init__(self, model, model_context, aliases, wlst_mode)
        self._topology = self.model.get_model_topology()
        self._resources = self.model.get_model_resources()
        self._exception_type = ExceptionType.DEPLOY
        self._topology_helper = TopologyHelper(self.aliases,
                                               self._exception_type,
                                               self.logger)
        self._domain_typedef = self.model_context.get_domain_typedef()

        self._security_provider_creator = SecurityProviderCreator(
            model.get_model(), model_context, aliases, self._exception_type,
            self.logger)

        self.library_helper = LibraryHelper(self.model, self.model_context,
                                            self.aliases,
                                            model_context.get_domain_home(),
                                            self._exception_type, self.logger)

        self.target_helper = TargetHelper(self.model, self.model_context,
                                          self.aliases, self._exception_type,
                                          self.logger)

    # Override
    def _add_named_elements(self, type_name, model_nodes, location):
        """
        Override default behavior to create placeholders for referenced Coherence clusters.
        :param type_name: the model folder type
        :param model_nodes: the model dictionary of the specified model folder type
        :param location: the location object to use to create the MBeans
        :raises: DeployException: if an error occurs
        """
        self._topology_helper.check_coherence_cluster_references(
            type_name, model_nodes)
        # continue with regular processing

        Deployer._add_named_elements(self, type_name, model_nodes, location)

    # Override
    def _add_model_elements(self, type_name, model_nodes, location):
        Deployer._add_model_elements(self, type_name, model_nodes, location)

        # check for file paths that need to be qualified
        self._topology_helper.qualify_nm_properties(type_name, model_nodes,
                                                    location,
                                                    self.model_context,
                                                    self.attribute_setter)

    def update(self):
        """
        Deploy resource model elements at the domain level, including multi-tenant elements.
        """
        # For issue in setServerGroups in online mode (new configured clusters and stand-alone managed servers
        # will not have extension template resources targeted)
        existing_managed_servers, existing_configured_clusters = self._create_list_of_setservergroups_targets(
        )
        domain_token = deployer_utils.get_domain_token(self.alias_helper)

        location = LocationContext()
        location.add_name_token(domain_token,
                                self.model_context.get_domain_name())

        # create a list, then remove each element as it is processed
        folder_list = self.alias_helper.get_model_topology_top_level_folder_names(
        )

        # /Security cannot be updated on existing domain
        folder_list.remove(SECURITY)

        self._security_provider_creator.create_security_configuration(location)
        folder_list.remove(SECURITY_CONFIGURATION)

        # set the domain attributes
        self._set_domain_attributes()

        self._process_section(self._topology, folder_list, ADMIN_CONSOLE,
                              location)
        self._process_section(self._topology, folder_list, MACHINE, location)
        self._process_section(self._topology, folder_list, UNIX_MACHINE,
                              location)

        # avoid circular references between clusters and server templates
        self._topology_helper.create_placeholder_server_templates(
            self._topology)

        # create placeholders for JDBC resources that may be referenced in cluster definition.
        self._topology_helper.create_placeholder_jdbc_resources(
            self._resources)

        self._process_section(self._topology, folder_list, CLUSTER, location)
        self._process_section(self._topology, folder_list, SERVER_TEMPLATE,
                              location)

        # create placeholders for Servers that are in a cluster as /Server/JTAMigratableTarget
        # can reference "other" servers
        self._topology_helper.create_placeholder_servers_in_cluster(
            self._topology)

        self._process_section(self._topology, folder_list, SERVER, location)

        self._process_section(self._topology, folder_list, MIGRATABLE_TARGET,
                              location)

        new_managed_server_list, new_configured_cluster_list = self._create_list_of_setservergroups_targets(
        )

        self._check_for_online_setservergroups_issue(existing_managed_servers,
                                                     new_managed_server_list)
        self._check_for_online_setservergroups_issue(
            existing_configured_clusters, new_configured_cluster_list)

        # process remaining top-level folders. copy list to avoid concurrent update in loop
        remaining = list(folder_list)
        for folder_name in remaining:
            self._process_section(self._topology, folder_list, folder_name,
                                  location)

        if self.wls_helper.is_set_server_groups_supported():
            server_groups_to_target = self._domain_typedef.get_server_groups_to_target(
            )
            server_assigns, dynamic_assigns = \
                self.target_helper.target_server_groups_to_servers(server_groups_to_target)
            if len(dynamic_assigns) > 0:
                self.wlst_helper.save_and_close(self.model_context)
                self.target_helper.target_server_groups_to_dynamic_clusters(
                    dynamic_assigns)
                self.wlst_helper.reopen(self.model_context)
            if len(server_assigns) > 0:
                self.target_helper.target_server_groups(server_assigns)
        elif self._domain_typedef.is_jrf_domain_type():
            self.target_helper.target_jrf_groups_to_clusters_servers()

        self.library_helper.install_domain_libraries()
        self.library_helper.extract_classpath_libraries()

    def _process_section(self, folder_dict, folder_list, key, location):
        if key in folder_dict:
            nodes = dictionary_utils.get_dictionary_element(folder_dict, key)
            sub_location = LocationContext(location).append_location(key)
            if self.alias_helper.supports_multiple_mbean_instances(
                    sub_location):
                self._add_named_elements(key, nodes, location)
            else:
                self._add_model_elements(key, nodes, location)

        if key in folder_list:
            folder_list.remove(key)

    def _set_domain_attributes(self):
        _method_name = '_set_domain_attributes'
        self.logger.fine('WLSDPLY-09700',
                         self.model_context.get_domain_name(),
                         class_name=self._class_name,
                         method_name=_method_name)
        attrib_dict = dictionary_utils.get_dictionary_attributes(
            self._topology)

        # skip any attributes that have special handling in create
        for attribute in CREATE_ONLY_DOMAIN_ATTRIBUTES:
            if attribute in attrib_dict:
                del attrib_dict[attribute]

        location = LocationContext()
        attribute_path = self.alias_helper.get_wlst_attributes_path(location)
        self.wlst_helper.cd(attribute_path)
        self.set_attributes(location, attrib_dict)

    def is_online_with_ext_templates(self):
        return self.model_context.is_wlst_online(
        ) and self.model_context.get_domain_typedef().has_extension_templates(
        )

    def _check_for_online_setservergroups_issue(self, existing_list, new_list):
        _method_name = '_check_for_online_setservergroups_issue'
        if len(existing_list) != len(new_list):
            for entity_name in new_list:
                if entity_name not in existing_list:
                    self.logger.warning('WLSDPLY-09701',
                                        entity_name,
                                        class_name=self._class_name,
                                        method_name=_method_name)
        return

    def _create_list_of_setservergroups_targets(self):
        """
        If an update is executed in online WLST mode, return a list of all existing configured / mixed clusters and
        stand-alone managed servers. This method will be invoked to create a list of existing, and a list of new
        as added by the update tool. These lists will be compared to determine if they will encounter
        the online WLST problem with setServerGroups. The setServerGroups will target template resources to the
        new entities, but this targeting is not persisted to the config.xml.
        """
        _method_name = '_create_list_of_setservergroups_targets'
        self.logger.entering(class_name=self._class_name,
                             method_name=_method_name)

        if not self.is_online_with_ext_templates():
            self.logger.exiting(class_name=self._class_name,
                                method_name=_method_name)
            return list(), list()

        location = LocationContext().append_location(SERVER)
        server_path = self.alias_helper.get_wlst_list_path(location)
        existing_managed_servers = list()
        existing_servers = self.wlst_helper.get_existing_object_list(
            server_path)
        if existing_servers is not None:
            name_token = self.alias_helper.get_name_token(location)
            for server_name in existing_servers:
                location.add_name_token(name_token, server_name)
                wlst_path = self.alias_helper.get_wlst_attributes_path(
                    location)
                self.wlst_helper.cd(wlst_path)
                cluster_attribute = self.alias_helper.get_wlst_attribute_name(
                    location, CLUSTER)
                cluster_value = self.wlst_helper.get(cluster_attribute)
                if cluster_value is None:
                    existing_managed_servers.append(server_name)
                location.remove_name_token(name_token)

        existing_configured_clusters = list()
        location = LocationContext().append_location(CLUSTER)
        cluster_path = self.alias_helper.get_wlst_list_path(location)
        existing_clusters = self.wlst_helper.get_existing_object_list(
            cluster_path)
        if existing_clusters is not None:
            name_token = self.alias_helper.get_name_token(location)
            for cluster_name in existing_clusters:
                location.add_name_token(name_token, cluster_name)
                wlst_path = self.alias_helper.get_wlst_attributes_path(
                    location)
                self.wlst_helper.cd(wlst_path)
                ds_mbean = self.alias_helper.get_wlst_mbean_type(location)
                if not self.wlst_helper.subfolder_exists(
                        ds_mbean,
                        self.alias_helper.get_wlst_subfolders_path(location)):
                    existing_configured_clusters.append(cluster_name)
                location.remove_name_token(name_token)

        self.logger.exiting(
            class_name=self._class_name,
            method_name=_method_name,
            result='configured_clusters=' + str(existing_configured_clusters) +
            ' managed servers=' + str(existing_managed_servers))
        return existing_configured_clusters, existing_managed_servers
示例#4
0
    def __init__(self, model_dictionary, model_context, aliases):
        _method_name = '__init__'
        Creator.__init__(self, model_dictionary, model_context, aliases)

        # domainInfo section is required to get the admin password, everything else
        # is optional and will use the template defaults
        if model_helper.get_model_domain_info_key() not in model_dictionary:
            ex = exception_helper.create_create_exception('WLSDPLY-12200', self.__program_name,
                                                          model_helper.get_model_domain_info_key(),
                                                          self.model_context.get_model_file())
            self.logger.throwing(ex, class_name=self.__class_name, method_name=_method_name)
            raise ex

        self.topology_helper = TopologyHelper(self.aliases, ExceptionType.CREATE, self.logger)
        self.security_provider_creator = SecurityProviderCreator(model_dictionary, model_context, aliases,
                                                                 ExceptionType.CREATE, self.logger)

        self._domain_typedef = self.model_context.get_domain_typedef()
        self._topology = self.model.get_model_topology()
        self._domain_info = self.model.get_model_domain_info()

        if DOMAIN_NAME in self._topology:
            self._domain_name = self._topology[DOMAIN_NAME]
        else:
            self._domain_name = DEFAULT_WLS_DOMAIN_NAME
        self._domain_home = os.path.join(self.model_context.get_domain_parent_dir(), self._domain_name)

        if ADMIN_SERVER_NAME in self._topology:
            self._admin_server_name = self._topology[ADMIN_SERVER_NAME]
        else:
            self._admin_server_name = DEFAULT_ADMIN_SERVER_NAME

        self.__default_domain_name = None
        self.__default_admin_server_name = None
        self.__default_security_realm_name = None

        archive_file_name = self.model_context.get_archive_file_name()
        if archive_file_name is not None:
            self.archive_helper = ArchiveHelper(archive_file_name, self._domain_home, self.logger,
                                                exception_helper.ExceptionType.CREATE)

        self.library_helper = LibraryHelper(self.model, self.model_context, self.aliases, self._domain_home,
                                            ExceptionType.CREATE, self.logger)

        self.target_helper = TargetHelper(self.model, self.model_context, self.aliases, ExceptionType.CREATE,
                                          self.logger)

        #
        # Creating domains with the wls.jar template is busted for pre-12.1.2 domains with regards to the
        # names of the default authentication providers (both the DefaultAuthenticator and the
        # DefaultIdentityAsserter names are 'Provider', making it impossible to work with in WLST.  If
        # the WLS version is earlier than fix this as part of domain creation...
        #
        self.__fix_default_authentication_provider_names = \
            self.wls_helper.do_default_authentication_provider_names_need_fixing()

        #
        # This list gets modified as the domain is being created so do use this list for anything else...
        #
        self.__topology_folder_list = self.alias_helper.get_model_topology_top_level_folder_names()
        return
示例#5
0
class DomainCreator(Creator):
    """
    The class that driver domain creation.
    """
    __program_name = 'createDomain'
    __class_name = 'DomainCreator'

    def __init__(self, model_dictionary, model_context, aliases):
        _method_name = '__init__'
        Creator.__init__(self, model_dictionary, model_context, aliases)

        # domainInfo section is required to get the admin password, everything else
        # is optional and will use the template defaults
        if model_helper.get_model_domain_info_key() not in model_dictionary:
            ex = exception_helper.create_create_exception('WLSDPLY-12200', self.__program_name,
                                                          model_helper.get_model_domain_info_key(),
                                                          self.model_context.get_model_file())
            self.logger.throwing(ex, class_name=self.__class_name, method_name=_method_name)
            raise ex

        self.topology_helper = TopologyHelper(self.aliases, ExceptionType.CREATE, self.logger)
        self.security_provider_creator = SecurityProviderCreator(model_dictionary, model_context, aliases,
                                                                 ExceptionType.CREATE, self.logger)

        self._domain_typedef = self.model_context.get_domain_typedef()
        self._topology = self.model.get_model_topology()
        self._domain_info = self.model.get_model_domain_info()

        if DOMAIN_NAME in self._topology:
            self._domain_name = self._topology[DOMAIN_NAME]
        else:
            self._domain_name = DEFAULT_WLS_DOMAIN_NAME
        self._domain_home = os.path.join(self.model_context.get_domain_parent_dir(), self._domain_name)

        if ADMIN_SERVER_NAME in self._topology:
            self._admin_server_name = self._topology[ADMIN_SERVER_NAME]
        else:
            self._admin_server_name = DEFAULT_ADMIN_SERVER_NAME

        self.__default_domain_name = None
        self.__default_admin_server_name = None
        self.__default_security_realm_name = None

        archive_file_name = self.model_context.get_archive_file_name()
        if archive_file_name is not None:
            self.archive_helper = ArchiveHelper(archive_file_name, self._domain_home, self.logger,
                                                exception_helper.ExceptionType.CREATE)

        self.library_helper = LibraryHelper(self.model, self.model_context, self.aliases, self._domain_home,
                                            ExceptionType.CREATE, self.logger)

        self.target_helper = TargetHelper(self.model, self.model_context, self.aliases, ExceptionType.CREATE,
                                          self.logger)

        #
        # Creating domains with the wls.jar template is busted for pre-12.1.2 domains with regards to the
        # names of the default authentication providers (both the DefaultAuthenticator and the
        # DefaultIdentityAsserter names are 'Provider', making it impossible to work with in WLST.  If
        # the WLS version is earlier than fix this as part of domain creation...
        #
        self.__fix_default_authentication_provider_names = \
            self.wls_helper.do_default_authentication_provider_names_need_fixing()

        #
        # This list gets modified as the domain is being created so do use this list for anything else...
        #
        self.__topology_folder_list = self.alias_helper.get_model_topology_top_level_folder_names()
        return

    def create(self):
        """
        The create() method triggers domain creation.
        :raises CreateException: if domain creation fails
        :raises DeployException: if resource and application deployment fails
        """
        _method_name = 'create'

        self.logger.entering(class_name=self.__class_name, method_name=_method_name)
        self.__run_rcu()
        self.__fail_mt_1221_domain_creation()
        self.__create_domain()
        self.__deploy_resources_and_apps()
        self.logger.exiting(class_name=self.__class_name, method_name=_method_name)
        return

    # Override
    def _create_named_mbeans(self, type_name, model_nodes, base_location, log_created=False):
        """
        Override default behavior to create placeholders for referenced Coherence clusters.
        :param type_name: the model folder type
        :param model_nodes: the model dictionary of the specified model folder type
        :param base_location: the base location object to use to create the MBeans
        :param log_created: whether or not to log created at INFO level, by default it is logged at the FINE level
        :raises: CreateException: if an error occurs
        """
        self.topology_helper.check_coherence_cluster_references(type_name, model_nodes)
        # continue with regular processing

        Creator._create_named_mbeans(self, type_name, model_nodes, base_location, log_created=log_created)

    def __run_rcu(self):
        """
        The method that runs RCU to drop and then create the schemas.
        :raises CreateException: if running rcu fails
        """
        _method_name = '__run_rcu'

        self.logger.entering(class_name=self.__class_name, method_name=_method_name)
        if not self.model_context.is_run_rcu():
            self.logger.exiting(class_name=self.__class_name, method_name=_method_name)
            return
        elif not self.wls_helper.is_weblogic_version_or_above('12.1.2'):
            ex = exception_helper.create_create_exception('WLSDPLY-12201', self.__program_name,
                                                          self.wls_helper.get_actual_weblogic_version())
            self.logger.throwing(ex, class_name=self.__class_name, method_name=_method_name)
            raise ex

        rcu_schemas = self._domain_typedef.get_rcu_schemas()
        if len(rcu_schemas) == 0:
            self.logger.exiting(class_name=self.__class_name, method_name=_method_name)
            return

        domain_type = self.model_context.get_domain_type()
        oracle_home = self.model_context.get_oracle_home()
        java_home = self.model_context.get_java_home()
        rcu_db = self.model_context.get_rcu_database()
        rcu_prefix = self.model_context.get_rcu_prefix()
        rcu_sys_pass = self.model_context.get_rcu_sys_pass()
        rcu_schema_pass = self.model_context.get_rcu_schema_pass()

        runner = RCURunner(domain_type, oracle_home, java_home, rcu_db, rcu_prefix, rcu_schemas)
        runner.runRcu(rcu_sys_pass, rcu_schema_pass)

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

    def __fail_mt_1221_domain_creation(self):
        """
        Abort create if domain contains MT artifacts that cannot be created in the version of WLST offline being used.
        :raises: CreateException: if the MT domain cannot be provision on the specified version of WLST offline
        """
        _method_name = '__fail_mt_1221_domain_creation'

        if self.wls_helper.is_mt_offline_provisioning_supported():
            return

        resources_dict = self.model.get_model_resources()
        if (not dictionary_utils.is_empty_dictionary_element(self._topology, VIRTUAL_TARGET)) or \
                (not dictionary_utils.is_empty_dictionary_element(resources_dict, RESOURCE_GROUP_TEMPLATE)) or \
                (not dictionary_utils.is_empty_dictionary_element(resources_dict, RESOURCE_GROUP)) or \
                (not dictionary_utils.is_empty_dictionary_element(resources_dict, PARTITION)):

            ex = exception_helper.create_create_exception('WLSDPLY-12202', self.wls_helper.wl_version)
            self.logger.throwing(ex, class_name=self.__class_name, method_name=_method_name)
            raise ex
        return

    def __create_domain(self):
        """
        Create the domain.
        :raises: CreateException: if an error occurs
        """
        _method_name = '__create_domain'

        self.logger.entering(class_name=self.__class_name, method_name=_method_name)
        domain_type = self.model_context.get_domain_type()
        self.logger.info('WLSDPLY-12203', domain_type, class_name=self.__class_name, method_name=_method_name)
        self.model_context.set_domain_home(self._domain_home)

        if self.wls_helper.is_select_template_supported():
            self.__create_domain_with_select_template(self._domain_home)
        else:
            self.__create_base_domain(self._domain_home)
            self.__extend_domain(self._domain_home)

        if len(self.files_to_extract_from_archive) > 0:
            for file_to_extract in self.files_to_extract_from_archive:
                self.archive_helper.extract_file(file_to_extract)

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

    def __deploy_resources_and_apps(self):
        """
        Deploy the resources and applications.
        :raises: CreateException: if an error occurs while reading or updating the domain.
        :raises: DeployException: if an error occurs while deploy the resources or applications
        """
        _method_name = '__deploy_resources_and_apps'

        self.logger.entering(class_name=self.__class_name, method_name=_method_name)
        self.model_context.set_domain_home(self._domain_home)
        self.wlst_helper.read_domain(self._domain_home)
        model_deployer.deploy_resources_and_apps_for_create(self.model, self.model_context, self.aliases)
        self.wlst_helper.update_domain()
        self.wlst_helper.close_domain()
        self.logger.exiting(class_name=self.__class_name, method_name=_method_name)
        return

    def __create_base_domain(self, domain_home):
        """
        Create the base domain for versions of WLS prior to 12.2.1.
        :param domain_home: the domain home directory
        :raises: CreateException: if an error occurs
        """
        _method_name = '__create_base_domain'

        self.logger.entering(domain_home, class_name=self.__class_name, method_name=_method_name)
        base_template = self._domain_typedef.get_base_template()
        self.logger.info('WLSDPLY-12204', base_template, class_name=self.__class_name, method_name=_method_name)
        self.wlst_helper.read_template(base_template)
        self.__apply_base_domain_config(self.__topology_folder_list)

        self.logger.info('WLSDPLY-12205', self._domain_name, domain_home,
                         class_name=self.__class_name, method_name=_method_name)
        self.wlst_helper.write_domain(domain_home)

        self.logger.info('WLSDPLY-12206', self._domain_name, class_name=self.__class_name, method_name=_method_name)
        self.wlst_helper.close_template()

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

    def __extend_domain(self, domain_home):
        """
        Extend the base domain with extension templates, as needed, for versions of WebLogic Server prior to 12.2.1.
        :param domain_home: the domain home directory
        :raises: CreateException: if an error occurs
        """
        _method_name = '__extend_domain'

        self.logger.entering(domain_home, class_name=self.__class_name, method_name=_method_name)
        extension_templates = self._domain_typedef.get_extension_templates()
        if len(extension_templates) == 0:
            return

        self.logger.info('WLSDPLY-12207', self._domain_name, domain_home,
                         class_name=self.__class_name, method_name=_method_name)
        self.wlst_helper.read_domain(domain_home)
        self.__set_app_dir()

        for extension_template in extension_templates:
            self.logger.info('WLSDPLY-12208', extension_template,
                             class_name=self.__class_name, method_name=_method_name)
            self.wlst_helper.add_template(extension_template)

        self.__configure_fmw_infra_database()

        server_groups_to_target = self._domain_typedef.get_server_groups_to_target()
        self.target_helper.target_server_groups_to_servers(server_groups_to_target)

        self.logger.info('WLSDPLY-12209', self._domain_name,
                         class_name=self.__class_name, method_name=_method_name)
        self.wlst_helper.update_domain()
        self.wlst_helper.close_domain()

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

    def __create_domain_with_select_template(self, domain_home):
        """
        Create and extend the domain, as needed, for WebLogic Server versions 12.2.1 and above.
        :param domain_home: the domain home directory
        :raises: CreateException: if an error occurs
        """
        _method_name = '__create_domain_with_select_template'

        self.logger.entering(domain_home, class_name=self.__class_name, method_name=_method_name)
        base_template = self._domain_typedef.get_base_template()
        self.logger.info('WLSDPLY-12210', base_template,
                         class_name=self.__class_name, method_name=_method_name)

        self.wlst_helper.select_template(base_template)

        extension_templates = self._domain_typedef.get_extension_templates()
        for extension_template in extension_templates:
            self.logger.info('WLSDPLY-12211', extension_template,
                             class_name=self.__class_name, method_name=_method_name)
            self.wlst_helper.select_template(extension_template)

        self.logger.info('WLSDPLY-12212', class_name=self.__class_name, method_name=_method_name)
        self.wlst_helper.load_templates()

        topology_folder_list = self.alias_helper.get_model_topology_top_level_folder_names()
        self.__apply_base_domain_config(topology_folder_list)

        if len(extension_templates) > 0:
            self.__set_app_dir()
            self.__configure_fmw_infra_database()

            server_groups_to_target = self._domain_typedef.get_server_groups_to_target()
            self.target_helper.target_server_groups_to_servers(server_groups_to_target)

        self.logger.info('WLSDPLY-12206', self._domain_name, domain_home,
                         class_name=self.__class_name, method_name=_method_name)
        self.wlst_helper.write_domain(domain_home)
        self.wlst_helper.close_template()
        self.logger.exiting(class_name=self.__class_name, method_name=_method_name)
        return

    def __apply_base_domain_config(self, topology_folder_list):
        """
        Apply the base domain configuration from the model topology section.
        :param topology_folder_list: the model topology folder list to process
        :raises: CreateException: if an error occurs
        """
        _method_name = '__apply_base_domain_config'

        self.logger.entering(topology_folder_list, class_name=self.__class_name, method_name=_method_name)
        self.logger.fine('WLSDPLY-12219', class_name=self.__class_name, method_name=_method_name)

        location = LocationContext()
        domain_name_token = self.alias_helper.get_name_token(location)
        location.add_name_token(domain_name_token, self._domain_name)

        self.__set_core_domain_params()
        self.__create_security_folder(location)
        topology_folder_list.remove(SECURITY)

        # SecurityConfiguration is special since the subfolder name does not change when you change the domain name.
        # It only changes once the domain is written and re-read...
        security_config_location = LocationContext().add_name_token(domain_name_token, self.__default_domain_name)
        self.security_provider_creator.create_security_configuration(security_config_location)
        topology_folder_list.remove(SECURITY_CONFIGURATION)

        self.__create_machines(location)
        topology_folder_list.remove(MACHINE)
        topology_folder_list.remove(UNIX_MACHINE)

        self.__create_clusters_and_servers(location)
        topology_folder_list.remove(CLUSTER)
        if SERVER_TEMPLATE in topology_folder_list:
            topology_folder_list.remove(SERVER_TEMPLATE)
        topology_folder_list.remove(SERVER)

        self.__create_migratable_targets(location)
        topology_folder_list.remove(MIGRATABLE_TARGET)

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

    def __set_core_domain_params(self):
        """
        Set the core domain parameters.
        :raises: CreateException: if an error occurs
        """
        _method_name = '__set_core_domain_params'

        self.logger.entering(class_name=self.__class_name, method_name=_method_name)
        self.wlst_helper.set_option_if_needed(SET_OPTION_DOMAIN_NAME, self._domain_name)

        java_home = self.model_context.get_java_home()
        self.wlst_helper.set_option_if_needed(SET_OPTION_JAVA_HOME, java_home)

        if SERVER_START_MODE in self._domain_info:
            server_start_mode = self._domain_info[SERVER_START_MODE]
            self.wlst_helper.set_option_if_needed(SET_OPTION_SERVER_START_MODE, server_start_mode)

        self.__set_domain_name()
        self.__set_admin_password()
        self.__set_admin_server_name()

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

    def __create_security_folder(self, location):
        """
        Create the /Security folder objects, if any.
        :param location: the location to use
        :raises: CreateException: if an error occurs
        """
        _method_name = '__create_security_folder'

        self.logger.entering(str(location), class_name=self.__class_name, method_name=_method_name)
        security_nodes = dictionary_utils.get_dictionary_element(self._topology, SECURITY)
        if len(security_nodes) > 0:
            self._create_mbean(SECURITY, security_nodes, location)
        self.logger.exiting(class_name=self.__class_name, method_name=_method_name)
        return

    def __create_machines(self, location):
        """
        Create the /Machine and /UnixMachine folder objects, if any.
        :param location: the location to use
        :raises: CreateException: if an error occurs
        """
        _method_name = '__create_machines'

        self.logger.entering(str(location), class_name=self.__class_name, method_name=_method_name)
        machine_nodes = dictionary_utils.get_dictionary_element(self._topology, MACHINE)
        unix_machine_nodes = dictionary_utils.get_dictionary_element(self._topology, UNIX_MACHINE)

        if len(machine_nodes) > 0:
            self._create_named_mbeans(MACHINE, machine_nodes, location, log_created=True)
        if len(unix_machine_nodes) > 0:
            self._create_named_mbeans(UNIX_MACHINE, unix_machine_nodes, location, log_created=True)
        self.logger.exiting(class_name=self.__class_name, method_name=_method_name)
        return

    def __create_clusters_and_servers(self, location):
        """
        Create the /Cluster, /ServerTemplate, and /Server folder objects.
        :param location: the location to use
        :raises: CreateException: if an error occurs
        """
        _method_name = '__create_clusters_and_servers'

        self.logger.entering(str(location), class_name=self.__class_name, method_name=_method_name)
        #
        # In order for source domain provisioning to work with dynamic clusters, we have to provision
        # the ServerTemplates.  There is a cyclical dependency between Server Template and Clusters so we
        # need for the ServerTemplates to exist before create clusters.  Once the clusters are provisioned,
        # then we can fully populate the ServerTemplates.
        #
        server_template_nodes = dictionary_utils.get_dictionary_element(self._topology, SERVER_TEMPLATE)
        if len(server_template_nodes) > 0 and self._is_type_valid(location, SERVER_TEMPLATE):
            st_location = LocationContext(location).append_location(SERVER_TEMPLATE)
            st_mbean_type = self.alias_helper.get_wlst_mbean_type(st_location)
            st_create_path = self.alias_helper.get_wlst_create_path(st_location)
            self.wlst_helper.cd(st_create_path)

            st_token_name = self.alias_helper.get_name_token(st_location)
            for server_template_name in server_template_nodes:
                st_name = self.wlst_helper.get_quoted_name_for_wlst(server_template_name)
                if st_token_name is not None:
                    st_location.add_name_token(st_token_name, st_name)

                st_mbean_name = self.alias_helper.get_wlst_mbean_name(st_location)
                self.logger.info('WLSDPLY-12220', SERVER_TEMPLATE, st_mbean_name)
                self.wlst_helper.create(st_mbean_name, st_mbean_type)

        cluster_nodes = dictionary_utils.get_dictionary_element(self._topology, CLUSTER)
        if len(cluster_nodes) > 0:
            self._create_named_mbeans(CLUSTER, cluster_nodes, location, log_created=True)

        #
        # Now, fully populate the ServerTemplates, if any.
        #
        if len(server_template_nodes) > 0:
            self._create_named_mbeans(SERVER_TEMPLATE, server_template_nodes, location, log_created=True)

        #
        # Finally, create/update the servers.
        #
        server_nodes = dictionary_utils.get_dictionary_element(self._topology, SERVER)
        if len(server_nodes) > 0:
            self._create_named_mbeans(SERVER, server_nodes, location, log_created=True)

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

    def __create_migratable_targets(self, location):
        """
        Create the /MigratableTarget folder objects, if any.
        :param location: the location to use
        :raises: CreateException: if an error occurs
        """
        _method_name = '__create_migratable_targets'

        self.logger.entering(str(location), class_name=self.__class_name, method_name=_method_name)
        migratable_target_nodes = dictionary_utils.get_dictionary_element(self._topology, MIGRATABLE_TARGET)

        if len(migratable_target_nodes) > 0:
            self._create_named_mbeans(MIGRATABLE_TARGET, migratable_target_nodes, location, log_created=True)

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

    def __create_other_domain_artifacts(self, location, mbean_type_list):
        """
        Create the remaining model topology-related folder objects, if any.
        :param location: the location to use
        :raises: CreateException: if an error occurs
        """
        _method_name = '__create_other_domain_artifacts'

        self.logger.entering(str(location), mbean_type_list, class_name=self.__class_name, method_name=_method_name)
        for mbean_type in mbean_type_list:
            mbean_nodes = dictionary_utils.get_dictionary_element(self._topology, mbean_type)

            if len(mbean_nodes) > 0:
                mbean_location = LocationContext(location).append_location(mbean_type)
                if self.alias_helper.supports_multiple_mbean_instances(mbean_location):
                    self._create_named_mbeans(mbean_type, mbean_nodes, location, log_created=True)
                else:
                    self._create_mbean(mbean_type, mbean_nodes, location, log_created=True)

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

    def __configure_fmw_infra_database(self):
        """
        Configure the FMW Infrastructure DataSources.
        :raises: CreateException: if an error occurs
        """
        _method_name = '__configure_fmw_infra_database'

        self.logger.entering(class_name=self.__class_name, method_name=_method_name)
        rcu_database = self.model_context.get_rcu_database()
        if rcu_database is None:
            return

        # No need to validate since these were validated at the entry point...
        rcu_prefix = self.model_context.get_rcu_prefix()
        rcu_schema_pwd = self.model_context.get_rcu_schema_pass()

        fmw_database = self.wls_helper.get_jdbc_url_from_rcu_connect_string(rcu_database)
        self.logger.fine('WLSDPLY-12221', fmw_database, class_name=self.__class_name, method_name=_method_name)

        location = LocationContext()
        location.append_location(JDBC_SYSTEM_RESOURCE)
        token_name = self.alias_helper.get_name_token(location)
        svc_table_ds_name = self.wls_helper.get_jrf_service_table_datasource_name()
        if token_name is not None:
            location.add_name_token(token_name, svc_table_ds_name)

        location.append_location(JDBC_RESOURCE)
        location.append_location(JDBC_DRIVER_PARAMS)
        wlst_path = self.alias_helper.get_wlst_attributes_path(location)
        self.wlst_helper.cd(wlst_path)

        svc_table_driver_name = self.wls_helper.get_stb_data_source_jdbc_driver_name()
        wlst_name, wlst_value = \
            self.alias_helper.get_wlst_attribute_name_and_value(location, DRIVER_NAME, svc_table_driver_name)
        self.wlst_helper.set_if_needed(wlst_name, wlst_value, JDBC_DRIVER_PARAMS, svc_table_ds_name)

        wlst_name, wlst_value = \
            self.alias_helper.get_wlst_attribute_name_and_value(location, URL, fmw_database)
        self.wlst_helper.set_if_needed(wlst_name, wlst_value, JDBC_DRIVER_PARAMS, svc_table_ds_name)

        wlst_name, wlst_value = \
            self.alias_helper.get_wlst_attribute_name_and_value(location, PASSWORD_ENCRYPTED,
                                                                rcu_schema_pwd, masked=True)
        self.wlst_helper.set_if_needed(wlst_name, wlst_value, JDBC_DRIVER_PARAMS, svc_table_ds_name, masked=True)

        location.append_location(JDBC_DRIVER_PARAMS_PROPERTIES)
        token_name = self.alias_helper.get_name_token(location)
        if token_name is not None:
            location.add_name_token(token_name, DRIVER_PARAMS_USER_PROPERTY)

        stb_user = self.wls_helper.get_stb_user_name(rcu_prefix)
        self.logger.fine('WLSDPLY-12222', stb_user, class_name=self.__class_name, method_name=_method_name)

        wlst_path = self.alias_helper.get_wlst_attributes_path(location)
        self.wlst_helper.cd(wlst_path)
        wlst_name, wlst_value = \
            self.alias_helper.get_wlst_attribute_name_and_value(location, DRIVER_PARAMS_PROPERTY_VALUE, stb_user)
        self.wlst_helper.set_if_needed(wlst_name, wlst_value,
                                       JDBC_DRIVER_PARAMS_PROPERTIES, DRIVER_PARAMS_USER_PROPERTY)

        self.logger.info('WLSDPLY-12223', class_name=self.__class_name, method_name=_method_name)
        self.wlst_helper.get_database_defaults()

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

    def __set_app_dir(self):
        """
        Set the AppDir domain option.
        :raises: CreateException: if an error occurs
        """
        _method_name = '__set_app_dir'

        self.logger.entering(class_name=self.__class_name, method_name=_method_name)
        if APP_DIR in self._domain_info:
            app_dir = self._domain_info[APP_DIR]
            self.logger.fine('WLSDPLY-12225', model_helper.get_model_domain_info_key(), APP_DIR, app_dir,
                             class_name=self.__class_name, method_name=_method_name)
        else:
            app_dir = os.path.join(self.model_context.get_domain_parent_dir(), 'applications')
            self.logger.fine('WLSDPLY-12226', model_helper.get_model_domain_info_key(), APP_DIR, app_dir,
                             class_name=self.__class_name, method_name=_method_name)

        self.wlst_helper.set_option_if_needed(SET_OPTION_APP_DIR, app_dir)

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

    def __set_domain_name(self):
        _method_name = '__set_domain_name'
        # Stash the default name since the SecurityConfiguration subfolder name does not change
        # to the new domain name until after the domain has been written to disk and re-read.
        #
        self.__default_domain_name = self.wlst_helper.get(NAME)
        if self.__default_domain_name is None or len(self.__default_domain_name) == 0:
            self.__default_domain_name = DEFAULT_WLS_DOMAIN_NAME

        if self._domain_name != self.__default_domain_name:
            #
            # We cannot use the aliases for the Server Name attribute since we
            # filter out any name fields.
            #
            self.wlst_helper.set_if_needed(DOMAIN_NAME, self._domain_name, DOMAIN_NAME, self._domain_name)
            self.logger.info('WLSDPLY-12227', self.__default_domain_name, self._domain_name,
                             class_name=self.__class_name, method_name=_method_name)
        return

    def __set_admin_password(self):
        """
        Set the administrative user's password.
        :raises: CreateException: if an error occurs
        """
        _method_name = '__set_admin_password'

        if ADMIN_PASSWORD in self._domain_info:
            admin_password = self._domain_info[ADMIN_PASSWORD]
            admin_username = self.wls_helper.get_default_admin_username()
            if ADMIN_USERNAME in self._domain_info:
                admin_username = self._domain_info[ADMIN_USERNAME]

            location = LocationContext().append_location(SECURITY)
            token_name = self.alias_helper.get_name_token(location)
            if token_name is not None:
                location.add_name_token(token_name, self._domain_name)

            location.append_location(USER)
            token_name = self.alias_helper.get_name_token(location)
            if token_name is not None:
                location.add_name_token(token_name, self.wls_helper.get_default_admin_username())

            admin_user_path = self.alias_helper.get_wlst_attributes_path(location)
            self.wlst_helper.cd(admin_user_path)
            wlst_name, wlst_value = \
                self.alias_helper.get_wlst_attribute_name_and_value(location, NAME, admin_username)
            self.wlst_helper.set_if_needed(wlst_name, wlst_value, NAME, admin_username)
            wlst_name, wlst_value = \
                self.alias_helper.get_wlst_attribute_name_and_value(location, PASSWORD, admin_password, masked=True)
            self.wlst_helper.set_if_needed(wlst_name, wlst_value, PASSWORD, '<masked>', masked=True)

        else:
            ex = exception_helper.create_create_exception('WLSDPLY-12228', 'AdminPassword',
                                                          model_helper.get_model_domain_info_key())
            self.logger.throwing(ex, class_name=self.__class_name, method_name=_method_name)
            raise ex
        return

    def __set_admin_server_name(self):
        """
        Set the name of the AdminServer, if required.
        :raises: CreateException: if an error occurs
        """
        _method_name = '__set_admin_server_name'

        # Test to see if the name was specified to see whether we need to do this or not...
        self.wlst_helper.cd('/')
        self.__default_admin_server_name = self.wlst_helper.get(ADMIN_SERVER_NAME)
        if self._admin_server_name != self.__default_admin_server_name:
            location = LocationContext().append_location(SERVER)
            token_name = self.alias_helper.get_name_token(location)
            if token_name is not None:
                location.add_name_token(token_name, self.__default_admin_server_name)

            wlst_path = self.alias_helper.get_wlst_attributes_path(location)
            self.wlst_helper.cd(wlst_path)
            #
            # We cannot use the aliases for the Server Name attribute since we
            # filter out any name fields.
            #
            self.wlst_helper.set_if_needed(NAME, self._admin_server_name, SERVER, self.__default_admin_server_name)
            self.logger.info('WLSDPLY-12229', self.__default_admin_server_name, self._admin_server_name,
                             class_name=self.__class_name, method_name=_method_name)
        else:
            self._admin_server_name = self.__default_admin_server_name
        return
    def __init__(self, model_dictionary, model_context, aliases):
        _method_name = '__init__'
        Creator.__init__(self, model_dictionary, model_context, aliases)

        # domainInfo section is required to get the admin password, everything else
        # is optional and will use the template defaults
        if model_helper.get_model_domain_info_key() not in model_dictionary:
            ex = exception_helper.create_create_exception(
                'WLSDPLY-12200', self.__program_name,
                model_helper.get_model_domain_info_key(),
                self.model_context.get_model_file())
            self.logger.throwing(ex,
                                 class_name=self.__class_name,
                                 method_name=_method_name)
            raise ex

        self.topology_helper = TopologyHelper(self.aliases,
                                              ExceptionType.CREATE,
                                              self.logger)
        self.security_provider_creator = SecurityProviderCreator(
            model_dictionary, model_context, aliases, ExceptionType.CREATE,
            self.logger)

        self._domain_typedef = self.model_context.get_domain_typedef()
        self._topology = self.model.get_model_topology()
        self._domain_info = self.model.get_model_domain_info()

        if DOMAIN_NAME in self._topology:
            self._domain_name = self._topology[DOMAIN_NAME]
        else:
            self._domain_name = DEFAULT_WLS_DOMAIN_NAME

        # if domain home specified on command line, set it here, otherwise append domain name to domain parent
        model_domain_home = self.model_context.get_domain_home()
        if model_domain_home:
            self._domain_home = model_domain_home
        else:
            self._domain_home = os.path.join(
                self.model_context.get_domain_parent_dir(), self._domain_name)

        if ADMIN_SERVER_NAME in self._topology:
            self._admin_server_name = self._topology[ADMIN_SERVER_NAME]
        else:
            self._admin_server_name = DEFAULT_ADMIN_SERVER_NAME

        self.__default_domain_name = None
        self.__default_admin_server_name = None
        self.__default_security_realm_name = None

        archive_file_name = self.model_context.get_archive_file_name()
        if archive_file_name is not None:
            self.archive_helper = ArchiveHelper(
                archive_file_name, self._domain_home, self.logger,
                exception_helper.ExceptionType.CREATE)

        self.library_helper = LibraryHelper(self.model, self.model_context,
                                            self.aliases, self._domain_home,
                                            ExceptionType.CREATE, self.logger)

        self.target_helper = TargetHelper(self.model, self.model_context,
                                          self.aliases, ExceptionType.CREATE,
                                          self.logger)

        #
        # This list gets modified as the domain is being created so do use this list for anything else...
        #
        self.__topology_folder_list = self.alias_helper.get_model_topology_top_level_folder_names(
        )
        return