Monday, January 14, 2013

Initiate Infinispan with a Custom JChannel

In all Infinispan sample the JGroups part is almost omitted. You are told that you should provide a configuration xml and the infinispan-core.jar contains three samples: udp, tcp and ec2.

But what happens if you don't want to use samples? What happens if you want to have a dynamic configuration that changes based on the environment/database/external configuration tool? What happens if you want to configure it from code?

It appears to be not an easy task, but not very complicated. A special interface org.infinispan.remoting.transport.jgroups.JGroupsChannelLookup exists that allows an injection of org.jgroups.Channel.

So you can write something like:
public classJGroupsChannelLookupImpl implements JGroupsChannelLookup {
    public Channel getJGroupsChannel(Properties p) {
        return new JChannel();  // of course the code here might be quite complex, initializing the channel with a custom configuration

    public boolean shouldStartAndConnect() {
        return true; // change to false if you start and connect the channel yourself

    public boolean shouldStopAndDisconnect() {
        return true; // change to false if you stop and disconnect the channel yourself

Make sure to have a default public noargs constructor or a static getInstance() method that returns an instance of JGroupsChannelLookup.
(Personally I prefer a static method, so I have control how the instance is created and managed)

Now you need to tell the Infinispan to use your JGroupsChannelLookup:
Configuration conf = new ConfigurationBuilder().clustering().cacheMode(CacheMode.REPL_SYNC).sync().build();
GlobalConfiguration globalConf = new GlobalConfigurationBuilder().clusteredDefault().transport()
                    .addProperty(JGroupsTransport.CHANNEL_LOOKUP, JGroupsChannelLookupImpl.class.getName()).asyncTransportExecutor()

DefaultCacheManager manager = new DefaultCacheManager(globalConf, conf);