Defining a partition mapper

Partition mappers are defined by extending com.kabira.platform.highavailability.PartitionMapper and implementing the getPartition method. Partition mappers are installed on a specific class using the PartitionManager.setMapper() method.

All child classes extending a parent class inherit the parent's partition mapper. The parent's partition mapper can be overridden in a child class by installing a partition mapper on the child. Only a child's partition mapper is called when the child is created.

The getPartition method is called when objects are created, or re-partitioning (the section called “Updating partition mapping”) is requested. The method is passed an object of the type for which it was registered. The getPartition method must return a valid partition name for the object. The object is assigned to the returned partition name.

Partition mappers must be installed on each node in the cluster that has the managed object type installed. This includes all replica nodes for the managed object type. Failure to do so will cause inconsistent behavior in the cluster because the type will be partitioned on some nodes, but not on others. The partition mapper should be installed as part of application initialization before a node joins the cluster and before any objects of that type are created.

When a partition mapper is installed an audit is performed to validate the current state of partitioned objects on the node. The audit to perform can be one of:

The decision on which partition should be associated with an object is based on an application specific criteria. For example all customers on the west coast could be in a partition named westcoast, while all customers on the east coast could be in a partition named eastcoast. Partitions could also be assigned based on load balancing, or other system resource criteria.

If an invalid partition name is returned from the getPartition method a com.kabira.platform.ResourceUnavailableException is thrown.

Partition mappers can be cleared using the PartitionManager.clearMapper() method.

Example 7.1, “Defining , installing, and clearing a partition mapper” shows the definition and installation of a partition mapper.

Example 7.1. Defining , installing, and clearing a partition mapper

//     $Revision: 1.1.2.4 $
package com.kabira.snippets.highavailability;

import com.kabira.platform.Transaction;
import com.kabira.platform.annotation.Managed;
import com.kabira.platform.highavailability.PartitionManager;
import com.kabira.platform.highavailability.PartitionMapper;

/**
 * Defining and installing a partition mapper.
 * <p>
 * <h2> Target Nodes</h2>
 * <ul>
 * <li> <b>domainnode</b> = A</li>
 * </ul>
 * </p>
 */
public class HighAvailability
{
    @Managed
    private static class MyObject
    {
    };

    //
    //  Partition mapper that just returns a hard-coded partition name
    //
    private static class MyPartitionMapper extends PartitionMapper
    {
        @Override
        public String getPartition(Object obj)
        {
            return "Unknown Partition";
        }
    }

    /**
     * Main entry point
     *
     * @param args Not used
     */
    public static void main(String[] args)
    {
        new Transaction("High Availability")
        {
            @Override
            protected void run() throws Rollback
            {
                //
                //    Define partition mapper properties to audit for any
                //    unpartitioned objects
                //
                PartitionMapper.Properties properties = new PartitionMapper.Properties();
                properties.setAudit(PartitionMapper.Properties.Audit.VERIFY_PARTIONING);

                //
                //  Install the partition mapper
                //
                PartitionManager.setMapper(
                    MyObject.class, new MyPartitionMapper(), properties);

                //
                //  Create an instance of MyObject.
                //    This will fail because partition mapper
                //    is returning an unknown partition
                //
                try
                {
                    new MyObject();
                }
                finally
                {
                    //
                    //    Clear the partition mapper
                    //
                    PartitionManager.clearMapper(MyPartitionMapper.class);
                }
            }
        }.execute();
    }
}

When Example 7.1, “Defining , installing, and clearing a partition mapper” is run it fails with the following output:

[A] Java main class com.kabira.snippets.highavailability.HighAvailability.main exited with an exception.
[A] com.kabira.platform.ResourceUnavailableException: 
           could not find partition 'Unknown Partition' for object 
           'com.kabira.snippets.highavailability.MyObject:1 (1352756:1794744:14616904711:1 offset 68152136)'
[A]  at com.kabira.platform.ManagedObject.createSMObject(Native Method)
[A]  at com.kabira.snippets.highavailability.MyObject.<init>(HighAvailability.java:11)
[A]  at com.kabira.snippets.highavailability.HighAvailability$1.run(HighAvailability.java:56)
[A]  at com.kabira.platform.Transaction.execute(Transaction.java:303)
[A]  at com.kabira.snippets.highavailability.HighAvailability.main(HighAvailability.java:43)
[A]  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[A]  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
[A]  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
[A]  at java.lang.reflect.Method.invoke(Method.java:597)
[A]  at com.kabira.platform.MainWrapper.invokeMain(MainWrapper.java:49)

This is expected, because the partition name returned by getPartition was not defined. Defining partitions is described in the section called “Defining and enabling partitions”.