Hazelcast Integration for Spring Environments

This chapter describes the Spring configuration required to setup Hazelcast in-memory cache in Spring-managed environments. Hazelcast is a clustering and scalable data distribution platform. For detailed information on Hazelcast refer to http://www.hazelcast.com/product.jsp.

For details on tuning via an in-memory cache in Stardust refer to chapter Retrieving Entities from In-Memory Cache in the Developer Handbook.

The in-memory cache is turned on by default with the property below in your server-side carnot.properties file.

Infinity.Engine.Caching = true

If not, set this property explicitly.

Deployment Preparation

Perform the following steps to prepare a Spring deployment with Hazelcast integration:

  1. Integrate the following Spring Application Context by putting a file ending with -context.xml and the following content into the WEB-INF/config/ipp/spring folder of your WAR file:
    <?xml version="1.0" encoding="UTF-8"?>
    
    <beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
       
       <bean name="springContextPostProcessor"
          class="com.infinity.bpm.rt.integration.cache.hazelcast.SpringContextPostProcessor" />
    
       <bean id="localHazelcastConnectionFactory" class="org.springframework.jca.support.LocalConnectionFactoryBean" lazy-init="true" >
          <property name="managedConnectionFactory">
             <bean class="com.hazelcast.jca.ManagedConnectionFactoryImpl" />
          </property>
          <property name="connectionManager">
             <bean id="connectionManagerFactory" class="org.jencks.factory.ConnectionManagerFactoryBean">
                <property name="transactionManager" ref="xaTransactionManager" />
                <property name="transaction" value="local" />
                <property name="poolingSupport" ref="poolingSupport" />
             </bean>
          </property>
       </bean>
       
       <bean id="poolingSupport" class="org.jencks.factory.PoolingSupportFactoryBean">
          <property name="poolMaxSize" value="100" />
          <property name="poolMinSize" value="10" />
          <property name="connectionMaxWaitMilliseconds" value="5000" />
          <property name="connectionMaxIdleMinutes" value="1" />
       </bean>
    </beans>   
  2. Put the following Hazelcast artifacts into the WEB-INF/lib of your WAR file:
  3. Add the following entry to your server-side carnot.properties file to enable the Spring-based version of the Hazelcast Cache Factory:
    Carnot.Engine.Hazelcast.JcaConnectionFactoryProvider = org.eclipse.stardust.engine.spring.integration.jca.SpringAppContextHazelcastJcaConnectionFactoryProvider
  4. Optional: Put an appropriate hazelcast.xml into WEB-INF/classes folder of your WAR (or a default configuration will be taken from com.hazelcast:hazelcast:1.9).

Spring Context Post Processor

The cache is created and accessed first during engine bootstrap. At that point the Spring context loaded by the ContextLoaderListener might not be available yet. Therefore, the below Spring context post processor is required to avoid any such race conditions and to make sure the Spring context with all loaded beans are available when the cache is accessed the first time.

package com.infinity.bpm.rt.integration.cache.hazelcast;
 
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
 
import org.eclipse.stardust.engine.api.spring.SpringUtils;
 
public class SpringContextPostProcessor implements BeanFactoryPostProcessor,
		ApplicationContextAware {
 
	private ApplicationContext context;
 
	@Override
	public void postProcessBeanFactory(
			ConfigurableListableBeanFactory beanFactory) throws BeansException {
 
		SpringUtils
				.setApplicationContext((ConfigurableApplicationContext) this.context);
	}
 
	@Override
	public void setApplicationContext(ApplicationContext context)
			throws BeansException {
		this.context = context;
	}
 
}

The corresponding Spring configuration looks like the following:

<bean name="springContextPostProcessor"
		class="com.infinity.bpm.rt.integration.cache.hazelcast.SpringContextPostProcessor" />

Hazelcast Configuration

Create the following default configuration template hazelcast.xml defining one Stardust specific distributed cache object ipp-2nd-level-cache:

hazelcast.xml

The engine then uses Hazelcast as second level cache provider. Add the configuration file to your runtime's classpath.