Camel Components

Hazelcast

Since Camel 2.7

The hazelcast- component allows you to work with the Hazelcast distributed data grid / cache. Hazelcast is an in-memory data grid, entirely written in Java (single jar). It offers a great palette of different data stores like map, multimap (same key, n values), queue, list and atomic number. The main reason to use Hazelcast is its simple cluster support. If you have enabled multicast on your network, you can run a cluster with a hundred nodes with no extra configuration. Hazelcast can simply configure to add additional features like n copies between nodes (default is 1), cache persistence, network configuration (if needed), near cache, eviction, and so on. For more information, consult the Hazelcast documentation on http://www.hazelcast.com/docs.jsp.

Hazelcast components

See the following for usage of each component:

Hazelcast Instance

Consume join/leave events of a cache instance in a Hazelcast cluster.

Hazelcast List

Perform operations on Hazelcast distributed list.

Hazelcast Map

Perform operations on Hazelcast distributed map.

Hazelcast Multimap

Perform operations on Hazelcast distributed multimap.

Hazelcast PN Counter

Increment, decrement, get, etc. operations on a Hazelcast PN Counter (CRDT counter).

Hazelcast Queue

Perform operations on Hazelcast distributed queue.

Hazelcast Replicated Map

Perform operations on Hazelcast replicated map.

Hazelcast Ringbuffer

Perform operations on Hazelcast distributed ringbuffer.

Hazelcast SEDA

Asynchronously send/receive Exchanges between Camel routes running on potentially distinct JVMs/hosts backed by Hazelcast BlockingQueue.

Hazelcast Set

Perform operations on Hazelcast distributed set.

Hazelcast Topic

Send and receive messages to/from Hazelcast distributed topic.

Installation

Maven users will need to add the following dependency to their pom.xml for this component:

<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-hazelcast</artifactId>
    <version>x.x.x</version>
    <!-- use the same version as your Camel core version -->
</dependency>

Using hazelcast reference

By its name

XML-only: Spring bean configuration with Hazelcast instance by name
<bean id="hazelcastLifecycle" class="com.hazelcast.core.LifecycleService"
      factory-bean="hazelcastInstance" factory-method="getLifecycleService"
      destroy-method="shutdown" />

<bean id="config" class="com.hazelcast.config.Config">
    <constructor-arg type="java.lang.String" value="HZ.INSTANCE" />
</bean>

<bean id="hazelcastInstance" class="com.hazelcast.core.Hazelcast" factory-method="newHazelcastInstance">
    <constructor-arg type="com.hazelcast.config.Config" ref="config"/>
</bean>
<camelContext xmlns="http://camel.apache.org/schema/spring">
    <route id="testHazelcastInstanceBeanRefPut">
        <from uri="direct:testHazelcastInstanceBeanRefPut"/>
        <setHeader name="CamelHazelcastOperationType">
            <constant>put</constant>
        </setHeader>
        <to uri="hazelcast-map:testmap?hazelcastInstanceName=HZ.INSTANCE"/>
    </route>

    <route id="testHazelcastInstanceBeanRefGet">
        <from uri="direct:testHazelcastInstanceBeanRefGet" />
        <setHeader name="CamelHazelcastOperationType">
            <constant>get</constant>
        </setHeader>
        <to uri="hazelcast-map:testmap?hazelcastInstanceName=HZ.INSTANCE"/>
        <to uri="seda:out" />
    </route>
</camelContext>

By instance

XML-only: Spring bean configuration with Hazelcast instance by reference
<bean id="hazelcastInstance" class="com.hazelcast.core.Hazelcast"
      factory-method="newHazelcastInstance" />
<bean id="hazelcastLifecycle" class="com.hazelcast.core.LifecycleService"
      factory-bean="hazelcastInstance" factory-method="getLifecycleService"
      destroy-method="shutdown" />

<camelContext xmlns="http://camel.apache.org/schema/spring">
    <route id="testHazelcastInstanceBeanRefPut">
        <from uri="direct:testHazelcastInstanceBeanRefPut"/>
        <setHeader name="CamelHazelcastOperationType">
            <constant>put</constant>
        </setHeader>
        <to uri="hazelcast-map:testmap?hazelcastInstance=#hazelcastInstance"/>
    </route>

    <route id="testHazelcastInstanceBeanRefGet">
        <from uri="direct:testHazelcastInstanceBeanRefGet" />
        <setHeader name="CamelHazelcastOperationType">
            <constant>get</constant>
        </setHeader>
        <to uri="hazelcast-map:testmap?hazelcastInstance=#hazelcastInstance"/>
        <to uri="seda:out" />
    </route>
</camelContext>

Configuring HazelcastInstance on component

You can also configure the hazelcast instance on the component which will then be used by all hazelcast endpoints. In the example above we set up this for the hazelcast map component and setup hazelcast via verbose <bean> configurations.

<bean id="config" class="com.hazelcast.config.Config">
    <constructor-arg type="java.lang.String" value="HZ.INSTANCE" />
    <property name="networkConfig" ref="myNetworkConfig"/>
</bean>

<bean id="myNetworkConfig" class="com.hazelcast.config.NetworkConfig">
  <property name="port">1234</property>
</bean>

<bean id="myHazelcastInstance" class="com.hazelcast.core.Hazelcast" factory-method="newHazelcastInstance">
    <constructor-arg type="com.hazelcast.config.Config" ref="config"/>
</bean>

<bean id="hazelcast" class="org.apache.camel.component.hazelcast.map.HazelcastMapComponent">
  <property name="hazelcastInstance" ref="myHazelcastInstance"/>
</bean>

Java serialization filter

Hazelcast stores objects that implement Serializable or Externalizable using Java serialization, and deserializes them when Camel reads them back from a map, queue, topic or any other data structure. A Hazelcast JavaSerializationFilterConfig limits which classes Hazelcast deserializes.

When Camel creates the Hazelcast instance itself, it applies a default filter. The default allows class names that start with java., javax. or org.apache.camel., and rejects those that start with java.net.. Camel creates the instance itself when:

  • an endpoint sets none of hazelcastInstance, hazelcastInstanceName, hazelcastConfig or hazelcastConfigUri, and no instance is configured on the component;

  • a Hazelcast aggregation repository, idempotent repository, key-value repository or route policy starts its own instance because none was given to it.

Camel uses a configuration you supply as it is: a Config or ClientConfig bean set with hazelcastConfig, a file set with hazelcastConfigUri, or an existing instance set with hazelcastInstance or found with hazelcastInstanceName. Hazelcast’s own default configuration declares no serialization filter, so declare one in your configuration, and make it cover the classes your application stores in the cluster:

<hazelcast xmlns="http://www.hazelcast.com/schema/config">
    <serialization>
        <java-serialization-filter>
            <whitelist>
                <prefix>java.</prefix>
                <prefix>javax.</prefix>
                <prefix>org.apache.camel.</prefix>
                <prefix>com.example.model.</prefix>
            </whitelist>
            <blacklist>
                <prefix>java.net.</prefix>
            </blacklist>
        </java-serialization-filter>
    </serialization>
</hazelcast>

A hazelcast-client configuration takes the same serialization element. In Java, set the filter on the SerializationConfig of a Config or a ClientConfig:

JavaSerializationFilterConfig filter = new JavaSerializationFilterConfig();
filter.setWhitelist(new ClassFilter().addPrefixes("java.", "javax.", "org.apache.camel.", "com.example.model."));
filter.setBlacklist(new ClassFilter().addPrefixes("java.net."));

Config config = new Config();
config.getSerializationConfig().setJavaSerializationFilterConfig(filter);

Alternatively, set a JVM-wide filter with the jdk.serialFilter system property, for example -Djdk.serialFilter='!java.net.**;java.**;javax.**;org.apache.camel.**;com.example.model.**;!*'. It applies to all Java deserialization in the JVM, not only to Hazelcast.

When Camel starts a Hazelcast member or client from a Config or ClientConfig you supplied that declares no filter, and no JVM-wide filter is set, it logs a WARN.