...
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>
|
URI format
Code Block |
cache://cacheName[?options]
|
You can append query options to the URI in the following format, ?option=value&option=#beanRef&...
Options
Wiki Markup |
{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. | |
Cache Component options
Wiki Markup |
|| {div}Name || Default Value || Description ||
| {{configuration}} | | To use a custom {{org.apache.camel.component.cache.CacheConfiguration}} configuration. |
| {{cacheManagerFactory}} | | To use a custom {{org.apache.camel.component.cache.CacheManagerFactory}}. |
| {{configurationFile}} | | *Camel 2.13/2.12.3:* To configure the location of the {{ehcache.xml}} file to use, such as {{classpath:com/foo/mycache.xml}} to load from classpath. By default the configuration is loaded from {{classpath:ehcache.xml}}. |
|
Sending/Receiving Messages to/from the cache
...
Example 1: Configuring the cache
Code Block |
from("cache://MyApplicationCache" +
"?maxElementsInMemory=1000" +
"&memoryStoreEvictionPolicy=" +
"MemoryStoreEvictionPolicy.LFU" +
"&overflowToDisk=true" +
"&eternal=true" +
"&timeToLiveSeconds=300" +
"&timeToIdleSeconds=true" +
"&diskPersistent=true" +
"&diskExpiryThreadIntervalSeconds=300")
|
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")
}
};
|
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")
}
};
|
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")
}
};
|
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");
}
};
|
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
}
})
}
};
|
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");
}
};
|
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");
|
...
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();
|
...
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>
|
Of course you can do the same thing in straight Java:
Code Block |
|
ManagementService.registerMBeans(CacheManager.getInstance(), mbeanServer, true, true, true, true);
|
...