def _find_dictionary_merge_key(dictionary, new_key, variable_map):
    """
    Find the key corresponding to new_key in the specified dictionary.
    Determine if the new_key should completely replace the value in the dictionary.
    If no direct match is found, and a variable map is specified, perform check with variable substitution.
    If keys have the same name, but one has delete notation (!server), that is a match, and replace is true.
    :param dictionary: the dictionary to be searched
    :param new_key: the key being checked
    :param variable_map: variables to be used for name resolution, or None
    :return: tuple - the corresponding key from the dictionary, True if dictionary key should be replaced
    """
    if new_key in dictionary:
        return new_key, False

    new_is_delete = model_helper.is_delete_name(new_key)
    match_new_key = _get_merge_match_key(new_key, variable_map)

    for dictionary_key in dictionary.keys():
        dictionary_is_delete = model_helper.is_delete_name(dictionary_key)
        match_dictionary_key = _get_merge_match_key(dictionary_key, variable_map)
        if match_dictionary_key == match_new_key:
            replace_key = new_is_delete != dictionary_is_delete
            return dictionary_key, replace_key

    return None, False
    def create_placeholder_named_elements(self, location, model_type, model_nodes):
        """
        Create a placeholder entry for each element in the specified named element nodes.
        This is necessary when there can be circular references with other elements.
        :param location: the location for the nodes to be added
        :param model_type: the type of the specified model nodes
        :param model_nodes: the model nodes
        :return: a list of names of created placeholders
        """
        _method_name = 'create_placeholder_named_elements'
        holder_names = []
        original_location = self.wlst_helper.get_pwd()
        resource_location = LocationContext(location).append_location(model_type)

        if self.aliases.get_wlst_mbean_type(resource_location) is not None:
            existing_names = deployer_utils.get_existing_object_list(resource_location, self.aliases)

            name_nodes = dictionary_utils.get_dictionary_element(model_nodes, model_type)
            for name in name_nodes.keys():
                if model_helper.is_delete_name(name):
                    # don't create placeholder for delete names
                    continue

                if name not in existing_names:
                    self.logger.info('WLSDPLY-19403', model_type, name, class_name=self.__class_name,
                                     method_name=_method_name)

                    token = self.aliases.get_name_token(resource_location)
                    resource_location.add_name_token(token, name)
                    deployer_utils.create_and_cd(resource_location, existing_names, self.aliases)
                    self._update_placeholder(model_type, name, resource_location)
                    holder_names.append(name)

        self.wlst_helper.cd(original_location)
        return holder_names
def _merge_dictionaries(dictionary, new_dictionary, variable_map):
    """
    Merge the values from the new dictionary to the existing one.
    Use variables to resolve keys.
    :param dictionary: the existing dictionary
    :param new_dictionary: the new dictionary to be merged
    :param variable_map: variables to be used for name resolution, or None
    """
    for new_key in new_dictionary:
        new_value = new_dictionary[new_key]
        dictionary_key, replace_key = _find_dictionary_merge_key(dictionary, new_key, variable_map)

        # the key is not in the original dictionary, just add it
        if dictionary_key is None:
            dictionary[new_key] = new_value

        # the new key should replace the existing one - delete the existing key and add the new one
        elif replace_key:
            del dictionary[dictionary_key]
            if not model_helper.is_delete_name(new_key):
                dictionary[new_key] = new_value

        # the key is in both dictionaries - merge if the values are dictionaries, otherwise replace the value
        else:
            value = dictionary[dictionary_key]
            if isinstance(value, dict) and isinstance(new_value, dict):
                _merge_dictionaries(value, new_value, variable_map)
            else:
                dictionary[new_key] = new_value
    def _add_group_params(self, group_name_nodes, location):
        """
        Add each group param entry from group name nodes and set its attributes.
        A two-pass approach is required since the new folder's name does not always match the group name.
        Special processing for error destination attributes (build mbean)
        :param group_name_nodes: the nodes containing group parameter names
        :param location: the WLST location where the parameters should be added
        """
        _method_name = '_add_group_params'
        if len(group_name_nodes) == 0:
            return

        # use a copy of the dictionary to remove items as they are deleted
        remaining_name_nodes = group_name_nodes.copy()

        parent_type, parent_name = self.get_location_type_and_name(location)
        template_path = self.alias_helper.get_wlst_subfolders_path(location)
        groups_location = LocationContext(location)
        groups_location.append_location(GROUP_PARAMS)
        groups_token = self.alias_helper.get_name_token(groups_location)
        name_attribute = self.alias_helper.get_wlst_attribute_name(groups_location, SUB_DEPLOYMENT_NAME)
        mbean_type = self.alias_helper.get_wlst_mbean_type(groups_location)

        for group_name in group_name_nodes:
            if model_helper.is_delete_name(group_name):
                group_nodes = group_name_nodes[group_name]
                name = model_helper.get_delete_item_name(group_name)
                sub_name = self._get_subdeployment_name(group_nodes, name)
                self._delete_mapped_mbean(groups_location, groups_token, mbean_type, name_attribute, sub_name)
                del remaining_name_nodes[group_name]

        # loop once to create and name any missing folders.
        folder_map = self._build_folder_map(groups_location, groups_token, name_attribute)

        for group_name in remaining_name_nodes:
            group_nodes = remaining_name_nodes[group_name]
            sub_deployment_name = self._get_subdeployment_name(group_nodes, group_name)
            folder_name = dictionary_utils.get_element(folder_map, sub_deployment_name)
            if folder_name is None:
                self.wlst_helper.cd(template_path)
                group = self.wlst_helper.create(sub_deployment_name, mbean_type)
                group.setSubDeploymentName(sub_deployment_name)

        # loop a second time to set attributes
        new_folder_map = self._build_folder_map(groups_location, groups_token, name_attribute)

        for group_name in remaining_name_nodes:
            group_nodes = remaining_name_nodes[group_name]
            sub_deployment_name = self._get_subdeployment_name(group_nodes, group_name)
            is_add = sub_deployment_name not in folder_map
            log_helper.log_updating_named_folder(GROUP_PARAMS, group_name, parent_type, parent_name, is_add,
                                                 self._class_name, _method_name)

            folder_name = dictionary_utils.get_element(new_folder_map, sub_deployment_name)
            groups_location.add_name_token(groups_token, folder_name)
            self.wlst_helper.cd(self.alias_helper.get_wlst_attributes_path(groups_location))
            self.set_attributes(groups_location, group_nodes)
    def _add_jndi_properties(self, property_name_nodes, location):
        """
        Add each property entry from property nodes and set its attributes.
        A two-pass approach is required since the new folder's name does not always match the property name.
        :param property_name_nodes: the nodes containing property names
        :param location: the WLST location where the properties should be added
        """
        _method_name = '_add_jndi_properties'
        if len(property_name_nodes) == 0:
            return

        # use a copy of the dictionary to remove items as they are deleted
        remaining_name_nodes = property_name_nodes.copy()

        parent_type, parent_name = self.get_location_type_and_name(location)
        is_online = self.wlst_mode == WlstModes.ONLINE
        if is_online and deployer_utils.is_in_resource_group_or_template(location):
            self.logger.info('WLSDPLY-09501', JNDI_PROPERTY, parent_type, parent_name, class_name=self._class_name,
                             method_name=_method_name)
            return

        foreign_server_path = self.alias_helper.get_wlst_subfolders_path(location)
        properties_location = LocationContext(location).append_location(JNDI_PROPERTY)
        properties_token = self.alias_helper.get_name_token(properties_location)
        name_attribute = self.alias_helper.get_wlst_attribute_name(properties_location, KEY)
        mbean_type = self.alias_helper.get_wlst_mbean_type(properties_location)

        for property_name in property_name_nodes:
            if model_helper.is_delete_name(property_name):
                name = model_helper.get_delete_item_name(property_name)
                self._delete_mapped_mbean(properties_location, properties_token, mbean_type, name_attribute, name)
                del remaining_name_nodes[property_name]

        # loop once to create and name any missing folders.
        folder_map = self._build_folder_map(properties_location, properties_token, name_attribute)

        for property_name in remaining_name_nodes:
            folder_name = dictionary_utils.get_element(folder_map, property_name)
            if folder_name is None:
                self.wlst_helper.cd(foreign_server_path)
                new_property = self.wlst_helper.create(property_name, mbean_type)
                new_property.setKey(property_name)

        # loop a second time to set attributes
        new_folder_map = self._build_folder_map(properties_location, properties_token, name_attribute)

        for property_name in remaining_name_nodes:
            is_add = property_name not in folder_map
            log_helper.log_updating_named_folder(JNDI_PROPERTY, property_name, parent_type, parent_name, is_add,
                                                 self._class_name, _method_name)

            folder_name = dictionary_utils.get_element(new_folder_map, property_name)
            properties_location.add_name_token(properties_token, folder_name)
            self.wlst_helper.cd(self.alias_helper.get_wlst_attributes_path(properties_location))

            property_nodes = remaining_name_nodes[property_name]
            self.set_attributes(properties_location, property_nodes)
Пример #6
0
    def _add_named_elements(self,
                            type_name,
                            model_nodes,
                            location,
                            delete_now=True):
        """
        Add each named element from the specified nodes in WLST and set its attributes.
        Sub-folders are processed in a generic manner if present.
        It is assumed that there are no attributes or sub-folders with special processing.
        :param type_name: the type name of the child nodes
        :param model_nodes: the child nodes of a model element
        :param location: the location where elements should be added
        :param delete_now: Flag to determine whether to delay delete of element
        """
        _method_name = '_add_named_elements'

        if len(model_nodes) == 0:
            return

        parent_type, parent_name = self.get_location_type_and_name(location)
        location = LocationContext(location).append_location(type_name)
        if not self._check_location(location):
            return

        deployer_utils.check_flattened_folder(location, self.aliases)
        existing_names = deployer_utils.get_existing_object_list(
            location, self.aliases)

        token = self.aliases.get_name_token(location)
        for name in model_nodes:
            if model_helper.is_delete_name(name):
                if delete_now:
                    deployer_utils.delete_named_element(
                        location, name, existing_names, self.aliases)
                continue

            is_add = name not in existing_names
            log_helper.log_updating_named_folder(type_name, name, parent_type,
                                                 parent_name, is_add,
                                                 self._class_name,
                                                 _method_name)

            if token is not None:
                location.add_name_token(token, name)
            deployer_utils.create_and_cd(location, existing_names,
                                         self.aliases)

            child_nodes = dictionary_utils.get_dictionary_element(
                model_nodes, name)
            self._set_attributes_and_add_subfolders(location, child_nodes)
        return
def _get_merge_match_key(key, variable_map):
    """
    Get the key name to use for matching in model merge.
    This includes resolving any variables, and removing delete notation if present.
    :param key: the key to be examined
    :param variable_map: variable map to use for substitutions
    :return: the key to use for matching
    """

    match_key = variables.substitute_key(key, variable_map)

    if model_helper.is_delete_name(match_key):
        match_key = model_helper.get_delete_item_name(match_key)
    return match_key
    def remove_deleted_clusters_and_servers(self, domain_location, model_topology):
        """
        Remove clusters, servers, server templates, and migratable targets that were flagged for deletion
        in the model. The deletions are intentionally skipped when these elements are first created.
        :param domain_location: the location for the root of the domain
        :param model_topology: the topology folder from the model
        """
        _method_name = 'remove_deleted_clusters_and_servers'
        self.logger.entering(str(domain_location), class_name=self.__class_name, method_name=_method_name)

        for folder_name in [CLUSTER, SERVER_TEMPLATE, SERVER, MIGRATABLE_TARGET]:
            location = LocationContext(domain_location).append_location(folder_name)
            existing_names = deployer_utils.get_existing_object_list(location, self.aliases)
            folder_nodes = dictionary_utils.get_dictionary_element(model_topology, folder_name)

            for mbean_name in folder_nodes:
                if model_helper.is_delete_name(mbean_name):
                    deployer_utils.delete_named_element(location, mbean_name, existing_names, self.aliases)

        self.logger.exiting(class_name=self.__class_name, method_name=_method_name)
def merge_model_and_existing_lists(model_list, existing_list, location_path="(unknown)", attribute_name="(unknown)"):
    """
    Merge the two lists so that the resulting list contains all of the elements in both lists one time.
    :param model_list: the list to merge, possibly a string or None
    :param existing_list: the existing list, possibly a string or None
    :param location_path: optional, the path of the attribute location, for logging
    :param attribute_name: optional, the attribute name, for logging
    :return: the merged list as a list or a string, depending on the type of the model_list
    :raises: DeployException: if either list is not either a string or a list
    """
    _method_name = 'merge_model_and_existing_lists'

    _logger.entering(model_list, existing_list, location_path, attribute_name, class_name=_class_name,
                     method_name=_method_name)

    if model_list is None:
        result_is_string = isinstance(existing_list, basestring)
    else:
        result_is_string = isinstance(model_list, basestring)

    result = create_list(existing_list, 'WLSDPLY-08001')
    model_iterator = create_list(model_list, 'WLSDPLY-08000')

    for item in model_iterator:
        if model_helper.is_delete_name(item):
            item_name = model_helper.get_delete_item_name(item)
            if item_name in result:
                result.remove(item_name)
            else:
                _logger.warning('WLSDPLY-08022', item_name, attribute_name, location_path, class_name=_class_name,
                                method_name=_method_name)

        elif item not in result:
            result.append(item)

    if result_is_string:
        result = MODEL_LIST_DELIMITER.join(result)

    _logger.exiting(class_name=_class_name, method_name=_method_name, result=result)
    return result
Пример #10
0
def __delete_online_targets(app_deployments, model_type, aliases):
    """
    For online deploy and update, remove any deleted targets from existing objects of the specified type.
    Objects may be applications or libraries.
    :param app_deployments: the APP_DEPLOYMENTS dictionary from the model
    :param model_type: map of library targets to be deleted
    :param aliases: the parent location of the apps and libraries
    """
    _method_name = '__delete_online_targets'

    location = LocationContext().append_location(model_type)
    wlst_path = aliases.get_wlst_list_path(location)
    wlst_names = _wlst_helper.get_existing_object_list(wlst_path)
    name_token = aliases.get_name_token(location)

    deploy_dict = dictionary_utils.get_dictionary_element(app_deployments, model_type)
    for deploy_name in deploy_dict.keys():
        if deploy_name in wlst_names:
            value_dict = deploy_dict[deploy_name]

            delete_names = []
            model_targets = dictionary_utils.get_element(value_dict, TARGET)
            targets = alias_utils.create_list(model_targets, 'WLSDPLY-08000')
            for target in targets:
                if model_helper.is_delete_name(target):
                    delete_names.append(model_helper.get_delete_item_name(target))

            location.add_name_token(name_token, deploy_name)
            mbean_path = aliases.get_wlst_attributes_path(location)
            mbean = _wlst_helper.get_mbean_for_wlst_path(mbean_path)
            mbean_targets = mbean.getTargets()
            for mbean_target in mbean_targets:
                mbean_name = mbean_target.getName()
                if mbean_name in delete_names:
                    _logger.info('WLSDPLY-09114', mbean_name, model_type, deploy_name, class_name=_class_name,
                                 method_name=_method_name)
                    mbean.removeTarget(mbean_target)
Пример #11
0
    def _create_named_mbeans(self,
                             type_name,
                             model_nodes,
                             base_location,
                             log_created=False,
                             delete_now=True):
        """
        Create the specified type of MBeans that support multiple instances in the specified location.
        :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
        """
        _method_name = '_create_named_mbeans'

        self.logger.entering(type_name,
                             str(base_location),
                             log_created,
                             class_name=self.__class_name,
                             method_name=_method_name)
        if model_nodes is None or len(
                model_nodes) == 0 or not self._is_type_valid(
                    base_location, type_name):
            return

        location = LocationContext(base_location).append_location(type_name)
        self._process_flattened_folder(location)

        token_name = self.aliases.get_name_token(location)
        create_path = self.aliases.get_wlst_create_path(location)
        list_path = self.aliases.get_wlst_list_path(location)
        existing_folder_names = self._get_existing_folders(list_path)
        for model_name in model_nodes.keys():
            name = self.wlst_helper.get_quoted_name_for_wlst(model_name)
            if model_helper.is_delete_name(name):
                if delete_now:
                    deployer_utils.delete_named_element(
                        location, name, existing_folder_names, self.aliases)
                continue

            if token_name is not None:
                location.add_name_token(token_name, name)

            wlst_type, wlst_name = self.aliases.get_wlst_mbean_type_and_name(
                location)
            if wlst_name not in existing_folder_names:
                if log_created:
                    self.logger.info('WLSDPLY-12100',
                                     type_name,
                                     name,
                                     class_name=self.__class_name,
                                     method_name=_method_name)
                else:
                    self.logger.fine('WLSDPLY-12100',
                                     type_name,
                                     name,
                                     class_name=self.__class_name,
                                     method_name=_method_name)
                self.wlst_helper.create_and_cd(self.aliases, wlst_type,
                                               wlst_name, location,
                                               create_path)
            else:
                if log_created:
                    self.logger.info('WLSDPLY-12101',
                                     type_name,
                                     name,
                                     class_name=self.__class_name,
                                     method_name=_method_name)
                else:
                    self.logger.fine('WLSDPLY-12101',
                                     type_name,
                                     name,
                                     class_name=self.__class_name,
                                     method_name=_method_name)

                attribute_path = self.aliases.get_wlst_attributes_path(
                    location)
                self.wlst_helper.cd(attribute_path)

            child_nodes = dictionary_utils.get_dictionary_element(
                model_nodes, name)
            self._process_child_nodes(location, child_nodes)

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