You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@polygene.apache.org by pa...@apache.org on 2016/09/18 23:08:09 UTC

[3/3] zest-java git commit: ZEST-178 Rework EhCache Cache for EhCache 3

ZEST-178 Rework EhCache Cache for EhCache 3

Breaks API compatibility
Breaks Configuration compatibility


Project: http://git-wip-us.apache.org/repos/asf/zest-java/repo
Commit: http://git-wip-us.apache.org/repos/asf/zest-java/commit/c0752e4f
Tree: http://git-wip-us.apache.org/repos/asf/zest-java/tree/c0752e4f
Diff: http://git-wip-us.apache.org/repos/asf/zest-java/diff/c0752e4f

Branch: refs/heads/develop
Commit: c0752e4f0112856f5880c5c4c78b9920ffd542b2
Parents: 1449822
Author: Paul Merlin <pa...@apache.org>
Authored: Sun Sep 18 16:07:55 2016 -0700
Committer: Paul Merlin <pa...@apache.org>
Committed: Sun Sep 18 16:07:55 2016 -0700

----------------------------------------------------------------------
 extensions/cache-ehcache/build.gradle           |   1 +
 .../cache/ehcache/EhCacheConfiguration.java     | 150 ++++++-----
 .../apache/zest/cache/ehcache/EhCacheImpl.java  |  16 +-
 .../zest/cache/ehcache/EhCachePoolMixin.java    | 247 +++++++------------
 libraries.gradle                                |   4 +-
 5 files changed, 196 insertions(+), 222 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/zest-java/blob/c0752e4f/extensions/cache-ehcache/build.gradle
----------------------------------------------------------------------
diff --git a/extensions/cache-ehcache/build.gradle b/extensions/cache-ehcache/build.gradle
index 29b2618..b56383a 100644
--- a/extensions/cache-ehcache/build.gradle
+++ b/extensions/cache-ehcache/build.gradle
@@ -26,6 +26,7 @@ dependencies {
 
   compile(project(':org.apache.zest.core:org.apache.zest.core.spi'))
   compile(project(':org.apache.zest.core:org.apache.zest.core.bootstrap'))
+  compile( project( ":org.apache.zest.libraries:org.apache.zest.library.constraints" ) )
   compile(libraries.ehcache)
 
   testCompile( project(':org.apache.zest.core:org.apache.zest.core.testsupport') )

http://git-wip-us.apache.org/repos/asf/zest-java/blob/c0752e4f/extensions/cache-ehcache/src/main/java/org/apache/zest/cache/ehcache/EhCacheConfiguration.java
----------------------------------------------------------------------
diff --git a/extensions/cache-ehcache/src/main/java/org/apache/zest/cache/ehcache/EhCacheConfiguration.java b/extensions/cache-ehcache/src/main/java/org/apache/zest/cache/ehcache/EhCacheConfiguration.java
index 3974605..19478b0 100644
--- a/extensions/cache-ehcache/src/main/java/org/apache/zest/cache/ehcache/EhCacheConfiguration.java
+++ b/extensions/cache-ehcache/src/main/java/org/apache/zest/cache/ehcache/EhCacheConfiguration.java
@@ -19,87 +19,125 @@
  */
 package org.apache.zest.cache.ehcache;
 
-import net.sf.ehcache.config.PersistenceConfiguration.Strategy;
 import org.apache.zest.api.common.Optional;
 import org.apache.zest.api.common.UseDefaults;
 import org.apache.zest.api.configuration.ConfigurationComposite;
 import org.apache.zest.api.property.Property;
+import org.apache.zest.library.constraints.annotation.OneOf;
 
 // START SNIPPET: config
-public interface EhCacheConfiguration
-    extends ConfigurationComposite
-{
+public interface EhCacheConfiguration extends ConfigurationComposite {
 
-    @Optional @UseDefaults
-    Property<Boolean> clearOnFlush();
-
-    @Optional @UseDefaults
-    Property<Integer> diskAccessStripes();
+    /**
+     * Heap tier size.
+     *
+     * Default to 1MB, you may want to change this.
+     *
+     * @return Heap tier size
+     */
+    @UseDefaults( "1" )
+    Property<Long> heapSize();
 
-    @Optional @UseDefaults
-    Property<Long> diskExpiryThreadIntervalSeconds();
+    /**
+     * Heap tier size unit.
+     *
+     * @return Heap tier size unit
+     */
+    @OneOf( { "B", "KB", "MB", "GB", "TB", "PB" } )
+    @UseDefaults( "MB" )
+    Property<String> heapUnit();
 
     /**
-     * Cache Persistence Strategy.
+     * Optional off-heap tier size.
      *
-     * Can be:
-     * <ul>
-     *   <li>LOCALTEMPSWAP: Standard open source (non fault-tolerant) on-disk persistence.</li>
-     *   <li>LOCALRESTARTABLE: Enterprise fault tolerant persistence.</li>
-     *   <li>NONE: No persistence.</li>
-     *   <li>DISTRIBUTED: Terracotta clustered persistence (requires a Terracotta clustered cache).</li>
-     * </ul>
-     * Defaults to NONE.
+     * @return Optional off-heap tier size
      */
     @Optional
-    Property<Strategy> persistenceStrategy();
-
-    @Optional @UseDefaults
-    Property<String> diskStorePath();
-
-    @Optional @UseDefaults
-    Property<Integer> diskSpoolBufferSizeMB();
-
-    @Optional @UseDefaults
-    Property<Boolean> eternal();
-
-    @Optional @UseDefaults
-    Property<Boolean> loggingEnabled();
+    Property<Long> offHeapSize();
 
     /**
-     * Number of objects the ehCache should keep in memory.
-     * Defaults to 1000
+     * Off-heap tier size unit.
      *
-     * @return The maximum number of elements to be kept in memory.
+     * @return Off-heap tier size unit
      */
-    @Optional @UseDefaults
-    Property<Integer> maxElementsInMemory();
+    @OneOf( { "B", "KB", "MB", "GB", "TB", "PB" } )
+    @UseDefaults( "MB" )
+    Property<String> offHeapUnit();
 
-    @Optional @UseDefaults
-    Property<Integer> maxElementsOnDisk();
+    /**
+     * Optional disk tier size.
+     *
+     * @return Optional disk tier size
+     */
+    @Optional
+    Property<Long> diskSize();
 
-    @Optional @UseDefaults
-    Property<String> memoryStoreEvictionPolicy();
+    /**
+     * Disk tier size unit.
+     *
+     * @return Disk tier size unit
+     */
+    @OneOf( { "B", "KB", "MB", "GB", "TB", "PB" } )
+    @UseDefaults( "MB" )
+    Property<String> diskUnit();
 
-    @Optional @UseDefaults
-    Property<String> name();
+    /**
+     * If the disk tier is persistent or not.
+     *
+     * @return If the disk tier is persistent or not
+     */
+    @UseDefaults
+    Property<Boolean> diskPersistent();
 
-    @Optional @UseDefaults
-    Property<String> transactionalMode();
+    /**
+     * Maximum size of cached objects.
+     *
+     * @return Maximum size of cached objects
+     */
+    @Optional
+    Property<Long> maxObjectSize();
 
-    @Optional @UseDefaults
-    Property<Long> timeToLiveSeconds();
+    /**
+     * Unit for maximum size of cached objects.
+     *
+     * @return Unit for maximum size of cached objects
+     */
+    @OneOf( { "B", "KB", "MB", "GB", "TB", "PB" } )
+    @UseDefaults( "MB" )
+    Property<String> maxObjectSizeUnit();
 
-    @Optional @UseDefaults
-    Property<Long> timeToIdleSeconds();
+    /**
+     * Maximum cached object graph depth.
+     *
+     * @return Maximum cached object graph depth
+     */
+    @Optional
+    Property<Long> maxObjectGraphDepth();
 
-    @Optional @UseDefaults
-    Property<String> cacheManagerName();
+    /**
+     * Expiry policy.
+     *
+     * @return Expiry policy
+     */
+    @OneOf( { "NONE", "TIME_TO_IDLE", "TIME_TO_LIVE" } )
+    @UseDefaults( "NONE" )
+    Property<String> expiry();
 
-    @Optional @UseDefaults
-    Property<String> monitoring();
+    /**
+     * Expiry length.
+     *
+     * @return Expiry length
+     */
+    @Optional
+    Property<Long> expiryLength();
 
-    @Optional @UseDefaults
-    Property<Boolean> updateCheck();
+    /**
+     * Expiry time unit.
+     *
+     * @return Expiry time unit
+     */
+    @OneOf( { "MILLISECONDS", "SECONDS", "MINUTES", "HOURS", "DAYS" } )
+    @UseDefaults( "SECONDS" )
+    Property<String> expiryTimeUnit();
 }
 // END SNIPPET: config

http://git-wip-us.apache.org/repos/asf/zest-java/blob/c0752e4f/extensions/cache-ehcache/src/main/java/org/apache/zest/cache/ehcache/EhCacheImpl.java
----------------------------------------------------------------------
diff --git a/extensions/cache-ehcache/src/main/java/org/apache/zest/cache/ehcache/EhCacheImpl.java b/extensions/cache-ehcache/src/main/java/org/apache/zest/cache/ehcache/EhCacheImpl.java
index 6d0a214..594b7fd 100644
--- a/extensions/cache-ehcache/src/main/java/org/apache/zest/cache/ehcache/EhCacheImpl.java
+++ b/extensions/cache-ehcache/src/main/java/org/apache/zest/cache/ehcache/EhCacheImpl.java
@@ -19,18 +19,17 @@
  */
 package org.apache.zest.cache.ehcache;
 
-import net.sf.ehcache.Element;
 import org.apache.zest.spi.cache.Cache;
 
 public class EhCacheImpl<T>
     implements Cache<T>
 {
     private int refCount;
-    private final net.sf.ehcache.Cache backingCache;
+    private final org.ehcache.Cache backingCache;
     private final Class<T> valueType;
     private final String id;
 
-    public EhCacheImpl( String cacheId, net.sf.ehcache.Cache cache, Class<T> valueType )
+    public EhCacheImpl( String cacheId, org.ehcache.Cache cache, Class<T> valueType )
     {
         this.id = cacheId;
         this.backingCache = cache;
@@ -40,18 +39,18 @@ public class EhCacheImpl<T>
     @Override
     public T get( String key )
     {
-        Element element = backingCache.get( key );
+        Object element = backingCache.get( key );
         if( element == null )
         {
             return null;
         }
-        return valueType.cast( element.getObjectValue() );
+        return valueType.cast( element );
     }
 
     @Override
     public T remove( String key )
     {
-        T old = valueType.cast( backingCache.get( key ).getObjectValue() );
+        T old = valueType.cast( backingCache.get( key ) );
         backingCache.remove( key );
         return old;
     }
@@ -59,14 +58,13 @@ public class EhCacheImpl<T>
     @Override
     public void put( String key, T value )
     {
-        Element element = new Element( key, value );
-        backingCache.put( element );
+        backingCache.put( key, value );
     }
 
     @Override
     public boolean exists( String key )
     {
-        return backingCache.isKeyInCache( key );
+        return backingCache.containsKey( key );
     }
 
     synchronized void decRefCount()

http://git-wip-us.apache.org/repos/asf/zest-java/blob/c0752e4f/extensions/cache-ehcache/src/main/java/org/apache/zest/cache/ehcache/EhCachePoolMixin.java
----------------------------------------------------------------------
diff --git a/extensions/cache-ehcache/src/main/java/org/apache/zest/cache/ehcache/EhCachePoolMixin.java b/extensions/cache-ehcache/src/main/java/org/apache/zest/cache/ehcache/EhCachePoolMixin.java
index 3b7c586..927c2cb 100644
--- a/extensions/cache-ehcache/src/main/java/org/apache/zest/cache/ehcache/EhCachePoolMixin.java
+++ b/extensions/cache-ehcache/src/main/java/org/apache/zest/cache/ehcache/EhCachePoolMixin.java
@@ -20,51 +20,119 @@
 package org.apache.zest.cache.ehcache;
 
 import java.util.concurrent.ConcurrentHashMap;
-import net.sf.ehcache.CacheManager;
-import net.sf.ehcache.config.CacheConfiguration;
-import net.sf.ehcache.config.PersistenceConfiguration;
-import net.sf.ehcache.config.PersistenceConfiguration.Strategy;
-import org.apache.zest.api.common.Optional;
+import java.util.concurrent.TimeUnit;
+
 import org.apache.zest.api.configuration.Configuration;
+import org.apache.zest.api.entity.Identity;
 import org.apache.zest.api.injection.scope.This;
 import org.apache.zest.api.util.NullArgumentException;
 import org.apache.zest.spi.cache.Cache;
+import org.ehcache.CacheManager;
+import org.ehcache.config.CacheConfiguration;
+import org.ehcache.config.builders.CacheConfigurationBuilder;
+import org.ehcache.config.builders.CacheManagerBuilder;
+import org.ehcache.config.builders.ResourcePoolsBuilder;
+import org.ehcache.config.units.MemoryUnit;
+import org.ehcache.expiry.Duration;
+import org.ehcache.expiry.Expirations;
 
 public abstract class EhCachePoolMixin
     implements EhCachePoolService
 {
-
+    private static final long DEFAULT_HEAP_SIZE = 1024 * 1024;
     private final ConcurrentHashMap<String, EhCacheImpl<?>> caches = new ConcurrentHashMap<>();
-    @This @Optional
-    private Configuration<EhCacheConfiguration> config;
+
+    @This
+    private Identity identity;
+
+    @This
+    private Configuration<EhCacheConfiguration> configuration;
+
     private CacheManager cacheManager;
 
     @Override
-    @SuppressWarnings( "unchecked" )
+    public void activateService()
+            throws Exception
+    {
+        cacheManager = CacheManagerBuilder.newCacheManagerBuilder()
+                .withDefaultDiskStoreThreadPool( cacheManagerThreadPoolName( "disk-store" ) )
+                .withDefaultEventListenersThreadPool( cacheManagerThreadPoolName( "event-listeners" ) )
+                .withDefaultWriteBehindThreadPool( cacheManagerThreadPoolName( "write-behind" ) )
+                .build();
+        cacheManager.init();
+    }
+
+    @Override
+    public void passivateService()
+            throws Exception
+    {
+        cacheManager.close();
+        cacheManager = null;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
     public <T> Cache<T> fetchCache( String cacheId, Class<T> valueType )
     {
         // Note: Small bug in Ehcache; If the cache name is an empty String it will actually work until
         //       you try to remove the Cache instance from the CacheManager, at which point it is silently
-        //       ignored but not removed so there is an follow up problem of too much in the CacheManager.
+        //       ignored but not removed so there is a follow up problem of too much in the CacheManager.
         NullArgumentException.validateNotEmpty( "cacheId", cacheId );
-        EhCacheImpl<?> cache = caches.get( cacheId );
-        if( cache == null )
-        {
-            cache = createNewCache( cacheId, valueType );
-            caches.put( cacheId, cache );
-        }
+        EhCacheImpl<?> cache = caches.computeIfAbsent( cacheId, key -> createNewCache( cacheId, valueType ) );
         cache.incRefCount();
         return (Cache<T>) cache;
     }
 
     private <T> EhCacheImpl<T> createNewCache( String cacheId, Class<T> valueType )
     {
-        CacheConfiguration cc = createCacheConfiguration( cacheId );
-
-        // TODO: We also need all the other Configurations that are possible, like cacheLoaderFactoryConfiguration
-        net.sf.ehcache.Cache cache = new net.sf.ehcache.Cache( cc );
-        cacheManager.addCache( cache );
-
+        configuration.refresh();
+        EhCacheConfiguration config = configuration.get();
+
+        ResourcePoolsBuilder poolsBuilder = ResourcePoolsBuilder.newResourcePoolsBuilder()
+                .heap( config.heapSize().get(), MemoryUnit.valueOf( config.heapUnit().get() ) );
+        if( config.offHeapSize().get() != null )
+        {
+            poolsBuilder = poolsBuilder
+                    .offheap( config.offHeapSize().get(), MemoryUnit.valueOf( config.offHeapUnit().get() ) );
+        }
+        if( config.diskSize().get() != null )
+        {
+            poolsBuilder = poolsBuilder
+                    .disk( config.diskSize().get(), MemoryUnit.valueOf( config.diskUnit().get() ), config.diskPersistent().get() );
+        }
+
+        CacheConfigurationBuilder<String, T> configBuilder = CacheConfigurationBuilder
+                .newCacheConfigurationBuilder( String.class, valueType, poolsBuilder );
+        if( config.maxObjectSize().get() != null )
+        {
+            configBuilder = configBuilder
+                    .withSizeOfMaxObjectSize( config.maxObjectSize().get(), MemoryUnit.valueOf( config.maxObjectSizeUnit().get() ) );
+        }
+        if( config.maxObjectGraphDepth().get() != null )
+        {
+            configBuilder = configBuilder
+                    .withSizeOfMaxObjectGraph( config.maxObjectGraphDepth().get() );
+        }
+        switch( config.expiry().get() ) {
+            case "TIME_TO_IDLE":
+                configBuilder = configBuilder.withExpiry( Expirations.timeToIdleExpiration( Duration.of(
+                    config.expiryLength().get() == null ? -1L : config.expiryLength().get(),
+                    TimeUnit.valueOf( config.expiryTimeUnit().get() )
+                ) ) );
+                break;
+            case "TIME_TO_LIVE":
+                configBuilder = configBuilder.withExpiry( Expirations.timeToLiveExpiration( Duration.of(
+                    config.expiryLength().get() == null ? -1L : config.expiryLength().get(),
+                    TimeUnit.valueOf( config.expiryTimeUnit().get() )
+                ) ) );
+                break;
+            case "NONE":
+            default:
+                configBuilder = configBuilder.withExpiry( Expirations.noExpiration() );
+                break;
+        }
+        CacheConfiguration<String, T> cacheConfig = configBuilder.build();
+        org.ehcache.Cache<String,T> cache =  cacheManager.createCache( cacheId, cacheConfig );
         return new EhCacheImpl<>( cacheId, cache, valueType );
     }
 
@@ -80,139 +148,8 @@ public abstract class EhCachePoolMixin
         }
     }
 
-    @Override
-    public void activateService()
-        throws Exception
-    {
-        net.sf.ehcache.config.Configuration configuration = new net.sf.ehcache.config.Configuration();
-        configureEhCache( configuration );
-        CacheConfiguration cc = createCacheConfiguration( "zest.ehcache.config.default" );
-        configuration.setDefaultCacheConfiguration( cc );
-        cacheManager = CacheManager.newInstance( configuration );
-    }
-
-    @Override
-    public void passivateService()
-        throws Exception
-    {
-        cacheManager.shutdown();
-    }
-
-    private void configureEhCache( net.sf.ehcache.config.Configuration configuration )
+    private String cacheManagerThreadPoolName( String name )
     {
-        EhCacheConfiguration conf = config.get();
-        Boolean updateCheck = conf.updateCheck().get();
-        configuration.setUpdateCheck( updateCheck );
-        configuration.setDynamicConfig( true );
-        String monitoring = conf.monitoring().get().trim();
-        if( monitoring.length() > 0 )
-        {
-            configuration.setMonitoring( monitoring );
-        }
-        String name = conf.cacheManagerName().get();
-        if( name == null )
-        {
-            name = "Zest Cache Extension";
-        }
-        configuration.setName( name );
-        String diskStorePath = conf.diskStorePath().get();
-        if( diskStorePath.length() > 0 )
-        {
-            configuration.getDiskStoreConfiguration().path( diskStorePath );
-        }
+        return identity.identity().getClass() + "-" + name;
     }
-
-    private CacheConfiguration createCacheConfiguration( String cacheId )
-    {
-        EhCacheConfiguration conf = config.get();
-        Integer maxElementsInMemory = conf.maxElementsInMemory().get();
-        if( maxElementsInMemory <= 0 )
-        {
-            maxElementsInMemory = 10000;
-        }
-        CacheConfiguration cacheConfig = new CacheConfiguration( cacheId, maxElementsInMemory );
-        String transactionalMode = conf.transactionalMode().get();
-        if( transactionalMode.length() > 0 )
-        {
-            cacheConfig.transactionalMode( transactionalMode );
-        }
-
-        Long timeToLiveSeconds = conf.timeToLiveSeconds().get();
-        if( timeToLiveSeconds > 0 )
-        {
-            cacheConfig.timeToLiveSeconds( timeToLiveSeconds );
-        }
-
-        Long timeToIdleSeconds = conf.timeToIdleSeconds().get();
-        if( timeToIdleSeconds > 0 )
-        {
-            cacheConfig.timeToIdleSeconds( timeToIdleSeconds );
-        }
-
-        String name = conf.name().get();
-        if( name.length() > 0 )
-        {
-            cacheConfig.name( name );
-        }
-
-        String memoryStoreEvictionPolicy = conf.memoryStoreEvictionPolicy().get();
-        if( memoryStoreEvictionPolicy.length() > 0 )
-        {
-            cacheConfig.memoryStoreEvictionPolicy( memoryStoreEvictionPolicy );
-        }
-
-        Integer maxElementsOnDisk = conf.maxElementsOnDisk().get();
-        if( maxElementsOnDisk > 0 )
-        {
-            cacheConfig.maxElementsOnDisk( maxElementsOnDisk );
-        }
-
-        Boolean loggingEnabled = conf.loggingEnabled().get();
-        if( loggingEnabled != null )
-        {
-            cacheConfig.logging( loggingEnabled );
-        }
-
-        Boolean eternal = conf.eternal().get();
-        cacheConfig.eternal( eternal );
-
-        Integer diskSpoolBufferSizeMB = conf.diskSpoolBufferSizeMB().get();
-        if( diskSpoolBufferSizeMB > 0 )
-        {
-            cacheConfig.diskSpoolBufferSizeMB( diskSpoolBufferSizeMB );
-        }
-
-        Long diskExpiryThreadIntervalSeconds = conf.diskExpiryThreadIntervalSeconds().get();
-        if( diskExpiryThreadIntervalSeconds > 0 )
-        {
-            cacheConfig.diskExpiryThreadIntervalSeconds( diskExpiryThreadIntervalSeconds );
-        }
-
-        Integer diskAccessStripes = conf.diskAccessStripes().get();
-        if( diskAccessStripes > 0 )
-        {
-            cacheConfig.diskAccessStripes( diskAccessStripes );
-        }
-        Boolean clearOnFlush = conf.clearOnFlush().get();
-        if( clearOnFlush != null )
-        {
-            cacheConfig.clearOnFlush( clearOnFlush );
-        }
-
-        // Persistence Configuration
-        PersistenceConfiguration persistenceConfig = new PersistenceConfiguration();
-        Strategy strategy = conf.persistenceStrategy().get();
-        if( strategy == null )
-        {
-            persistenceConfig.strategy( Strategy.NONE );
-        }
-        else
-        {
-            persistenceConfig.strategy( strategy );
-        }
-        cacheConfig.persistence( persistenceConfig );
-
-        return cacheConfig;
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/zest-java/blob/c0752e4f/libraries.gradle
----------------------------------------------------------------------
diff --git a/libraries.gradle b/libraries.gradle
index 9f14383..589924d 100644
--- a/libraries.gradle
+++ b/libraries.gradle
@@ -26,7 +26,7 @@ def commonsDbcpVersion = '2.1.1'
 def commonsLangVersion = '3.4'
 def derbyVersion = '10.12.1.1'
 def dnsJavaVersion = '2.1.7'
-def ehcacheVersion = '2.10.2.2.21' // 3.x exists
+def ehcacheVersion = '3.1.2'
 def elasticsearchVersion = '2.4.0'
 def freemarkerVersion = '2.3.25-incubating'
 def geodeVersion = '1.0.0-incubating.M3'
@@ -187,7 +187,7 @@ rootProject.ext {
 
           // Library & Extension dependencies
           jackson_mapper: "com.fasterxml.jackson.core:jackson-databind:$jacksonVersion",
-          ehcache: "net.sf.ehcache:ehcache:$ehcacheVersion",
+          ehcache: "org.ehcache:ehcache:$ehcacheVersion",
           elasticsearch: "org.elasticsearch:elasticsearch:$elasticsearchVersion",
           geode: "org.apache.geode:geode-core:$geodeVersion",
           h2: "com.h2database:h2:$h2Version",