CloudTran Home

 
  
<< Back Contents  >  4.  Developing with CloudTran and TopLink Grid Forward >>

4.1 Changing a TopLink Grid application to use CloudTran

This section gives step-by-step instructions for creating CloudTran applications, using Java and TopLink Grid.

There is a complete example application in the ChildActivities example. You may find it easier to start by copying and changing this application, and consult the documentation on an as-needed basis.

 4.1.1  Java Changes
 4.1.2  persistence.xml
 4.1.3  coherence-cache-config
 4.1.4  POF Config
 4.1.5  The configuration file 'config.properties'

4.1.1  Java Changes
The following diagram illustrates the Java changes required:

  1. These four imports are necessary because they are referenced later.
  2. The @Customizer annotation shown indicates that the Entity uses CloudTran for transactions - the class CTReadWriteCustomizer indicates this entity runs in Grid Entity mode, where the system of record is in the grid. The CloudTran Customizer intercepts read and write calls to TopLink and forwards them to CloudTran.

    You can also use "CTGridCacheCustomizer", which runs in Grid Cache mode, where the database is the system of record - and other applications might use it alongside your application.

    These names are derived from the TopLink Grid names; see here for details.

    What CloudTran does 

    CloudTran uses these properties to inject its integrate its transaction with the Coherence cache management. As the names suggest, these customizers are closely related to the TopLink grid with similar names - CTReadWriteCustomizer to TopLink's ReadWriteCustomizer, CTGridCacheCustomizer to GridCacheCustomizer. The effect is to add on CloudTran transaction management to the basic TopLink Grid features. What you must do 

    1. Because CloudTran transaction depends on a Customizer being present, one of these Customizers must be present on every entity in the persistence unit if CloudTran is specified as the persistence provider (see CTPersistenceProvider above).
    2. This is the reverse of rule A: a CloudTran Customizer can only be specified if CloudTran is specified as the persistence provider.

  3. Because TopLink Grid passes entities over the wire, all domain classes must implement Serializable. In addition, we recommend (but do not require) you make domain classes POF serializable. The simplest way to do this is to implement PortableObject. The code which does this is at the end of each domain class in the ChildActivities application. POF serialization is described here.
  4. The JPA @GeneratedValue annotation is used to get an ID for a new object (i.e. inserted row).

    On entities that use a CT*Customizer, you can get CloudTran to allocate entity primary keys. CloudTran provides grid-wide ID generation, that is unique and ensures correct routing across distributed caches. This reduces the load somewhat on the database compared to standard database allocation techniques, which is useful in high-volume insert applications.

    To get CloudTran to allocate entity primary keys, you specify a generator with a name beginning with "$CT", which then acts in much the same way as the normal Oracle/EclipseLink sequences. Normally, you can use just "$CT", which means allocate based on this entity's target table (or, if you have an inheritance hierarchy, from the root of the hierarchy). If you want an entity to use another entity's generator, then you can use the form "$CT.Customer" - "$CT." + the entity name - or "$CT." plus the full class name of an entity in this persistence unit, e.g. "$CT.com.cloudtran.model.Customer". You can't just use any name after the "$CT" - it must identify an entity, by name or class.

    When the 'generator' begins with "$CT", the 'strategy' property ('identity', 'sequence' or 'auto') is ignored.

    What CloudTran does  At start of day, the Isolator interrogates all the tables backing entities with a $CT generator and retrieves the last allocated ID on the table. It then provides a service to request the next block of IDs for the entity. At the client, when EclipseLink requests IDs, the entity generator returns cached values, which are replenished in advance from the service on the Isolator, so the client never has to wait to get the next ID.

    CloudTran allocates IDs in batches of 1000 per client by default. You can change this with the ct.client.primaryKeyPreallocationSize configuration property.

    The complete name of a CloudTran generator is of the form "persistenceUnit/fully.qualified.class.name"; our customer generator might be "child-activities-server-1/com.cloudtran.model.Customer". This ensures that the names are unique across all persistence units

    It also validates that the other configuration changes described in this section are correct.

    Rules 

    1. To emphasize: only use CloudTran generators when the system of record is in the grid.
    2. Generated values must be single keys (not part of composite keys) and must be Integer or Long (or int/long) types.
    3. Because of the role of the Isolator, if you use CloudTran generators, you will only be able to deploy a single CloudTran application on the grid.

4.1.2  persistence.xml
CloudTran-Coherence uses JPA's persistence.xml file(s) to define entities and the mapping to datastores.

CloudTran writes a trace line to the console when it starts loading information from a persistence unit, noting the location of the persistence.xml file:
Loading CloudTran persistence unit 'child-activities-server-1' from persistence.xml 
at URL 'file:/C:/workspace/ChildActivities/classes/'
The persistence.xml file is used by the application program and the Manager and Isolator nodes - but each of these instances uses it in slightly different ways.

However, CloudTran allows you to use the same persistence.xml file in all cases; under the covers it adapts the EclipseLink configuration as necessary on each JVM.

  1. <provider>. For each persistence unit to be managed by CloudTran, you must use CloudTran's CTPersistenceProvider class as the provider:
    <persistence-unit name="client" transaction-type="RESOURCE_LOCAL">
        <provider>com.cloudtran.jpa.CTPersistenceProvider</provider>
    
    What CloudTran does  When you specify CTPersistenceProvider here, CloudTran makes sure that its own classes are used instead of the EclipseLink/TopLink standard classes for the entity manager factory, entity manager and transaction manager.

    It also validates that the other configuration changes described in this section are correct.

  2. <properties>. The persistence unit can also have properties, e.g.
    <properties>.  
        <presistence-unit>
            <properties>
                <property name="eclipselink.target-database" value="MYSQL" />
    These properties are defined by EclipseLink and TopLink Grid to configure the default operation of the persistence unit. Each persistence unit has a different set of properties, for example to define how to connect to the database.

    What you must do 

    1. Define valid java.persistence.jdbc.* properties (e.g. url, user, password) to access the database you want for the persistence unit.
    2. Not specify the "eclipselink.session.customizer" property.
    3. Not disable the the shared cache by default, by specifying <property name= "eclipselink.cache.shared.default" value="false">. CloudTran needs the shared (Level 2) cache to operate. Remove this property if it is present (the default is "true", meaning the shared cache will be used) .

    What CloudTran does 

    CloudTran, like TopLink Grid, depends on intercepting the level 2 cache and applying its wrappers to the Coherence cache. If you set the shared cache false, no data is sent to the Cache and CloudTran will not persist information correctly. All the entities in a CloudTran persistence unit must use the shared cache.

    You can generate the database schema using DDL generation in EclipseLink. However, note that this is only done on the Isolator.


4.1.3  coherence-cache-config
The Coherence cache configuration for TopLink Grid in Grid Entity configuration is described here.

In order to add functionality to TopLink Grid, CloudTran-Coherence requires some changes to this configuration. We explain these changes, making reference to the ChildActivities application's 'coherence-cache-config' file - which is duplicated here.

  1. There are some caches predefined by CloudTran, namely PrimaryKeyCache, CohortFlushInfoCache, IsolatorControlCache, ManagerControlCache and DistributedTxInfoCache.
  2. The other caches are defined per-entity. The example uses the convention that the cache name is the same as the entity name. Also, there is a separate Coherence scheme per entity (AppCache, AppCache2 etc.). This allows each entity to be on a separate service, which is better for performance when reading from or writing to the cache.
  3. As a starting point, when you define a new entity:
    • Create a <cache-mapping> entry within the <caching-scheme-mapping> element, specifying the entity name as the <cache-name> and the appropriate service name as the <scheme-name>.
    • Create a <distributed-scheme> within the <caching-schemes> element, copying one of the existing AppCache* schemes. The <scheme-name> must match the scheme-name from the previous step. Also, create a unique name for the <service-name>

4.1.4  POF Config
You must ensure that the CloudTran jars appear before the Coherence jar in your classpath.

The 'cloudTranCoherence' jar has a pof-config.xml file which pulls in other POF config files in the following order:

  • coherence-pof-config.xml
  • coherence-tools-pof-config.xml (see the Google project)
  • the CloudTran base POF config, which defines POF information for all the classes within CloudTran
  • the "application-pof-config.xml"
Of course, you can override this with your own POF config definition.

If you don't, then you must specify the application-pof-config.xml file. The example project has a starter file in the ChildActivities/cache-config directory which you can change.

For each domain model object whose fully qualified class-name is represented by '[CN]', you need to specify <user-type> entries that look like this

    <user-type>
        <type-id>6000</type-id>
        <class-name>[CN]</class-name>
    </user-type>
    <user-type>
        <type-id>6001</type-id>
        <class-name>oracle.eclipselink.coherence.integrated.cache.wrappers.[CN]_Wrapper</class-name>
        <serializer>
            <class-name>com.cloudtran.coherence.serializers.CtWrapperObjectSerializer</class-name>
        </serializer>
    </user-type>
You don't need to create the '[CN]_Wrapper' class; CloudTran does that. But you do need to define the classes in CloudTran.

However, you do need to ensure that all the <type-id> values are unique


4.1.5  The configuration file 'config.properties'
There are CloudTran-specific properties as described in the next section.

Copyright (c) 2008-2013 CloudTran Inc.