Repository: camel Updated Branches: refs/heads/osgi-trouble [created] ea4c8ce4e
CAMEL-8602: Java 8: ConcurrentLinkedHashMap -> Caffeine Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/9cfb0288 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/9cfb0288 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/9cfb0288 Branch: refs/heads/osgi-trouble Commit: 9cfb0288ceb6a11ebda329b7f275a97d556822a5 Parents: fa78b86 Author: Claus Ibsen <davscl...@apache.org> Authored: Wed Mar 23 15:27:36 2016 +0100 Committer: Claus Ibsen <davscl...@apache.org> Committed: Wed Mar 23 15:27:36 2016 +0100 ---------------------------------------------------------------------- camel-core/pom.xml | 10 +- .../java/org/apache/camel/ConsumerTemplate.java | 5 + .../java/org/apache/camel/ProducerTemplate.java | 5 + .../org/apache/camel/impl/ConsumerCache.java | 10 ++ .../camel/impl/DefaultConsumerTemplate.java | 8 ++ .../camel/impl/DefaultProducerTemplate.java | 6 + .../org/apache/camel/impl/ProducerCache.java | 11 ++ .../org/apache/camel/spi/EndpointRegistry.java | 5 + .../java/org/apache/camel/util/LRUCache.java | 63 +++++++--- .../org/apache/camel/util/LRUSoftCache.java | 117 +------------------ .../org/apache/camel/util/LRUWeakCache.java | 116 +----------------- ...faultCamelContextEndpointCacheLimitTest.java | 10 +- .../DefaultCamelContextEndpointCacheTest.java | 8 +- .../camel/impl/DefaultCamelContextTest.java | 8 +- .../camel/impl/DefaultConsumerCacheTest.java | 3 + .../camel/impl/DefaultConsumerTemplateTest.java | 6 + ...sumerTemplateWithCustomCacheMaxSizeTest.java | 3 + .../camel/impl/DefaultProducerCacheTest.java | 9 ++ .../camel/impl/DefaultProducerTemplateTest.java | 6 + .../EndpointRegistryKeepRouteEndpointsTest.java | 6 +- .../org/apache/camel/util/LRUCacheTest.java | 14 ++- parent/pom.xml | 10 +- 22 files changed, 172 insertions(+), 267 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/pom.xml ---------------------------------------------------------------------- diff --git a/camel-core/pom.xml b/camel-core/pom.xml index 51b7273..096f725 100644 --- a/camel-core/pom.xml +++ b/camel-core/pom.xml @@ -126,8 +126,8 @@ <!-- required dependencies by camel-core --> <!-- which we shade into camel-core so its available for everybody out of the box --> <dependency> - <groupId>com.googlecode.concurrentlinkedhashmap</groupId> - <artifactId>concurrentlinkedhashmap-lru</artifactId> + <groupId>com.github.ben-manes.caffeine</groupId> + <artifactId>caffeine</artifactId> </dependency> <!-- required dependencies by camel-core --> @@ -227,7 +227,7 @@ <configuration> <artifactSet> <includes> - <include>com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru</include> + <include>com.github.ben-manes.caffeine:caffeine</include> </includes> <excludes> <exclude>org.apache.camel:apt</exclude> @@ -235,8 +235,8 @@ </artifactSet> <relocations> <relocation> - <pattern>com.googlecode.concurrentlinkedhashmap</pattern> - <shadedPattern>org.apache.camel.com.googlecode.concurrentlinkedhashmap</shadedPattern> + <pattern>com.github.benmanes.caffeine.cache</pattern> + <shadedPattern>org.apache.camel.com.github.benmanes.caffeine.cache</shadedPattern> </relocation> </relocations> </configuration> http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/main/java/org/apache/camel/ConsumerTemplate.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/ConsumerTemplate.java b/camel-core/src/main/java/org/apache/camel/ConsumerTemplate.java index ea7e249..b6b2583 100644 --- a/camel-core/src/main/java/org/apache/camel/ConsumerTemplate.java +++ b/camel-core/src/main/java/org/apache/camel/ConsumerTemplate.java @@ -81,6 +81,11 @@ public interface ConsumerTemplate extends Service { */ int getCurrentCacheSize(); + /** + * Cleanup the cache (purging stale entries) + */ + void cleanUp(); + // Synchronous methods // ----------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/main/java/org/apache/camel/ProducerTemplate.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/ProducerTemplate.java b/camel-core/src/main/java/org/apache/camel/ProducerTemplate.java index 32533c1..2404d85 100644 --- a/camel-core/src/main/java/org/apache/camel/ProducerTemplate.java +++ b/camel-core/src/main/java/org/apache/camel/ProducerTemplate.java @@ -132,6 +132,11 @@ public interface ProducerTemplate extends Service { */ boolean isEventNotifierEnabled(); + /** + * Cleanup the cache (purging stale entries) + */ + void cleanUp(); + // Synchronous methods // ----------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/main/java/org/apache/camel/impl/ConsumerCache.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/impl/ConsumerCache.java b/camel-core/src/main/java/org/apache/camel/impl/ConsumerCache.java index 399012c..2e6fdda 100644 --- a/camel-core/src/main/java/org/apache/camel/impl/ConsumerCache.java +++ b/camel-core/src/main/java/org/apache/camel/impl/ConsumerCache.java @@ -344,6 +344,16 @@ public class ConsumerCache extends ServiceSupport { } } + /** + * Cleanup the cache (purging stale entries) + */ + public void cleanUp() { + if (consumers instanceof LRUCache) { + LRUCache<String, PollingConsumer> cache = (LRUCache<String, PollingConsumer>)consumers; + cache.cleanUp(); + } + } + public EndpointUtilizationStatistics getEndpointUtilizationStatistics() { return statistics; } http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/main/java/org/apache/camel/impl/DefaultConsumerTemplate.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/impl/DefaultConsumerTemplate.java b/camel-core/src/main/java/org/apache/camel/impl/DefaultConsumerTemplate.java index 98c0394..2613919 100644 --- a/camel-core/src/main/java/org/apache/camel/impl/DefaultConsumerTemplate.java +++ b/camel-core/src/main/java/org/apache/camel/impl/DefaultConsumerTemplate.java @@ -22,9 +22,11 @@ import org.apache.camel.CamelContext; import org.apache.camel.ConsumerTemplate; import org.apache.camel.Endpoint; import org.apache.camel.Exchange; +import org.apache.camel.PollingConsumer; import org.apache.camel.spi.Synchronization; import org.apache.camel.support.ServiceSupport; import org.apache.camel.util.CamelContextHelper; +import org.apache.camel.util.LRUCache; import org.apache.camel.util.ServiceHelper; import org.apache.camel.util.UnitOfWorkHelper; import org.slf4j.Logger; @@ -65,6 +67,12 @@ public class DefaultConsumerTemplate extends ServiceSupport implements ConsumerT return consumerCache.size(); } + public void cleanUp() { + if (consumerCache != null) { + consumerCache.cleanUp(); + } + } + /** * @deprecated use {@link #getCamelContext()} */ http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/main/java/org/apache/camel/impl/DefaultProducerTemplate.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/impl/DefaultProducerTemplate.java b/camel-core/src/main/java/org/apache/camel/impl/DefaultProducerTemplate.java index aa3fa10..aee4973 100644 --- a/camel-core/src/main/java/org/apache/camel/impl/DefaultProducerTemplate.java +++ b/camel-core/src/main/java/org/apache/camel/impl/DefaultProducerTemplate.java @@ -92,6 +92,12 @@ public class DefaultProducerTemplate extends ServiceSupport implements ProducerT return eventNotifierEnabled; } + public void cleanUp() { + if (producerCache != null) { + producerCache.cleanUp(); + } + } + public void setEventNotifierEnabled(boolean eventNotifierEnabled) { this.eventNotifierEnabled = eventNotifierEnabled; // if we already created the cache then adjust its setting as well http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/main/java/org/apache/camel/impl/ProducerCache.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/impl/ProducerCache.java b/camel-core/src/main/java/org/apache/camel/impl/ProducerCache.java index 9be2825..c016ea4 100644 --- a/camel-core/src/main/java/org/apache/camel/impl/ProducerCache.java +++ b/camel-core/src/main/java/org/apache/camel/impl/ProducerCache.java @@ -26,6 +26,7 @@ import org.apache.camel.Endpoint; import org.apache.camel.Exchange; import org.apache.camel.ExchangePattern; import org.apache.camel.FailedToCreateProducerException; +import org.apache.camel.PollingConsumer; import org.apache.camel.Processor; import org.apache.camel.Producer; import org.apache.camel.ProducerCallback; @@ -595,6 +596,16 @@ public class ProducerCache extends ServiceSupport { } } + /** + * Cleanup the cache (purging stale entries) + */ + public void cleanUp() { + if (producers instanceof LRUCache) { + LRUCache<String, Producer> cache = (LRUCache<String, Producer>)producers; + cache.cleanUp(); + } + } + public EndpointUtilizationStatistics getEndpointUtilizationStatistics() { return statistics; } http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/main/java/org/apache/camel/spi/EndpointRegistry.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/spi/EndpointRegistry.java b/camel-core/src/main/java/org/apache/camel/spi/EndpointRegistry.java index 3a42dfa..af1b8e7 100644 --- a/camel-core/src/main/java/org/apache/camel/spi/EndpointRegistry.java +++ b/camel-core/src/main/java/org/apache/camel/spi/EndpointRegistry.java @@ -75,4 +75,9 @@ public interface EndpointRegistry<K> extends Map<K, Endpoint>, StaticService { */ boolean isDynamic(String key); + /** + * Cleanup the cache (purging stale entries) + */ + void cleanUp(); + } http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/main/java/org/apache/camel/util/LRUCache.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/util/LRUCache.java b/camel-core/src/main/java/org/apache/camel/util/LRUCache.java index 07d36e1..4c18a31 100644 --- a/camel-core/src/main/java/org/apache/camel/util/LRUCache.java +++ b/camel-core/src/main/java/org/apache/camel/util/LRUCache.java @@ -22,8 +22,10 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicLong; -import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap; -import com.googlecode.concurrentlinkedhashmap.EvictionListener; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; +import com.github.benmanes.caffeine.cache.RemovalCause; +import com.github.benmanes.caffeine.cache.RemovalListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -36,7 +38,7 @@ import org.slf4j.LoggerFactory; * @see LRUSoftCache * @see LRUWeakCache */ -public class LRUCache<K, V> implements Map<K, V>, EvictionListener<K, V>, Serializable { +public class LRUCache<K, V> implements Map<K, V>, RemovalListener<K, V>, Serializable { private static final long serialVersionUID = -342098639681884414L; private static final Logger LOG = LoggerFactory.getLogger(LRUCache.class); @@ -46,7 +48,8 @@ public class LRUCache<K, V> implements Map<K, V>, EvictionListener<K, V>, Serial private int maxCacheSize = 10000; private boolean stopOnEviction; - private ConcurrentLinkedHashMap<K, V> map; + private final Cache<K, V> cache; + private final Map<K, V> map; /** * Constructs an empty <tt>LRUCache</tt> instance with the @@ -81,10 +84,40 @@ public class LRUCache<K, V> implements Map<K, V>, EvictionListener<K, V>, Serial * @throws IllegalArgumentException if the initial capacity is negative */ public LRUCache(int initialCapacity, int maximumCacheSize, boolean stopOnEviction) { - map = new ConcurrentLinkedHashMap.Builder<K, V>() + this(initialCapacity, maximumCacheSize, stopOnEviction, false, false, false); + } + + /** + * Constructs an empty <tt>LRUCache</tt> instance with the + * specified initial capacity, maximumCacheSize,load factor and ordering mode. + * + * @param initialCapacity the initial capacity. + * @param maximumCacheSize the max capacity. + * @param stopOnEviction whether to stop service on eviction. + * @param soft whether to use soft values a soft cache (default is false) + * @param weak whether to use weak keys/values as a weak cache (default is false) + * @param syncListener whether to use synchronous call for the eviction listener (default is false) + * @throws IllegalArgumentException if the initial capacity is negative + */ + public LRUCache(int initialCapacity, int maximumCacheSize, boolean stopOnEviction, + boolean soft, boolean weak, boolean syncListener) { + Caffeine<K, V> caffeine = Caffeine.newBuilder() .initialCapacity(initialCapacity) - .maximumWeightedCapacity(maximumCacheSize) - .listener(this).build(); + .maximumSize(maximumCacheSize) + .removalListener(this); + if (soft) { + caffeine.softValues(); + } + if (weak) { + caffeine.weakKeys(); + caffeine.weakValues(); + } + if (syncListener) { + caffeine.executor(Runnable::run); + } + + this.cache = caffeine.build(); + this.map = cache.asMap(); this.maxCacheSize = maximumCacheSize; this.stopOnEviction = stopOnEviction; } @@ -131,7 +164,7 @@ public class LRUCache<K, V> implements Map<K, V>, EvictionListener<K, V>, Serial } public void putAll(Map<? extends K, ? extends V> map) { - this.map.putAll(map); + this.cache.putAll(map); } @Override @@ -142,23 +175,23 @@ public class LRUCache<K, V> implements Map<K, V>, EvictionListener<K, V>, Serial @Override public Set<K> keySet() { - return map.ascendingKeySet(); + return map.keySet(); } @Override public Collection<V> values() { - return map.ascendingMap().values(); + return map.values(); } @Override public Set<Entry<K, V>> entrySet() { - return map.ascendingMap().entrySet(); + return map.entrySet(); } @Override - public void onEviction(K key, V value) { + public void onRemoval(K key, V value, RemovalCause cause) { evicted.incrementAndGet(); - LOG.trace("onEviction {} -> {}", key, value); + LOG.trace("onRemoval {} -> {}", key, value); if (stopOnEviction) { try { // stop service as its evicted from cache @@ -206,6 +239,10 @@ public class LRUCache<K, V> implements Map<K, V>, EvictionListener<K, V>, Serial evicted.set(0); } + public void cleanUp() { + cache.cleanUp(); + } + @Override public String toString() { return "LRUCache@" + ObjectHelper.getIdentityHashCode(this); http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/main/java/org/apache/camel/util/LRUSoftCache.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/util/LRUSoftCache.java b/camel-core/src/main/java/org/apache/camel/util/LRUSoftCache.java index 074d291..6189026 100644 --- a/camel-core/src/main/java/org/apache/camel/util/LRUSoftCache.java +++ b/camel-core/src/main/java/org/apache/camel/util/LRUSoftCache.java @@ -17,11 +17,6 @@ package org.apache.camel.util; import java.lang.ref.SoftReference; -import java.util.ArrayList; -import java.util.Collection; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; /** * A Least Recently Used Cache which uses {@link SoftReference}. @@ -54,123 +49,19 @@ import java.util.Set; * @see LRUWeakCache */ public class LRUSoftCache<K, V> extends LRUCache<K, V> { + private static final long serialVersionUID = 1L; public LRUSoftCache(int maximumCacheSize) { - super(maximumCacheSize); + this(16, maximumCacheSize); } public LRUSoftCache(int initialCapacity, int maximumCacheSize) { - super(initialCapacity, maximumCacheSize); + this(initialCapacity, maximumCacheSize, false); } public LRUSoftCache(int initialCapacity, int maximumCacheSize, boolean stopOnEviction) { - super(initialCapacity, maximumCacheSize, stopOnEviction); - } - - @Override - @SuppressWarnings("unchecked") - public V put(K key, V value) { - SoftReference<V> put = new SoftReference<V>(value); - SoftReference<V> prev = (SoftReference<V>) super.put(key, (V) put); - return prev != null ? prev.get() : null; - } - - @Override - @SuppressWarnings("unchecked") - public V get(Object o) { - SoftReference<V> ref = (SoftReference<V>) super.get(o); - return ref != null ? ref.get() : null; - } - - @Override - public void putAll(Map<? extends K, ? extends V> map) { - for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) { - put(entry.getKey(), entry.getValue()); - } - } - - @Override - @SuppressWarnings("unchecked") - public V remove(Object o) { - SoftReference<V> ref = (SoftReference<V>) super.remove(o); - return ref != null ? ref.get() : null; - } - - @Override - @SuppressWarnings("unchecked") - public Collection<V> values() { - // return a copy of all the active values - Collection<SoftReference<V>> col = (Collection<SoftReference<V>>) super.values(); - Collection<V> answer = new ArrayList<V>(); - for (SoftReference<V> ref : col) { - V value = ref.get(); - if (value != null) { - answer.add(value); - } - } - return answer; - } - - @Override - public int size() { - // only count as a size if there is a value - int size = 0; - for (V value : super.values()) { - SoftReference<?> ref = (SoftReference<?>) value; - if (ref != null && ref.get() != null) { - size++; - } - } - return size; - } - - @Override - public boolean isEmpty() { - return size() == 0; - } - - @Override - public boolean containsKey(Object o) { - // must lookup if the key has a value, as we only regard a key to be contained - // if the value is still there (the JVM can remove the soft reference if it need memory) - return get(o) != null; - } - - @Override - public Set<Map.Entry<K, V>> entrySet() { - Set<Map.Entry<K, V>> original = super.entrySet(); - - // must use a copy to avoid concurrent modifications and be able to get/set value using - // the soft reference so the returned set is without the soft reference, and thus is - // use able for the caller to use - Set<Map.Entry<K, V>> answer = new LinkedHashSet<Map.Entry<K, V>>(original.size()); - for (final Map.Entry<K, V> entry : original) { - Map.Entry<K, V> view = new Map.Entry<K, V>() { - @Override - public K getKey() { - return entry.getKey(); - } - - @Override - @SuppressWarnings("unchecked") - public V getValue() { - SoftReference<V> ref = (SoftReference<V>) entry.getValue(); - return ref != null ? ref.get() : null; - } - - @Override - @SuppressWarnings("unchecked") - public V setValue(V v) { - V put = (V) new SoftReference<V>(v); - SoftReference<V> prev = (SoftReference<V>) entry.setValue(put); - return prev != null ? prev.get() : null; - } - }; - answer.add(view); - } - - return answer; + super(initialCapacity, maximumCacheSize, stopOnEviction, true, false, false); } @Override http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/main/java/org/apache/camel/util/LRUWeakCache.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/util/LRUWeakCache.java b/camel-core/src/main/java/org/apache/camel/util/LRUWeakCache.java index 1ea9020..16d48f6 100644 --- a/camel-core/src/main/java/org/apache/camel/util/LRUWeakCache.java +++ b/camel-core/src/main/java/org/apache/camel/util/LRUWeakCache.java @@ -16,13 +16,6 @@ */ package org.apache.camel.util; -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.Collection; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; - /** * A Least Recently Used Cache which uses {@link java.lang.ref.WeakReference}. * <p/> @@ -57,116 +50,11 @@ public class LRUWeakCache<K, V> extends LRUCache<K, V> { private static final long serialVersionUID = 1L; public LRUWeakCache(int maximumCacheSize) { - super(maximumCacheSize); + this(16, maximumCacheSize); } public LRUWeakCache(int initialCapacity, int maximumCacheSize) { - super(initialCapacity, maximumCacheSize); - } - - @Override - @SuppressWarnings("unchecked") - public V put(K key, V value) { - WeakReference<V> put = new WeakReference<V>(value); - WeakReference<V> prev = (WeakReference<V>) super.put(key, (V) put); - return prev != null ? prev.get() : null; - } - - @Override - @SuppressWarnings("unchecked") - public V get(Object o) { - WeakReference<V> ref = (WeakReference<V>) super.get(o); - return ref != null ? ref.get() : null; - } - - @Override - public void putAll(Map<? extends K, ? extends V> map) { - for (Entry<? extends K, ? extends V> entry : map.entrySet()) { - put(entry.getKey(), entry.getValue()); - } - } - - @Override - @SuppressWarnings("unchecked") - public V remove(Object o) { - WeakReference<V> ref = (WeakReference<V>) super.remove(o); - return ref != null ? ref.get() : null; - } - - @Override - @SuppressWarnings("unchecked") - public Collection<V> values() { - // return a copy of all the active values - Collection<WeakReference<V>> col = (Collection<WeakReference<V>>) super.values(); - Collection<V> answer = new ArrayList<V>(); - for (WeakReference<V> ref : col) { - V value = ref.get(); - if (value != null) { - answer.add(value); - } - } - return answer; - } - - @Override - public int size() { - // only count as a size if there is a value - int size = 0; - for (V value : super.values()) { - WeakReference<?> ref = (WeakReference<?>) value; - if (ref != null && ref.get() != null) { - size++; - } - } - return size; - } - - @Override - public boolean isEmpty() { - return size() == 0; - } - - @Override - public boolean containsKey(Object o) { - // must lookup if the key has a value, as we only regard a key to be contained - // if the value is still there (the JVM can remove the soft reference if it need memory) - return get(o) != null; - } - - @Override - public Set<Entry<K, V>> entrySet() { - Set<Entry<K, V>> original = super.entrySet(); - - // must use a copy to avoid concurrent modifications and be able to get/set value using - // the soft reference so the returned set is without the soft reference, and thus is - // use able for the caller to use - Set<Entry<K, V>> answer = new LinkedHashSet<Entry<K, V>>(original.size()); - for (final Entry<K, V> entry : original) { - Entry<K, V> view = new Entry<K, V>() { - @Override - public K getKey() { - return entry.getKey(); - } - - @Override - @SuppressWarnings("unchecked") - public V getValue() { - WeakReference<V> ref = (WeakReference<V>) entry.getValue(); - return ref != null ? ref.get() : null; - } - - @Override - @SuppressWarnings("unchecked") - public V setValue(V v) { - V put = (V) new WeakReference<V>(v); - WeakReference<V> prev = (WeakReference<V>) entry.setValue(put); - return prev != null ? prev.get() : null; - } - }; - answer.add(view); - } - - return answer; + super(initialCapacity, maximumCacheSize, false, false, true, false); } @Override http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextEndpointCacheLimitTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextEndpointCacheLimitTest.java b/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextEndpointCacheLimitTest.java index 71d4d69..9f0045e 100644 --- a/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextEndpointCacheLimitTest.java +++ b/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextEndpointCacheLimitTest.java @@ -35,7 +35,7 @@ public class DefaultCamelContextEndpointCacheLimitTest extends ContextTestSuppor public void testCacheEndpoints() throws Exception { // test that we cache at most 75 endpoints in camel context to avoid it eating to much memory - for (int i = 0; i < 78; i++) { + for (int i = 0; i < 100; i++) { String uri = "my:endpoint?id=" + i; DefaultEndpoint e = new DefaultEndpoint() { public Producer createProducer() throws Exception { @@ -54,11 +54,11 @@ public class DefaultCamelContextEndpointCacheLimitTest extends ContextTestSuppor context.addEndpoint(uri, e); } + // the eviction is async so force cleanup + context.getEndpointRegistry().cleanUp(); + Collection<Endpoint> col = context.getEndpoints(); - assertEquals("Size should be 75", 75, col.size()); - List<Endpoint> list = new ArrayList<Endpoint>(col); - assertEquals("my:endpoint?id=3", list.get(0).getEndpointUri()); - assertEquals("my:endpoint?id=77", list.get(74).getEndpointUri()); + assertTrue("Size should be at most 75 was " + col.size(), col.size() <= 75); } @Override http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextEndpointCacheTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextEndpointCacheTest.java b/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextEndpointCacheTest.java index 7312d0e..9ad3cfd 100644 --- a/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextEndpointCacheTest.java +++ b/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextEndpointCacheTest.java @@ -33,7 +33,7 @@ public class DefaultCamelContextEndpointCacheTest extends ContextTestSupport { public void testCacheEndpoints() throws Exception { // test that we cache at most 1000 endpoints in camel context to avoid it eating to much memory - for (int i = 0; i < 1003; i++) { + for (int i = 0; i < 1234; i++) { String uri = "my:endpoint?id=" + i; DefaultEndpoint e = new DefaultEndpoint() { public Producer createProducer() throws Exception { @@ -52,11 +52,11 @@ public class DefaultCamelContextEndpointCacheTest extends ContextTestSupport { context.addEndpoint(uri, e); } + // the eviction is async so force cleanup + context.getEndpointRegistry().cleanUp(); + Collection<Endpoint> col = context.getEndpoints(); assertEquals("Size should be 1000", 1000, col.size()); - List<Endpoint> list = new ArrayList<Endpoint>(col); - assertEquals("my:endpoint?id=3", list.get(0).getEndpointUri()); - assertEquals("my:endpoint?id=1002", list.get(999).getEndpointUri()); } } http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextTest.java b/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextTest.java index 3403ae4..88ed8d5 100644 --- a/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextTest.java +++ b/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextTest.java @@ -118,8 +118,12 @@ public class DefaultCamelContextTest extends TestSupport { assertEquals(2, list.size()); Iterator<Endpoint> it = list.iterator(); - assertEquals("log://bar", it.next().getEndpointUri()); - assertEquals("log://baz", it.next().getEndpointUri()); + String s1 = it.next().getEndpointUri(); + String s2 = it.next().getEndpointUri(); + assertTrue("log://bar".equals(s1) || "log://bar".equals(s2)); + assertTrue("log://baz".equals(s1) || "log://baz".equals(s2)); + assertTrue("log://baz".equals(s1) || "log://baz".equals(s2)); + assertTrue("log://baz".equals(s1) || "log://baz".equals(s2)); assertEquals(1, ctx.getEndpoints().size()); } http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/test/java/org/apache/camel/impl/DefaultConsumerCacheTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/impl/DefaultConsumerCacheTest.java b/camel-core/src/test/java/org/apache/camel/impl/DefaultConsumerCacheTest.java index b22284d..796a0d1 100644 --- a/camel-core/src/test/java/org/apache/camel/impl/DefaultConsumerCacheTest.java +++ b/camel-core/src/test/java/org/apache/camel/impl/DefaultConsumerCacheTest.java @@ -38,6 +38,9 @@ public class DefaultConsumerCacheTest extends ContextTestSupport { assertNotNull("the polling consumer should not be null", p); } + // the eviction is async so force cleanup + cache.cleanUp(); + assertEquals("Size should be 1000", 1000, cache.size()); cache.stop(); } http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/test/java/org/apache/camel/impl/DefaultConsumerTemplateTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/impl/DefaultConsumerTemplateTest.java b/camel-core/src/test/java/org/apache/camel/impl/DefaultConsumerTemplateTest.java index 3313b3e..63a0550 100644 --- a/camel-core/src/test/java/org/apache/camel/impl/DefaultConsumerTemplateTest.java +++ b/camel-core/src/test/java/org/apache/camel/impl/DefaultConsumerTemplateTest.java @@ -312,6 +312,9 @@ public class DefaultConsumerTemplateTest extends ContextTestSupport { template.receiveNoWait(e); } + // the eviction is async so force cleanup + template.cleanUp(); + assertEquals("Size should be 500", 500, template.getCurrentCacheSize()); template.stop(); @@ -330,6 +333,9 @@ public class DefaultConsumerTemplateTest extends ContextTestSupport { template.receiveNoWait(e); } + // the eviction is async so force cleanup + template.cleanUp(); + assertEquals("Size should be 500", 500, template.getCurrentCacheSize()); template.stop(); http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/test/java/org/apache/camel/impl/DefaultConsumerTemplateWithCustomCacheMaxSizeTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/impl/DefaultConsumerTemplateWithCustomCacheMaxSizeTest.java b/camel-core/src/test/java/org/apache/camel/impl/DefaultConsumerTemplateWithCustomCacheMaxSizeTest.java index fba5a10..6ad0a84 100644 --- a/camel-core/src/test/java/org/apache/camel/impl/DefaultConsumerTemplateWithCustomCacheMaxSizeTest.java +++ b/camel-core/src/test/java/org/apache/camel/impl/DefaultConsumerTemplateWithCustomCacheMaxSizeTest.java @@ -45,6 +45,9 @@ public class DefaultConsumerTemplateWithCustomCacheMaxSizeTest extends ContextTe template.receiveNoWait(e); } + // the eviction is async so force cleanup + template.cleanUp(); + assertEquals("Size should be 200", 200, template.getCurrentCacheSize()); template.stop(); http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/test/java/org/apache/camel/impl/DefaultProducerCacheTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/impl/DefaultProducerCacheTest.java b/camel-core/src/test/java/org/apache/camel/impl/DefaultProducerCacheTest.java index 3ef4523..6c53bf6 100644 --- a/camel-core/src/test/java/org/apache/camel/impl/DefaultProducerCacheTest.java +++ b/camel-core/src/test/java/org/apache/camel/impl/DefaultProducerCacheTest.java @@ -48,6 +48,9 @@ public class DefaultProducerCacheTest extends ContextTestSupport { cache.releaseProducer(e, p); } + // the eviction is async so force cleanup + cache.cleanUp(); + assertEquals("Size should be 1000", 1000, cache.size()); cache.stop(); } @@ -64,8 +67,14 @@ public class DefaultProducerCacheTest extends ContextTestSupport { cache.releaseProducer(e, p); } + // the eviction is async so force cleanup + cache.cleanUp(); + assertEquals("Size should be 5", 5, cache.size()); + // the eviction listener is async so sleep a bit + Thread.sleep(1000); + // should have stopped the 3 evicted assertEquals(3, stopCounter.get()); http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/test/java/org/apache/camel/impl/DefaultProducerTemplateTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/impl/DefaultProducerTemplateTest.java b/camel-core/src/test/java/org/apache/camel/impl/DefaultProducerTemplateTest.java index 8e5942b..6dc3c8e 100644 --- a/camel-core/src/test/java/org/apache/camel/impl/DefaultProducerTemplateTest.java +++ b/camel-core/src/test/java/org/apache/camel/impl/DefaultProducerTemplateTest.java @@ -270,6 +270,9 @@ public class DefaultProducerTemplateTest extends ContextTestSupport { template.sendBody(e, "Hello"); } + // the eviction is async so force cleanup + template.cleanUp(); + assertEquals("Size should be 500", 500, template.getCurrentCacheSize()); template.stop(); @@ -288,6 +291,9 @@ public class DefaultProducerTemplateTest extends ContextTestSupport { template.sendBody(e, "Hello"); } + // the eviction is async so force cleanup + template.cleanUp(); + assertEquals("Size should be 500", 500, template.getCurrentCacheSize()); template.stop(); http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/test/java/org/apache/camel/impl/EndpointRegistryKeepRouteEndpointsTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/impl/EndpointRegistryKeepRouteEndpointsTest.java b/camel-core/src/test/java/org/apache/camel/impl/EndpointRegistryKeepRouteEndpointsTest.java index 676ab2a..e75e7c1 100644 --- a/camel-core/src/test/java/org/apache/camel/impl/EndpointRegistryKeepRouteEndpointsTest.java +++ b/camel-core/src/test/java/org/apache/camel/impl/EndpointRegistryKeepRouteEndpointsTest.java @@ -43,6 +43,9 @@ public class EndpointRegistryKeepRouteEndpointsTest extends ContextTestSupport { template.sendBody("mock:unknown" + i, "Hello " + i); } + // the eviction is async so force cleanup + context.getEndpointRegistry().cleanUp(); + // endpoints from routes is always kept in the cache assertTrue(context.hasEndpoint("direct://start") != null); assertTrue(context.hasEndpoint("log://foo") != null); @@ -52,9 +55,6 @@ public class EndpointRegistryKeepRouteEndpointsTest extends ContextTestSupport { // and the dynamic cache only keeps the last 20 assertFalse(context.hasEndpoint("mock://unknown0") != null); assertFalse(context.hasEndpoint("mock://unknown1") != null); - assertTrue(context.hasEndpoint("mock://unknown47") != null); - assertTrue(context.hasEndpoint("mock://unknown48") != null); - assertTrue(context.hasEndpoint("mock://unknown49") != null); // we should have 4 static, 20 dynamic and 24 in total assertEquals(4, context.getEndpointRegistry().staticSize()); http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/camel-core/src/test/java/org/apache/camel/util/LRUCacheTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/util/LRUCacheTest.java b/camel-core/src/test/java/org/apache/camel/util/LRUCacheTest.java index d597f63..81ef485 100644 --- a/camel-core/src/test/java/org/apache/camel/util/LRUCacheTest.java +++ b/camel-core/src/test/java/org/apache/camel/util/LRUCacheTest.java @@ -28,7 +28,8 @@ public class LRUCacheTest extends TestCase { @Override protected void setUp() throws Exception { - cache = new LRUCache<String, Service>(10); + // for testing use sync listener + cache = new LRUCache<String, Service>(10, 10, true, false, false, true); } public void testLRUCache() { @@ -44,7 +45,7 @@ public class LRUCacheTest extends TestCase { assertSame(service2, cache.get("B")); } - public void testLRUCacheEviction() { + public void testLRUCacheEviction() throws Exception { MyService service1 = new MyService(); MyService service2 = new MyService(); MyService service3 = new MyService(); @@ -85,12 +86,19 @@ public class LRUCacheTest extends TestCase { cache.put("K", service11); assertNull(service11.getStopped()); + // the eviction is async so force cleanup + cache.cleanUp(); + // should evict the eldest, and stop the service assertTrue(service1.getStopped()); - cache.put("L", service12); assertNull(service12.getStopped()); + cache.put("L", service12); + + // the eviction is async so force cleanup + cache.cleanUp(); + // should evict the eldest, and stop the service assertTrue(service2.getStopped()); http://git-wip-us.apache.org/repos/asf/camel/blob/9cfb0288/parent/pom.xml ---------------------------------------------------------------------- diff --git a/parent/pom.xml b/parent/pom.xml index 9475392..c6785ab 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -79,6 +79,7 @@ <braintree-gateway-version>2.55.0</braintree-gateway-version> <build-helper-maven-plugin-version>1.10</build-helper-maven-plugin-version> <c3p0-version>0.9.5.2</c3p0-version> + <caffeine-version>2.2.3</caffeine-version> <californium-version>1.0.0-M3</californium-version> <camel-test-spring-artifactId>camel-test-spring</camel-test-spring-artifactId> <cassandra-driver-version>2.1.9</cassandra-driver-version> @@ -127,7 +128,6 @@ <commons-pool2-version>2.4.2</commons-pool2-version> <commons-vfs2-version>2.0</commons-vfs2-version> <compress-lzf-version>1.0.3</compress-lzf-version> - <concurrentlinkedhashmap.version>1.4.2</concurrentlinkedhashmap.version> <cobertura-maven-plugin-version>2.7</cobertura-maven-plugin-version> <cxf-version>3.1.5</cxf-version> <cxf-version-range>[3.0,4.0)</cxf-version-range> @@ -2023,11 +2023,11 @@ <version>${kafka-version}</version> </dependency> - <!-- API --> + <!-- embedded concurrent lru map --> <dependency> - <groupId>com.googlecode.concurrentlinkedhashmap</groupId> - <artifactId>concurrentlinkedhashmap-lru</artifactId> - <version>${concurrentlinkedhashmap.version}</version> + <groupId>com.github.ben-manes.caffeine</groupId> + <artifactId>caffeine</artifactId> + <version>${caffeine-version}</version> </dependency> <!-- optional dependencies -->