...
Cache
...
Component
...
Available
...
as
...
of
...
Camel
...
2.1
...
The
...
cache
...
component
...
enables
...
you
...
to
...
perform
...
caching
...
operations
...
using
...
EHCache
...
as
...
the
...
Cache
...
Implementation.
...
The
...
cache
...
itself
...
is
...
created
...
on
...
demand
...
or
...
if
...
a
...
cache
...
of
...
that
...
name
...
already
...
exists
...
then
...
it
...
is
...
simply
...
utilized
...
with
...
its
...
original
...
settings.
...
This
...
component
...
supports
...
producer
...
and
...
event
...
based
...
consumer
...
endpoints.
...
The
...
Cache
...
consumer
...
is
...
an
...
event
...
based
...
consumer
...
and
...
can
...
be
...
used
...
to
...
listen
...
and
...
respond
...
to
...
specific
...
cache
...
activities.
...
If
...
you
...
need
...
to
...
perform
...
selections
...
from
...
a
...
pre-existing
...
cache,
...
use
...
the
...
processors
...
defined
...
for
...
the
...
cache
...
component.
...
Maven
...
users
...
will
...
need
...
to
...
add
...
the
...
following
...
dependency
...
to
...
their
...
pom.xml
...
for
...
this
...
component:
Code Block | |||||
---|---|---|---|---|---|
| |||||
} <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-cache</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency> {code} h3. URI format {code} |
URI format
Code Block |
---|
cache://cacheName[?options]
{code}
|
You
...
can
...
append
...
query
...
options
...
to
...
the
...
URI
...
in
...
the
...
following
...
format,
...
?option=value&option=#beanRef&...
Options
Wiki Markup |
---|
}} h3. Options {div:class=confluenceTableSmall} || Name || Default Value || Description || | {{maxElementsInMemory}} | {{1000}} | The number of elements that may be stored in the defined cache | | {{memoryStoreEvictionPolicy}} | {{MemoryStoreEvictionPolicy.LFU}} | The number of elements that may be stored in the defined cache. Options include - MemoryStoreEvictionPolicy.LFU - Least frequently used - MemoryStoreEvictionPolicy.LRU - Least recently used - MemoryStoreEvictionPolicy.FIFO - first in first out, the oldest element by creation time | | {{overflowToDisk}} | {{true}} | Specifies whether cache may overflow to disk | | {{eternal}} | {{false}} | Sets whether elements are eternal. If eternal, timeouts are ignored and the\\ element never expires. | | {{timeToLiveSeconds}} | {{300}} | The maximum time between creation time and when an element expires.\\ Is used only if the element is not eternal | | {{timeToIdleSeconds}} | {{300}} | The maximum amount of time between accesses before an element expires | | {{diskPersistent}} | {{false}} | Whether the disk store persists between restarts of the Virtual Machine. | | {{diskExpiryThreadIntervalSeconds}} | {{120}} | The number of seconds between runs of the disk expiry thread. | | {{cacheManagerFactory}} | {{null}} | *Camel 2.8:* If you want to use a custom factory which instantiates and creates the EHCache {{net.sf.ehcache.CacheManager}}. \\ \\ _Type:_ abstract org.apache.camel.component.cache.CacheManagerFactory | | {{eventListenerRegistry}} | {{null}} | *Camel 2.8:* Sets a list of EHCache {{net.sf.ehcache.event.CacheEventListener}} for all new caches\- no need to define it per cache in EHCache xml config anymore. \\ \\ _Type:_ org.apache.camel.component.cache.CacheEventListenerRegistry | | {{cacheLoaderRegistry}} | {{null}} | *Camel 2.8:* Sets a list of {{org.apache.camel.component.cache.CacheLoaderWrapper}} that extends EHCache {{net.sf.ehcache.loader.CacheLoader}} for all new caches\- no need to define it per cache in EHCache xml config anymore. \\ \\ _Type:_ org.apache.camel.component.cache.CacheLoaderRegistry | | {{key}} | {{null}} | *Camel 2.10:* To configure using a cache key by default. If a key is provided in the message header, then the key from the header takes precedence. | | {{operation}} | {{null}} | *Camel 2.10:* To configure using an cache operation by default. If an operation in the message header, then the operation from the header takes precedence. | {div} h3. |
Sending/Receiving
...
Messages
...
to/from
...
the cache
Message Headers up to Camel 2.7
Wiki Markup |
---|
cache h4. Message Headers up to Camel 2.7 {div:class=confluenceTableSmall} || Header || Description || | {{CACHE_OPERATION}} | The operation to be performed on the cache. Valid options are - GET - CHECK - ADD - UPDATE - DELETE - DELETEALL\\ {{GET}} and {{CHECK}} requires *Camel 2.3* onwards. | | {{CACHE_KEY}} | The cache key used to store the Message in the cache. The cache key is optional if the CACHE_OPERATION is DELETEALL | {div} h4. |
Message
...
Headers
...
Camel
...
2.8
...
+
Info | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
| =
|
|
|
|
| |||||||
}
The header names and supported values have changed to be prefixed with 'CamelCache' and use mixed case. This makes them easier to identify and keep separate from other headers. The CacheConstants variable names remain unchanged, just their values have been changed. Also, these headers are now removed from the exchange after the cache operation is performed. |
Wiki Markup |
---|
{info} {div:class=confluenceTableSmall} || Header || Description || | {{CamelCacheOperation}} | The operation to be performed on the cache. The valid options are - CamelCacheGet - CamelCacheCheck - CamelCacheAdd - CamelCacheUpdate - CamelCacheDelete - CamelCacheDeleteAll | | {{CamelCacheKey}} | The cache key used to store the Message in the cache. The cache key is optional if the CamelCacheOperation is CamelCacheDeleteAll | {div} |
The
...
CamelCacheAdd
...
and
...
CamelCacheUpdate
...
operations
...
support
...
additional
...
headers:
Wiki Markup |
---|
{ {div:class=confluenceTableSmall} || Header || Type || Description || | {{CamelCacheTimeToLive}} | {{Integer}} | *Camel 2.11:* Time to live in seconds. | | {{CamelCacheTimeToIdle}} | {{Integer}} | *Camel 2.11:* Time to idle in seconds. | | {{CamelCacheEternal}} | {{Boolean}} | *Camel 2.11:* Whether the content is eternal. | {div} h4. Cache Producer Sending data to the cache involves the ability to direct payloads in exchanges to be stored in a pre-existing or |
Cache Producer
Sending data to the cache involves the ability to direct payloads in exchanges to be stored in a pre-existing or created-on-demand
...
cache.
...
The
...
mechanics
...
of
...
doing
...
this
...
involve
...
- setting
...
- the
...
- Message
...
- Exchange
...
- Headers
...
- shown
...
- above.
...
- ensuring
...
- that
...
- the
...
- Message
...
- Exchange
...
- Body
...
- contains
...
- the
...
- message
...
- directed
...
- to
...
- the
...
- cache
...
Cache
...
Consumer
...
Receiving
...
data
...
from
...
the
...
cache
...
involves
...
the
...
ability
...
of
...
the
...
CacheConsumer
...
to
...
listen
...
on
...
a
...
pre-existing
...
or
...
created-on-demand
...
Cache
...
using
...
an
...
event
...
Listener
...
and
...
receive
...
automatic
...
notifications
...
when
...
any
...
cache
...
activity
...
take
...
place
...
(i.e
...
CamelCacheGet/CamelCacheUpdate/CamelCacheDelete/CamelCacheDeleteAll).
...
Upon
...
such
...
an
...
activity
...
taking
...
place
...
- an
...
- exchange
...
- containing
...
- Message
...
- Exchange
...
- Headers
...
- and
...
- a
...
- Message
...
- Exchange
...
- Body
...
- containing
...
- the
...
- just
...
- added/updated
...
- payload
...
- is
...
- placed
...
- and
...
- sent.
...
- in
...
- case
...
- of
...
- a
...
- CamelCacheDeleteAll
...
- operation,
...
- the
...
- Message
...
- Exchange
...
- Header
...
- CamelCacheKey
...
- and
...
- the
...
- Message
...
- Exchange
...
- Body
...
- are
...
- not
...
- populated.
...
Cache
...
Processors
...
There
...
are
...
a
...
set
...
of
...
nice
...
processors
...
with
...
the
...
ability
...
to
...
perform
...
cache
...
lookups
...
and
...
selectively
...
replace
...
payload
...
content
...
at
...
the
- body
- token
- xpath level
Cache Usage Samples
Example 1: Configuring the cache
Code Block |
---|
- body - token - xpath level h3. Cache Usage Samples h4. Example 1: Configuring the cache {code} from("cache://MyApplicationCache" + "?maxElementsInMemory=1000" + "&memoryStoreEvictionPolicy=" + "MemoryStoreEvictionPolicy.LFU" + "&overflowToDisk=true" + "&eternal=true" + "&timeToLiveSeconds=300" + "&timeToIdleSeconds=true" + "&diskPersistent=true" + "&diskExpiryThreadIntervalSeconds=300") {code} h4. Example |
Example 2:
...
Adding
...
keys
...
to
...
the
...
cache
Code Block |
---|
} RouteBuilder builder = new RouteBuilder() { public void configure() { from("direct:start") .setHeader(CacheConstants.CACHE_OPERATION, constant(CacheConstants.CACHE_OPERATION_ADD)) .setHeader(CacheConstants.CACHE_KEY, constant("Ralph_Waldo_Emerson")) .to("cache://TestCache1") } }; {code} h4. Example |
Example 2:
...
Updating
...
existing
...
keys
...
in
...
a
...
cache
Code Block |
---|
} RouteBuilder builder = new RouteBuilder() { public void configure() { from("direct:start") .setHeader(CacheConstants.CACHE_OPERATION, constant(CacheConstants.CACHE_OPERATION_UPDATE)) .setHeader(CacheConstants.CACHE_KEY, constant("Ralph_Waldo_Emerson")) .to("cache://TestCache1") } }; {code} h4. Example |
Example 3:
...
Deleting
...
existing
...
keys
...
in
...
a
...
cache
Code Block |
---|
} RouteBuilder builder = new RouteBuilder() { public void configure() { from("direct:start") .setHeader(CacheConstants.CACHE_OPERATION, constant(CacheConstants.CACHE_DELETE)) .setHeader(CacheConstants.CACHE_KEY", constant("Ralph_Waldo_Emerson")) .to("cache://TestCache1") } }; {code} h4. Example |
Example 4:
...
Deleting
...
all
...
existing
...
keys
...
in
...
a
...
cache
Code Block |
---|
} RouteBuilder builder = new RouteBuilder() { public void configure() { from("direct:start") .setHeader(CacheConstants.CACHE_OPERATION, constant(CacheConstants.CACHE_DELETEALL)) .to("cache://TestCache1"); } }; {code} h4. Example |
Example 5:
...
Notifying
...
any
...
changes
...
registering
...
in
...
a
...
Cache
...
to
...
Processors
...
and
...
other
...
Producers
Code Block |
---|
} RouteBuilder builder = new RouteBuilder() { public void configure() { from("cache://TestCache1") .process(new Processor() { public void process(Exchange exchange) throws Exception { String operation = (String) exchange.getIn().getHeader(CacheConstants.CACHE_OPERATION); String key = (String) exchange.getIn().getHeader(CacheConstants.CACHE_KEY); Object body = exchange.getIn().getBody(); // Do something } }) } }; {code} h4. Example |
Example 6:
...
Using
...
Processors
...
to
...
selectively
...
replace
...
payload
...
with
...
cache
...
values
Code Block |
---|
} RouteBuilder builder = new RouteBuilder() { public void configure() { //Message Body Replacer from("cache://TestCache1") .filter(header(CacheConstants.CACHE_KEY).isEqualTo("greeting")) .process(new CacheBasedMessageBodyReplacer("cache://TestCache1","farewell")) .to("direct:next"); //Message Token replacer from("cache://TestCache1") .filter(header(CacheConstants.CACHE_KEY).isEqualTo("quote")) .process(new CacheBasedTokenReplacer("cache://TestCache1","novel","#novel#")) .process(new CacheBasedTokenReplacer("cache://TestCache1","author","#author#")) .process(new CacheBasedTokenReplacer("cache://TestCache1","number","#number#")) .to("direct:next"); //Message XPath replacer from("cache://TestCache1"). .filter(header(CacheConstants.CACHE_KEY).isEqualTo("XML_FRAGMENT")) .process(new CacheBasedXPathReplacer("cache://TestCache1","book1","/books/book1")) .process (new CacheBasedXPathReplacer("cache://TestCache1","book2","/books/book2")) .to("direct:next"); } }; {code} h4. Example |
Example 7:
...
Getting
...
an
...
entry
...
from
...
the
...
Cache
Code Block |
---|
} from("direct:start") // Prepare headers .setHeader(CacheConstants.CACHE_OPERATION, constant(CacheConstants.CACHE_OPERATION_GET)) .setHeader(CacheConstants.CACHE_KEY, constant("Ralph_Waldo_Emerson")). .to("cache://TestCache1"). // Check if entry was not found .choice().when(header(CacheConstants.CACHE_ELEMENT_WAS_FOUND).isNull()). // If not found, get the payload and put it to cache .to("cxf:bean:someHeavyweightOperation"). .setHeader(CacheConstants.CACHE_OPERATION, constant(CacheConstants.CACHE_OPERATION_ADD)) .setHeader(CacheConstants.CACHE_KEY, constant("Ralph_Waldo_Emerson")) .to("cache://TestCache1") .end() .to("direct:nextPhase"); {code} h4. Example |
Example 8:
...
Checking
...
for
...
an
...
entry
...
in
...
the
...
Cache
...
Note:
...
The
...
CHECK
...
command
...
tests
...
existence
...
of
...
an
...
entry
...
in
...
the
...
cache
...
but
...
doesn't
...
place
...
a
...
message
...
in
...
the
...
body.
Code Block |
---|
} from("direct:start") // Prepare headers .setHeader(CacheConstants.CACHE_OPERATION, constant(CacheConstants.CACHE_OPERATION_CHECK)) .setHeader(CacheConstants.CACHE_KEY, constant("Ralph_Waldo_Emerson")). .to("cache://TestCache1"). // Check if entry was not found .choice().when(header(CacheConstants.CACHE_ELEMENT_WAS_FOUND).isNull()). // If not found, get the payload and put it to cache .to("cxf:bean:someHeavyweightOperation"). .setHeader(CacheConstants.CACHE_OPERATION, constant(CacheConstants.CACHE_OPERATION_ADD)) .setHeader(CacheConstants.CACHE_KEY, constant("Ralph_Waldo_Emerson")) .to("cache://TestCache1") .end(); {code} h3. Management of EHCache [EHCache|http://ehcache.org/] has its own statistics and management from [JMX|Camel JMX]. Here's a snippet on how to expose them via JMX in a Spring application context: {code:xml} |
Management of EHCache
EHCache has its own statistics and management from JMX.
Here's a snippet on how to expose them via JMX in a Spring application context:
Code Block | ||||
---|---|---|---|---|
| ||||
<bean id="ehCacheManagementService" class="net.sf.ehcache.management.ManagementService" init-method="init" lazy-init="false">
<constructor-arg>
<bean class="net.sf.ehcache.CacheManager" factory-method="getInstance"/>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.jmx.support.JmxUtils" factory-method="locateMBeanServer"/>
</constructor-arg>
<constructor-arg value="true"/>
<constructor-arg value="true"/>
<constructor-arg value="true"/>
<constructor-arg value="true"/>
</bean>
{code}
|
Of
...
course
...
you
...
can
...
do
...
the
...
same
...
thing
...
in
...
straight
...
Java:
Code Block | ||||
---|---|---|---|---|
| ||||
{code:java} ManagementService.registerMBeans(CacheManager.getInstance(), mbeanServer, true, true, true, true); {code} |
You
...
can
...
get
...
cache
...
hits,
...
misses,
...
in-memory
...
hits,
...
disk
...
hits,
...
size
...
stats
...
this
...
way.
...
You
...
can
...
also
...
change
...
CacheConfiguration
...
parameters
...
on
...
the
...
fly.
...
Cache
...
replication
...
Camel
...
2.8
...
+
...
The
...
Camel
...
Cache
...
component
...
is
...
able
...
to
...
distribute
...
a
...
cache
...
across
...
server
...
nodes
...
using
...
several
...
different
...
replication
...
mechanisms
...
including:
...
RMI,
...
JGroups,
...
JMS
...
and
...
Cache
...
Server.
...
There
...
are
...
two
...
different
...
ways
...
to
...
make
...
it
...
work:
...
1.
...
You
...
can
...
configure
...
ehcache.xml
...
manually
...
OR
2.
...
You
...
can
...
configure
...
these
...
three
...
options:
...
- cacheManagerFactory
- eventListenerRegistry
- cacheLoaderRegistry
Configuring Camel Cache replication using the first option is a bit of hard work as you have to configure all caches separately. So in a situation when the all names of caches are not known, using ehcache.xml
is not a good idea.
The second option is much better when you want to use many different caches as you do not need to define options per cache. This is because replication options are set per CacheManager
and per CacheEndpoint
. Also it is the only way when cache names are not know at the development phase.
Note |
---|
It might be useful to read the EHCache manual to get a better understanding of the Camel Cache replication mechanism. |
Example: JMS cache replication
JMS replication is the most powerful and secured replication method. Used together with Camel Cache replication makes it also rather simple.
An example is available on a separate page.