Version 9

    XMBeanAttributePersistenceService,

    (or Yet Another Persistence Manager)

     

    Motivation

     

    JBoss ModelMBeans (XMBeans) can specify a PersistenceManager (PM) that is

    used during XMBean instantiation to load any attributes previously saved,

    and during normal operation to save attributes, based on the chosen Persistence

    Policy.

     

    The supplied ObjectStreamPersistenceManager uses serialization to files

    in order to persist and restore the XMBean state (infact, it saves the full

    XMBean metadata, including descriptors and everything).

     

    There are some problems with this setup:

     

    1. Lack of management interface - we cannot tell programmatically or otherwise

    (e.g. through the jmx-console) if some XMBean has been persisted. We cannot

    remove the persistent image unless we know how a particular persistence

    manager is implemented.

    1. We don't have central control over the configuration or lifecycle of a PM.

    If multiple instances use the same PM implementation (although a

    different instance of it), each could have different settings.

    1. It's not possible to apply the notion of "versions" of persistent data

    in a uniform way, in case we want to version a particular configuration.

    1. ObjectStreamPersistenceManager, in particular, that acts as a baseline PM

    doesn't not offer "visibility" over the persisted data.

     

    So, given the need for (a) persisting and managing MBean configuration changes,

    and (b) the possibility for supporting configuration versioning in jboss,

    we came up with the idea of an external MBean service called

    AttributePersistenceService (APS) that manages a new form of

    PersistenceManagers called AttributePersistenceManagers (APMs),

    offering a basic management interface.

     

    This facility along with an XML-based implementation of an APM

    is available from JBoss 3.2.6+ onwards, including JBoss 4.x.

     

    Design

     

    The classes and interfaces involved can be seen in the attached class diagram.

     

     

    A description of the new elements follows:

     

    • org.jboss.mx.persistence.DelegatingPersistenceManager

    This is an implementation of the usual PersistenceManager

    interface that hooks into the existing PM framework. The difference is that instead

    of providing a PM implementation, it contacts a factory method (by default: apmCreate())

    on an external MBean service (by default jboss:service=AttributePersistenceService)

    in order to get an implementation of the new AttributePersistenceManager

    (APM) interface. It will then use the load() and store() methods on this

    interface whenever called by the ModelMBeanInvoker.

    The DelegatingPersistenceManager also handles all details, like which

    attributes to persist, or how to load them back and it only leaves the actual

    loading and storing of an AttributeList to the APM implementation.

     

    • org.jboss.mx.persistence.AttributePersistenceManager

    This is a new interface for an enhanced, but probably simpler PM. To begin with,

    it has an explicit lifecycle interface, with a create() that accepts a

    versionTag and an XML Element containing arbitrary configuration information,

    and a destroy() that makes the APM unusable. An APM implementation must

    be thread-safe since it is shared by many DelegatingPersistenceManagers.

    The configuration is set only at the beginning of a session and it cannot change.

    If a versionTag is specified then the APM implementation must make sure that

    data stored/loaded under different version tags are partitioned.

    store() & load() operate on AttributeLists and like most other methods

    require an id to identify the persistent data image. The calling

    DelegatingPersistenceManager will pick the XMBean ObjectName as the default

    id. There are also methods to get all saved ids, check the existence of an

    image, remove it, or remove all persistent data.

     

    • org.jboss.system.pm.AttributePersistenceService (APS).

    This is a simple MBean service that instantiates and configures an

    AttributePersistenceManager implementation. The APM is then shared

    by all DelegatedPersistentManagers that request it. It also provides

    an entry point to the APM administrative interface (e.g. listAll(),

    remove(), etc.) This service is most probably started during JBoss

    boot time (i.e. from conf/jboss-service.xml) so that is present to

    all XMBeans that use it as an APM factory.

    The service may be stopped, re-configured and restarted to perform

    e.g. a versionTag change, presuming that a different JBoss configuration

    version is about to be used. The service is also persistent itself

    so that it's configuration changes may survive server restarts.

     

    • org.jboss.system.pm.XMLAttributePersistenceManager

    This is an implementation of the AttributePersistenceManager interface

    and the default APM to be instantiated by the APS. It creates XML files

    whose format looks similar to that of the JBoss MBean deployment descriptor,

    so that the persited data is as visible as possible (could be partially

    edited by hand). The strategy for persisting attributes is the following:

      1. Null values will be marked as such.

      2. XML Element will be saved as XML.

      3. A PropertyEditor for converting to Text will be used, if available.

      4. If the value is Serializable and serialization is succesful it will

      be saved as a hex encoded string (ala CORBA IOR).

      1. If all fails, record an XML comment and log a warning.

     

    Usage/Example

     

    Provided the AttributePersistenceService is started (e.g. ./conf/jboss-service.xml)

    ...
    <!-- ==================================================================== -->
    <!-- XMBean Persistence                                                   -->
    <!-- ==================================================================== -->   
    <mbean code="org.jboss.system.pm.AttributePersistenceService"
       name="jboss:service=AttributePersistenceService"
       xmbean-dd="resource:xmdesc/AttributePersistenceService-xmbean.xml">
    </mbean>
    ...
    

    you may copy/paste to the ./deploy directory the example from

    docs/examples/jmx/persistent-service.sar that instantiates a persistent service

    with 10 different attribute types, using the name

    jboss.jmx:service=PersistentServiceExample. The jboss-service.xml descriptor

    of the said service contains inline the xmbean descriptor that specifies

    the DelegatingPersistenceManager:

    <xmbean>
       <description>PersistentServiceExample</description>
       <descriptors>
          <persistence persistPolicy="OnUpdate"></persistence>
          <persistence-manager value="org.jboss.mx.persistence.DelegatingPersistenceManager"></persistence-manager>
       </descriptors>
       <class>org.jboss.jmx.examples.persistence.PersistentServiceExample</class>
       ...
    

    Find the instantiated MBean jboss.jmx:service=PersistentServiceExample

    in the jmx-console, change an attribute (e.g. SomeInteger) and press

    on "Apply Changes". Going to the default location ./data/xmbean-attrs/

    you'll find the file jboss.jmx@3Aservice@3DPersistentServiceExample.xml

    whose content should be something close to:

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- automatically produced by XMLAttributePersistenceManager -->
    <attribute-list date="20040824220829" id="jboss.jmx:service=PersistentServiceExample">
    <attribute name="SomeBigDecimal" type="java.math.BigDecimal">31400000000000000</attribute>
    <attribute name="SomeBoolean" type="java.lang.Boolean">true</attribute>
    <attribute name="SomeElement" type="org.w3c.dom.Element">
    <some-message>Welcome to the Athens 2004, Olympic Games!</some-message>
    </attribute>
    <attribute name="SomeInt" type="java.lang.Integer">666</attribute>
    <attribute name="SomeInteger" type="java.lang.Integer">888</attribute>
    <attribute name="SomeString" type="java.lang.String">I've got the devil inside me</attribute>
    <attribute name="SomeTimestamp" serialized="true" type="java.sql.Timestamp">
    ACED0005737200126A6176612E73716C2E54696D657374616D702618D5C80153BF6502000149000
    56E616E6F737872000E6A6176612E7574696C2E44617465686A81014B5974190300007870770800
    0000FE922D3F207808B3C880</attribute>
    <attribute name="SomeNullObject" null="true"></attribute>
    </attribute-list>
    

    Touch the service descriptor

    (./deploy/persistent-service.sar/META-INF/jboss-service.xml) and see how

    the re-deployed MBean retains/reloads the saved values.

     

    Going back to the jmx-console, locate the jboss:service=AttributePersistenceService

    and execute the apmListAllAsString() operation. You should get the id

    (ObjectName) of the persisted MBean. Copy the id and feed it to the

    apmRemove() operation. The persisted .xml file will be gone.

     

    Configuration Options

     

    The AttributePersistenceService has the following configurable attributes:

    <attribute name="AttributePersistenceManagerClass">org.jboss.system.pm.XMLAttributePersistenceManager</attribute>
    <attribute name="AttributePersistenceManagerConfig"></attribute>      
    <attribute name="ApmDestroyOnServiceStop">false</attribute>
    <attribute name="VersionTag"></attribute>
    

     

    • AttributePersistenceManagerClass can be used to specify an alternative APM

    implementation. The default is org.jboss.system.pm.XMLAttributePersistenceManager

     

    • AttributePersistenceManagerConfig is an XML Element that is passed to the APM to

    perform arbitrary configuration and will differ from APM to APM. For the

    default XMLAttributePersistenceManager it can be used to specify the

    directory to use for saving the .xml files, as follows:

     

     <data-directory>data/xmbean-attrs</data-directory>
     

     

    • ApmDestroyOnServiceStop is a boolean flag used to indicate whether destroy()

    should be called on the APM upon service stop. Doing so will render the APM

    unusable and every DelegatingPersistenceManager with a reference to this APM

    will get back an IllegalStateException if it tries to load/store data. This

    may be useful in cases we want to be sure no MBean is writing data, e.g.

    in case we want to alter the active configured version.

     

     

    • VersionTag by default it is null by it can take any value (e.g. "1.0"). The

    way a version is interpreted by an APM will be different. The default

    XMLAttributePersistenceManager will create/use a new subdirectory using the tag

    name (e.g. ./data/xmbean-attrs/1.0) to store/load its data. Thus, assuming we have

    a way to activate alternative deployment configuration, we can also alter the

    persistent images used, according to the active version by simply stopping,

    reconfiguring and restarting APS, dynamically. (This will instantiate a new APM.)

    Note also that APS is by default persistent itself (using the old

    ObjectStreamPersistenceManager) so any change, e.g. in the VersionTag

    will survive server restarts. The persistent image of APS is stored at

    ./data/xmbean-attrs/AttributePersistenceService.ser

     

    XMBean Configuration

     

    Configurable options of interest on the XMBean descriptor of the MBeans to

    be persisted, are the following (MBean level):

     

    • persistName - can be used to specify a specific id, instead of the default

    ObjectName

     

    • attribute-persistence-service - can be used to point to a different service name

    than the default jboss:service=AttributePersistenceService

     

    • attribute-persistence-operation - can be used to specify a different

    factory method on the target MBean service; the default is apmCreate

     

    Options on the XMBean attribute level:

     

    • For attributes that cannot be persisted, it may be useful to mark them with:

          <descriptors>
             <descriptor name="persistPolicy" value="Never"></descriptor>
          </descriptors>
    

     

    Known Issues

     

    All issues mentioned in the previous version of this page have been solved.

     

    Questions

     

    Please forward any comments/suggestions/bug-reports to dimitris@jboss.org

     

    Thanks!

     

    Referenced by: