Author: nzamosenchuk
Date: 2010-11-24 09:02:56 -0500 (Wed, 24 Nov 2010)
New Revision: 3538
Added:
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/cache/
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/cache/impl/
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/cache/impl/infinispan/
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/cache/impl/infinispan/AbstractExoCache.java
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/cache/impl/infinispan/ExoCacheCreator.java
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/cache/impl/infinispan/ExoCacheCreatorPlugin.java
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/cache/impl/infinispan/ExoCacheFactoryConfigPlugin.java
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/cache/impl/infinispan/ExoCacheFactoryImpl.java
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/cache/impl/infinispan/generic/
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/cache/impl/infinispan/generic/GenericExoCacheConfig.java
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/cache/impl/infinispan/generic/GenericExoCacheCreator.java
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/resources/
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/resources/conf/
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/resources/conf/portal/
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/resources/conf/portal/cache-configuration-template.xml
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/resources/conf/portal/configuration.xml
Log:
EXOJCR-1054 : porting ISPN code of Kernel project. Attention: RPCService test added to
excludes, since int fails with newer JGroups.
Added:
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/cache/impl/infinispan/AbstractExoCache.java
===================================================================
---
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/cache/impl/infinispan/AbstractExoCache.java
(rev 0)
+++
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/cache/impl/infinispan/AbstractExoCache.java 2010-11-24
14:02:56 UTC (rev 3538)
@@ -0,0 +1,576 @@
+/*
+ * Copyright (C) 2010 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.exoplatform.services.cache.impl.infinispan;
+
+import org.exoplatform.services.cache.CacheInfo;
+import org.exoplatform.services.cache.CacheListener;
+import org.exoplatform.services.cache.CacheListenerContext;
+import org.exoplatform.services.cache.CachedObjectSelector;
+import org.exoplatform.services.cache.ExoCache;
+import org.exoplatform.services.cache.ExoCacheConfig;
+import org.exoplatform.services.cache.ObjectCacheInfo;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+import org.infinispan.AdvancedCache;
+import org.infinispan.Cache;
+import org.infinispan.context.Flag;
+import org.infinispan.notifications.Listener;
+import org.infinispan.notifications.cachelistener.annotation.CacheEntryModified;
+import org.infinispan.notifications.cachelistener.annotation.CacheEntryRemoved;
+import org.infinispan.notifications.cachelistener.event.CacheEntryModifiedEvent;
+import org.infinispan.notifications.cachelistener.event.CacheEntryRemovedEvent;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * An {@link org.exoplatform.services.cache.ExoCache} implementation based on {@link
Cache}.
+ *
+ * @author <a href="mailto:nicolas.filotto@exoplatform.com">Nicolas
Filotto</a>
+ * @version $Id$
+ *
+ */
+public abstract class AbstractExoCache<K extends Serializable, V> implements
ExoCache<K, V>
+{
+
+ /**
+ * Logger.
+ */
+ private static final Log LOG =
ExoLogger.getLogger("exo.kernel.component.ext.cache.impl.infinispan.v4.AbstractExoCache");
+
+ private final AtomicInteger hits = new AtomicInteger(0);
+
+ private final AtomicInteger misses = new AtomicInteger(0);
+
+ private String label;
+
+ private String name;
+
+ private boolean distributed;
+
+ private boolean replicated;
+
+ private boolean logEnabled;
+
+ private final CopyOnWriteArrayList<ListenerContext<K, V>> listeners;
+
+ protected final AdvancedCache<K, V> cache;
+
+ public AbstractExoCache(ExoCacheConfig config, Cache<K, V> cache)
+ {
+ this.cache = cache.getAdvancedCache();
+ this.listeners = new CopyOnWriteArrayList<ListenerContext<K, V>>();
+ setDistributed(config.isDistributed());
+ setLabel(config.getLabel());
+ setName(config.getName());
+ setLogEnabled(config.isLogEnabled());
+ setReplicated(config.isRepicated());
+ cache.addListener(new CacheEventListener());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addCacheListener(CacheListener<? super K, ? super V> listener)
+ {
+ if (listener == null)
+ {
+ throw new NullPointerException();
+ }
+ listeners.add(new ListenerContext<K, V>(listener, this));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void clearCache()
+ {
+ cache.withFlags(Flag.CACHE_MODE_LOCAL).clear();
+ onClearCache();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ public V get(Serializable name)
+ {
+ if (name == null)
+ {
+ return null;
+ }
+ final V result = cache.get(name);
+ if (result == null)
+ {
+ misses.incrementAndGet();
+ }
+ else
+ {
+ hits.incrementAndGet();
+ }
+ onGet((K)name, result);
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getCacheHit()
+ {
+ return hits.get();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getCacheMiss()
+ {
+ return misses.get();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getCacheSize()
+ {
+ return cache.size();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<V> getCachedObjects()
+ {
+ Collection<V> values = cache.values();
+ if (values == null || values.isEmpty())
+ {
+ return Collections.emptyList();
+ }
+ else
+ {
+ return new ArrayList<V>(values);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getLabel()
+ {
+ return label;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getName()
+ {
+ return name;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isDistributed()
+ {
+ return distributed;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isLogEnabled()
+ {
+ return logEnabled;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isReplicated()
+ {
+ return replicated;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void put(K key, V value) throws NullPointerException
+ {
+ if (key == null)
+ {
+ throw new NullPointerException("No null cache key accepted");
+ }
+ putOnly(key, value);
+ onPut(key, value);
+ }
+
+ /**
+ * Only puts the data into the cache nothing more
+ */
+ protected void putOnly(K key, V value)
+ {
+ cache.withFlags(Flag.SKIP_REMOTE_LOOKUP).put(key, value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void putMap(Map<? extends K, ? extends V> objs) throws
NullPointerException, IllegalArgumentException
+ {
+ if (objs == null)
+ {
+ throw new NullPointerException("No null map accepted");
+ }
+ for (Serializable name : objs.keySet())
+ {
+ if (name == null)
+ {
+ throw new IllegalArgumentException("No null cache key accepted");
+ }
+ }
+ cache.startBatch();
+ try
+ {
+ // Start transaction
+ for (Map.Entry<? extends K, ? extends V> entry : objs.entrySet())
+ {
+ putOnly(entry.getKey(), entry.getValue());
+ }
+ cache.endBatch(true);
+ // End transaction
+ for (Map.Entry<? extends K, ? extends V> entry : objs.entrySet())
+ {
+ onPut(entry.getKey(), entry.getValue());
+ }
+ }
+ catch (Exception e)
+ {
+ cache.endBatch(false);
+ LOG.warn("An error occurs while executing the putMap method", e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ public V remove(Serializable name) throws NullPointerException
+ {
+ if (name == null)
+ {
+ throw new NullPointerException("No null cache key accepted");
+ }
+ V result = cache.remove(name);
+ onRemove((K)name, result);
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<V> removeCachedObjects()
+ {
+ final List<V> list = getCachedObjects();
+ clearCache();
+ return list;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void select(CachedObjectSelector<? super K, ? super V> selector) throws
Exception
+ {
+ if (selector == null)
+ {
+ throw new IllegalArgumentException("No null selector");
+ }
+ for (K key : cache.keySet())
+ {
+ if (key == null)
+ {
+ continue;
+ }
+ final V value = cache.withFlags(Flag.SKIP_LOCKING).get(key);
+ ObjectCacheInfo<V> info = new ObjectCacheInfo<V>()
+ {
+ public V get()
+ {
+ return value;
+ }
+
+ public long getExpireTime()
+ {
+ // Cannot know: The expire time is managed by Infinispan itself
+ return -1;
+ }
+ };
+ if (selector.select(key, info))
+ {
+ selector.onSelect(this, key, info);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setDistributed(boolean distributed)
+ {
+ this.distributed = distributed;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setLabel(String label)
+ {
+ this.label = label;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setLogEnabled(boolean logEnabled)
+ {
+ this.logEnabled = logEnabled;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setReplicated(boolean replicated)
+ {
+ this.replicated = replicated;
+ }
+
+ void onExpire(K key, V obj)
+ {
+ if (listeners.isEmpty())
+ {
+ return;
+ }
+ for (ListenerContext<K, V> context : listeners)
+ {
+ try
+ {
+ context.onExpire(key, obj);
+ }
+ catch (Exception e)
+ {
+ if (LOG.isWarnEnabled())
+ LOG.warn("Cannot execute the CacheListener properly", e);
+ }
+ }
+ }
+
+ void onRemove(K key, V obj)
+ {
+ if (listeners.isEmpty())
+ {
+ return;
+ }
+ for (ListenerContext<K, V> context : listeners)
+ {
+ try
+ {
+ context.onRemove(key, obj);
+ }
+ catch (Exception e)
+ {
+ if (LOG.isWarnEnabled())
+ LOG.warn("Cannot execute the CacheListener properly", e);
+ }
+ }
+ }
+
+ void onPut(K key, V obj)
+ {
+ if (listeners.isEmpty())
+ {
+ return;
+ }
+ for (ListenerContext<K, V> context : listeners)
+ try
+ {
+ context.onPut(key, obj);
+ }
+ catch (Exception e)
+ {
+ if (LOG.isWarnEnabled())
+ LOG.warn("Cannot execute the CacheListener properly", e);
+ }
+ }
+
+ void onGet(K key, V obj)
+ {
+ if (listeners.isEmpty())
+ {
+ return;
+ }
+ for (ListenerContext<K, V> context : listeners)
+ try
+ {
+ context.onGet(key, obj);
+ }
+ catch (Exception e)
+ {
+ if (LOG.isWarnEnabled())
+ LOG.warn("Cannot execute the CacheListener properly", e);
+ }
+ }
+
+ void onClearCache()
+ {
+ if (listeners.isEmpty())
+ {
+ return;
+ }
+ for (ListenerContext<K, V> context : listeners)
+ try
+ {
+ context.onClearCache();
+ }
+ catch (Exception e)
+ {
+ if (LOG.isWarnEnabled())
+ LOG.warn("Cannot execute the CacheListener properly", e);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Listener
+ public class CacheEventListener
+ {
+// Infinispan triggers a CacheEntryEvictedEvent only at explicit eviction which is
+// not what we want here. So it will be considered as non supported
+// @CacheEntryEvicted
+// public void cacheEntryEvicted(CacheEntryEvictedEvent evt)
+// {
+// if (evt.isPre())
+// {
+// final K key = (K)evt.getKey();
+// final V value = cache.withFlags(Flag.SKIP_LOCKING).get(key);
+// onExpire(key, value);
+// }
+// }
+
+ @CacheEntryRemoved
+ public void cacheEntryRemoved(CacheEntryRemovedEvent evt)
+ {
+ if (evt.isPre() && !evt.isOriginLocal())
+ {
+ final K key = (K)evt.getKey();
+ final V value = (V)evt.getValue();
+ onRemove(key, value);
+ }
+ }
+
+ @CacheEntryModified
+ public void cacheEntryModified(CacheEntryModifiedEvent evt)
+ {
+ if (!evt.isOriginLocal() && !evt.isPre())
+ {
+ final K key = (K)evt.getKey();
+ final V value = (V)evt.getValue();
+ onPut(key, value);
+ }
+ }
+ }
+
+ private static class ListenerContext<K extends Serializable, V> implements
CacheListenerContext, CacheInfo
+ {
+
+ /** . */
+ private final ExoCache<K, V> cache;
+
+ /** . */
+ final CacheListener<? super K, ? super V> listener;
+
+ public ListenerContext(CacheListener<? super K, ? super V> listener,
ExoCache<K, V> cache)
+ {
+ this.listener = listener;
+ this.cache = cache;
+ }
+
+ public CacheInfo getCacheInfo()
+ {
+ return this;
+ }
+
+ public String getName()
+ {
+ return cache.getName();
+ }
+
+ public int getMaxSize()
+ {
+ return cache.getMaxSize();
+ }
+
+ public long getLiveTime()
+ {
+ return cache.getLiveTime();
+ }
+
+ public int getSize()
+ {
+ return cache.getCacheSize();
+ }
+
+ void onExpire(K key, V obj) throws Exception
+ {
+ listener.onExpire(this, key, obj);
+ }
+
+ void onRemove(K key, V obj) throws Exception
+ {
+ listener.onRemove(this, key, obj);
+ }
+
+ void onPut(K key, V obj) throws Exception
+ {
+ listener.onPut(this, key, obj);
+ }
+
+ void onGet(K key, V obj) throws Exception
+ {
+ listener.onGet(this, key, obj);
+ }
+
+ void onClearCache() throws Exception
+ {
+ listener.onClearCache(this);
+ }
+ }
+}
\ No newline at end of file
Added:
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/cache/impl/infinispan/ExoCacheCreator.java
===================================================================
---
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/cache/impl/infinispan/ExoCacheCreator.java
(rev 0)
+++
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/cache/impl/infinispan/ExoCacheCreator.java 2010-11-24
14:02:56 UTC (rev 3538)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2010 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.exoplatform.services.cache.impl.infinispan;
+
+import org.exoplatform.services.cache.ExoCache;
+import org.exoplatform.services.cache.ExoCacheConfig;
+import org.exoplatform.services.cache.ExoCacheInitException;
+import org.infinispan.Cache;
+import org.infinispan.config.Configuration;
+
+import java.io.Serializable;
+import java.util.Set;
+import java.util.concurrent.Callable;
+
+/**
+ * This class is used to create the cache according to the given
+ * configuration {@link org.exoplatform.services.cache.ExoCacheConfig}
+ *
+ * @author <a href="mailto:nicolas.filotto@exoplatform.com">Nicolas
Filotto</a>
+ * @version $Id$
+ */
+public interface ExoCacheCreator
+{
+
+ /**
+ * Creates an eXo cache according to the given configuration {@link
org.exoplatform.services.cache.ExoCacheConfig}
+ * @param config the configuration of the cache to apply
+ * @param cacheConfig the configuration of the infinispan cache
+ * @param cacheGetter a {@link Callable} instance from which we can get the cache
+ * @exception ExoCacheInitException if an exception happens while initializing the
cache
+ */
+ public ExoCache<Serializable, Object> create(ExoCacheConfig config,
Configuration cacheConfig, Callable<Cache<Serializable, Object>> cacheGetter)
throws ExoCacheInitException;
+
+ /**
+ * Returns the type of {@link org.exoplatform.services.cache.ExoCacheConfig} expected
by the creator
+ * @return the expected type
+ */
+ public Class<? extends ExoCacheConfig> getExpectedConfigType();
+
+ /**
+ * Returns a set of all the implementations expected by the creator. This is mainly
used to be backward compatible
+ * @return the expected by the creator
+ */
+ public Set<String> getExpectedImplementations();
+}
Added:
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/cache/impl/infinispan/ExoCacheCreatorPlugin.java
===================================================================
---
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/cache/impl/infinispan/ExoCacheCreatorPlugin.java
(rev 0)
+++
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/cache/impl/infinispan/ExoCacheCreatorPlugin.java 2010-11-24
14:02:56 UTC (rev 3538)
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2010 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.exoplatform.services.cache.impl.infinispan;
+
+import org.exoplatform.container.component.BaseComponentPlugin;
+import org.exoplatform.container.xml.InitParams;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class allows us to define new creators
+ * @author <a href="mailto:nicolas.filotto@exoplatform.com">Nicolas
Filotto</a>
+ * @version $Id$
+ */
+public class ExoCacheCreatorPlugin extends BaseComponentPlugin
+{
+
+ /**
+ * The list of all the creators defined for this ComponentPlugin
+ */
+ private final List<ExoCacheCreator> creators;
+
+ public ExoCacheCreatorPlugin(InitParams params)
+ {
+ creators = new ArrayList<ExoCacheCreator>();
+ List<?> configs = params.getObjectParamValues(ExoCacheCreator.class);
+ for (int i = 0; i < configs.size(); i++)
+ {
+ ExoCacheCreator config = (ExoCacheCreator)configs.get(i);
+ creators.add(config);
+ }
+ }
+
+ /**
+ * Returns all the creators defined for this ComponentPlugin
+ */
+ public List<ExoCacheCreator> getCreators()
+ {
+ return creators;
+ }
+}
Added:
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/cache/impl/infinispan/ExoCacheFactoryConfigPlugin.java
===================================================================
---
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/cache/impl/infinispan/ExoCacheFactoryConfigPlugin.java
(rev 0)
+++
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/cache/impl/infinispan/ExoCacheFactoryConfigPlugin.java 2010-11-24
14:02:56 UTC (rev 3538)
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2010 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.exoplatform.services.cache.impl.infinispan;
+
+import org.exoplatform.container.component.BaseComponentPlugin;
+import org.exoplatform.container.xml.InitParams;
+import org.exoplatform.container.xml.ValueParam;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * This class is used to define custom configurations
+ *
+ * @author <a href="mailto:nicolas.filotto@exoplatform.com">Nicolas
Filotto</a>
+ * @version $Id$
+ */
+public class ExoCacheFactoryConfigPlugin extends BaseComponentPlugin
+{
+
+ /**
+ * The map of all the creators defined for this ComponentPlugin
+ */
+ private final Map<String, String> configs;
+
+ public ExoCacheFactoryConfigPlugin(InitParams params)
+ {
+ configs = new HashMap<String, String>();
+ for (Iterator<ValueParam> iterator = params.getValueParamIterator();
iterator.hasNext();)
+ {
+ ValueParam vParam = iterator.next();
+ configs.put(vParam.getName(), vParam.getValue());
+ }
+ }
+
+ /**
+ * Returns all the configurations defined for this ComponentPlugin
+ */
+ public Map<String, String> getConfigs()
+ {
+ return configs;
+ }
+}
Added:
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/cache/impl/infinispan/ExoCacheFactoryImpl.java
===================================================================
---
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/cache/impl/infinispan/ExoCacheFactoryImpl.java
(rev 0)
+++
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/cache/impl/infinispan/ExoCacheFactoryImpl.java 2010-11-24
14:02:56 UTC (rev 3538)
@@ -0,0 +1,430 @@
+/*
+ * Copyright (C) 2010 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.exoplatform.services.cache.impl.infinispan;
+
+import org.exoplatform.container.ExoContainerContext;
+import org.exoplatform.container.configuration.ConfigurationManager;
+import org.exoplatform.container.xml.InitParams;
+import org.exoplatform.container.xml.ValueParam;
+import org.exoplatform.services.cache.ExoCache;
+import org.exoplatform.services.cache.ExoCacheConfig;
+import org.exoplatform.services.cache.ExoCacheFactory;
+import org.exoplatform.services.cache.ExoCacheInitException;
+import org.exoplatform.services.cache.impl.infinispan.generic.GenericExoCacheCreator;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+import org.infinispan.Cache;
+import org.infinispan.config.Configuration;
+import org.infinispan.config.GlobalConfiguration;
+import org.infinispan.config.Configuration.CacheMode;
+import org.infinispan.eviction.EvictionStrategy;
+import org.infinispan.manager.DefaultCacheManager;
+import org.infinispan.remoting.transport.jgroups.JGroupsTransport;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.Callable;
+
+/**
+ * This class is the Infinispan implementation of the {@link
org.exoplatform.services.cache.ExoCacheFactory}
+ *
+ * @author <a href="mailto:nicolas.filotto@exoplatform.com">Nicolas
Filotto</a>
+ * @version $Id$
+ *
+ */
+public class ExoCacheFactoryImpl implements ExoCacheFactory
+{
+
+ /**
+ * The logger
+ */
+ private static final Log LOG =
+
ExoLogger.getLogger("exo.kernel.component.ext.cache.impl.infinispan.v4.ExoCacheFactoryImpl");
+
+ /**
+ * The initial parameter key that defines the full path of the configuration template
+ */
+ private static final String CACHE_CONFIG_TEMPLATE_KEY =
"cache.config.template";
+
+ /**
+ * The current {@link ExoContainerContext}
+ */
+ private final ExoContainerContext ctx;
+
+ /**
+ * The configuration manager that allows us to retrieve a configuration file in
several different
+ * manners
+ */
+ private final ConfigurationManager configManager;
+
+ /**
+ * The {@link DefaultCacheManager} used for all the cache regions
+ */
+ private final DefaultCacheManager cacheManager;
+
+ /**
+ * The mapping between the configuration types and the creators
+ */
+ private final Map<Class<? extends ExoCacheConfig>, ExoCacheCreator>
mappingConfigTypeCreators =
+ new HashMap<Class<? extends ExoCacheConfig>, ExoCacheCreator>();
+
+ /**
+ * The mapping between the implementations and the creators. This is mainly used for
backward compatibility
+ */
+ private final Map<String, ExoCacheCreator> mappingImplCreators = new
HashMap<String, ExoCacheCreator>();
+
+ /**
+ * The mapping between the cache names and the configuration paths
+ */
+ private final Map<String, String> mappingCacheNameConfig = new
HashMap<String, String>();
+
+ /**
+ * The mapping between the global configuration and the cache managers
+ */
+ private final Map<GlobalConfiguration, DefaultCacheManager>
mappingGlobalConfigCacheManager = new HashMap<GlobalConfiguration,
DefaultCacheManager>();
+
+ /**
+ * The default creator
+ */
+ private final ExoCacheCreator defaultCreator = new GenericExoCacheCreator();
+
+ public ExoCacheFactoryImpl(ExoContainerContext ctx, InitParams params,
ConfigurationManager configManager)
+ throws ExoCacheInitException
+ {
+ this(ctx, getValueParam(params, CACHE_CONFIG_TEMPLATE_KEY), configManager);
+ }
+
+ ExoCacheFactoryImpl(ExoContainerContext ctx, String cacheConfigTemplate,
ConfigurationManager configManager)
+ throws ExoCacheInitException
+ {
+ this.ctx = ctx;
+ this.configManager = configManager;
+ if (cacheConfigTemplate == null)
+ {
+ throw new RuntimeException("The parameter '" +
CACHE_CONFIG_TEMPLATE_KEY + "' must be set");
+ }
+ // Initialize the main cache manager
+ this.cacheManager = initCacheManager(cacheConfigTemplate);
+ // Register the main cache manager
+ mappingGlobalConfigCacheManager.put(cacheManager.getGlobalConfiguration(),
cacheManager);
+ }
+
+ /**
+ * Initializes the {@link DefaultCacheManager}
+ * @throws ExoCacheInitException if the cache manager cannot be initialized
+ */
+ private DefaultCacheManager initCacheManager(String cacheConfigTemplate)
+ throws ExoCacheInitException
+ {
+ InputStream is = null;
+ try
+ {
+ // Read the configuration file of the cache
+ is = configManager.getInputStream(cacheConfigTemplate);
+ }
+ catch (Exception e)
+ {
+ throw new ExoCacheInitException("The configuration of the CacheManager
cannot be loaded from '"
+ + cacheConfigTemplate + "'", e);
+ }
+ if (is == null)
+ {
+ throw new ExoCacheInitException("The configuration of the CacheManager
cannot be found at '"
+ + cacheConfigTemplate + "'");
+ }
+ DefaultCacheManager cacheManager = null;
+ try
+ {
+ // Create the CacheManager from the input stream
+ cacheManager = new DefaultCacheManager(is, false);
+ }
+ catch (Exception e)
+ {
+ throw new ExoCacheInitException("Cannot initialize the CacheManager
corresponding to the configuration '"
+ + cacheConfigTemplate + "'", e);
+ }
+
+ GlobalConfiguration config = cacheManager.getGlobalConfiguration();
+
+ configureJGroups(config);
+ return cacheManager;
+ }
+
+ /**
+ * If some JGoups properties has been set, it will load the configuration and set
+ * the cluster name by adding as suffix the name of the {@link ExoContainerContext}
+ *
+ * @param config the global configuration from which the JGroups config will be
extracted
+ * @throws ExoCacheInitException if any exception occurs while configuring JGroups
+ */
+ private void configureJGroups(GlobalConfiguration config) throws
ExoCacheInitException
+ {
+ if (loadJGroupsConfig(config))
+ {
+ // The JGroups Config could be loaded which means that the configuration is for
a cluster
+ config.setClusterName(config.getClusterName() + "-" + ctx.getName());
+ }
+ }
+
+ /**
+ * Load the JGroups configuration file thanks to the {@link ConfigurationManager}
+ * @param config the global configuration from which the JGroups config will be
extracted
+ * @return <code>true</code> if the JGoups config could be loaded
successfully,
+ * <code>false</code> if there were no JGroups config to load
+ * @throws ExoCacheInitException if the JGroups config could not be loaded
+ */
+ private boolean loadJGroupsConfig(GlobalConfiguration config) throws
ExoCacheInitException
+ {
+ Properties properties = config.getTransportProperties();
+ if (properties == null ||
!properties.containsKey(JGroupsTransport.CONFIGURATION_FILE))
+ {
+ return false;
+ }
+ InputStream is;
+ String jgroupsFileLocation =
properties.getProperty(JGroupsTransport.CONFIGURATION_FILE);
+ try
+ {
+ // Read the jgroups configuration file
+ URL url = configManager.getURL(jgroupsFileLocation);
+ is = url == null ? null : url.openStream();
+ }
+ catch (Exception e)
+ {
+ throw new ExoCacheInitException("The jgroups configuration cannot be loaded
from '" + jgroupsFileLocation
+ + "'", e);
+ }
+ if (is != null)
+ {
+ try
+ {
+ // Set the jgroups configuration as XML
+ properties.setProperty(JGroupsTransport.CONFIGURATION_XML, readStream(is));
+ }
+ catch (IOException e)
+ {
+ throw new ExoCacheInitException("The jgroups configuration cannot be
read from '" + jgroupsFileLocation
+ + "'");
+ }
+ // Remove the property corresponding to the configuration file
+ properties.remove(JGroupsTransport.CONFIGURATION_FILE);
+ }
+ return true;
+ }
+
+ /**
+ * Reads bytes from input stream and builds a string from them
+ *
+ * @param inputStream
+ * @return
+ * @throws IOException
+ */
+ protected String readStream(InputStream inputStream) throws IOException
+ {
+ StringBuilder out = new StringBuilder(4096);
+ byte[] b = new byte[4096];
+ try
+ {
+ for (int length; (length = inputStream.read(b)) != -1;)
+ {
+ out.append(new String(b, 0, length));
+ }
+ }
+ finally
+ {
+ try
+ {
+ inputStream.close();
+ }
+ catch (Exception e)
+ {
+ LOG.debug("Cannot close stream", e);
+ }
+ }
+ return out.toString();
+ }
+
+ /**
+ * To create a new cache instance according to the given configuration, we follow the
steps below:
+ *
+ * We first try to find if a specific location of the cache configuration has been
defined thanks
+ * to an external component plugin of type ExoCacheFactoryConfigPlugin. If so we use
the default cache
+ * configuration defined in this file otherwise we use the default cache configuration
defined in
+ * "${CACHE_CONFIG_TEMPLATE_KEY}"
+ */
+ public ExoCache<Serializable, Object> createCache(ExoCacheConfig config) throws
ExoCacheInitException
+ {
+ final String region = config.getName();
+ final String customConfig = mappingCacheNameConfig.get(region);
+ final ExoCache<Serializable, Object> eXoCache;
+ final DefaultCacheManager cacheManager;
+ try
+ {
+ final Configuration conf;
+ if (customConfig != null)
+ {
+ // A custom configuration has been set
+ if (LOG.isInfoEnabled())
+ LOG.info("A custom configuration has been set for the cache
'" + region + "'.");
+ // Create the CacheManager by loading the configuration
+ DefaultCacheManager customCacheManager = new
DefaultCacheManager(configManager.getInputStream(customConfig), false);
+ GlobalConfiguration gc = customCacheManager.getGlobalConfiguration();
+ // Configure JGroups since it could affect the state of the Global Config
+ configureJGroups(gc);
+ // Check if a CacheManager with the same GlobalConfiguration exists
+ DefaultCacheManager currentCacheManager =
mappingGlobalConfigCacheManager.get(gc);
+ if (currentCacheManager == null)
+ {
+ // No cache manager has been defined so far for this Cache Configuration
+ currentCacheManager = customCacheManager;
+ // We register this new cache manager
+ mappingGlobalConfigCacheManager.put(gc, customCacheManager);
+ }
+ conf = currentCacheManager.getDefaultConfiguration().clone();
+ cacheManager = currentCacheManager;
+ }
+ else
+ {
+ cacheManager = this.cacheManager;
+ // No custom configuration has been found, a configuration template will be
used
+ if (LOG.isInfoEnabled())
+ LOG.info("The configuration template will be used for the the cache
'" + region + "'.");
+ conf = cacheManager.getDefaultConfiguration().clone();
+ if (!config.isDistributed() && !config.isRepicated())
+ {
+ // The cache is local
+ conf.setCacheMode(CacheMode.LOCAL);
+ }
+ }
+ // Reset the configuration to avoid conflicts
+ resetConfiguration(conf);
+ final ExoCacheCreator creator = getExoCacheCreator(config);
+ // Create the cache
+ eXoCache = creator.create(config, conf, new Callable<Cache<Serializable,
Object>>()
+ {
+ @Override
+ public Cache<Serializable, Object> call() throws Exception
+ {
+ // Define the configuration
+ cacheManager.defineConfiguration(region, conf);
+ // create and start the cache
+ return cacheManager.getCache(region);
+ }
+ });
+ }
+ catch (Exception e)
+ {
+ throw new ExoCacheInitException("The cache '" + region +
"' could not be initialized", e);
+ }
+ return eXoCache;
+ }
+
+ /**
+ * Add a list of creators to register
+ * @param plugin the plugin that contains the creators
+ */
+ public void addCreator(ExoCacheCreatorPlugin plugin)
+ {
+ final List<ExoCacheCreator> creators = plugin.getCreators();
+ for (ExoCacheCreator creator : creators)
+ {
+ mappingConfigTypeCreators.put(creator.getExpectedConfigType(), creator);
+ Set<String> implementations = creator.getExpectedImplementations();
+ if (implementations == null)
+ {
+ throw new NullPointerException("The set of implementations cannot be
null");
+ }
+ for (String imp : implementations)
+ {
+ mappingImplCreators.put(imp, creator);
+ }
+ }
+ }
+
+ /**
+ * Add a list of custom configuration to register
+ * @param plugin the plugin that contains the configs
+ */
+ public void addConfig(ExoCacheFactoryConfigPlugin plugin)
+ {
+ final Map<String, String> configs = plugin.getConfigs();
+ mappingCacheNameConfig.putAll(configs);
+ }
+
+ /**
+ * Returns the value of the ValueParam if and only if the value is not empty
+ */
+ private static String getValueParam(InitParams params, String key)
+ {
+ if (params == null)
+ {
+ return null;
+ }
+ final ValueParam vp = params.getValueParam(key);
+ String result;
+ if (vp == null || (result = vp.getValue()) == null || (result =
result.trim()).length() == 0)
+ {
+ return null;
+ }
+ return result;
+ }
+
+ /**
+ * Returns the most relevant ExoCacheCreator according to the give configuration
+ */
+ protected ExoCacheCreator getExoCacheCreator(ExoCacheConfig config)
+ {
+ ExoCacheCreator creator = mappingConfigTypeCreators.get(config.getClass());
+ if (creator == null)
+ {
+ // No creator for this type has been found, let's try the implementation
field
+ creator = mappingImplCreators.get(config.getImplementation());
+ if (creator == null)
+ {
+ // No creator can be found, we will use the default creator
+ if (LOG.isInfoEnabled())
+ LOG.info("No cache creator has been found for the the cache
'" + config.getName()
+ + "', the default one will be used.");
+ return defaultCreator;
+ }
+ }
+ if (LOG.isInfoEnabled())
+ LOG.info("The cache '" + config.getName() + "' will be
created with '" + creator.getClass() + "'.");
+ return creator;
+ }
+
+ /**
+ * Clean the configuration template to prevent conflicts
+ */
+ protected void resetConfiguration(Configuration config)
+ {
+ config.setInvocationBatchingEnabled(true);
+ config.setEvictionStrategy(EvictionStrategy.NONE);
+ config.setEvictionMaxEntries(-1);
+ config.setExpirationLifespan(-1);
+ config.setExpirationMaxIdle(-1);
+ config.setEvictionWakeUpInterval(5000);
+ }
+}
Added:
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/cache/impl/infinispan/generic/GenericExoCacheConfig.java
===================================================================
---
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/cache/impl/infinispan/generic/GenericExoCacheConfig.java
(rev 0)
+++
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/cache/impl/infinispan/generic/GenericExoCacheConfig.java 2010-11-24
14:02:56 UTC (rev 3538)
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2010 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.exoplatform.services.cache.impl.infinispan.generic;
+
+import org.exoplatform.services.cache.ExoCacheConfig;
+
+/**
+ * The {@link org.exoplatform.services.cache.ExoCacheConfig} for all the eviction
algorithms
+ * available in infinispan
+ *
+ * @author <a href="mailto:nicolas.filotto@exoplatform.com">Nicolas
Filotto</a>
+ * @version $Id$
+ *
+ */
+public class GenericExoCacheConfig extends ExoCacheConfig
+{
+
+ private String strategy;
+
+ private int maxEntries;
+
+ private long lifespan;
+
+ private long maxIdle;
+
+ private long wakeUpInterval;
+
+ /**
+ * @return the strategy
+ */
+ public String getStrategy()
+ {
+ return strategy;
+ }
+
+ /**
+ * @param strategy the strategy to set
+ */
+ public void setStrategy(String strategy)
+ {
+ this.strategy = strategy;
+ }
+
+ /**
+ * @return the wakeUpInterval
+ */
+ public long getWakeUpInterval()
+ {
+ return wakeUpInterval;
+ }
+
+ /**
+ * @param wakeUpInterval the wakeUpInterval to set
+ */
+ public void setWakeUpInterval(long wakeUpInterval)
+ {
+ this.wakeUpInterval = wakeUpInterval;
+ }
+
+ /**
+ * @return the maxEntries
+ */
+ public int getMaxEntries()
+ {
+ return maxEntries;
+ }
+
+ /**
+ * @param maxEntries the maxEntries to set
+ */
+ public void setMaxEntries(int maxEntries)
+ {
+ this.maxEntries = maxEntries;
+ }
+
+ /**
+ * @return the lifespan
+ */
+ public long getLifespan()
+ {
+ return lifespan;
+ }
+
+ /**
+ * @param lifespan the lifespan to set
+ */
+ public void setLifespan(long lifespan)
+ {
+ this.lifespan = lifespan;
+ }
+
+ /**
+ * @return the maxIdle
+ */
+ public long getMaxIdle()
+ {
+ return maxIdle;
+ }
+
+ /**
+ * @param maxIdle the maxIdle to set
+ */
+ public void setMaxIdle(long maxIdle)
+ {
+ this.maxIdle = maxIdle;
+ }
+}
\ No newline at end of file
Added:
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/cache/impl/infinispan/generic/GenericExoCacheCreator.java
===================================================================
---
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/cache/impl/infinispan/generic/GenericExoCacheCreator.java
(rev 0)
+++
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/java/org/exoplatform/services/cache/impl/infinispan/generic/GenericExoCacheCreator.java 2010-11-24
14:02:56 UTC (rev 3538)
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2010 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.exoplatform.services.cache.impl.infinispan.generic;
+
+import org.exoplatform.management.annotations.Managed;
+import org.exoplatform.management.annotations.ManagedDescription;
+import org.exoplatform.management.annotations.ManagedName;
+import org.exoplatform.services.cache.ExoCache;
+import org.exoplatform.services.cache.ExoCacheConfig;
+import org.exoplatform.services.cache.ExoCacheInitException;
+import org.exoplatform.services.cache.impl.infinispan.AbstractExoCache;
+import org.exoplatform.services.cache.impl.infinispan.ExoCacheCreator;
+import org.infinispan.Cache;
+import org.infinispan.config.Configuration;
+
+import java.io.Serializable;
+import java.util.Set;
+import java.util.concurrent.Callable;
+
+/**
+ * The generic {@link ExoCacheCreator} for all the expiration available in infinispan.
+ *
+ * @author <a href="mailto:nicolas.filotto@exoplatform.com">Nicolas
Filotto</a>
+ * @version $Id$
+ *
+ */
+public class GenericExoCacheCreator implements ExoCacheCreator
+{
+
+ /**
+ * The default value for the eviction strategy
+ */
+ protected String defaultStrategy = "LRU";
+
+ /**
+ * The default value for maxIdle
+ */
+ protected long defaultMaxIdle = -1;
+
+ /**
+ * The default value for wakeUpInterval
+ */
+ protected long defaultWakeUpInterval = 5000;
+
+ /**
+ * A set of all the implementations supported by this creator
+ */
+ protected Set<String> implementations;
+
+ /**
+ * {@inheritDoc}
+ */
+ public Set<String> getExpectedImplementations()
+ {
+ return implementations;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Class<? extends ExoCacheConfig> getExpectedConfigType()
+ {
+ return GenericExoCacheConfig.class;
+ }
+
+ /**
+ * @see
org.exoplatform.services.cache.impl.infinispan.ExoCacheCreator#create(org.exoplatform.services.cache.ExoCacheConfig,
java.util.concurrent.Callable)
+ */
+ public ExoCache<Serializable, Object> create(ExoCacheConfig config,
Configuration cacheConfig,
+ Callable<Cache<Serializable, Object>> cacheGetter) throws
ExoCacheInitException
+ {
+ if (config instanceof GenericExoCacheConfig)
+ {
+ final GenericExoCacheConfig gConfig = (GenericExoCacheConfig)config;
+ return create(config, cacheConfig, cacheGetter, gConfig.getStrategy(),
gConfig.getMaxEntries(), gConfig
+ .getLifespan(), gConfig.getMaxIdle() == 0 ? defaultMaxIdle :
gConfig.getMaxIdle(), gConfig
+ .getWakeUpInterval() == 0 ? defaultWakeUpInterval :
gConfig.getWakeUpInterval());
+ }
+ else
+ {
+ final long period = config.getLiveTime();
+ return create(config, cacheConfig, cacheGetter, config.getImplementation() ==
null ? defaultStrategy : config
+ .getImplementation(), config.getMaxSize(), period > 0 ? period * 1000 :
-1, defaultMaxIdle,
+ defaultWakeUpInterval);
+ }
+ }
+
+ /**
+ * Creates a new ExoCache instance with the relevant parameters
+ * @throws ExoCacheInitException If any exception occurs while creating the cache
+ */
+ private ExoCache<Serializable, Object> create(ExoCacheConfig config,
Configuration cacheConfig,
+ Callable<Cache<Serializable, Object>> cacheGetter, String strategy, int
maxEntries, long lifespan, long maxIdle,
+ long wakeUpInterval) throws ExoCacheInitException
+ {
+ cacheConfig.setEvictionStrategy(strategy);
+ cacheConfig.setEvictionMaxEntries(maxEntries);
+ cacheConfig.setExpirationLifespan(lifespan);
+ cacheConfig.setExpirationMaxIdle(maxIdle);
+ cacheConfig.setEvictionWakeUpInterval(wakeUpInterval);
+ try
+ {
+ return new GenericExoCache(cacheConfig, config, cacheGetter.call());
+ }
+ catch (Exception e)
+ {
+ throw new ExoCacheInitException("Cannot create the cache '" +
config.getName() + "'", e);
+ }
+ }
+
+ /**
+ * The Generic implementation of an ExoCache
+ */
+ public static class GenericExoCache extends AbstractExoCache<Serializable,
Object>
+ {
+
+ private final Configuration cacheConfig;
+
+ public GenericExoCache(Configuration cacheConfig, ExoCacheConfig config,
Cache<Serializable, Object> cache)
+ {
+ super(config, cache);
+ this.cacheConfig = cacheConfig;
+ }
+
+ public void setMaxSize(int max)
+ {
+ cacheConfig.setEvictionMaxEntries(max);
+ }
+
+ public void setLiveTime(long period)
+ {
+ cacheConfig.setExpirationLifespan(period);
+ }
+
+ public void setMaxIdle(long maxIdle)
+ {
+ cacheConfig.setExpirationMaxIdle(maxIdle);
+ }
+
+ public void setWakeUpInterval(long wakeUpInterval)
+ {
+ cacheConfig.setEvictionWakeUpInterval(wakeUpInterval);
+ }
+
+ @ManagedName("MaxEntries")
+ @ManagedDescription("Maximum number of entries in a cache instance. -1 means
no limit.")
+ public int getMaxSize()
+ {
+ return cacheConfig.getEvictionMaxEntries();
+ }
+
+ @ManagedName("Lifespan")
+ @ManagedDescription("Maximum lifespan of a cache entry, after which the entry
is expired cluster-wide. -1 means the entries never expire.")
+ public long getLiveTime()
+ {
+ return cacheConfig.getExpirationLifespan();
+ }
+
+ @Managed
+ @ManagedName("MaxIdle")
+ @ManagedDescription("Maximum idle time a cache entry will be maintained in the
cache. If the idle time is exceeded, the entry will be expired cluster-wide. -1 means the
entries never expire.")
+ public long getMaxIdle()
+ {
+ return cacheConfig.getExpirationMaxIdle();
+ }
+
+ @Managed
+ @ManagedName("WakeUpInterval")
+ @ManagedDescription("Interval between subsequent eviction runs. If you wish to
disable the periodic eviction process altogether, set wakeupInterval to -1.")
+ public long getWakeUpInterval()
+ {
+ return cacheConfig.getEvictionWakeUpInterval();
+ }
+ }
+}
\ No newline at end of file
Added:
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/resources/conf/portal/cache-configuration-template.xml
===================================================================
---
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/resources/conf/portal/cache-configuration-template.xml
(rev 0)
+++
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/resources/conf/portal/cache-configuration-template.xml 2010-11-24
14:02:56 UTC (rev 3538)
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (C) 2010 eXo Platform SAS.
+
+ This is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this software; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+
+-->
+<infinispan
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:infinispan:config:4.0
http://www.infinispan.org/schemas/infinispan-config-4.0.xsd"
+ xmlns="urn:infinispan:config:4.0">
+ <global>
+ <asyncListenerExecutor
factory="org.infinispan.executors.DefaultExecutorFactory">
+ <properties>
+ <property name="maxThreads" value="1"/>
+ <property name="queueSize" value="100000"/>
+ <property name="threadNamePrefix"
value="AsyncListenerThread"/>
+ </properties>
+ </asyncListenerExecutor>
+ <asyncTransportExecutor
factory="org.infinispan.executors.DefaultExecutorFactory">
+ <properties>
+ <property name="threadNamePrefix"
value="AsyncSerializationThread"/>
+ </properties>
+ </asyncTransportExecutor>
+ <evictionScheduledExecutor
factory="org.infinispan.executors.DefaultScheduledExecutorFactory">
+ <properties>
+ <property name="threadNamePrefix"
value="EvictionThread"/>
+ </properties>
+ </evictionScheduledExecutor>
+ <replicationQueueScheduledExecutor
factory="org.infinispan.executors.DefaultScheduledExecutorFactory">
+ <properties>
+ <property name="threadNamePrefix"
value="ReplicationQueueThread"/>
+ </properties>
+ </replicationQueueScheduledExecutor>
+ <globalJmxStatistics jmxDomain="infinispan"
enabled="true"/>
+ <transport
transportClass="org.infinispan.remoting.transport.jgroups.JGroupsTransport"
clusterName="Infinispan-cluster" distributedSyncTimeout="20000">
+ <properties>
+ <property name="configurationFile"
value="flush-udp.xml"/>
+ </properties>
+ </transport>
+ <shutdown hookBehavior="DEFAULT"/>
+ </global>
+ <default>
+ <locking isolationLevel="READ_COMMITTED"
lockAcquisitionTimeout="10000" writeSkewCheck="false"
concurrencyLevel="500"/>
+ <transaction
transactionManagerLookupClass="org.infinispan.transaction.lookup.GenericTransactionManagerLookup"
syncRollbackPhase="false" syncCommitPhase="false"/>
+ <jmxStatistics enabled="true"/>
+ <invocationBatching enabled="true"/>
+ <clustering mode="replication">
+ <stateRetrieval timeout="20000"
fetchInMemoryState="false"/>
+ <sync replTimeout="20000"/>
+ </clustering>
+ </default>
+</infinispan>
\ No newline at end of file
Added:
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/resources/conf/portal/configuration.xml
===================================================================
---
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/resources/conf/portal/configuration.xml
(rev 0)
+++
kernel/trunk/exo.kernel.component.ext.cache.impl.infinispan.v4/src/main/resources/conf/portal/configuration.xml 2010-11-24
14:02:56 UTC (rev 3538)
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+
+ Copyright (C) 2009 eXo Platform SAS.
+
+ This is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this software; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+
+-->
+<configuration
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd
http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
+
xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">
+ <component>
+ <key>org.exoplatform.services.cache.ExoCacheFactory</key>
+
<type>org.exoplatform.services.cache.impl.infinispan.ExoCacheFactoryImpl</type>
+ <init-params>
+ <value-param>
+ <name>cache.config.template</name>
+ <value>jar:/conf/portal/cache-configuration-template.xml</value>
+ </value-param>
+ </init-params>
+ </component>
+</configuration>