The code of this project has been committed to th Apache Camel project. In future all changes will be directly send to the Apache SVN. So this repository will never be updated and is now outdated.
Hazelcast is a ligthwight data grid written entirely in Java and published under apache licence. You can find more on www.hazelcast.com. Inside the datagrid you can store your data in maps, multimaps (same key, n values), queues, sets, topics and as a special artifact atomic numbers. This camel component focuses on maps, multimaps and atomic numbers. As special feature it provides a simple cluster support.
A camel-hazelcast URI looks always like:
hazelcast:[map|multimap|list|queue|seda|atomicvalue|instance]:cachename
An URI without the second prefix is not valid. All additional things like a id for a stored object are provided over header variables.
If you want to store a value in a map you can use the map cache producer. The map cache producer provides 5 operations (put, get, update, delete, query). For the first 4 you have to provide the operation inside the “hazelcast.operation.type” header variable. The values are (see also org.apache.camel.component.hazelcast.HazelcastConstants
):
public static final int PUT_OPERATION = 1;
public static final int DELETE_OPERATION = 2;
public static final int GET_OPERATION = 3;
public static final int UPDATE_OPERATION = 4;
public static final int QUERY_OPERATION = 5;
Sample for put:
Java DSL:
from("direct:put")
.setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.PUT_OPERATION))
.to(String.format("hazelcast:%sfoo", HazelcastConstants.MAP_PREFIX));
Spring DSL:
<route>
<from uri="direct:put" />
<setHeader headerName="hazelcast.operation.type">
<constant>put</constant>
</setHeader>
<to uri="hazelcast:map:foo" />
</route>
Sample for get:
Java DSL:
from("direct:get")
.setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.GET_OPERATION))
.to(String.format("hazelcast:%sfoo", HazelcastConstants.MAP_PREFIX))
.to("seda:out");
Spring DSL:
<route>
<from uri="direct:get" />
<setHeader headerName="hazelcast.operation.type">
<constant>get</constant>
</setHeader>
<to uri="hazelcast:map:foo" />
<to uri="seda:out" />
</route>
Sample for update:
Java DSL:
from("direct:update")
.setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.UPDATE_OPERATION))
.to(String.format("hazelcast:%sfoo", HazelcastConstants.MAP_PREFIX));
Spring DSL:
<route>
<from uri="direct:update" />
<setHeader headerName="hazelcast.operation.type">
<constant>update</constant>
</setHeader>
<to uri="hazelcast:map:foo" />
</route>
Sample for delete:
Java DSL:
from("direct:delete")
.setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.DELETE_OPERATION))
.to(String.format("hazelcast:%sfoo", HazelcastConstants.MAP_PREFIX));
Spring DSL:
<route>
<from uri="direct:delete" />
<setHeader headerName="hazelcast.operation.type">
<constant>delete</constant>
</setHeader>
<to uri="hazelcast:map:foo" />
</route>
Sample for query
Java DSL:
from("direct:query")
.setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.QUERY_OPERATION))
.to(String.format("hazelcast:%sfoo", HazelcastConstants.MAP_PREFIX))
.to("seda:out");
Spring DSL:
<route>
<from uri="direct:query" />
<setHeader headerName="hazelcast.operation.type">
<constant>query</constant>
</setHeader>
<to uri="hazelcast:map:foo" />
<to uri="seda:out" />
</route>
you can call them in your test class with:
template.sendBodyAndHeader("direct:[put|get|update|delete|query]", "my-foo", HazelcastConstants.OBJECT_ID, "4711");
For query you have to provide the SQL like query syntax in the message body:
String q1 = "bar > 1000";
template.sendBodyAndHeader("direct:query", null, HazelcastConstants.QUERY, q1);
Hazelcast provides event listeners on their data grid. If you want to be notified if a cache will be manipulated, you can use the map consumer. There’re 4 events: put, update, delete and envict. The event type will be stored in the “hazelcast.listener.action” header variable. The map consumer provides some additional information inside these variables:
variable | meaning |
---|---|
hazelcast.listener.time | time of the event in millis |
hazelcast.listener.type | the map consumer sets here “cachelistener” |
hazelcast.objectId | the oid of the object |
hazelcast.cache.name | the name of the cache – e.g. “foo” |
hazelcast.cache.type | the type of the cache – here map, but can also be multimap |
The object value will be stored within put and update actions inside the message body.
Here a sample:
from(String.format("hazelcast:%sfoo", HazelcastConstants.MAP_PREFIX))
.log("object...")
.choice()
.when(header(HazelcastConstants.LISTENER_ACTION).isEqualTo(HazelcastConstants.ADDED))
.log("...added")
.to("mock:added")
.when(header(HazelcastConstants.LISTENER_ACTION).isEqualTo(HazelcastConstants.ENVICTED))
.log("...envicted")
.to("mock:envicted")
.when(header(HazelcastConstants.LISTENER_ACTION).isEqualTo(HazelcastConstants.UPDATED))
.log("...updated")
.to("mock:updated")
.when(header(HazelcastConstants.LISTENER_ACTION).isEqualTo(HazelcastConstants.REMOVED))
.log("...removed")
.to("mock:removed")
.otherwise()
.log("fail!");
A multimap is a cache where you can store n values to one key. The multimap producer provides 4 operations (put, get, removevalue, delete).
Sample for put:
Java DSL:
from("direct:put")
.setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.PUT_OPERATION))
.to(String.format("hazelcast:%sbar", HazelcastConstants.MULTIMAP_PREFIX));
Spring DSL:
<route>
<from uri="direct:put" />
<log message="put.."/>
<setHeader headerName="hazelcast.operation.type">
<constant>put</constant>
</setHeader>
<to uri="hazelcast:multimap:foo" />
</route>
Sample for removevalue:
Java DSL:
from("direct:removevalue")
.setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.REMOVEVALUE_OPERATION))
.to(String.format("hazelcast:%sbar", HazelcastConstants.MULTIMAP_PREFIX));
Spring DSL:
<route>
<from uri="direct:removevalue" />
<log message="removevalue..."/>
<setHeader headerName="hazelcast.operation.type">
<constant>removevalue</constant>
</setHeader>
<to uri="hazelcast:multimap:foo" />
</route>
To remove a value you have to provide the value you want to remove inside the message body. If you have a multimap object {key: "4711" values: { "my-foo", "my-bar"}}
you have to put “my-foo” inside the message body to remove the “my-foo” value.
Sample for get:
Java DSL:
from("direct:get")
.setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.GET_OPERATION))
.to(String.format("hazelcast:%sbar", HazelcastConstants.MULTIMAP_PREFIX))
.to("seda:out");
Spring DSL:
<route>
<from uri="direct:get" />
<log message="get.."/>
<setHeader headerName="hazelcast.operation.type">
<constant>get</constant>
</setHeader>
<to uri="hazelcast:multimap:foo" />
<to uri="seda:out" />
</route>
Sample for delete:
Java DSL:
from("direct:delete")
.setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.DELETE_OPERATION))
.to(String.format("hazelcast:%sbar", HazelcastConstants.MULTIMAP_PREFIX));
Spring DSL:
<route>
<from uri="direct:delete" />
<log message="delete.."/>
<setHeader headerName="hazelcast.operation.type">
<constant>delete</constant>
</setHeader>
<to uri="hazelcast:multimap:foo" />
</route>
you can call them in your test class with:
template.sendBodyAndHeader("direct:[put|get|removevalue|delete]", "my-foo", HazelcastConstants.OBJECT_ID, "4711");
For the multimap cache this component provides the same listeners / variables as for the map cache consumer (except the update and enviction listener). The only difference is the multimap prefix inside the URI. Here is a sample:
from(String.format("hazelcast:%sbar", HazelcastConstants.MULTIMAP_PREFIX))
.log("object...")
.choice()
.when(header(HazelcastConstants.LISTENER_ACTION).isEqualTo(HazelcastConstants.ADDED))
.log("...added")
.to("mock:added")
//.when(header(HazelcastConstants.LISTENER_ACTION).isEqualTo(HazelcastConstants.ENVICTED))
// .log("...envicted")
// .to("mock:envicted")
.when(header(HazelcastConstants.LISTENER_ACTION).isEqualTo(HazelcastConstants.REMOVED))
.log("...removed")
.to("mock:removed")
.otherwise()
.log("fail!");
Enviction will be added as feature, soon (this is a Hazelcast issue).
The queue producer provides 6 operations (add, put, poll, peek, offer, removevalue).
Sample for add:
from("direct:add")
.setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.ADD_OPERATION))
.to(String.format("hazelcast:%sbar", HazelcastConstants.QUEUE_PREFIX));
Sample for put:
from("direct:put")
.setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.PUT_OPERATION))
.to(String.format("hazelcast:%sbar", HazelcastConstants.QUEUE_PREFIX));
Sample for poll:
from("direct:poll")
.setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.POLL_OPERATION))
.to(String.format("hazelcast:%sbar", HazelcastConstants.QUEUE_PREFIX));
Sample for peek:
from("direct:peek")
.setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.PEEK_OPERATION))
.to(String.format("hazelcast:%sbar", HazelcastConstants.QUEUE_PREFIX));
Sample for offer:
from("direct:offer")
.setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.OFFER_OPERATION))
.to(String.format("hazelcast:%sbar", HazelcastConstants.QUEUE_PREFIX));
Sample for removevalue:
from("direct:removevalue")
.setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.REMOVEVALUE_OPERATION))
.to(String.format("hazelcast:%sbar", HazelcastConstants.QUEUE_PREFIX));
The queue consumer provides 2 operations (add, remove).
Sample :
from(String.format("hazelcast:%smm", HazelcastConstants.QUEUE_PREFIX))
.log("object...")
.choice()
.when(header(HazelcastConstants.LISTENER_ACTION).isEqualTo(HazelcastConstants.ADDED))
.log("...added")
.to("mock:added")
.when(header(HazelcastConstants.LISTENER_ACTION).isEqualTo(HazelcastConstants.REMOVED))
.log("...removed")
.to("mock:removed")
.otherwise()
.log("fail!");
The list producer provides 4 operations (add, set, get, removevalue).
Sample for add:
from("direct:add")
.setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.ADD_OPERATION))
.to(String.format("hazelcast:%sbar", HazelcastConstants.LIST_PREFIX));
Sample for get:
from("direct:get")
.setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.GET_OPERATION))
.to(String.format("hazelcast:%sbar", HazelcastConstants.LIST_PREFIX))
.to("seda:out");
Sample for setvalue:
from("direct:set")
.setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.SETVALUE_OPERATION))
.to(String.format("hazelcast:%sbar", HazelcastConstants.LIST_PREFIX));
Sample for removevalue:
from("direct:removevalue")
.setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.REMOVEVALUE_OPERATION))
.to(String.format("hazelcast:%sbar", HazelcastConstants.LIST_PREFIX));
Please note that set,get and removevalue and not yet supported by hazelcast, will be added in the future..
The list consumer provides 2 operations (add, remove).
Sample :
from(String.format("hazelcast:%smm", HazelcastConstants.LIST_PREFIX))
.log("object...")
.choice()
.when(header(HazelcastConstants.LISTENER_ACTION).isEqualTo(HazelcastConstants.ADDED))
.log("...added").to("mock:added")
.when(header(HazelcastConstants.LISTENER_ACTION).isEqualTo(HazelcastConstants.REMOVED))
.log("...removed").to("mock:removed").otherwise().log("fail!");
SEDA component differs from the rest components provided. It implements a work-queue in order to support asynchronous SEDA architectures, similar to the core “SEDA” component.
The SEDA producer provides no operations. You only send data to the specified queue.
Java DSL :
from("direct:foo")
.to("hazelcast:seda:foo");
Spring DSL :
<route>
<from uri="direct:start" />
<to uri="hazelcast:seda:foo" />
</route
The SEDA consumer provides no operations. You only retrieve data from the specified queue.
Java DSL :
from("hazelcast:seda:foo")
.to("mock:result");
Spring DSL:
<route>
<from uri="hazelcast:seda:foo" />
<to uri="mock:result" />
</route>
An atomic number is an object that simply provides a grid wide number (long). The operations for this producer are set (set the number with a given value), get, increase (+1), decrease (-1) and destroy.
Sample for set:
Java DSL:
from("direct:set")
.setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.SETVALUE_OPERATION))
.to(String.format("hazelcast:%sfoo", HazelcastConstants.ATOMICNUMBER_PREFIX));
Spring DSL:
<route>
<from uri="direct:set" />
<setHeader headerName="hazelcast.operation.type">
<constant>setvalue</constant>
</setHeader>
<to uri="hazelcast:atomicvalue:foo" />
</route>
Provide the value to set inside the message body (here the value is 10): template.sendBody("direct:set", 10);
Sample for get:
Java DSL:
from("direct:get")
.setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.GET_OPERATION))
.to(String.format("hazelcast:%sfoo", HazelcastConstants.ATOMICNUMBER_PREFIX));
Spring DSL:
<route>
<from uri="direct:get" />
<setHeader headerName="hazelcast.operation.type">
<constant>get</constant>
</setHeader>
<to uri="hazelcast:atomicvalue:foo" />
</route>
You can get the number with long body = template.requestBody("direct:get", null, Long.class);
.
Sample for increment:
Java DSL:
from("direct:increment")
.setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.INCREMENT_OPERATION))
.to(String.format("hazelcast:%sfoo", HazelcastConstants.ATOMICNUMBER_PREFIX));
Spring DSL:
<route>
<from uri="direct:increment" />
<setHeader headerName="hazelcast.operation.type">
<constant>increment</constant>
</setHeader>
<to uri="hazelcast:atomicvalue:foo" />
</route>
The actual value (after increment) will be provided inside the message body.
Sample for decrement:
Java DSL:
from("direct:decrement")
.setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.DECREMENT_OPERATION))
.to(String.format("hazelcast:%sfoo", HazelcastConstants.ATOMICNUMBER_PREFIX));
Spring DSL:
<route>
<from uri="direct:decrement" />
<setHeader headerName="hazelcast.operation.type">
<constant>decrement</constant>
</setHeader>
<to uri="hazelcast:atomicvalue:foo" />
</route>
The actual value (after decrement) will be provided inside the message body.
Sample for destroy
Java DSL:
from("direct:destroy")
.setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.DESTROY_OPERATION))
.to(String.format("hazelcast:%sfoo", HazelcastConstants.ATOMICNUMBER_PREFIX));
Spring DSL:
<route>
<from uri="direct:destroy" />
<setHeader headerName="hazelcast.operation.type">
<constant>destroy</constant>
</setHeader>
<to uri="hazelcast:atomicvalue:foo" />
</route>
Hazelcast makes sense in one single “server node”, but it’s extremly powerful in a clustered environment. The instance consumer fires if a new cache instance will join or leave the cluster.
Here’s a sample:
from(String.format("hazelcast:%sfoo", HazelcastConstants.INSTANCE_PREFIX))
.log("instance...")
.choice()
.when(header(HazelcastConstants.LISTENER_ACTION).isEqualTo(HazelcastConstants.ADDED))
.log("...added")
.to("mock:added")
.otherwise()
.log("...removed")
.to("mock:removed");
Each event provides the following information inside the message header:
variable | meaning |
---|---|
hazelcast.listener.action | type of event – here added or removed |
hazelcast.listener.time | time of the event in millis |
hazelcast.listener.type | the map consumer sets here “instancelistener” |
hazelcast.instance.host | host name of the instance |
hazelcast.instance.port | port number of the instance |
If you have further questions don’t hesitate to send a mail to info(at)catify.com
, or post to the camel mailinglist (preferred way ;)