class MBeanInfoAttributes(MBeanAttributes): """ MBeanInfoAttributes extends the MBeanAttributes class. It encapsulates the attribute information found from the PropertyDescriptors in the MBeanInfo for the MBean type. """ __class_name = 'MBeanInfoAttributes' def __init__(self, model_context, alias_helper, exception_type, location): MBeanAttributes.__init__(self, model_context, alias_helper, exception_type, location) self.__weblogic_helper = WebLogicHelper(_logger) self.__mbean_info_descriptors = None self.__mbean_info_map = None def get_mbean_attributes(self): """ Return the sorted list of attributes compiled from the MBeanInfo PropertyDescriptors including the child MBeans. :return: list of all attributes from the MBeanInfo property descriptors, or an empty list if none """ _method_name = 'get_mbean_attributes' _logger.entering(class_name=self.__class__.__name__, method_name=_method_name) map_to_list = list() attributes = self.__get_mbean_info_map() if len(attributes) > 0: map_to_list = [attribute for attribute in attributes.iterkeys()] map_to_list.sort() _logger.exiting(class_name=self.__class__.__name__, method_name=_method_name, result=len(map_to_list)) return map_to_list def exists(self, attribute_name): """ Determine if the attribute name exists for the MBean in MBeanInfo. :param attribute_name: to search for in the MBeanInfo :return: True if the attribute is found in the MBeanInfo """ return attribute_name in self.__get_mbean_info_map() def is_child_mbean(self, attribute_name): """ Determine if the attribute exists in MBeanInfo and if the attribute is a child MBean. :param attribute_name: to search for in the MBeanInfo :return: True if the attribute is a child MBean or None if the attribute is not found in MBeanInfo """ _method_name = 'is_child_mbean' descriptor = self.__get_mbean_attribute(attribute_name) if descriptor is not None: relationship = descriptor.getValue('relationship') is_child = relationship == 'containment' or \ (relationship == 'reference' and self.is_read_only(attribute_name)) if is_child: _logger.finer('WLSDPLY-01780', attribute_name, class_name=self.__class__.__name__, method_name=_method_name) return is_child return None def is_read_only(self, attribute_name): """ Determine if the attribute exists in MBeanInfo and if the attribute is readonly. :param attribute_name: to search for in the MBeanInfo :return: True if the attribute is readonly or None if the attribute does not exist in MBeanInfo """ if self.exists(attribute_name): return self.setter(attribute_name) is None return None def getter(self, attribute_name): """ Return the read method name string for the attribute in the MBeanInfo. :param attribute_name: to search for in the MBeanInfo :return: getter for the attribute or None if the attribute does not exist """ descriptor = self.__get_mbean_attribute(attribute_name) if descriptor is not None: return descriptor.getReadMethod().getName() return None def is_valid_getter(self, attribute_name): """ Try to invoke the getter method on the mbean_instance. Some of the attributes in the PropertyDescriptors have read methods that cannot be invoked on the MBean instance. :return: True if can invoke the getter on the MBean instance """ _method_name = 'is_valid_getter' _logger.entering(attribute_name, class_name=self.__class__.__name__, method_name=_method_name) valid = False getter = self.getter(attribute_name) if getter is not None: valid, __ = self._get_from_bean_proxy(getter) _logger.exiting(class_name=self.__class__.__name__, method_name=_method_name, result=Boolean(valid)) return valid def setter(self, attribute_name): """ Return the set method name for the attribute in the MBeanInfo. :param attribute_name: to search for in the MBeanInfo :return: setter for the attribute or None if the attribute is readonly or the attribute does not exist """ descriptor = self.__get_mbean_attribute(attribute_name) if descriptor is not None: setter = descriptor.getWriteMethod() if setter is not None and str(setter.getReturnType()) == 'void': return setter.getName() return None def is_encrypted(self, attribute_name): """ Determine if the property is an encrypted attribute. :param attribute_name: to search for in the MBeanInfo :return: True if it is an encrypted attribute or None if the attribute does not exist in the MBeanInfo """ descriptor = self.__get_mbean_attribute(attribute_name) if descriptor is not None: return descriptor.getValue('encrypted') is True return None def is_clear_text_encrypted(self, attribute_name): """ The tool does not discover security attributes that are clear text. Determine if the attribute is a an attribute returning clear text form of the matching encrypted attribute and skip if True. :param attribute_name: name of the attribute to test :return: True if the attribute is a clear text security attribute """ return self.is_encrypted(attribute_name) and str( self.get_type(attribute_name)) == 'java.lang.String' def get_type(self, attribute_name): """ Return the type of the attribute value if the attribute exists in MBeanInfo. :param attribute_name: to search for in the MBeanInfo :return: Type of the property attribute or None if the attribute does not exist in the MBeanInfo """ descriptor = self.__get_mbean_attribute(attribute_name) if descriptor is not None: return descriptor.getPropertyType() return None def get_default_value(self, attribute_name): """ Return the default value if the attribute exists in MBeanInfo :param attribute_name: to search for in the MBeanInfo :return: The default value for the attribute """ descriptor = self.__get_mbean_attribute(attribute_name) values = _get_descriptor_values_keys(descriptor) if 'defaultValueNull' in values and descriptor.getValue( 'defaultValueNull') is True: default = None else: default = descriptor.getValue('default') return default def get_value(self, attribute_name): """ Return the attribute value from the mbean instance. :param attribute_name: name of the attribute :return: Value of the MBean attribute in the format retrieved from the mbean instance """ value = None getter = self.getter(attribute_name) if getter is not None: __, value = self._get_from_bean_proxy(getter) return value def __get_mbean_info_map(self): if self.__mbean_info_map is None: self.__mbean_info_map = dict() for descriptor in self.__get_mbean_descriptors(): self.__mbean_info_map[descriptor.getName()] = descriptor return self.__mbean_info_map def __get_mbean_descriptors(self): _method_name = '__get_mbean_descriptors' if self.__mbean_info_descriptors is None: mbean_info = self.__weblogic_helper.get_bean_info_for_interface( self.get_mbean_interface_name()) if mbean_info is None: ex = exception_helper.create_exception( self._get_exception_type(), 'WLSDPLY-01774', self.get_mbean_interface_name(), self.mbean_string()) _logger.throwing(ex, class_name=self.__class__.__name__, method_name=_method_name) raise ex self.__mbean_info_descriptors = mbean_info.getPropertyDescriptors() return self.__mbean_info_descriptors def __get_mbean_attribute(self, attribute): descriptor_map = self.__get_mbean_info_map() if attribute in descriptor_map: return descriptor_map[attribute] return None def __str__(self): return self.__class__.__name__ + self._get_mbean_name()
class CustomFolderHelper(object): """ Shared code for custom (user-defined) folders in the model. These require special handling, since they do not have alias definitions. """ __class_name = 'CustomFolderHelper' __cipher_text_prefixes = ["{AES}", "{AES-256}"] def __init__(self, aliases, logger, model_context, exception_type): self.logger = logger self.model_context = model_context self.exception_type = exception_type self.alias_helper = AliasHelper(aliases, self.logger, self.exception_type) self.weblogic_helper = WebLogicHelper(self.logger) self.wlst_helper = WlstHelper(self.logger, self.exception_type) def update_security_folder(self, location, model_type, model_subtype, model_name, model_nodes): """ Update the specified security model nodes in WLST. :param location: the location for the provider :param model_type: the type of the provider to be updated, such as AuthenticationProvider :param model_subtype: the subtype of the provider to be updated, such as 'custom.my.CustomIdentityAsserter' :param model_name: the name of the provider to be updated, such as 'My custom IdentityAsserter' :param model_nodes: a child model nodes of the provider to be updated :raises: BundleAwareException of the specified type: if an error occurs """ _method_name = 'update_security_folder' location_path = self.alias_helper.get_model_folder_path(location) self.logger.entering(location_path, model_subtype, model_name, class_name=self.__class_name, method_name=_method_name) self.logger.info('WLSDPLY-12124', model_type, model_name, model_subtype, location_path, class_name=self.__class_name, method_name=_method_name) create_path = self.alias_helper.get_wlst_subfolders_path(location) self.wlst_helper.cd(create_path) # create the MBean using the model type, name, and subtype type_location = LocationContext(location).append_location(model_type) token = self.alias_helper.get_name_token(type_location) type_location.add_name_token(token, model_name) mbean_type = self.alias_helper.get_wlst_mbean_type(type_location) self.wlst_helper.create(model_name, model_subtype, mbean_type) provider_path = self.alias_helper.get_wlst_attributes_path( type_location) provider_mbean = self.wlst_helper.cd(provider_path) interface_name = model_subtype + 'MBean' bean_info = self.weblogic_helper.get_bean_info_for_interface( interface_name) if bean_info is None: ex = exception_helper.create_exception(self.exception_type, 'WLSDPLY-12125', interface_name) self.logger.throwing(ex, class_name=self.__class_name, method_name=_method_name) raise ex property_map = dict() for property_descriptor in bean_info.getPropertyDescriptors(): self.logger.finer('WLSDPLY-12126', str(property_descriptor), class_name=self.__class_name, method_name=_method_name) property_map[property_descriptor.getName()] = property_descriptor for model_key in model_nodes: model_value = model_nodes[model_key] property_descriptor = property_map.get(model_key) if not property_descriptor: ex = exception_helper.create_exception(self.exception_type, 'WLSDPLY-12128', model_key) self.logger.throwing(ex, class_name=self.__class_name, method_name=_method_name) raise ex # find the setter method for the attribute method = property_descriptor.writeMethod if not method: # this must be a read-only attribute, just log it and continue with next attribute self.logger.info('WLSDPLY-12129', str(model_key), class_name=self.__class_name, method_name=_method_name) continue self.logger.finer('WLSDPLY-12127', str(model_key), str(model_value), class_name=self.__class_name, method_name=_method_name) # determine the data type from the set method parameter_types = method.getParameterTypes() parameter_count = len(parameter_types) if parameter_count != 1: ex = exception_helper.create_exception(self.exception_type, 'WLSDPLY-12130', model_key, parameter_count) self.logger.throwing(ex, class_name=self.__class_name, method_name=_method_name) raise ex # if the property requires encryption, and the value is not encrypted, # encrypt the value with domain encryption. requires_encrypted = property_descriptor.getValue('encrypted') if requires_encrypted and not self.is_encrypted( model_value) and isinstance(model_value, str): model_value = self.weblogic_helper.encrypt( model_value, self.model_context.get_domain_home()) property_type = parameter_types[0] # convert the model value to the target type and call the setter with the target value. # these are done together in Java to avoid automatic Jython type conversions. try: CustomBeanUtils.callMethod(provider_mbean, method, property_type, model_value) # failure converting value or calling method except (IllegalAccessException, IllegalArgumentException, InvocationTargetException), ex: ex = exception_helper.create_exception( self.exception_type, 'WLSDPLY-12131', method, str(model_value), ex.getLocalizedMessage(), error=ex) self.logger.throwing(ex, class_name=self.__class_name, method_name=_method_name) raise ex