h1. Documentation for the Hazelcast module

bq. This module is a @dropin@ replacement for EhCacheImpl or MemcachedImpl from Play. 
It allow your application to have a clustered cache when you can't install a memcached server on your platform.
It's also a great free open source *In-Memory Data Grid*

See "Hazelcast Documentation":http://www.hazelcast.com/documentation.jsp for more details.

h2. Installing Hazelcast Module

p. To install Hazelcast Plugin module, you do like every other Play Modules:

bc. play install hazelcast[-version]

h2. Using Hazelcast Module in your application (Dependency management)

h3. There is two way to use the module


* The Play 1.x way (*in application.conf*)

bc. module.hazelcast=${play.path}/modules/hazelcast-[version]

* The Play 1.2.x way (*in dependencies.yml*)

bc.. require:
	- play -> hazelcast [version]

h3. Parameters

You can disable the module in your application by using a parameter in @application.conf@:

bc. hazelcast.disabled=true

The value defaults to false.

bc. hazelcast.configFile=conf/hazelcast-dev.xml

You can specify the configuration file to be used. The value defaults to conf/hazelcast.xml

h2. Using standard Play! Framework Cache Mechanisms

p. All the standard Play annotations or methods work seamlessly with *Hazelcast* instead of *EhCache* or *Memcached*.

* @CacheFor("1h")@
* @Cache.xxx()@
* Etc...

bq. See "Play Framework Cache Documentation":/@documentation/cache for @CacheFor("1h")@ and provided Play! @Cache.xxx()@ usage.


h2. Using features from Hazelcast

h3. Using @Inject to inject an instance of *Hazelcast* in your controller

bc(Java). @Inject private static HazelcastInstance hazel;

h3. Injecting the default ExecutorService

bc(Java). @Inject private static ExecutorService executor;

h3. Using @Named to inject a named resource 

bc(Java). @Named("MyQueue") private static Queue myQueue;


h2. Hazelcast clustered services

* Distributed Queues (Entries are consumed by one and only one JVM)
* Distributed Topics (Entries are consumed by all JVM)
* Distributed Events
* Distributed AtomicNumber provider
* Distributed ExecutorService
* Distributed ID Generator (_ID are UNIQUE in all cluster nodes_)
* Distributed List (_to share a list in the cluster between many JVM_)
* Distributed Lock (_to apply a lock on an object and share between JVM_)
* Distributed Set
* Distributed Map/MultiMap (_Maps are shared between JMV, MultiMap allow for multiple values for the same key_)
* Distributed Transaction (_affect transactions on clustered objects, not database!_)

h3. Configuration file *hazelcast.xml*

You can modify *hazelcast.xml* to your need to create more Queues or Map and modify the default ExecutorService parameters. Just copy the hazelcast.xml file from the module _conf_ directory to your application _conf_ directory. This is also the file that allow you to change from multicast to TCPIP static cluster definition.

h3. Hazelcast Object type that can be retreived via @@Named@ annotation

* Queue
* Topic
* AtomicNumber
* ExecutorService
* Set
* Map
* MultiMap
* IdGenerator

h3. Hazelcast Object type that can by retreived via @@Inject@ annotation

* Transaction
* ExecutorService
* PartitionService
* Event

h3. Method directly accessible on @HazelcastPlugin@ class

* @HazelcastPlugin.getTransaction()@ [1]
* @HazelcastPlugin.getLock(Object o)@ [2]
* @HazelcastPlugin.getHazel()@ [3]

fn1. Use this to get a Transaction object then you can @begin()@ or @commit()@ or @rollback()@ operations on cluster.

fn2. Use this to lock an object across the cluster.

fn3. Use this if you absolutly _NEED_ to directly get the Default Hazelcast instance.

h2. Hibernate second level cache configuration

* application.conf
<code>hibernate.cache.region.factory_class=com.hazelcast.hibernate.HazelcastCacheRegionFactory</code>
<code>hibernate.cache.use_query_cache=false</code>
<code>hibernate.cache.use_minimal_puts=true</code>
<code>hibernate.cache.use_second_level_cache=true</code>
<code>hibernate.cache.region_prefix=myApp</code>
<code>hibernate.cache.use_structured_entries=true</code>


* dependencies.yml
<code># Application dependencies</code>
<code>require:</code>
<code>    - play</code>
<code>    - play -> hazelcast 0.4</code>
<code>    - com.hazelcast -> hazelcast-hibernate 1.9.4.4</code>


* Entity class annotation
<code>@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "model")</code>

* hazelcast.xml - add following map definition
<code><map name="myApp.model"></code>
<code>    <backup-count>1</backup-count></code>
<code>    <time-to-live-seconds>0</time-to-live-seconds></code>
<code>    <max-idle-seconds>3600</max-idle-seconds></code>
<code>    <eviction-policy>LRU</eviction-policy></code>
<code>    <max-size policy="cluster_wide_map_size">10000</max-size></code>
<code>    <eviction-percentage>25</eviction-percentage></code>
<code></map></code>

h2. Roadmap

p. I'd like to see some basic Play! features use Hazel capabilities:

* Play! Jobs could use Hazelcast ExecutorService automaticaly
* Integrating Hazelcast with my other upcoming module "Camel":http://myuri.me/3VAE for "EIP":http://myuri.me/3Vh8
* Etc...
