Written on
CacheManager's diskStorePath
Lately I had to configure the Ehcache [0] CacheManager's diskStorePath property. That alone wouldn't be a problem, but I had to come up with a mechanism that allowed to set the diskStorePath based on customer-specific configuration settings. As I couldn't find proper instructions on the web or on stackoverflow, I thought it would be worth sharing the outcome.The problem
The Grails plugin collective (GPC) offers the so-called "Spring-Cache Plugin" [1], a great plugin by Robert Fletcher. The plugin comes with a @Cacheable annotation. Whenever a type, method or field is annotated as "cacheable" the result is put into a Ehcache instance and further calls might return a cached result (depending on the cache settings). Let's start with the default settings. The default Ehcache cache setting look like this (extracted from ehcache-failsafe.xml):
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
maxElementsOnDisk="10000000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
<diskStore path="here comes the customer-specific directory"/>
Setting the diskStorePath
The Springcache plugin works with Spring's EhCacheManagerFactoryBean and EhCacheFactoryBean. Given the following configuration in Config.groovy ...
springcache.enabled = true
springcache {
defaults {
// set default cache properties that will apply to all caches that do not override them
eternal = false
diskPersistent = true
maxElementsInMemory = 1000
maxElementsOnDisk = 10000
// 24 hours
timeToIdle = 86400
timeToLive = 86400
overflowToDisk = true
memoryStoreEvictionPolicy = "LRU"
}
caches {
myCache {
// set any properties unique to this cache
}
// more caches follow ...
}
springcacheDefaultCache(EhCacheFactoryBean) { bean ->
bean."abstract" = true
cacheManager = ref("springcacheCacheManager")
application.config.springcache.defaults.each {
bean.setPropertyValue it.key, it.value
}
}
application.config.springcache.caches.each {String name, ConfigObject cacheConfig ->
"$name"(EhCacheFactoryBean) {bean ->
bean.parent = springcacheDefaultCache
cacheName = name
cacheConfig.each {
bean.setPropertyValue it.key, it.value
}
}
}
public class EhCacheManagerFactoryBean {
// ...
public void setConfigLocation(org.springframework.core.io.Resource configLocation)
}
springcacheCacheManager(EhCacheManagerFactoryBean) {
// ... set other props
def writer = new StringWriter()
def xml = new MarkupBuilder(writer)
xml.ehcache() {
diskStore(path: config.app.cache.diskStorePath ?: 'java.io.tmpdir/springcache')
defaultCache(config.springcache.defaults)
}
def ehCacheXmlTempFile = File.createTempFile("ehcache-springcache", ".xml")
ehCacheXmlTempFile.setText(writer.toString())
// set the spring bean property
configLocation = new FileSystemResource(ehCacheXmlTempFile)
}