exo-jcr SVN: r2806 - in jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr: impl/core/lock/jbosscache and 1 other directories.
by do-not-reply@jboss.org
Author: tolusha
Date: 2010-07-21 04:00:15 -0400 (Wed, 21 Jul 2010)
New Revision: 2806
Added:
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/AbstractCacheableLockManagerImpl.java
Modified:
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/InfinispanLockManagerImpl.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/infinispan/InfinispanCacheFactory.java
Log:
EXOJCR-831: add abstract class AbstractCacheableLockManagerImpl
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/InfinispanLockManagerImpl.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/InfinispanLockManagerImpl.java 2010-07-20 15:58:02 UTC (rev 2805)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/InfinispanLockManagerImpl.java 2010-07-21 08:00:15 UTC (rev 2806)
@@ -19,89 +19,52 @@
import org.exoplatform.container.configuration.ConfigurationManager;
import org.exoplatform.management.annotations.Managed;
-import org.exoplatform.management.annotations.ManagedDescription;
import org.exoplatform.management.jmx.annotations.NameTemplate;
import org.exoplatform.management.jmx.annotations.Property;
import org.exoplatform.services.jcr.config.MappedParametrizedObjectEntry;
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
import org.exoplatform.services.jcr.config.WorkspaceEntry;
-import org.exoplatform.services.jcr.dataflow.ChangesLogIterator;
-import org.exoplatform.services.jcr.dataflow.CompositeChangesLog;
-import org.exoplatform.services.jcr.dataflow.DataManager;
-import org.exoplatform.services.jcr.dataflow.ItemState;
-import org.exoplatform.services.jcr.dataflow.ItemStateChangesLog;
-import org.exoplatform.services.jcr.dataflow.PlainChangesLog;
-import org.exoplatform.services.jcr.dataflow.PlainChangesLogImpl;
-import org.exoplatform.services.jcr.dataflow.TransactionChangesLog;
-import org.exoplatform.services.jcr.dataflow.persistent.ItemsPersistenceListener;
-import org.exoplatform.services.jcr.datamodel.ItemData;
-import org.exoplatform.services.jcr.datamodel.NodeData;
-import org.exoplatform.services.jcr.datamodel.PropertyData;
-import org.exoplatform.services.jcr.datamodel.QPathEntry;
-import org.exoplatform.services.jcr.impl.Constants;
-import org.exoplatform.services.jcr.impl.core.SessionDataManager;
-import org.exoplatform.services.jcr.impl.core.lock.LockRemover;
-import org.exoplatform.services.jcr.impl.core.lock.SessionLockManager;
-import org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManager;
+import org.exoplatform.services.jcr.impl.core.lock.jbosscache.AbstractCacheableLockManagerImpl;
import org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableSessionLockManager;
import org.exoplatform.services.jcr.impl.core.lock.jbosscache.LockData;
-import org.exoplatform.services.jcr.impl.dataflow.TransientItemData;
-import org.exoplatform.services.jcr.impl.dataflow.TransientPropertyData;
import org.exoplatform.services.jcr.impl.dataflow.persistent.WorkspacePersistentDataManager;
-import org.exoplatform.services.jcr.impl.storage.JCRInvalidItemStateException;
import org.exoplatform.services.jcr.impl.storage.jdbc.DBConstants;
import org.exoplatform.services.jcr.impl.storage.jdbc.DialectDetecter;
import org.exoplatform.services.jcr.impl.util.io.PrivilegedCacheHelper;
import org.exoplatform.services.jcr.infinispan.InfinispanCacheFactory;
-import org.exoplatform.services.jcr.observation.ExtendedEvent;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.naming.InitialContextInitializer;
-import org.exoplatform.services.security.IdentityConstants;
import org.exoplatform.services.transaction.TransactionService;
import org.infinispan.Cache;
-import org.picocontainer.Startable;
import java.io.Serializable;
-import java.math.BigInteger;
import java.security.AccessController;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
import javax.jcr.RepositoryException;
import javax.jcr.lock.LockException;
import javax.naming.InitialContext;
import javax.sql.DataSource;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
+import javax.transaction.Transaction
/**
* @author <a href="anatoliy.bazko(a)exoplatform.org">Anatoliy Bazko</a>
- * @version $Id: InfinispanLockManagerImpl.java 111 2010-11-11 11:11:11Z tolusha $
+ * @version $Id$
*
*/
@Managed
@NameTemplate(@Property(key = "service", value = "lockmanager"))
-public class InfinispanLockManagerImpl implements CacheableLockManager, ItemsPersistenceListener, Startable
+public class InfinispanLockManagerImpl extends AbstractCacheableLockManagerImpl
{
/**
- * The name to property time out.
- */
- public static final String TIME_OUT = "time-out";
-
- /**
* The name to property cache configuration.
*/
public static final String INFINISPAN_JDBC_CL_DATASOURCE = "infinispan-cl-cache.jdbc.datasource";
@@ -115,44 +78,12 @@
public static final String INFINISPAN_JDBC_CL_AUTO = "auto";
/**
- * Default lock time out. 30min
- */
- public static final long DEFAULT_LOCK_TIMEOUT = 1000 * 60 * 30;
-
- /**
* Logger
*/
private final Log LOG = ExoLogger.getLogger("exo.jcr.component.core.InfinispanLockManagerImpl");
- /**
- * Data manager.
- */
- private final DataManager dataManager;
-
- /**
- * Run time lock time out.
- */
- private long lockTimeOut;
-
- /**
- * Lock remover thread.
- */
- private LockRemover lockRemover;
-
- /**
- * The current Transaction Manager
- */
- private TransactionManager tm;
-
private Cache<Serializable, Object> cache;
- // private final Fqn<String> lockRoot;
-
- /**
- * SessionLockManagers that uses this LockManager.
- */
- private Map<String, CacheableSessionLockManager> sessionLockManagers;
-
public InfinispanLockManagerImpl(WorkspacePersistentDataManager dataManager, WorkspaceEntry config,
InitialContextInitializer context, TransactionService transactionService, ConfigurationManager cfm)
throws RepositoryConfigurationException, RepositoryException
@@ -171,35 +102,11 @@
InitialContextInitializer context, TransactionManager transactionManager, ConfigurationManager cfm)
throws RepositoryConfigurationException, RepositoryException
{
- this.dataManager = dataManager;
+ super(dataManager, config, transactionManager);
- if (config.getLockManager() != null)
- {
- if (config.getLockManager().getParameters() != null
- && config.getLockManager().getParameterValue(TIME_OUT, null) != null)
- {
- long timeOut = config.getLockManager().getParameterTime(TIME_OUT);
- lockTimeOut = timeOut > 0 ? timeOut : DEFAULT_LOCK_TIMEOUT;
- }
- else
- {
- lockTimeOut =
- config.getLockManager().getTimeout() > 0 ? config.getLockManager().getTimeout() : DEFAULT_LOCK_TIMEOUT;
- }
- }
- else
- {
- lockTimeOut = DEFAULT_LOCK_TIMEOUT;
- }
-
- sessionLockManagers = new ConcurrentHashMap<String, CacheableSessionLockManager>();
- dataManager.addItemPersistenceListener(this);
-
// make cache
if (config.getLockManager() != null)
{
- this.tm = transactionManager;
-
// create cache using custom factory
InfinispanCacheFactory<Serializable, Object> factory = new InfinispanCacheFactory<Serializable, Object>(cfm);
@@ -218,6 +125,83 @@
{
throw new RepositoryConfigurationException("Cache configuration not found");
}
+
+ this.getNumLocks = new LockActionNonTxAware<Integer, Object>()
+ {
+ public Integer execute(Object arg)
+ {
+ return cache.size();
+ }
+ };
+
+ this.hasLocks = new LockActionNonTxAware<Boolean, Object>()
+ {
+ public Boolean execute(Object arg)
+ {
+ return !cache.isEmpty();
+ }
+ };
+
+ this.isLockLive = new LockActionNonTxAware<Boolean, String>()
+ {
+ public Boolean execute(String nodeId)
+ {
+ if (cache.get(nodeId) != null)
+ {
+ return true;
+ }
+
+ return false;
+ }
+ };
+
+ this.refresh = new LockActionNonTxAware<Object, LockData>()
+ {
+ public Object execute(LockData newLockData) throws LockException
+ {
+ Object oldValue = PrivilegedCacheHelper.putIfAbsent(cache, newLockData.getNodeIdentifier(), newLockData);
+ if (oldValue == null)
+ {
+ throw new LockException("Can't refresh lock for node " + newLockData.getNodeIdentifier()
+ + " since lock is not exist");
+ }
+ return null;
+ }
+ };
+
+ this.lockExist = new LockActionNonTxAware<Boolean, String>()
+ {
+ public Boolean execute(String nodeId) throws LockException
+ {
+ return cache.get(nodeId) != null;
+ }
+ };
+
+ this.getLockDataById = new LockActionNonTxAware<LockData, String>()
+ {
+ public LockData execute(String nodeId) throws LockException
+ {
+ return (LockData)cache.get(nodeId);
+ }
+ };
+
+ this.getLockList = new LockActionNonTxAware<List<LockData>, Object>()
+ {
+ public List<LockData> execute(Object arg) throws LockException
+ {
+ Collection<Object> datas = cache.values();
+
+ List<LockData> locksData = new ArrayList<LockData>();
+ for (Object lockData : datas)
+ {
+ if (lockData != null)
+ {
+ locksData.add((LockData)lockData);
+ }
+ }
+ return locksData;
+ }
+ };
}
/**
@@ -365,388 +349,23 @@
}
}
- @Managed
- @ManagedDescription("Remove the expired locks")
- public void cleanExpiredLocks()
- {
- removeExpired();
- }
-
- public long getDefaultLockTimeOut()
- {
- return lockTimeOut;
- }
-
- private final LockActionNonTxAware<Integer, Object> getNumLocks = new LockActionNonTxAware<Integer, Object>()
- {
- public Integer execute(Object arg)
- {
- return cache.size();
- }
- };
-
- @Managed
- @ManagedDescription("The number of active locks")
- public int getNumLocks()
- {
- try
- {
- return executeLockActionNonTxAware(getNumLocks, null);
- }
- catch (LockException e)
- {
- // ignore me will never occur
- }
- return -1;
- }
-
- private final LockActionNonTxAware<Boolean, Object> hasLocks = new LockActionNonTxAware<Boolean, Object>()
- {
- public Boolean execute(Object arg)
- {
- return !cache.isEmpty();
- }
- };
-
/**
- * Indicates if some locks have already been created
- */
- private boolean hasLocks()
- {
- try
- {
- return executeLockActionNonTxAware(hasLocks, null);
- }
- catch (LockException e)
- {
- // ignore me will never occur
- }
- return true;
- }
-
- /**
- * Return new instance of session lock manager.
- */
- public SessionLockManager getSessionLockManager(String sessionId, SessionDataManager transientManager)
- {
- CacheableSessionLockManager sessionManager = new CacheableSessionLockManager(sessionId, this, transientManager);
- sessionLockManagers.put(sessionId, sessionManager);
- return sessionManager;
- }
-
- private final LockActionNonTxAware<Boolean, String> isLockLive = new LockActionNonTxAware<Boolean, String>()
- {
- public Boolean execute(String nodeId)
- {
- if (cache.get(nodeId) != null) //pendingLocks.containsKey(nodeId) ||
- {
- return true;
- }
-
- return false;
- }
- };
-
- /**
- * Check is LockManager contains lock. No matter it is in pending or persistent state.
- *
- * @param nodeId - locked node id
- * @return
- */
- public boolean isLockLive(String nodeId) throws LockException
- {
- try
- {
- return executeLockActionNonTxAware(isLockLive, nodeId);
- }
- catch (LockException e)
- {
- // ignore me will never occur
- }
- return false;
- }
-
- /**
* {@inheritDoc}
*/
- public boolean isTXAware()
- {
- return true;
- }
-
- /*
- * (non-Javadoc)
- * @seeorg.exoplatform.services.jcr.dataflow.persistent.ItemsPersistenceListener#onSaveItems(org.
- * exoplatform.services.jcr.dataflow.ItemStateChangesLog)
- */
- public void onSaveItems(ItemStateChangesLog changesLog)
- {
- List<PlainChangesLog> chengesLogList = new ArrayList<PlainChangesLog>();
- if (changesLog instanceof TransactionChangesLog)
- {
- ChangesLogIterator logIterator = ((TransactionChangesLog)changesLog).getLogIterator();
-
- while (logIterator.hasNextLog())
- {
- chengesLogList.add(logIterator.nextLog());
- }
- }
- else if (changesLog instanceof PlainChangesLog)
- {
- chengesLogList.add((PlainChangesLog)changesLog);
- }
- else if (changesLog instanceof CompositeChangesLog)
- {
- for (ChangesLogIterator iter = ((CompositeChangesLog)changesLog).getLogIterator(); iter.hasNextLog();)
- {
- chengesLogList.add(iter.nextLog());
- }
- }
-
- List<LockOperationContainer> containers = new ArrayList<LockOperationContainer>();
-
- for (PlainChangesLog currChangesLog : chengesLogList)
- {
- String sessionId = currChangesLog.getSessionId();
-
- String nodeIdentifier;
- try
- {
- switch (currChangesLog.getEventType())
- {
- case ExtendedEvent.LOCK :
- if (currChangesLog.getSize() < 2)
- {
- LOG.error("Incorrect changes log of type ExtendedEvent.LOCK size=" + currChangesLog.getSize()
- + "<2 \n" + currChangesLog.dump());
- break;
- }
- nodeIdentifier = currChangesLog.getAllStates().get(0).getData().getParentIdentifier();
-
- CacheableSessionLockManager session = sessionLockManagers.get(sessionId);
- if (session != null && session.containsPendingLock(nodeIdentifier))
- {
- containers.add(new LockOperationContainer(nodeIdentifier, currChangesLog.getSessionId(),
- ExtendedEvent.LOCK));
- }
- else
- {
- LOG.error("Lock must exist in pending locks.");
- }
- break;
- case ExtendedEvent.UNLOCK :
- if (currChangesLog.getSize() < 2)
- {
- LOG.error("Incorrect changes log of type ExtendedEvent.UNLOCK size=" + currChangesLog.getSize()
- + "<2 \n" + currChangesLog.dump());
- break;
- }
-
- containers.add(new LockOperationContainer(currChangesLog.getAllStates().get(0).getData()
- .getParentIdentifier(), currChangesLog.getSessionId(), ExtendedEvent.UNLOCK));
- break;
- default :
- HashSet<String> removedLock = new HashSet<String>();
- for (ItemState itemState : currChangesLog.getAllStates())
- {
- // this is a node and node is locked
- if (itemState.getData().isNode() && lockExist(itemState.getData().getIdentifier()))
- {
- nodeIdentifier = itemState.getData().getIdentifier();
- if (itemState.isDeleted())
- {
- removedLock.add(nodeIdentifier);
- }
- else if (itemState.isAdded() || itemState.isRenamed() || itemState.isUpdated())
- {
- removedLock.remove(nodeIdentifier);
- }
- }
- }
- for (String identifier : removedLock)
- {
- containers.add(new LockOperationContainer(identifier, currChangesLog.getSessionId(),
- ExtendedEvent.UNLOCK));
- }
- break;
- }
- }
- catch (IllegalStateException e)
- {
- LOG.error(e.getLocalizedMessage(), e);
- }
- }
-
- // sort locking and unlocking operations to avoid deadlocks in Infinispan
- Collections.sort(containers);
- for (LockOperationContainer container : containers)
- {
- try
- {
- container.apply();
- }
- catch (LockException e)
- {
- LOG.error(e.getMessage(), e);
- }
- }
- }
-
- /**
- * Class containing operation type (LOCK or UNLOCK) and all the needed information like node uuid and session id.
- */
- private class LockOperationContainer implements Comparable<LockOperationContainer>
- {
-
- private String identifier;
-
- private String sessionId;
-
- private int type;
-
- /**
- * @param identifier node identifier
- * @param sessionId id of session
- * @param type ExtendedEvent type specifying the operation (LOCK or UNLOCK)
- */
- public LockOperationContainer(String identifier, String sessionId, int type)
- {
- super();
- this.identifier = identifier;
- this.sessionId = sessionId;
- this.type = type;
- }
-
- /**
- * @return node identifier
- */
- public String getIdentifier()
- {
- return identifier;
- }
-
- public void apply() throws LockException
- {
- // invoke internalLock in LOCK operation
- if (type == ExtendedEvent.LOCK)
- {
- internalLock(sessionId, identifier);
- }
- // invoke internalUnLock in UNLOCK operation
- else if (type == ExtendedEvent.UNLOCK)
- {
- internalUnLock(sessionId, identifier);
- }
- }
-
- /**
- * @see java.lang.Comparable#compareTo(java.lang.Object)
- */
- public int compareTo(LockOperationContainer o)
- {
- return identifier.compareTo(o.getIdentifier());
- }
- }
-
- private final LockActionNonTxAware<Object, LockData> refresh = new LockActionNonTxAware<Object, LockData>()
- {
- public Object execute(LockData newLockData) throws LockException
- {
- Object oldValue = PrivilegedCacheHelper.putIfAbsent(cache, newLockData.getNodeIdentifier(), newLockData);
- if (oldValue == null)
- {
- throw new LockException("Can't refresh lock for node " + newLockData.getNodeIdentifier()
- + " since lock is not exist");
- }
- return null;
- }
- };
-
- /**
- * Refreshed lock data in cache
- *
- * @param newLockData
- */
- public void refreshLockData(LockData newLockData) throws LockException
- {
- executeLockActionNonTxAware(refresh, newLockData);
- }
-
- /**
- * Remove expired locks. Used from LockRemover.
- */
- public synchronized void removeExpired()
- {
- final List<String> removeLockList = new ArrayList<String>();
-
- for (LockData lock : getLockList())
- {
- if (!lock.isSessionScoped() && lock.getTimeToDeath() < 0)
- {
- removeLockList.add(lock.getNodeIdentifier());
- }
- }
-
- Collections.sort(removeLockList);
-
- for (String rLock : removeLockList)
- {
- removeLock(rLock);
- }
- }
-
- /*
- * (non-Javadoc)
- * @see org.picocontainer.Startable#start()
- */
- public void start()
- {
- lockRemover = new LockRemover(this);
- }
-
- /*
- * (non-Javadoc)
- * @see org.picocontainer.Startable#stop()
- */
+ @Override
public void stop()
{
- lockRemover.halt();
- lockRemover.interrupt();
- sessionLockManagers.clear();
+ super.stop();
PrivilegedCacheHelper.stop(cache);
}
/**
- * Copy <code>PropertyData prop<code> to new TransientItemData
- *
- * @param prop
- * @return
- * @throws RepositoryException
+ * {@inheritDoc}
*/
- private TransientItemData copyItemData(PropertyData prop) throws RepositoryException
+ @Override
+ protected synchronized void internalLock(String sessionId, String nodeIdentifier) throws LockException
{
- if (prop == null)
- {
- return null;
- }
-
- // make a copy, value may be null for deleting items
- TransientPropertyData newData =
- new TransientPropertyData(prop.getQPath(), prop.getIdentifier(), prop.getPersistedVersion(), prop.getType(),
- prop.getParentIdentifier(), prop.isMultiValued(), prop.getValues());
-
- return newData;
- }
-
- /**
- * Internal lock
- *
- * @param nodeIdentifier
- * @throws LockException
- */
- private synchronized void internalLock(String sessionId, String nodeIdentifier) throws LockException
- {
CacheableSessionLockManager session = sessionLockManagers.get(sessionId);
if (session != null && session.containsPendingLock(nodeIdentifier))
{
@@ -770,13 +389,10 @@
}
/**
- * Internal unlock.
- *
- * @param sessionId
- * @param nodeIdentifier
- * @throws LockException
+ * {@inheritDoc}
*/
- private synchronized void internalUnLock(String sessionId, String nodeIdentifier) throws LockException
+ @Override
+ protected synchronized void internalUnLock(String sessionId, String nodeIdentifier) throws LockException
{
LockData lData = getLockDataById(nodeIdentifier);
@@ -791,306 +407,4 @@
}
}
}
-
- private final LockActionNonTxAware<Boolean, String> lockExist = new LockActionNonTxAware<Boolean, String>()
- {
- public Boolean execute(String nodeId) throws LockException
- {
- return cache.get(nodeId) != null;
- }
- };
-
- /**
- * {@inheritDoc}
- */
- public boolean lockExist(String nodeId)
- {
- try
- {
- return executeLockActionNonTxAware(lockExist, nodeId);
- }
- catch (LockException e)
- {
- // ignore me will never occur
- }
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- public String getLockTokenHash(String token)
- {
- String hash = "";
- try
- {
- MessageDigest m = MessageDigest.getInstance("MD5");
- m.update(token.getBytes(), 0, token.length());
- hash = new BigInteger(1, m.digest()).toString(16);
- }
- catch (NoSuchAlgorithmException e)
- {
- LOG.error("Can't get instanse of MD5 MessageDigest!", e);
- }
- return hash;
- }
-
- /**
- * {@inheritDoc}
- */
- public LockData getExactNodeOrCloseParentLock(NodeData node) throws RepositoryException
- {
- return getExactNodeOrCloseParentLock(node, true);
- }
-
- private LockData getExactNodeOrCloseParentLock(NodeData node, boolean checkHasLocks) throws RepositoryException
- {
-
- if (node == null || (checkHasLocks && !hasLocks()))
- {
- return null;
- }
- LockData retval = null;
- retval = getLockDataById(node.getIdentifier());
- if (retval == null)
- {
- NodeData parentData = (NodeData)dataManager.getItemData(node.getParentIdentifier());
- if (parentData != null)
- {
- retval = getExactNodeOrCloseParentLock(parentData, false);
- }
- }
- return retval;
- }
-
- /**
- * {@inheritDoc}
- */
- public LockData getExactNodeLock(NodeData node) throws RepositoryException
- {
- if (node == null || !hasLocks())
- {
- return null;
- }
-
- return getLockDataById(node.getIdentifier());
- }
-
- /**
- * {@inheritDoc}
- */
- public LockData getClosedChild(NodeData node) throws RepositoryException
- {
- return getClosedChild(node, true);
- }
-
- private LockData getClosedChild(NodeData node, boolean checkHasLocks) throws RepositoryException
- {
-
- if (node == null || (checkHasLocks && !hasLocks()))
- {
- return null;
- }
- LockData retval = null;
-
- List<NodeData> childData = dataManager.getChildNodesData(node);
- for (NodeData nodeData : childData)
- {
- retval = getLockDataById(nodeData.getIdentifier());
- if (retval != null)
- return retval;
- }
- // child not found try to find dipper
- for (NodeData nodeData : childData)
- {
- retval = getClosedChild(nodeData, false);
- if (retval != null)
- return retval;
- }
- return retval;
- }
-
- private final LockActionNonTxAware<LockData, String> getLockDataById = new LockActionNonTxAware<LockData, String>()
- {
- public LockData execute(String nodeId) throws LockException
- {
- return (LockData)cache.get(nodeId);
- }
- };
-
- protected LockData getLockDataById(String nodeId)
- {
- try
- {
- return executeLockActionNonTxAware(getLockDataById, nodeId);
- }
- catch (LockException e)
- {
- // ignore me will never occur
- }
- return null;
- }
-
- private final LockActionNonTxAware<List<LockData>, Object> getLockList =
- new LockActionNonTxAware<List<LockData>, Object>()
- {
- public List<LockData> execute(Object arg) throws LockException
- {
- Collection<Object> datas = cache.values();
-
- List<LockData> locksData = new ArrayList<LockData>();
- for (Object lockData : datas)
- {
- if (lockData != null)
- {
- locksData.add((LockData)lockData);
- }
- }
- return locksData;
- }
- };
-
- protected synchronized List<LockData> getLockList()
- {
- try
- {
- return executeLockActionNonTxAware(getLockList, null);
- }
- catch (LockException e)
- {
- // ignore me will never occur
- }
- return null;
- }
-
- /**
- * Remove lock, used by Lock remover.
- *
- * @param nodeIdentifier String
- */
- protected void removeLock(String nodeIdentifier)
- {
- try
- {
- NodeData nData = (NodeData)dataManager.getItemData(nodeIdentifier);
-
- //TODO EXOJCR-412, should be refactored in future.
- //Skip removing, because that node was removed in other node of cluster.
- if (nData == null)
- {
- return;
- }
-
- PlainChangesLog changesLog =
- new PlainChangesLogImpl(new ArrayList<ItemState>(), IdentityConstants.SYSTEM, ExtendedEvent.UNLOCK);
-
- ItemData lockOwner =
- copyItemData((PropertyData)dataManager.getItemData(nData, new QPathEntry(Constants.JCR_LOCKOWNER, 1)));
-
- //TODO EXOJCR-412, should be refactored in future.
- //Skip removing, because that lock was removed in other node of cluster.
- if (lockOwner == null)
- {
- return;
- }
-
- changesLog.add(ItemState.createDeletedState(lockOwner));
-
- ItemData lockIsDeep =
- copyItemData((PropertyData)dataManager.getItemData(nData, new QPathEntry(Constants.JCR_LOCKISDEEP, 1)));
-
- //TODO EXOJCR-412, should be refactored in future.
- //Skip removing, because that lock was removed in other node of cluster.
- if (lockIsDeep == null)
- {
- return;
- }
-
- changesLog.add(ItemState.createDeletedState(lockIsDeep));
-
- // lock probably removed by other thread
- if (lockOwner == null && lockIsDeep == null)
- {
- return;
- }
-
- dataManager.save(new TransactionChangesLog(changesLog));
- }
- catch (JCRInvalidItemStateException e)
- {
- //TODO EXOJCR-412, should be refactored in future.
- //Skip property not found in DB, because that lock property was removed in other node of cluster.
- if (LOG.isDebugEnabled())
- {
- LOG.debug("The propperty was removed in other node of cluster.", e);
- }
-
- }
- catch (RepositoryException e)
- {
- LOG.error("Error occur during removing lock" + e.getLocalizedMessage(), e);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void closeSessionLockManager(String sessionID)
- {
- sessionLockManagers.remove(sessionID);
- }
-
- /**
- * Execute the given action outside a transaction. This is needed since the {@link Cache} used by {@link InfinispanLockManagerImpl}
- * manages the persistence of its locks thanks to a {@link CacheLoader} and a {@link CacheLoader} lock the Infinispan cache {@link Node}
- * even for read operations which cause deadlock issue when a XA {@link Transaction} is already opened
- * @throws LockException when a exception occurs
- */
- private <R, A> R executeLockActionNonTxAware(LockActionNonTxAware<R, A> action, A arg) throws LockException
- {
- Transaction tx = null;
- try
- {
- if (tm != null)
- {
- try
- {
- tx = tm.suspend();
- }
- catch (Exception e)
- {
- LOG.warn("Cannot suspend the current transaction", e);
- }
- }
- return action.execute(arg);
- }
- finally
- {
- if (tx != null)
- {
- try
- {
- tm.resume(tx);
- }
- catch (Exception e)
- {
- LOG.warn("Cannot resume the current transaction", e);
- }
- }
- }
- }
-
- /**
- * Actions that are not supposed to be called within a transaction
- *
- * Created by The eXo Platform SAS
- * Author : Nicolas Filotto
- * nicolas.filotto(a)exoplatform.com
- * 21 janv. 2010
- */
- private static interface LockActionNonTxAware<R, A>
- {
- R execute(A arg) throws LockException;
- }
-
}
Property changes on: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/InfinispanLockManagerImpl.java
___________________________________________________________________
Name: svn:keywords
+ Id
Added: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/AbstractCacheableLockManagerImpl.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/AbstractCacheableLockManagerImpl.java (rev 0)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/AbstractCacheableLockManagerImpl.java 2010-07-21 08:00:15 UTC (rev 2806)
@@ -0,0 +1,775 @@
+/*
+ * Copyright (C) 2003-2010 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.impl.core.lock.jbosscache;
+
+import org.exoplatform.management.annotations.Managed;
+import org.exoplatform.management.annotations.ManagedDescription;
+import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.config.WorkspaceEntry;
+import org.exoplatform.services.jcr.dataflow.ChangesLogIterator;
+import org.exoplatform.services.jcr.dataflow.CompositeChangesLog;
+import org.exoplatform.services.jcr.dataflow.DataManager;
+import org.exoplatform.services.jcr.dataflow.ItemState;
+import org.exoplatform.services.jcr.dataflow.ItemStateChangesLog;
+import org.exoplatform.services.jcr.dataflow.PlainChangesLog;
+import org.exoplatform.services.jcr.dataflow.PlainChangesLogImpl;
+import org.exoplatform.services.jcr.dataflow.TransactionChangesLog;
+import org.exoplatform.services.jcr.dataflow.persistent.ItemsPersistenceListener;
+import org.exoplatform.services.jcr.datamodel.ItemData;
+import org.exoplatform.services.jcr.datamodel.NodeData;
+import org.exoplatform.services.jcr.datamodel.PropertyData;
+import org.exoplatform.services.jcr.datamodel.QPathEntry;
+import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.core.SessionDataManager;
+import org.exoplatform.services.jcr.impl.core.lock.LockRemover;
+import org.exoplatform.services.jcr.impl.core.lock.SessionLockManager;
+import org.exoplatform.services.jcr.impl.dataflow.TransientItemData;
+import org.exoplatform.services.jcr.impl.dataflow.TransientPropertyData;
+import org.exoplatform.services.jcr.impl.dataflow.persistent.WorkspacePersistentDataManager;
+import org.exoplatform.services.jcr.impl.storage.JCRInvalidItemStateException;
+import org.exoplatform.services.jcr.observation.ExtendedEvent;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+import org.exoplatform.services.security.IdentityConstants;
+import org.picocontainer.Startable;
+
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.lock.LockException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * <br/>Date:
+ *
+ * @author <a href="karpenko.sergiy(a)gmail.com">Karpenko Sergiy</a>
+ * @version $Id$
+ */
+public abstract class AbstractCacheableLockManagerImpl implements CacheableLockManager, ItemsPersistenceListener,
+ Startable
+{
+ /**
+ * The name to property time out.
+ */
+ public static final String TIME_OUT = "time-out";
+
+ /**
+ * Default lock time out. 30min
+ */
+ public static final long DEFAULT_LOCK_TIMEOUT = 1000 * 60 * 30;
+
+ /**
+ * Data manager.
+ */
+ protected final DataManager dataManager;
+
+ /**
+ * Run time lock time out.
+ */
+ protected long lockTimeOut;
+
+ /**
+ * Lock remover thread.
+ */
+ protected LockRemover lockRemover;
+
+ /**
+ * SessionLockManagers that uses this LockManager.
+ */
+ protected Map<String, CacheableSessionLockManager> sessionLockManagers;
+
+ /**
+ * The current Transaction Manager
+ */
+ protected TransactionManager tm;
+
+ /**
+ * Logger
+ */
+ private final Log LOG = ExoLogger.getLogger("exo.jcr.component.core.AbstractCacheableLockManagerImpl");
+
+ protected LockActionNonTxAware<Integer, Object> getNumLocks;
+
+ protected LockActionNonTxAware<Boolean, Object> hasLocks;
+
+ protected LockActionNonTxAware<Boolean, String> isLockLive;
+
+ protected LockActionNonTxAware<Object, LockData> refresh;
+
+ protected LockActionNonTxAware<Boolean, String> lockExist;
+
+ protected LockActionNonTxAware<LockData, String> getLockDataById;
+
+ protected LockActionNonTxAware<List<LockData>, Object> getLockList;
+
+ /**
+ * Constructor.
+ *
+ * @param dataManager - workspace persistent data manager
+ * @param config - workspace entry
+ * @param transactionManager
+ * the transaction manager
+ * @throws RepositoryConfigurationException
+ */
+ public AbstractCacheableLockManagerImpl(WorkspacePersistentDataManager dataManager, WorkspaceEntry config,
+ TransactionManager transactionManager) throws RepositoryConfigurationException
+ {
+ if (config.getLockManager() != null)
+ {
+ if (config.getLockManager().getParameters() != null
+ && config.getLockManager().getParameterValue(TIME_OUT, null) != null)
+ {
+ long timeOut = config.getLockManager().getParameterTime(TIME_OUT);
+ lockTimeOut = timeOut > 0 ? timeOut : DEFAULT_LOCK_TIMEOUT;
+ }
+ else
+ {
+ lockTimeOut =
+ config.getLockManager().getTimeout() > 0 ? config.getLockManager().getTimeout() : DEFAULT_LOCK_TIMEOUT;
+ }
+ }
+ else
+ {
+ lockTimeOut = DEFAULT_LOCK_TIMEOUT;
+ }
+
+ this.dataManager = dataManager;
+ this.sessionLockManagers = new ConcurrentHashMap<String, CacheableSessionLockManager>();
+ this.tm = transactionManager;
+
+ dataManager.addItemPersistenceListener(this);
+ }
+
+ @Managed
+ @ManagedDescription("Remove the expired locks")
+ public void cleanExpiredLocks()
+ {
+ removeExpired();
+ }
+
+ public long getDefaultLockTimeOut()
+ {
+ return lockTimeOut;
+ }
+
+ @Managed
+ @ManagedDescription("The number of active locks")
+ public int getNumLocks()
+ {
+ try
+ {
+ return executeLockActionNonTxAware(getNumLocks, null);
+ }
+ catch (LockException e)
+ {
+ // ignore me will never occur
+ }
+ return -1;
+ }
+
+ /**
+ * Indicates if some locks have already been created
+ */
+ protected boolean hasLocks()
+ {
+ try
+ {
+ return executeLockActionNonTxAware(hasLocks, null);
+ }
+ catch (LockException e)
+ {
+ // ignore me will never occur
+ }
+ return true;
+ }
+
+ /**
+ * Return new instance of session lock manager.
+ */
+ public SessionLockManager getSessionLockManager(String sessionId, SessionDataManager transientManager)
+ {
+ CacheableSessionLockManager sessionManager = new CacheableSessionLockManager(sessionId, this, transientManager);
+ sessionLockManagers.put(sessionId, sessionManager);
+ return sessionManager;
+ }
+
+ /**
+ * Check is LockManager contains lock. No matter it is in pending or persistent state.
+ *
+ * @param nodeId - locked node id
+ * @return
+ */
+ public boolean isLockLive(String nodeId) throws LockException
+ {
+ try
+ {
+ return executeLockActionNonTxAware(isLockLive, nodeId);
+ }
+ catch (LockException e)
+ {
+ // ignore me will never occur
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isTXAware()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void onSaveItems(ItemStateChangesLog changesLog)
+ {
+ List<PlainChangesLog> chengesLogList = new ArrayList<PlainChangesLog>();
+ if (changesLog instanceof TransactionChangesLog)
+ {
+ ChangesLogIterator logIterator = ((TransactionChangesLog)changesLog).getLogIterator();
+
+ while (logIterator.hasNextLog())
+ {
+ chengesLogList.add(logIterator.nextLog());
+ }
+ }
+ else if (changesLog instanceof PlainChangesLog)
+ {
+ chengesLogList.add((PlainChangesLog)changesLog);
+ }
+ else if (changesLog instanceof CompositeChangesLog)
+ {
+ for (ChangesLogIterator iter = ((CompositeChangesLog)changesLog).getLogIterator(); iter.hasNextLog();)
+ {
+ chengesLogList.add(iter.nextLog());
+ }
+ }
+
+ List<LockOperationContainer> containers = new ArrayList<LockOperationContainer>();
+
+ for (PlainChangesLog currChangesLog : chengesLogList)
+ {
+ String sessionId = currChangesLog.getSessionId();
+
+ String nodeIdentifier;
+ try
+ {
+ switch (currChangesLog.getEventType())
+ {
+ case ExtendedEvent.LOCK :
+ if (currChangesLog.getSize() < 2)
+ {
+ LOG.error("Incorrect changes log of type ExtendedEvent.LOCK size=" + currChangesLog.getSize()
+ + "<2 \n" + currChangesLog.dump());
+ break;
+ }
+ nodeIdentifier = currChangesLog.getAllStates().get(0).getData().getParentIdentifier();
+
+ CacheableSessionLockManager session = sessionLockManagers.get(sessionId);
+ if (session != null && session.containsPendingLock(nodeIdentifier))
+ {
+ containers.add(new LockOperationContainer(nodeIdentifier, currChangesLog.getSessionId(),
+ ExtendedEvent.LOCK));
+ }
+ else
+ {
+ LOG.error("Lock must exist in pending locks.");
+ }
+ break;
+ case ExtendedEvent.UNLOCK :
+ if (currChangesLog.getSize() < 2)
+ {
+ LOG.error("Incorrect changes log of type ExtendedEvent.UNLOCK size=" + currChangesLog.getSize()
+ + "<2 \n" + currChangesLog.dump());
+ break;
+ }
+
+ containers.add(new LockOperationContainer(currChangesLog.getAllStates().get(0).getData()
+ .getParentIdentifier(), currChangesLog.getSessionId(), ExtendedEvent.UNLOCK));
+ break;
+ default :
+ HashSet<String> removedLock = new HashSet<String>();
+ for (ItemState itemState : currChangesLog.getAllStates())
+ {
+ // this is a node and node is locked
+ if (itemState.getData().isNode() && lockExist(itemState.getData().getIdentifier()))
+ {
+ nodeIdentifier = itemState.getData().getIdentifier();
+ if (itemState.isDeleted())
+ {
+ removedLock.add(nodeIdentifier);
+ }
+ else if (itemState.isAdded() || itemState.isRenamed() || itemState.isUpdated())
+ {
+ removedLock.remove(nodeIdentifier);
+ }
+ }
+ }
+ for (String identifier : removedLock)
+ {
+ containers.add(new LockOperationContainer(identifier, currChangesLog.getSessionId(),
+ ExtendedEvent.UNLOCK));
+ }
+ break;
+ }
+ }
+ catch (IllegalStateException e)
+ {
+ LOG.error(e.getLocalizedMessage(), e);
+ }
+ }
+
+ // sort locking and unlocking operations to avoid deadlocks
+ Collections.sort(containers);
+ for (LockOperationContainer container : containers)
+ {
+ try
+ {
+ container.apply();
+ }
+ catch (LockException e)
+ {
+ LOG.error(e.getMessage(), e);
+ }
+ }
+ }
+
+ /**
+ * Class containing operation type (LOCK or UNLOCK) and all the needed information like node uuid and session id.
+ */
+ private class LockOperationContainer implements Comparable<LockOperationContainer>
+ {
+
+ private String identifier;
+
+ private String sessionId;
+
+ private int type;
+
+ /**
+ * @param identifier node identifier
+ * @param sessionId id of session
+ * @param type ExtendedEvent type specifying the operation (LOCK or UNLOCK)
+ */
+ public LockOperationContainer(String identifier, String sessionId, int type)
+ {
+ super();
+ this.identifier = identifier;
+ this.sessionId = sessionId;
+ this.type = type;
+ }
+
+ /**
+ * @return node identifier
+ */
+ public String getIdentifier()
+ {
+ return identifier;
+ }
+
+ public void apply() throws LockException
+ {
+ // invoke internalLock in LOCK operation
+ if (type == ExtendedEvent.LOCK)
+ {
+ internalLock(sessionId, identifier);
+ }
+ // invoke internalUnLock in UNLOCK operation
+ else if (type == ExtendedEvent.UNLOCK)
+ {
+ internalUnLock(sessionId, identifier);
+ }
+ }
+
+ /**
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ public int compareTo(LockOperationContainer o)
+ {
+ return identifier.compareTo(o.getIdentifier());
+ }
+ }
+
+ /**
+ * Refreshed lock data in cache
+ *
+ * @param newLockData
+ */
+ public void refreshLockData(LockData newLockData) throws LockException
+ {
+ executeLockActionNonTxAware(refresh, newLockData);
+ }
+
+ /**
+ * Remove expired locks. Used from LockRemover.
+ */
+ public synchronized void removeExpired()
+ {
+ final List<String> removeLockList = new ArrayList<String>();
+
+ for (LockData lock : getLockList())
+ {
+ if (!lock.isSessionScoped() && lock.getTimeToDeath() < 0)
+ {
+ removeLockList.add(lock.getNodeIdentifier());
+ }
+ }
+
+ Collections.sort(removeLockList);
+
+ for (String rLock : removeLockList)
+ {
+ removeLock(rLock);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void start()
+ {
+ lockRemover = new LockRemover(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void stop()
+ {
+ lockRemover.halt();
+ lockRemover.interrupt();
+ sessionLockManagers.clear();
+ }
+
+ /**
+ * Copy <code>PropertyData prop<code> to new TransientItemData
+ *
+ * @param prop
+ * @return
+ * @throws RepositoryException
+ */
+ protected TransientItemData copyItemData(PropertyData prop) throws RepositoryException
+ {
+ if (prop == null)
+ {
+ return null;
+ }
+
+ // make a copy, value may be null for deleting items
+ TransientPropertyData newData =
+ new TransientPropertyData(prop.getQPath(), prop.getIdentifier(), prop.getPersistedVersion(), prop.getType(),
+ prop.getParentIdentifier(), prop.isMultiValued(), prop.getValues());
+
+ return newData;
+ }
+
+ /**
+ * Internal lock
+ *
+ * @param nodeIdentifier
+ * @throws LockException
+ */
+ protected abstract void internalLock(String sessionId, String nodeIdentifier) throws LockException;
+
+ /**
+ * Internal unlock.
+ *
+ * @param sessionId
+ * @param nodeIdentifier
+ * @throws LockException
+ */
+ protected abstract void internalUnLock(String sessionId, String nodeIdentifier) throws LockException;
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean lockExist(String nodeId)
+ {
+ try
+ {
+ return executeLockActionNonTxAware(lockExist, nodeId);
+ }
+ catch (LockException e)
+ {
+ // ignore me will never occur
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getLockTokenHash(String token)
+ {
+ String hash = "";
+ try
+ {
+ MessageDigest m = MessageDigest.getInstance("MD5");
+ m.update(token.getBytes(), 0, token.length());
+ hash = new BigInteger(1, m.digest()).toString(16);
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ LOG.error("Can't get instanse of MD5 MessageDigest!", e);
+ }
+ return hash;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public LockData getExactNodeOrCloseParentLock(NodeData node) throws RepositoryException
+ {
+ return getExactNodeOrCloseParentLock(node, true);
+ }
+
+ private LockData getExactNodeOrCloseParentLock(NodeData node, boolean checkHasLocks) throws RepositoryException
+ {
+
+ if (node == null || (checkHasLocks && !hasLocks()))
+ {
+ return null;
+ }
+ LockData retval = null;
+ retval = getLockDataById(node.getIdentifier());
+ if (retval == null)
+ {
+ NodeData parentData = (NodeData)dataManager.getItemData(node.getParentIdentifier());
+ if (parentData != null)
+ {
+ retval = getExactNodeOrCloseParentLock(parentData, false);
+ }
+ }
+ return retval;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public LockData getExactNodeLock(NodeData node) throws RepositoryException
+ {
+ if (node == null || !hasLocks())
+ {
+ return null;
+ }
+
+ return getLockDataById(node.getIdentifier());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public LockData getClosedChild(NodeData node) throws RepositoryException
+ {
+ return getClosedChild(node, true);
+ }
+
+ private LockData getClosedChild(NodeData node, boolean checkHasLocks) throws RepositoryException
+ {
+
+ if (node == null || (checkHasLocks && !hasLocks()))
+ {
+ return null;
+ }
+ LockData retval = null;
+
+ List<NodeData> childData = dataManager.getChildNodesData(node);
+ for (NodeData nodeData : childData)
+ {
+ retval = getLockDataById(nodeData.getIdentifier());
+ if (retval != null)
+ return retval;
+ }
+ // child not found try to find dipper
+ for (NodeData nodeData : childData)
+ {
+ retval = getClosedChild(nodeData, false);
+ if (retval != null)
+ return retval;
+ }
+ return retval;
+ }
+
+ protected LockData getLockDataById(String nodeId)
+ {
+ try
+ {
+ return executeLockActionNonTxAware(getLockDataById, nodeId);
+ }
+ catch (LockException e)
+ {
+ // ignore me will never occur
+ }
+ return null;
+ }
+
+ protected synchronized List<LockData> getLockList()
+ {
+ try
+ {
+ return executeLockActionNonTxAware(getLockList, null);
+ }
+ catch (LockException e)
+ {
+ // ignore me will never occur
+ }
+ return null;
+ }
+
+ /**
+ * Remove lock, used by Lock remover.
+ *
+ * @param nodeIdentifier String
+ */
+ protected void removeLock(String nodeIdentifier)
+ {
+ try
+ {
+ NodeData nData = (NodeData)dataManager.getItemData(nodeIdentifier);
+
+ //TODO EXOJCR-412, should be refactored in future.
+ //Skip removing, because that node was removed in other node of cluster.
+ if (nData == null)
+ {
+ return;
+ }
+
+ PlainChangesLog changesLog =
+ new PlainChangesLogImpl(new ArrayList<ItemState>(), IdentityConstants.SYSTEM, ExtendedEvent.UNLOCK);
+
+ ItemData lockOwner =
+ copyItemData((PropertyData)dataManager.getItemData(nData, new QPathEntry(Constants.JCR_LOCKOWNER, 1)));
+
+ //TODO EXOJCR-412, should be refactored in future.
+ //Skip removing, because that lock was removed in other node of cluster.
+ if (lockOwner == null)
+ {
+ return;
+ }
+
+ changesLog.add(ItemState.createDeletedState(lockOwner));
+
+ ItemData lockIsDeep =
+ copyItemData((PropertyData)dataManager.getItemData(nData, new QPathEntry(Constants.JCR_LOCKISDEEP, 1)));
+
+ //TODO EXOJCR-412, should be refactored in future.
+ //Skip removing, because that lock was removed in other node of cluster.
+ if (lockIsDeep == null)
+ {
+ return;
+ }
+
+ changesLog.add(ItemState.createDeletedState(lockIsDeep));
+
+ // lock probably removed by other thread
+ if (lockOwner == null && lockIsDeep == null)
+ {
+ return;
+ }
+
+ dataManager.save(new TransactionChangesLog(changesLog));
+ }
+ catch (JCRInvalidItemStateException e)
+ {
+ //TODO EXOJCR-412, should be refactored in future.
+ //Skip property not found in DB, because that lock property was removed in other node of cluster.
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("The propperty was removed in other node of cluster.", e);
+ }
+
+ }
+ catch (RepositoryException e)
+ {
+ LOG.error("Error occur during removing lock" + e.getLocalizedMessage(), e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void closeSessionLockManager(String sessionID)
+ {
+ sessionLockManagers.remove(sessionID);
+ }
+
+ /**
+ * Execute the given action outside a transaction. This is needed since the {@link Cache} used by {@link CacheableLockManagerImpl}
+ * manages the persistence of its locks thanks to a {@link CacheLoader} and a {@link CacheLoader} lock the JBoss cache {@link Node}
+ * even for read operations which cause deadlock issue when a XA {@link Transaction} is already opened
+ * @throws LockException when a exception occurs
+ */
+ private <R, A> R executeLockActionNonTxAware(LockActionNonTxAware<R, A> action, A arg) throws LockException
+ {
+ Transaction tx = null;
+ try
+ {
+ if (tm != null)
+ {
+ try
+ {
+ tx = tm.suspend();
+ }
+ catch (Exception e)
+ {
+ LOG.warn("Cannot suspend the current transaction", e);
+ }
+ }
+ return action.execute(arg);
+ }
+ finally
+ {
+ if (tx != null)
+ {
+ try
+ {
+ tm.resume(tx);
+ }
+ catch (Exception e)
+ {
+ LOG.warn("Cannot resume the current transaction", e);
+ }
+ }
+ }
+ }
+
+ /**
+ * Actions that are not supposed to be called within a transaction
+ *
+ * Created by The eXo Platform SAS
+ * Author : Nicolas Filotto
+ * nicolas.filotto(a)exoplatform.com
+ * 21 janv. 2010
+ */
+ protected static interface LockActionNonTxAware<R, A>
+ {
+ R execute(A arg) throws LockException;
+ }
+}
Property changes on: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/AbstractCacheableLockManagerImpl.java
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/infinispan/InfinispanCacheFactory.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/infinispan/InfinispanCacheFactory.java 2010-07-20 15:58:02 UTC (rev 2805)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/infinispan/InfinispanCacheFactory.java 2010-07-21 08:00:15 UTC (rev 2806)
@@ -44,7 +44,7 @@
* in Infinispan (this is highly recommended by RH specialists).
*
* @author <a href="mailto:nikolazius@gmail.com">Nikolay Zamosenchuk</a>
- * @version $Id: ExoCacheFactoryImpl.java 34360 2009-07-22 23:58:59Z nzamosenchuk $
+ * @version $Id$
*
*/
public class InfinispanCacheFactory<K, V>
Property changes on: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/infinispan/InfinispanCacheFactory.java
___________________________________________________________________
Name: svn:keywords
+ Id
14 years, 2 months
exo-jcr SVN: r2805 - jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy.
by do-not-reply@jboss.org
Author: aparfonov
Date: 2010-07-20 11:58:02 -0400 (Tue, 20 Jul 2010)
New Revision: 2805
Modified:
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyScript2RestLoader.java
Log:
EXOJCR-864
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyScript2RestLoader.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyScript2RestLoader.java 2010-07-20 14:57:30 UTC (rev 2804)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/script/groovy/GroovyScript2RestLoader.java 2010-07-20 15:58:02 UTC (rev 2805)
@@ -1253,109 +1253,12 @@
}
}
- // @POST
- // @Path("load/development/{repository}/{workspace}/{path:.*}")
- // @RolesAllowed({"developers"})
- // public Response loadDevelopment(@PathParam("repository") String repository,
- // @PathParam("workspace") String workspace, @PathParam("path") String path,
- // @DefaultValue("true") @QueryParam("state") boolean state, @Context SecurityContext security,
- // MultivaluedMap<String, String> properties)
- // {
- // if (state)
- // {
- // return loadResource(repository, workspace, path, security, properties == null ? new MultivaluedMapImpl()
- // : properties);
- // }
- // return unloadResource(repository, workspace, path, security);
- // }
+ @Deprecated
+ public Response load(String repository, String workspace, String path, boolean state)
+ {
+ return load(repository, workspace, path, state, null);
+ }
- // /**
- // * @param repository JCR repository
- // * @param workspace JCR workspace
- // * @param path path to script
- // * @param security see {@link SecurityContext}
- // * @param properties resource properties
- // * @return response with corresponded status and info
- // */
- // private Response loadResource(String repository, String workspace, String path, SecurityContext security,
- // MultivaluedMap<String, String> properties)
- // {
- // Session ses = null;
- // try
- // {
- // ses =
- // sessionProviderService.getSessionProvider(null).getSession(workspace,
- // repositoryService.getRepository(repository));
- // Node script = ((Node)ses.getItem("/" + path)).getNode("jcr:content");
- // ResourceId key = new NodeScriptKey(repository, workspace, script);
- // groovyPublisher.unpublishResource(key, security);
- // groovyPublisher.publishPerRequest(script.getProperty("jcr:data").getStream(), key, properties, security);
- // return Response.status(Response.Status.NO_CONTENT).build();
- // }
- // catch (PathNotFoundException e)
- // {
- // String msg = "Path " + path + " does not exists";
- // LOG.error(msg);
- // return Response.status(Response.Status.NOT_FOUND).entity(msg).type(MediaType.TEXT_PLAIN).build();
- // }
- // catch (ResourcePublicationException e)
- // {
- // return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).type(MediaType.TEXT_PLAIN).build();
- // }
- // catch (Exception e)
- // {
- // LOG.error(e.getMessage(), e);
- // return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.getMessage())
- // .type(MediaType.TEXT_PLAIN).build();
- // }
- // finally
- // {
- // if (ses != null)
- // {
- // ses.logout();
- // }
- // }
- // }
- //
- // private Response unloadResource(String repository, String workspace, String path, SecurityContext security)
- // {
- // Session ses = null;
- // try
- // {
- // ses =
- // sessionProviderService.getSessionProvider(null).getSession(workspace,
- // repositoryService.getRepository(repository));
- // Node script = ((Node)ses.getItem("/" + path)).getNode("jcr:content");
- // ResourceId key = new NodeScriptKey(repository, workspace, script);
- // if (null == groovyPublisher.unpublishResource(key, security))
- // {
- // return Response.status(Response.Status.BAD_REQUEST).entity(
- // "Can't unbind script " + path + ", not bound or has wrong mapping to the resource class ").type(
- // MediaType.TEXT_PLAIN).build();
- // }
- // return Response.status(Response.Status.NO_CONTENT).build();
- // }
- // catch (PathNotFoundException e)
- // {
- // String msg = "Path " + path + " does not exists";
- // LOG.error(msg);
- // return Response.status(Response.Status.NOT_FOUND).entity(msg).type(MediaType.TEXT_PLAIN).build();
- // }
- // catch (Exception e)
- // {
- // LOG.error(e.getMessage(), e);
- // return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.getMessage())
- // .type(MediaType.TEXT_PLAIN).build();
- // }
- // finally
- // {
- // if (ses != null)
- // {
- // ses.logout();
- // }
- // }
- // }
-
/**
* Returns the list of all groovy-scripts found in workspace.
*
14 years, 2 months
exo-jcr SVN: r2804 - in jcr/branches/1.14-ISPN/exo.jcr.component.core/src: main/java/org/exoplatform/services/jcr/infinispan and 1 other directories.
by do-not-reply@jboss.org
Author: tolusha
Date: 2010-07-20 10:57:30 -0400 (Tue, 20 Jul 2010)
New Revision: 2804
Modified:
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/InfinispanLockManagerImpl.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/infinispan/InfinispanCacheFactory.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-infinispan.xml
Log:
EXOJCR-831: first lock impl on Infinispan Test passed.
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/InfinispanLockManagerImpl.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/InfinispanLockManagerImpl.java 2010-07-20 13:06:41 UTC (rev 2803)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/InfinispanLockManagerImpl.java 2010-07-20 14:57:30 UTC (rev 2804)
@@ -22,7 +22,6 @@
import org.exoplatform.management.annotations.ManagedDescription;
import org.exoplatform.management.jmx.annotations.NameTemplate;
import org.exoplatform.management.jmx.annotations.Property;
-import org.exoplatform.services.jcr.access.SystemIdentity;
import org.exoplatform.services.jcr.config.MappedParametrizedObjectEntry;
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
import org.exoplatform.services.jcr.config.WorkspaceEntry;
@@ -44,7 +43,6 @@
import org.exoplatform.services.jcr.impl.core.lock.LockRemover;
import org.exoplatform.services.jcr.impl.core.lock.SessionLockManager;
import org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManager;
-import org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl;
import org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableSessionLockManager;
import org.exoplatform.services.jcr.impl.core.lock.jbosscache.LockData;
import org.exoplatform.services.jcr.impl.dataflow.TransientItemData;
@@ -59,6 +57,7 @@
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.naming.InitialContextInitializer;
+import org.exoplatform.services.security.IdentityConstants;
import org.exoplatform.services.transaction.TransactionService;
import org.infinispan.Cache;
import org.picocontainer.Startable;
@@ -123,7 +122,7 @@
/**
* Logger
*/
- private final Log LOG = ExoLogger.getLogger("exo.jcr.component.core.CacheableLockManagerImpl");
+ private final Log LOG = ExoLogger.getLogger("exo.jcr.component.core.InfinispanLockManagerImpl");
/**
* Data manager.
@@ -202,8 +201,7 @@
this.tm = transactionManager;
// create cache using custom factory
- InfinispanCacheFactory<Serializable, Object> factory =
- new InfinispanCacheFactory<Serializable, Object>(cfm, transactionManager);
+ InfinispanCacheFactory<Serializable, Object> factory = new InfinispanCacheFactory<Serializable, Object>(cfm);
// configure cache loader parameters with correct DB data-types
configureJDBCCacheLoader(config.getLockManager());
@@ -213,10 +211,6 @@
// Add the cache loader needed to prevent TimeoutException
// addCacheLoader();
- PrivilegedCacheHelper.start(cache);
-
- // createStructuredNode(lockRoot);
-
// Context recall is a workaround of JDBCCacheLoader starting.
context.recall();
}
@@ -319,6 +313,7 @@
{
// Oracle suggests the use VARCHAR2 instead of VARCHAR while declaring data type.
charType = "VARCHAR2(512)";
+ timeStampType = "NUMBER(19, 0)";
}
// POSTGRE SQL
else if (dialect.equals(DBConstants.DB_DIALECT_PGSQL))
@@ -582,7 +577,7 @@
}
}
- // sort locking and unlocking operations to avoid deadlocks in JBossCache
+ // sort locking and unlocking operations to avoid deadlocks in Infinispan
Collections.sort(containers);
for (LockOperationContainer container : containers)
{
@@ -987,7 +982,7 @@
}
PlainChangesLog changesLog =
- new PlainChangesLogImpl(new ArrayList<ItemState>(), SystemIdentity.SYSTEM, ExtendedEvent.UNLOCK);
+ new PlainChangesLogImpl(new ArrayList<ItemState>(), IdentityConstants.SYSTEM, ExtendedEvent.UNLOCK);
ItemData lockOwner =
copyItemData((PropertyData)dataManager.getItemData(nData, new QPathEntry(Constants.JCR_LOCKOWNER, 1)));
@@ -1046,8 +1041,8 @@
}
/**
- * Execute the given action outside a transaction. This is needed since the {@link Cache} used by {@link CacheableLockManagerImpl}
- * manages the persistence of its locks thanks to a {@link CacheLoader} and a {@link CacheLoader} lock the JBoss cache {@link Node}
+ * Execute the given action outside a transaction. This is needed since the {@link Cache} used by {@link InfinispanLockManagerImpl}
+ * manages the persistence of its locks thanks to a {@link CacheLoader} and a {@link CacheLoader} lock the Infinispan cache {@link Node}
* even for read operations which cause deadlock issue when a XA {@link Transaction} is already opened
* @throws LockException when a exception occurs
*/
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/infinispan/InfinispanCacheFactory.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/infinispan/InfinispanCacheFactory.java 2010-07-20 13:06:41 UTC (rev 2803)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/infinispan/InfinispanCacheFactory.java 2010-07-20 14:57:30 UTC (rev 2804)
@@ -33,18 +33,15 @@
import java.security.AccessController;
import java.security.PrivilegedAction;
-import javax.transaction.TransactionManager;
-
/**
- * Factory that creates pre-configured instances of Infinispan, without starting it.
- * Path to Infinispan configuration or template should be provided as
- * "infinispan-configuration" property in parameterEntry instance. If
- * transaction manager is configure in InfinispanCacheFactory, then it
- * is injected into the cache instance.
+ * Factory that creates and starts pre-configured instances of Infinispan.
+ * Path to Infinispan configuration or template and cache name should be
+ * provided as "infinispan-configuration" and "infinispan-cache-name" properties
+ * in parameterEntry instance respectively.
* <br>
* If parameterEntry has "jgroups-multiplexer-stack" (=true) and
* "jgroups-configuration" parameters then Multiplexing stack is enabled
- * in JBossCache (this is highly recommended by RH specialists).
+ * in Infinispan (this is highly recommended by RH specialists).
*
* @author <a href="mailto:nikolazius@gmail.com">Nikolay Zamosenchuk</a>
* @version $Id: ExoCacheFactoryImpl.java 34360 2009-07-22 23:58:59Z nzamosenchuk $
@@ -63,8 +60,6 @@
private final TemplateConfigurationHelper configurationHelper;
- private final TransactionManager transactionManager;
-
private ConfigurationManager configurationManager;
private final Log log = ExoLogger.getLogger("exo.jcr.component.core.InfinispanCacheFactory");
@@ -74,40 +69,27 @@
* Transaction manager will later be injected to cache instance.
*
* @param configurationManager
- * @param transactionManager
*/
- public InfinispanCacheFactory(ConfigurationManager configurationManager, TransactionManager transactionManager)
+ public InfinispanCacheFactory(ConfigurationManager configurationManager)
{
this.configurationManager = configurationManager;
this.configurationHelper = TemplateConfigurationHelper.createJBossCacheHelper(configurationManager);
- this.transactionManager = transactionManager;
}
/**
- * Creates InfinispanCacheFactory with provided configuration manager and without transaction manager.
- *
- * @param configurationManager
- */
- public InfinispanCacheFactory(ConfigurationManager configurationManager)
- {
- this(configurationManager, null);
- }
-
- /**
- * Creates pre-configured instance of Infinispan, without starting it.
- * Path to Infinispan configuration or template should be provided as
- * "jbosscache-configuration" property in parameterEntry instance. If
- * transaction manager is configure in ExoJBossCacheFactory, then it
- * is injected into the cache instance.
- * <br>
- * If parameterEntry has "jgroups-multiplexer-stack" (=true) and
- * "jgroups-configuration" parameters then Multiplexing stack is enabled
- * in JBossCache (this is highly recommended by RH specialists).
- *
- * @param parameterEntry
- * @return
- * @throws RepositoryConfigurationException
- */
+ * Factory that creates and starts pre-configured instances of Infinispan.
+ * Path to Infinispan configuration or template and cache name should be
+ * provided as "infinispan-configuration" and "infinispan-cache-name" properties
+ * in parameterEntry instance respectively.
+ * <br>
+ * If parameterEntry has "jgroups-multiplexer-stack" (=true) and
+ * "jgroups-configuration" parameters then Multiplexing stack is enabled
+ * in Infinispan (this is highly recommended by RH specialists)
+ *
+ * @param parameterEntry
+ * @return
+ * @throws RepositoryConfigurationException
+ */
public Cache<K, V> createCache(MappedParametrizedObjectEntry parameterEntry) throws RepositoryConfigurationException
{
// get Infinispan configuration file path and cache name
@@ -147,12 +129,6 @@
};
Cache<K, V> cache = AccessController.doPrivileged(action);
- // inject transaction manager if defined
- // if (transactionManager != null)
- // {
- // cache.getConfiguration().getRuntimeConfig().setTransactionManager(transactionManager);
- // }
-
// JGroups multiplexer configuration if enabled
// if (parameterEntry.getParameterBoolean(JGROUPS_MUX_ENABLED, false))
// {
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-infinispan.xml
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-infinispan.xml 2010-07-20 13:06:41 UTC (rev 2803)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-infinispan.xml 2010-07-20 14:57:30 UTC (rev 2804)
@@ -1,9 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
<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>
+ <globalJmxStatistics jmxDomain="infinispan" enabled="true" allowDuplicateDomains="true"/>
+ </global>
+
+ <default>
+ <locking isolationLevel="READ_COMMITTED" lockAcquisitionTimeout="20000" writeSkewCheck="false" concurrencyLevel="500"/>
+ <transaction transactionManagerLookupClass="org.infinispan.transaction.lookup.JBossStandaloneJTAManagerLookup" syncRollbackPhase="false" syncCommitPhase="false"/>
+ <jmxStatistics enabled="true"/>
+ <deadlockDetection enabled="true" spinDuration="100"/>
+ </default>
+
<namedCache name="lockCache">
<loaders passivation="false" shared="true" preload="true">
<loader class="org.infinispan.loaders.jdbc.stringbased.JdbcStringBasedCacheStore" fetchPersistentState="false" ignoreModifications="false" purgeOnStartup="false">
14 years, 2 months
exo-jcr SVN: r2803 - jcr/trunk/applications/product-patches/as/jonas.
by do-not-reply@jboss.org
Author: tolusha
Date: 2010-07-20 09:06:41 -0400 (Tue, 20 Jul 2010)
New Revision: 2803
Modified:
jcr/trunk/applications/product-patches/as/jonas/exo-configuration.xml
Log:
EXOJCR-844: add missed dependency
Modified: jcr/trunk/applications/product-patches/as/jonas/exo-configuration.xml
===================================================================
--- jcr/trunk/applications/product-patches/as/jonas/exo-configuration.xml 2010-07-20 09:40:23 UTC (rev 2802)
+++ jcr/trunk/applications/product-patches/as/jonas/exo-configuration.xml 2010-07-20 13:06:41 UTC (rev 2803)
@@ -290,6 +290,10 @@
<type>org.exoplatform.services.organization.auth.OrganizationAuthenticatorImpl</type>
</component>
+ <component>
+ <type>org.exoplatform.services.jcr.ext.resource.jcr.Handler</type>
+ </component>
+
<external-component-plugins>
<target-component>org.exoplatform.services.naming.InitialContextInitializer</target-component>
<component-plugin>
14 years, 2 months
exo-jcr SVN: r2802 - in jcr/trunk/applications/product-patches/as: tomcat and 1 other directory.
by do-not-reply@jboss.org
Author: tolusha
Date: 2010-07-20 05:40:23 -0400 (Tue, 20 Jul 2010)
New Revision: 2802
Modified:
jcr/trunk/applications/product-patches/as/jboss/exo-configuration.xml
jcr/trunk/applications/product-patches/as/tomcat/exo-configuration.xml
Log:
EXOJCR-844: add missed dependency
Modified: jcr/trunk/applications/product-patches/as/jboss/exo-configuration.xml
===================================================================
--- jcr/trunk/applications/product-patches/as/jboss/exo-configuration.xml 2010-07-20 09:21:29 UTC (rev 2801)
+++ jcr/trunk/applications/product-patches/as/jboss/exo-configuration.xml 2010-07-20 09:40:23 UTC (rev 2802)
@@ -290,6 +290,10 @@
<type>org.exoplatform.services.organization.auth.OrganizationAuthenticatorImpl</type>
</component>
+ <component>
+ <type>org.exoplatform.services.jcr.ext.resource.jcr.Handler</type>
+ </component>
+
<external-component-plugins>
<target-component>org.exoplatform.services.naming.InitialContextInitializer</target-component>
<component-plugin>
Modified: jcr/trunk/applications/product-patches/as/tomcat/exo-configuration.xml
===================================================================
--- jcr/trunk/applications/product-patches/as/tomcat/exo-configuration.xml 2010-07-20 09:21:29 UTC (rev 2801)
+++ jcr/trunk/applications/product-patches/as/tomcat/exo-configuration.xml 2010-07-20 09:40:23 UTC (rev 2802)
@@ -290,6 +290,10 @@
<type>org.exoplatform.services.organization.auth.OrganizationAuthenticatorImpl</type>
</component>
+ <component>
+ <type>org.exoplatform.services.jcr.ext.resource.jcr.Handler</type>
+ </component>
+
<external-component-plugins>
<target-component>org.exoplatform.services.naming.InitialContextInitializer</target-component>
<component-plugin>
14 years, 2 months
exo-jcr SVN: r2801 - in jcr/branches/1.14-ISPN/exo.jcr.component.core/src: main/java/org/exoplatform/services/jcr/infinispan and 1 other directories.
by do-not-reply@jboss.org
Author: tolusha
Date: 2010-07-20 05:21:29 -0400 (Tue, 20 Jul 2010)
New Revision: 2801
Added:
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/InfinispanLockManagerImpl.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/infinispan/InfinispanCacheFactory.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-infinispan.xml
Removed:
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-infinispan-lock.xml
Modified:
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-jcr-config.xml
Log:
EXOJCR-831: can use single file configuration
Added: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/InfinispanLockManagerImpl.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/InfinispanLockManagerImpl.java (rev 0)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/InfinispanLockManagerImpl.java 2010-07-20 09:21:29 UTC (rev 2801)
@@ -0,0 +1,1101 @@
+/*
+ *
+ * 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.jcr.impl.core.lock.infinispan;
+
+import org.exoplatform.container.configuration.ConfigurationManager;
+import org.exoplatform.management.annotations.Managed;
+import org.exoplatform.management.annotations.ManagedDescription;
+import org.exoplatform.management.jmx.annotations.NameTemplate;
+import org.exoplatform.management.jmx.annotations.Property;
+import org.exoplatform.services.jcr.access.SystemIdentity;
+import org.exoplatform.services.jcr.config.MappedParametrizedObjectEntry;
+import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.config.WorkspaceEntry;
+import org.exoplatform.services.jcr.dataflow.ChangesLogIterator;
+import org.exoplatform.services.jcr.dataflow.CompositeChangesLog;
+import org.exoplatform.services.jcr.dataflow.DataManager;
+import org.exoplatform.services.jcr.dataflow.ItemState;
+import org.exoplatform.services.jcr.dataflow.ItemStateChangesLog;
+import org.exoplatform.services.jcr.dataflow.PlainChangesLog;
+import org.exoplatform.services.jcr.dataflow.PlainChangesLogImpl;
+import org.exoplatform.services.jcr.dataflow.TransactionChangesLog;
+import org.exoplatform.services.jcr.dataflow.persistent.ItemsPersistenceListener;
+import org.exoplatform.services.jcr.datamodel.ItemData;
+import org.exoplatform.services.jcr.datamodel.NodeData;
+import org.exoplatform.services.jcr.datamodel.PropertyData;
+import org.exoplatform.services.jcr.datamodel.QPathEntry;
+import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.core.SessionDataManager;
+import org.exoplatform.services.jcr.impl.core.lock.LockRemover;
+import org.exoplatform.services.jcr.impl.core.lock.SessionLockManager;
+import org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManager;
+import org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl;
+import org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableSessionLockManager;
+import org.exoplatform.services.jcr.impl.core.lock.jbosscache.LockData;
+import org.exoplatform.services.jcr.impl.dataflow.TransientItemData;
+import org.exoplatform.services.jcr.impl.dataflow.TransientPropertyData;
+import org.exoplatform.services.jcr.impl.dataflow.persistent.WorkspacePersistentDataManager;
+import org.exoplatform.services.jcr.impl.storage.JCRInvalidItemStateException;
+import org.exoplatform.services.jcr.impl.storage.jdbc.DBConstants;
+import org.exoplatform.services.jcr.impl.storage.jdbc.DialectDetecter;
+import org.exoplatform.services.jcr.impl.util.io.PrivilegedCacheHelper;
+import org.exoplatform.services.jcr.infinispan.InfinispanCacheFactory;
+import org.exoplatform.services.jcr.observation.ExtendedEvent;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+import org.exoplatform.services.naming.InitialContextInitializer;
+import org.exoplatform.services.transaction.TransactionService;
+import org.infinispan.Cache;
+import org.picocontainer.Startable;
+
+import java.io.Serializable;
+import java.math.BigInteger;
+import java.security.AccessController;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.lock.LockException;
+import javax.naming.InitialContext;
+import javax.sql.DataSource;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+/**
+ * @author <a href="anatoliy.bazko(a)exoplatform.org">Anatoliy Bazko</a>
+ * @version $Id: InfinispanLockManagerImpl.java 111 2010-11-11 11:11:11Z tolusha $
+ *
+ */
+@Managed
+@NameTemplate(@Property(key = "service", value = "lockmanager"))
+public class InfinispanLockManagerImpl implements CacheableLockManager, ItemsPersistenceListener, Startable
+{
+
+ /**
+ * The name to property time out.
+ */
+ public static final String TIME_OUT = "time-out";
+
+ /**
+ * The name to property cache configuration.
+ */
+ public static final String INFINISPAN_JDBC_CL_DATASOURCE = "infinispan-cl-cache.jdbc.datasource";
+
+ public static final String INFINISPAN_JDBC_CL_DATA_COLUMN = "infinispan-cl-cache.jdbc.data.type";
+
+ public static final String INFINISPAN_JDBC_CL_TIMESTAMP_COLUMN = "infinispan-cl-cache.jdbc.timestamp.type";
+
+ public static final String INFINISPAN_JDBC_CL_ID_COLUMN = "infinispan-cl-cache.jdbc.id.type";
+
+ public static final String INFINISPAN_JDBC_CL_AUTO = "auto";
+
+ /**
+ * Default lock time out. 30min
+ */
+ public static final long DEFAULT_LOCK_TIMEOUT = 1000 * 60 * 30;
+
+ /**
+ * Logger
+ */
+ private final Log LOG = ExoLogger.getLogger("exo.jcr.component.core.CacheableLockManagerImpl");
+
+ /**
+ * Data manager.
+ */
+ private final DataManager dataManager;
+
+ /**
+ * Run time lock time out.
+ */
+ private long lockTimeOut;
+
+ /**
+ * Lock remover thread.
+ */
+ private LockRemover lockRemover;
+
+ /**
+ * The current Transaction Manager
+ */
+ private TransactionManager tm;
+
+ private Cache<Serializable, Object> cache;
+
+ // private final Fqn<String> lockRoot;
+
+ /**
+ * SessionLockManagers that uses this LockManager.
+ */
+ private Map<String, CacheableSessionLockManager> sessionLockManagers;
+
+ public InfinispanLockManagerImpl(WorkspacePersistentDataManager dataManager, WorkspaceEntry config,
+ InitialContextInitializer context, TransactionService transactionService, ConfigurationManager cfm)
+ throws RepositoryConfigurationException, RepositoryException
+ {
+ this(dataManager, config, context, transactionService.getTransactionManager(), cfm);
+ }
+
+ public InfinispanLockManagerImpl(WorkspacePersistentDataManager dataManager, WorkspaceEntry config,
+ InitialContextInitializer context, ConfigurationManager cfm) throws RepositoryConfigurationException,
+ RepositoryException
+ {
+ this(dataManager, config, context, (TransactionManager)null, cfm);
+ }
+
+ public InfinispanLockManagerImpl(WorkspacePersistentDataManager dataManager, WorkspaceEntry config,
+ InitialContextInitializer context, TransactionManager transactionManager, ConfigurationManager cfm)
+ throws RepositoryConfigurationException, RepositoryException
+ {
+ this.dataManager = dataManager;
+
+ if (config.getLockManager() != null)
+ {
+ if (config.getLockManager().getParameters() != null
+ && config.getLockManager().getParameterValue(TIME_OUT, null) != null)
+ {
+ long timeOut = config.getLockManager().getParameterTime(TIME_OUT);
+ lockTimeOut = timeOut > 0 ? timeOut : DEFAULT_LOCK_TIMEOUT;
+ }
+ else
+ {
+ lockTimeOut =
+ config.getLockManager().getTimeout() > 0 ? config.getLockManager().getTimeout() : DEFAULT_LOCK_TIMEOUT;
+ }
+ }
+ else
+ {
+ lockTimeOut = DEFAULT_LOCK_TIMEOUT;
+ }
+
+ sessionLockManagers = new ConcurrentHashMap<String, CacheableSessionLockManager>();
+ dataManager.addItemPersistenceListener(this);
+
+ // make cache
+ if (config.getLockManager() != null)
+ {
+ this.tm = transactionManager;
+
+ // create cache using custom factory
+ InfinispanCacheFactory<Serializable, Object> factory =
+ new InfinispanCacheFactory<Serializable, Object>(cfm, transactionManager);
+
+ // configure cache loader parameters with correct DB data-types
+ configureJDBCCacheLoader(config.getLockManager());
+
+ cache = factory.createCache(config.getLockManager());
+
+ // Add the cache loader needed to prevent TimeoutException
+ // addCacheLoader();
+
+ PrivilegedCacheHelper.start(cache);
+
+ // createStructuredNode(lockRoot);
+
+ // Context recall is a workaround of JDBCCacheLoader starting.
+ context.recall();
+ }
+ else
+ {
+ throw new RepositoryConfigurationException("Cache configuration not found");
+ }
+ }
+
+ /**
+ * If JDBC cache loader is used, then fills-in column types. If column type configured from jcr-configuration file,
+ * then nothing is overridden. Parameters are injected into the given parameterEntry.
+ */
+ private void configureJDBCCacheLoader(MappedParametrizedObjectEntry parameterEntry) throws RepositoryException
+ {
+ String dataSourceName = parameterEntry.getParameterValue(INFINISPAN_JDBC_CL_DATASOURCE, null);
+ // if data source is defined, then inject correct data-types.
+ // Also it cans be not defined and nothing should be injected (i.e. no cache loader is used (possibly pattern is changed, to used another cache loader))
+ if (dataSourceName != null)
+ {
+ String dialect;
+ // detect dialect of data-source
+ try
+ {
+ final DataSource dataSource = (DataSource)new InitialContext().lookup(dataSourceName);
+ if (dataSource == null)
+ {
+ throw new RepositoryException("DataSource (" + dataSourceName + ") can't be null");
+ }
+
+ Connection jdbcConn = null;
+ try
+ {
+ PrivilegedExceptionAction<Connection> action = new PrivilegedExceptionAction<Connection>()
+ {
+ public Connection run() throws Exception
+ {
+ return dataSource.getConnection();
+ }
+ };
+ try
+ {
+ jdbcConn = AccessController.doPrivileged(action);
+ }
+ catch (PrivilegedActionException pae)
+ {
+ Throwable cause = pae.getCause();
+ if (cause instanceof SQLException)
+ {
+ throw (SQLException)cause;
+ }
+ else if (cause instanceof RuntimeException)
+ {
+ throw (RuntimeException)cause;
+ }
+ else
+ {
+ throw new RuntimeException(cause);
+ }
+ }
+
+ dialect = DialectDetecter.detect(jdbcConn.getMetaData());
+ }
+ finally
+ {
+ if (jdbcConn != null && !jdbcConn.isClosed())
+ {
+ try
+ {
+ jdbcConn.close();
+ }
+ catch (SQLException e)
+ {
+ throw new RepositoryException("Error of connection close", e);
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ throw new RepositoryException("Error configuring JDBC cache loader", e);
+ }
+
+ // default values, will be overridden with types suitable for concrete data base.
+ String blobType = "BLOB";
+ String charType = "VARCHAR(512)";
+ String timeStampType = "BIGINT";
+ // HSSQL
+ if (dialect.equals(DBConstants.DB_DIALECT_HSQLDB))
+ {
+ blobType = "OBJECT";
+ }
+ // MYSQL
+ else if (dialect.equals(DBConstants.DB_DIALECT_MYSQL) || dialect.equals(DBConstants.DB_DIALECT_MYSQL_UTF8))
+ {
+ blobType = "LONGBLOB";
+ }
+ // ORACLE
+ else if (dialect.equals(DBConstants.DB_DIALECT_ORACLE) || dialect.equals(DBConstants.DB_DIALECT_ORACLEOCI))
+ {
+ // Oracle suggests the use VARCHAR2 instead of VARCHAR while declaring data type.
+ charType = "VARCHAR2(512)";
+ }
+ // POSTGRE SQL
+ else if (dialect.equals(DBConstants.DB_DIALECT_PGSQL))
+ {
+ blobType = "bytea";
+ }
+ // Microsoft SQL
+ else if (dialect.equals(DBConstants.DB_DIALECT_MSSQL))
+ {
+ blobType = "VARBINARY(MAX)";
+ }
+ // SYBASE
+ else if (dialect.equals(DBConstants.DB_DIALECT_SYBASE))
+ {
+ blobType = "IMAGE";
+ }
+ // INGRES
+ else if (dialect.equals(DBConstants.DB_DIALECT_INGRES))
+ {
+ blobType = "long byte";
+ }
+ // else GENERIC, DB2 etc
+
+ // set parameters if not defined
+ // if parameter is missing in configuration, then getParameterValue(INFINISPAN_JDBC_CL_NODE_COLUMN, INFINISPAN_JDBC_CL_AUTO)
+ // will return INFINISPAN_JDBC_CL_AUTO. If parameter is present in configuration and equals to "auto", then it should be replaced
+ // with correct value for given database
+ if (parameterEntry.getParameterValue(INFINISPAN_JDBC_CL_DATA_COLUMN, INFINISPAN_JDBC_CL_AUTO)
+ .equalsIgnoreCase(INFINISPAN_JDBC_CL_AUTO))
+ {
+ parameterEntry.putParameterValue(INFINISPAN_JDBC_CL_DATA_COLUMN, blobType);
+ }
+
+ if (parameterEntry.getParameterValue(INFINISPAN_JDBC_CL_ID_COLUMN, INFINISPAN_JDBC_CL_AUTO).equalsIgnoreCase(
+ INFINISPAN_JDBC_CL_AUTO))
+ {
+ parameterEntry.putParameterValue(INFINISPAN_JDBC_CL_ID_COLUMN, charType);
+ }
+
+ if (parameterEntry.getParameterValue(INFINISPAN_JDBC_CL_TIMESTAMP_COLUMN, INFINISPAN_JDBC_CL_AUTO)
+ .equalsIgnoreCase(INFINISPAN_JDBC_CL_AUTO))
+ {
+ parameterEntry.putParameterValue(INFINISPAN_JDBC_CL_TIMESTAMP_COLUMN, timeStampType);
+ }
+ }
+ else
+ {
+ LOG.warn("CacheLoader DataSource " + INFINISPAN_JDBC_CL_DATASOURCE + " is not configured.");
+ }
+ }
+
+ @Managed
+ @ManagedDescription("Remove the expired locks")
+ public void cleanExpiredLocks()
+ {
+ removeExpired();
+ }
+
+ public long getDefaultLockTimeOut()
+ {
+ return lockTimeOut;
+ }
+
+ private final LockActionNonTxAware<Integer, Object> getNumLocks = new LockActionNonTxAware<Integer, Object>()
+ {
+ public Integer execute(Object arg)
+ {
+ return cache.size();
+ }
+ };
+
+ @Managed
+ @ManagedDescription("The number of active locks")
+ public int getNumLocks()
+ {
+ try
+ {
+ return executeLockActionNonTxAware(getNumLocks, null);
+ }
+ catch (LockException e)
+ {
+ // ignore me will never occur
+ }
+ return -1;
+ }
+
+ private final LockActionNonTxAware<Boolean, Object> hasLocks = new LockActionNonTxAware<Boolean, Object>()
+ {
+ public Boolean execute(Object arg)
+ {
+ return !cache.isEmpty();
+ }
+ };
+
+ /**
+ * Indicates if some locks have already been created
+ */
+ private boolean hasLocks()
+ {
+ try
+ {
+ return executeLockActionNonTxAware(hasLocks, null);
+ }
+ catch (LockException e)
+ {
+ // ignore me will never occur
+ }
+ return true;
+ }
+
+ /**
+ * Return new instance of session lock manager.
+ */
+ public SessionLockManager getSessionLockManager(String sessionId, SessionDataManager transientManager)
+ {
+ CacheableSessionLockManager sessionManager = new CacheableSessionLockManager(sessionId, this, transientManager);
+ sessionLockManagers.put(sessionId, sessionManager);
+ return sessionManager;
+ }
+
+ private final LockActionNonTxAware<Boolean, String> isLockLive = new LockActionNonTxAware<Boolean, String>()
+ {
+ public Boolean execute(String nodeId)
+ {
+ if (cache.get(nodeId) != null) //pendingLocks.containsKey(nodeId) ||
+ {
+ return true;
+ }
+
+ return false;
+ }
+ };
+
+ /**
+ * Check is LockManager contains lock. No matter it is in pending or persistent state.
+ *
+ * @param nodeId - locked node id
+ * @return
+ */
+ public boolean isLockLive(String nodeId) throws LockException
+ {
+ try
+ {
+ return executeLockActionNonTxAware(isLockLive, nodeId);
+ }
+ catch (LockException e)
+ {
+ // ignore me will never occur
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isTXAware()
+ {
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @seeorg.exoplatform.services.jcr.dataflow.persistent.ItemsPersistenceListener#onSaveItems(org.
+ * exoplatform.services.jcr.dataflow.ItemStateChangesLog)
+ */
+ public void onSaveItems(ItemStateChangesLog changesLog)
+ {
+ List<PlainChangesLog> chengesLogList = new ArrayList<PlainChangesLog>();
+ if (changesLog instanceof TransactionChangesLog)
+ {
+ ChangesLogIterator logIterator = ((TransactionChangesLog)changesLog).getLogIterator();
+
+ while (logIterator.hasNextLog())
+ {
+ chengesLogList.add(logIterator.nextLog());
+ }
+ }
+ else if (changesLog instanceof PlainChangesLog)
+ {
+ chengesLogList.add((PlainChangesLog)changesLog);
+ }
+ else if (changesLog instanceof CompositeChangesLog)
+ {
+ for (ChangesLogIterator iter = ((CompositeChangesLog)changesLog).getLogIterator(); iter.hasNextLog();)
+ {
+ chengesLogList.add(iter.nextLog());
+ }
+ }
+
+ List<LockOperationContainer> containers = new ArrayList<LockOperationContainer>();
+
+ for (PlainChangesLog currChangesLog : chengesLogList)
+ {
+ String sessionId = currChangesLog.getSessionId();
+
+ String nodeIdentifier;
+ try
+ {
+ switch (currChangesLog.getEventType())
+ {
+ case ExtendedEvent.LOCK :
+ if (currChangesLog.getSize() < 2)
+ {
+ LOG.error("Incorrect changes log of type ExtendedEvent.LOCK size=" + currChangesLog.getSize()
+ + "<2 \n" + currChangesLog.dump());
+ break;
+ }
+ nodeIdentifier = currChangesLog.getAllStates().get(0).getData().getParentIdentifier();
+
+ CacheableSessionLockManager session = sessionLockManagers.get(sessionId);
+ if (session != null && session.containsPendingLock(nodeIdentifier))
+ {
+ containers.add(new LockOperationContainer(nodeIdentifier, currChangesLog.getSessionId(),
+ ExtendedEvent.LOCK));
+ }
+ else
+ {
+ LOG.error("Lock must exist in pending locks.");
+ }
+ break;
+ case ExtendedEvent.UNLOCK :
+ if (currChangesLog.getSize() < 2)
+ {
+ LOG.error("Incorrect changes log of type ExtendedEvent.UNLOCK size=" + currChangesLog.getSize()
+ + "<2 \n" + currChangesLog.dump());
+ break;
+ }
+
+ containers.add(new LockOperationContainer(currChangesLog.getAllStates().get(0).getData()
+ .getParentIdentifier(), currChangesLog.getSessionId(), ExtendedEvent.UNLOCK));
+ break;
+ default :
+ HashSet<String> removedLock = new HashSet<String>();
+ for (ItemState itemState : currChangesLog.getAllStates())
+ {
+ // this is a node and node is locked
+ if (itemState.getData().isNode() && lockExist(itemState.getData().getIdentifier()))
+ {
+ nodeIdentifier = itemState.getData().getIdentifier();
+ if (itemState.isDeleted())
+ {
+ removedLock.add(nodeIdentifier);
+ }
+ else if (itemState.isAdded() || itemState.isRenamed() || itemState.isUpdated())
+ {
+ removedLock.remove(nodeIdentifier);
+ }
+ }
+ }
+ for (String identifier : removedLock)
+ {
+ containers.add(new LockOperationContainer(identifier, currChangesLog.getSessionId(),
+ ExtendedEvent.UNLOCK));
+ }
+ break;
+ }
+ }
+ catch (IllegalStateException e)
+ {
+ LOG.error(e.getLocalizedMessage(), e);
+ }
+ }
+
+ // sort locking and unlocking operations to avoid deadlocks in JBossCache
+ Collections.sort(containers);
+ for (LockOperationContainer container : containers)
+ {
+ try
+ {
+ container.apply();
+ }
+ catch (LockException e)
+ {
+ LOG.error(e.getMessage(), e);
+ }
+ }
+ }
+
+ /**
+ * Class containing operation type (LOCK or UNLOCK) and all the needed information like node uuid and session id.
+ */
+ private class LockOperationContainer implements Comparable<LockOperationContainer>
+ {
+
+ private String identifier;
+
+ private String sessionId;
+
+ private int type;
+
+ /**
+ * @param identifier node identifier
+ * @param sessionId id of session
+ * @param type ExtendedEvent type specifying the operation (LOCK or UNLOCK)
+ */
+ public LockOperationContainer(String identifier, String sessionId, int type)
+ {
+ super();
+ this.identifier = identifier;
+ this.sessionId = sessionId;
+ this.type = type;
+ }
+
+ /**
+ * @return node identifier
+ */
+ public String getIdentifier()
+ {
+ return identifier;
+ }
+
+ public void apply() throws LockException
+ {
+ // invoke internalLock in LOCK operation
+ if (type == ExtendedEvent.LOCK)
+ {
+ internalLock(sessionId, identifier);
+ }
+ // invoke internalUnLock in UNLOCK operation
+ else if (type == ExtendedEvent.UNLOCK)
+ {
+ internalUnLock(sessionId, identifier);
+ }
+ }
+
+ /**
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ public int compareTo(LockOperationContainer o)
+ {
+ return identifier.compareTo(o.getIdentifier());
+ }
+ }
+
+ private final LockActionNonTxAware<Object, LockData> refresh = new LockActionNonTxAware<Object, LockData>()
+ {
+ public Object execute(LockData newLockData) throws LockException
+ {
+ Object oldValue = PrivilegedCacheHelper.putIfAbsent(cache, newLockData.getNodeIdentifier(), newLockData);
+ if (oldValue == null)
+ {
+ throw new LockException("Can't refresh lock for node " + newLockData.getNodeIdentifier()
+ + " since lock is not exist");
+ }
+ return null;
+ }
+ };
+
+ /**
+ * Refreshed lock data in cache
+ *
+ * @param newLockData
+ */
+ public void refreshLockData(LockData newLockData) throws LockException
+ {
+ executeLockActionNonTxAware(refresh, newLockData);
+ }
+
+ /**
+ * Remove expired locks. Used from LockRemover.
+ */
+ public synchronized void removeExpired()
+ {
+ final List<String> removeLockList = new ArrayList<String>();
+
+ for (LockData lock : getLockList())
+ {
+ if (!lock.isSessionScoped() && lock.getTimeToDeath() < 0)
+ {
+ removeLockList.add(lock.getNodeIdentifier());
+ }
+ }
+
+ Collections.sort(removeLockList);
+
+ for (String rLock : removeLockList)
+ {
+ removeLock(rLock);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.picocontainer.Startable#start()
+ */
+ public void start()
+ {
+ lockRemover = new LockRemover(this);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.picocontainer.Startable#stop()
+ */
+ public void stop()
+ {
+ lockRemover.halt();
+ lockRemover.interrupt();
+ sessionLockManagers.clear();
+
+ PrivilegedCacheHelper.stop(cache);
+ }
+
+ /**
+ * Copy <code>PropertyData prop<code> to new TransientItemData
+ *
+ * @param prop
+ * @return
+ * @throws RepositoryException
+ */
+ private TransientItemData copyItemData(PropertyData prop) throws RepositoryException
+ {
+ if (prop == null)
+ {
+ return null;
+ }
+
+ // make a copy, value may be null for deleting items
+ TransientPropertyData newData =
+ new TransientPropertyData(prop.getQPath(), prop.getIdentifier(), prop.getPersistedVersion(), prop.getType(),
+ prop.getParentIdentifier(), prop.isMultiValued(), prop.getValues());
+
+ return newData;
+ }
+
+ /**
+ * Internal lock
+ *
+ * @param nodeIdentifier
+ * @throws LockException
+ */
+ private synchronized void internalLock(String sessionId, String nodeIdentifier) throws LockException
+ {
+ CacheableSessionLockManager session = sessionLockManagers.get(sessionId);
+ if (session != null && session.containsPendingLock(nodeIdentifier))
+ {
+ LockData lockData = session.getPendingLock(nodeIdentifier);
+
+ // this will return null if success. And old data if something exists...
+ LockData oldLockData = (LockData)PrivilegedCacheHelper.putIfAbsent(cache, nodeIdentifier, lockData);
+
+ if (oldLockData != null)
+ {
+ throw new LockException("Unable to write LockData. Node [" + lockData.getNodeIdentifier()
+ + "] already has LockData!");
+ }
+
+ session.notifyLockPersisted(nodeIdentifier);
+ }
+ else
+ {
+ throw new LockException("No lock in pending locks");
+ }
+ }
+
+ /**
+ * Internal unlock.
+ *
+ * @param sessionId
+ * @param nodeIdentifier
+ * @throws LockException
+ */
+ private synchronized void internalUnLock(String sessionId, String nodeIdentifier) throws LockException
+ {
+ LockData lData = getLockDataById(nodeIdentifier);
+
+ if (lData != null)
+ {
+ cache.remove(nodeIdentifier);
+
+ CacheableSessionLockManager sessMgr = sessionLockManagers.get(sessionId);
+ if (sessMgr != null)
+ {
+ sessMgr.notifyLockRemoved(nodeIdentifier);
+ }
+ }
+ }
+
+ private final LockActionNonTxAware<Boolean, String> lockExist = new LockActionNonTxAware<Boolean, String>()
+ {
+ public Boolean execute(String nodeId) throws LockException
+ {
+ return cache.get(nodeId) != null;
+ }
+ };
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean lockExist(String nodeId)
+ {
+ try
+ {
+ return executeLockActionNonTxAware(lockExist, nodeId);
+ }
+ catch (LockException e)
+ {
+ // ignore me will never occur
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getLockTokenHash(String token)
+ {
+ String hash = "";
+ try
+ {
+ MessageDigest m = MessageDigest.getInstance("MD5");
+ m.update(token.getBytes(), 0, token.length());
+ hash = new BigInteger(1, m.digest()).toString(16);
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ LOG.error("Can't get instanse of MD5 MessageDigest!", e);
+ }
+ return hash;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public LockData getExactNodeOrCloseParentLock(NodeData node) throws RepositoryException
+ {
+ return getExactNodeOrCloseParentLock(node, true);
+ }
+
+ private LockData getExactNodeOrCloseParentLock(NodeData node, boolean checkHasLocks) throws RepositoryException
+ {
+
+ if (node == null || (checkHasLocks && !hasLocks()))
+ {
+ return null;
+ }
+ LockData retval = null;
+ retval = getLockDataById(node.getIdentifier());
+ if (retval == null)
+ {
+ NodeData parentData = (NodeData)dataManager.getItemData(node.getParentIdentifier());
+ if (parentData != null)
+ {
+ retval = getExactNodeOrCloseParentLock(parentData, false);
+ }
+ }
+ return retval;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public LockData getExactNodeLock(NodeData node) throws RepositoryException
+ {
+ if (node == null || !hasLocks())
+ {
+ return null;
+ }
+
+ return getLockDataById(node.getIdentifier());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public LockData getClosedChild(NodeData node) throws RepositoryException
+ {
+ return getClosedChild(node, true);
+ }
+
+ private LockData getClosedChild(NodeData node, boolean checkHasLocks) throws RepositoryException
+ {
+
+ if (node == null || (checkHasLocks && !hasLocks()))
+ {
+ return null;
+ }
+ LockData retval = null;
+
+ List<NodeData> childData = dataManager.getChildNodesData(node);
+ for (NodeData nodeData : childData)
+ {
+ retval = getLockDataById(nodeData.getIdentifier());
+ if (retval != null)
+ return retval;
+ }
+ // child not found try to find dipper
+ for (NodeData nodeData : childData)
+ {
+ retval = getClosedChild(nodeData, false);
+ if (retval != null)
+ return retval;
+ }
+ return retval;
+ }
+
+ private final LockActionNonTxAware<LockData, String> getLockDataById = new LockActionNonTxAware<LockData, String>()
+ {
+ public LockData execute(String nodeId) throws LockException
+ {
+ return (LockData)cache.get(nodeId);
+ }
+ };
+
+ protected LockData getLockDataById(String nodeId)
+ {
+ try
+ {
+ return executeLockActionNonTxAware(getLockDataById, nodeId);
+ }
+ catch (LockException e)
+ {
+ // ignore me will never occur
+ }
+ return null;
+ }
+
+ private final LockActionNonTxAware<List<LockData>, Object> getLockList =
+ new LockActionNonTxAware<List<LockData>, Object>()
+ {
+ public List<LockData> execute(Object arg) throws LockException
+ {
+ Collection<Object> datas = cache.values();
+
+ List<LockData> locksData = new ArrayList<LockData>();
+ for (Object lockData : datas)
+ {
+ if (lockData != null)
+ {
+ locksData.add((LockData)lockData);
+ }
+ }
+ return locksData;
+ }
+ };
+
+ protected synchronized List<LockData> getLockList()
+ {
+ try
+ {
+ return executeLockActionNonTxAware(getLockList, null);
+ }
+ catch (LockException e)
+ {
+ // ignore me will never occur
+ }
+ return null;
+ }
+
+ /**
+ * Remove lock, used by Lock remover.
+ *
+ * @param nodeIdentifier String
+ */
+ protected void removeLock(String nodeIdentifier)
+ {
+ try
+ {
+ NodeData nData = (NodeData)dataManager.getItemData(nodeIdentifier);
+
+ //TODO EXOJCR-412, should be refactored in future.
+ //Skip removing, because that node was removed in other node of cluster.
+ if (nData == null)
+ {
+ return;
+ }
+
+ PlainChangesLog changesLog =
+ new PlainChangesLogImpl(new ArrayList<ItemState>(), SystemIdentity.SYSTEM, ExtendedEvent.UNLOCK);
+
+ ItemData lockOwner =
+ copyItemData((PropertyData)dataManager.getItemData(nData, new QPathEntry(Constants.JCR_LOCKOWNER, 1)));
+
+ //TODO EXOJCR-412, should be refactored in future.
+ //Skip removing, because that lock was removed in other node of cluster.
+ if (lockOwner == null)
+ {
+ return;
+ }
+
+ changesLog.add(ItemState.createDeletedState(lockOwner));
+
+ ItemData lockIsDeep =
+ copyItemData((PropertyData)dataManager.getItemData(nData, new QPathEntry(Constants.JCR_LOCKISDEEP, 1)));
+
+ //TODO EXOJCR-412, should be refactored in future.
+ //Skip removing, because that lock was removed in other node of cluster.
+ if (lockIsDeep == null)
+ {
+ return;
+ }
+
+ changesLog.add(ItemState.createDeletedState(lockIsDeep));
+
+ // lock probably removed by other thread
+ if (lockOwner == null && lockIsDeep == null)
+ {
+ return;
+ }
+
+ dataManager.save(new TransactionChangesLog(changesLog));
+ }
+ catch (JCRInvalidItemStateException e)
+ {
+ //TODO EXOJCR-412, should be refactored in future.
+ //Skip property not found in DB, because that lock property was removed in other node of cluster.
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("The propperty was removed in other node of cluster.", e);
+ }
+
+ }
+ catch (RepositoryException e)
+ {
+ LOG.error("Error occur during removing lock" + e.getLocalizedMessage(), e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void closeSessionLockManager(String sessionID)
+ {
+ sessionLockManagers.remove(sessionID);
+ }
+
+ /**
+ * Execute the given action outside a transaction. This is needed since the {@link Cache} used by {@link CacheableLockManagerImpl}
+ * manages the persistence of its locks thanks to a {@link CacheLoader} and a {@link CacheLoader} lock the JBoss cache {@link Node}
+ * even for read operations which cause deadlock issue when a XA {@link Transaction} is already opened
+ * @throws LockException when a exception occurs
+ */
+ private <R, A> R executeLockActionNonTxAware(LockActionNonTxAware<R, A> action, A arg) throws LockException
+ {
+ Transaction tx = null;
+ try
+ {
+ if (tm != null)
+ {
+ try
+ {
+ tx = tm.suspend();
+ }
+ catch (Exception e)
+ {
+ LOG.warn("Cannot suspend the current transaction", e);
+ }
+ }
+ return action.execute(arg);
+ }
+ finally
+ {
+ if (tx != null)
+ {
+ try
+ {
+ tm.resume(tx);
+ }
+ catch (Exception e)
+ {
+ LOG.warn("Cannot resume the current transaction", e);
+ }
+ }
+ }
+ }
+
+ /**
+ * Actions that are not supposed to be called within a transaction
+ *
+ * Created by The eXo Platform SAS
+ * Author : Nicolas Filotto
+ * nicolas.filotto(a)exoplatform.com
+ * 21 janv. 2010
+ */
+ private static interface LockActionNonTxAware<R, A>
+ {
+ R execute(A arg) throws LockException;
+ }
+
+}
Added: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/infinispan/InfinispanCacheFactory.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/infinispan/InfinispanCacheFactory.java (rev 0)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/infinispan/InfinispanCacheFactory.java 2010-07-20 09:21:29 UTC (rev 2801)
@@ -0,0 +1,200 @@
+/*
+ * 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.jcr.infinispan;
+
+import org.exoplatform.container.configuration.ConfigurationManager;
+import org.exoplatform.services.jcr.config.MappedParametrizedObjectEntry;
+import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.config.TemplateConfigurationHelper;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+import org.infinispan.Cache;
+import org.infinispan.manager.DefaultCacheManager;
+import org.infinispan.manager.EmbeddedCacheManager;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import javax.transaction.TransactionManager;
+
+/**
+ * Factory that creates pre-configured instances of Infinispan, without starting it.
+ * Path to Infinispan configuration or template should be provided as
+ * "infinispan-configuration" property in parameterEntry instance. If
+ * transaction manager is configure in InfinispanCacheFactory, then it
+ * is injected into the cache instance.
+ * <br>
+ * If parameterEntry has "jgroups-multiplexer-stack" (=true) and
+ * "jgroups-configuration" parameters then Multiplexing stack is enabled
+ * in JBossCache (this is highly recommended by RH specialists).
+ *
+ * @author <a href="mailto:nikolazius@gmail.com">Nikolay Zamosenchuk</a>
+ * @version $Id: ExoCacheFactoryImpl.java 34360 2009-07-22 23:58:59Z nzamosenchuk $
+ *
+ */
+public class InfinispanCacheFactory<K, V>
+{
+
+ public static final String INFINISPAN_CONFIG = "infinispan-configuration";
+
+ public static final String INFINISPAN_CACHE_NAME = "infinispan-cache-name";
+
+ public static final String JGROUPS_CONFIG = "jgroups-configuration";
+
+ public static final String JGROUPS_MUX_ENABLED = "jgroups-multiplexer-stack";
+
+ private final TemplateConfigurationHelper configurationHelper;
+
+ private final TransactionManager transactionManager;
+
+ private ConfigurationManager configurationManager;
+
+ private final Log log = ExoLogger.getLogger("exo.jcr.component.core.InfinispanCacheFactory");
+
+ /**
+ * Creates InfinispanCacheFactory with provided configuration transaction managers.
+ * Transaction manager will later be injected to cache instance.
+ *
+ * @param configurationManager
+ * @param transactionManager
+ */
+ public InfinispanCacheFactory(ConfigurationManager configurationManager, TransactionManager transactionManager)
+ {
+ this.configurationManager = configurationManager;
+ this.configurationHelper = TemplateConfigurationHelper.createJBossCacheHelper(configurationManager);
+ this.transactionManager = transactionManager;
+ }
+
+ /**
+ * Creates InfinispanCacheFactory with provided configuration manager and without transaction manager.
+ *
+ * @param configurationManager
+ */
+ public InfinispanCacheFactory(ConfigurationManager configurationManager)
+ {
+ this(configurationManager, null);
+ }
+
+ /**
+ * Creates pre-configured instance of Infinispan, without starting it.
+ * Path to Infinispan configuration or template should be provided as
+ * "jbosscache-configuration" property in parameterEntry instance. If
+ * transaction manager is configure in ExoJBossCacheFactory, then it
+ * is injected into the cache instance.
+ * <br>
+ * If parameterEntry has "jgroups-multiplexer-stack" (=true) and
+ * "jgroups-configuration" parameters then Multiplexing stack is enabled
+ * in JBossCache (this is highly recommended by RH specialists).
+ *
+ * @param parameterEntry
+ * @return
+ * @throws RepositoryConfigurationException
+ */
+ public Cache<K, V> createCache(MappedParametrizedObjectEntry parameterEntry) throws RepositoryConfigurationException
+ {
+ // get Infinispan configuration file path and cache name
+ final String configurationPath = parameterEntry.getParameterValue(INFINISPAN_CONFIG);
+ final String cacheName = parameterEntry.getParameterValue(INFINISPAN_CACHE_NAME);
+ log.info("Infinispan Cache configuration used: " + configurationPath + " cache name: " + cacheName);
+
+ // prepare configuration
+ InputStream configStream;
+ try
+ {
+ // fill template
+ configStream = configurationHelper.fillTemplate(configurationPath, parameterEntry.getParameters());
+ }
+ catch (IOException e)
+ {
+ throw new RepositoryConfigurationException(e);
+ }
+
+ // create cache
+ final EmbeddedCacheManager manager;
+ try
+ {
+ manager = new DefaultCacheManager(configStream);
+ }
+ catch (IOException e)
+ {
+ throw new RepositoryConfigurationException(e);
+ }
+
+ PrivilegedAction<Cache<K, V>> action = new PrivilegedAction<Cache<K, V>>()
+ {
+ public Cache<K, V> run()
+ {
+ return manager.getCache(cacheName);
+ }
+ };
+ Cache<K, V> cache = AccessController.doPrivileged(action);
+
+ // inject transaction manager if defined
+ // if (transactionManager != null)
+ // {
+ // cache.getConfiguration().getRuntimeConfig().setTransactionManager(transactionManager);
+ // }
+
+ // JGroups multiplexer configuration if enabled
+ // if (parameterEntry.getParameterBoolean(JGROUPS_MUX_ENABLED, false))
+ // {
+ // try
+ // {
+ // // Get path to JGroups configuration
+ // String jgroupsConfigurationFilePath = parameterEntry.getParameterValue(JGROUPS_CONFIG);
+ // if (jgroupsConfigurationFilePath != null)
+ // {
+ // // Create and inject multiplexer factory
+ // JChannelFactory muxFactory = new JChannelFactory();
+ // muxFactory.setMultiplexerConfig(configurationManager.getResource(jgroupsConfigurationFilePath));
+ // cache.getConfiguration().getRuntimeConfig().setMuxChannelFactory(muxFactory);
+ // log.info("Multiplexer stack successfully enabled for the cache.");
+ // }
+ // }
+ // catch (Exception e)
+ // {
+ // // exception occurred setting mux factory
+ // e.printStackTrace();
+ // throw new RepositoryConfigurationException("Error setting multiplexer configuration.", e);
+ // }
+ // }
+ // else
+ // {
+ // // Multiplexer is not enabled. If jGroups configuration preset it is applied
+ // String jgroupsConfigurationFilePath = parameterEntry.getParameterValue(JGROUPS_CONFIG, null);
+ // if (jgroupsConfigurationFilePath != null)
+ // {
+ // try
+ // {
+ // cache.getConfiguration().setJgroupsConfigFile(
+ // configurationManager.getResource(jgroupsConfigurationFilePath));
+ // log.info("Custom JGroups configuration set:"
+ // + configurationManager.getResource(jgroupsConfigurationFilePath));
+ // }
+ // catch (Exception e)
+ // {
+ // throw new RepositoryConfigurationException("Error setting JGroups configuration.", e);
+ // }
+ // }
+ // }
+ return cache;
+ }
+}
Deleted: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-infinispan-lock.xml
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-infinispan-lock.xml 2010-07-20 08:15:54 UTC (rev 2800)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-infinispan-lock.xml 2010-07-20 09:21:29 UTC (rev 2801)
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<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">
-
- <default>
- <loaders passivation="false" shared="true" preload="true">
- <loader class="org.infinispan.loaders.jdbc.stringbased.JdbcStringBasedCacheStore" fetchPersistentState="false" ignoreModifications="false" purgeOnStartup="false">
- <properties>
- <property name="stringsTableNamePrefix" value="${infinispan-cl-cache.jdbc.table.name}"/>
- <property name="idColumnName" value="${infinispan-cl-cache.jdbc.id.column}"/>
- <property name="dataColumnName" value="${infinispan-cl-cache.jdbc.data.column}"/>
- <property name="timestampColumnName" value="${infinispan-cl-cache.jdbc.timestamp.column}"/>
- <property name="idColumnType" value="${infinispan-cl-cache.jdbc.id.type}"/>
- <property name="dataColumnType" value="${infinispan-cl-cache.jdbc.data.type}"/>
- <property name="timestampColumnType" value="${infinispan-cl-cache.jdbc.timestamp.type}"/>
- <property name="dropTableOnExit" value="${infinispan-cl-cache.jdbc.table.drop}"/>
- <property name="createTableOnStart" value="${infinispan-cl-cache.jdbc.table.create}"/>
- <property name="connectionFactoryClass" value="org.infinispan.loaders.jdbc.connectionfactory.ManagedConnectionFactory"/>
- <property name="datasourceJndiLocation" value="${infinispan-cl-cache.jdbc.datasource}"/>
- </properties>
- <async enabled="false"/>
- </loader>
- </loaders>
- </default>
-</infinispan>
Added: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-infinispan.xml
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-infinispan.xml (rev 0)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-infinispan.xml 2010-07-20 09:21:29 UTC (rev 2801)
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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">
+
+ <namedCache name="lockCache">
+ <loaders passivation="false" shared="true" preload="true">
+ <loader class="org.infinispan.loaders.jdbc.stringbased.JdbcStringBasedCacheStore" fetchPersistentState="false" ignoreModifications="false" purgeOnStartup="false">
+ <properties>
+ <property name="stringsTableNamePrefix" value="${infinispan-cl-cache.jdbc.table.name}"/>
+ <property name="idColumnName" value="${infinispan-cl-cache.jdbc.id.column}"/>
+ <property name="dataColumnName" value="${infinispan-cl-cache.jdbc.data.column}"/>
+ <property name="timestampColumnName" value="${infinispan-cl-cache.jdbc.timestamp.column}"/>
+ <property name="idColumnType" value="${infinispan-cl-cache.jdbc.id.type}"/>
+ <property name="dataColumnType" value="${infinispan-cl-cache.jdbc.data.type}"/>
+ <property name="timestampColumnType" value="${infinispan-cl-cache.jdbc.timestamp.type}"/>
+ <property name="dropTableOnExit" value="${infinispan-cl-cache.jdbc.table.drop}"/>
+ <property name="createTableOnStart" value="${infinispan-cl-cache.jdbc.table.create}"/>
+ <property name="connectionFactoryClass" value="${infinispan-cl-cache.jdbc.connectionFactory}"/>
+ <property name="datasourceJndiLocation" value="${infinispan-cl-cache.jdbc.datasource}"/>
+ </properties>
+ <async enabled="false"/>
+ </loader>
+ </loaders>
+ </namedCache>
+</infinispan>
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-jcr-config.xml
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-jcr-config.xml 2010-07-20 08:15:54 UTC (rev 2800)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-jcr-config.xml 2010-07-20 09:21:29 UTC (rev 2801)
@@ -81,14 +81,16 @@
<lock-manager class="org.exoplatform.services.jcr.impl.core.lock.infinispan.InfinispanLockManagerImpl">
<properties>
<property name="time-out" value="15m" />
- <property name="infinispan-configuration" value="conf/standalone/test-infinispan-lock.xml" />
+ <property name="infinispan-configuration" value="conf/standalone/test-infinispan.xml" />
+ <property name="infinispan-cache-name" value="lockCache" />
<property name="infinispan-cl-cache.jdbc.table.name" value="jcrlocks_db1_ws" />
<property name="infinispan-cl-cache.jdbc.table.create" value="true" />
<property name="infinispan-cl-cache.jdbc.table.drop" value="false" />
<property name="infinispan-cl-cache.jdbc.id.column" value="id" />
<property name="infinispan-cl-cache.jdbc.data.column" value="data" />
- <property name="infinispan-cl-cache.jdbc.timestamp.column" value="time_stamp" />
+ <property name="infinispan-cl-cache.jdbc.timestamp.column" value="timestamp" />
<property name="infinispan-cl-cache.jdbc.datasource" value="jdbcjcr" />
+ <property name="infinispan-cl-cache.jdbc.connectionFactory" value="org.infinispan.loaders.jdbc.connectionfactory.ManagedConnectionFactory" />
</properties>
</lock-manager>
</workspace>
@@ -133,14 +135,16 @@
<lock-manager class="org.exoplatform.services.jcr.impl.core.lock.infinispan.InfinispanLockManagerImpl">
<properties>
<property name="time-out" value="15m" />
- <property name="infinispan-configuration" value="conf/standalone/test-infinispan-lock.xml" />
+ <property name="infinispan-configuration" value="conf/standalone/test-infinispan.xml" />
+ <property name="infinispan-cache-name" value="lockCache" />
<property name="infinispan-cl-cache.jdbc.table.name" value="jcrlocks_db1_ws1" />
<property name="infinispan-cl-cache.jdbc.table.create" value="true" />
<property name="infinispan-cl-cache.jdbc.table.drop" value="false" />
<property name="infinispan-cl-cache.jdbc.id.column" value="id" />
<property name="infinispan-cl-cache.jdbc.data.column" value="data" />
- <property name="infinispan-cl-cache.jdbc.timestamp.column" value="time_stamp" />
- <property name="infinispan-cl-cache.jdbc.datasource" value="jdbcjcr1" />
+ <property name="infinispan-cl-cache.jdbc.timestamp.column" value="timestamp" />
+ <property name="infinispan-cl-cache.jdbc.datasource" value="jdbcjcr1" />
+ <property name="infinispan-cl-cache.jdbc.connectionFactory" value="org.infinispan.loaders.jdbc.connectionfactory.ManagedConnectionFactory" />
</properties>
</lock-manager>
</workspace>
@@ -185,14 +189,16 @@
<lock-manager class="org.exoplatform.services.jcr.impl.core.lock.infinispan.InfinispanLockManagerImpl">
<properties>
<property name="time-out" value="15m" />
- <property name="infinispan-configuration" value="conf/standalone/test-infinispan-lock.xml" />
+ <property name="infinispan-configuration" value="conf/standalone/test-infinispan.xml" />
+ <property name="infinispan-cache-name" value="lockCache" />
<property name="infinispan-cl-cache.jdbc.table.name" value="jcrlocks_db1_ws2" />
<property name="infinispan-cl-cache.jdbc.table.create" value="true" />
<property name="infinispan-cl-cache.jdbc.table.drop" value="false" />
<property name="infinispan-cl-cache.jdbc.id.column" value="id" />
<property name="infinispan-cl-cache.jdbc.data.column" value="data" />
- <property name="infinispan-cl-cache.jdbc.timestamp.column" value="time_stamp" />
+ <property name="infinispan-cl-cache.jdbc.timestamp.column" value="timestamp" />
<property name="infinispan-cl-cache.jdbc.datasource" value="jdbcjcr2" />
+ <property name="infinispan-cl-cache.jdbc.connectionFactory" value="org.infinispan.loaders.jdbc.connectionfactory.ManagedConnectionFactory" />
</properties>
</lock-manager>
</workspace>
@@ -266,14 +272,16 @@
<lock-manager class="org.exoplatform.services.jcr.impl.core.lock.infinispan.InfinispanLockManagerImpl">
<properties>
<property name="time-out" value="15m" />
- <property name="infinispan-configuration" value="conf/standalone/test-infinispan-lock.xml" />
+ <property name="infinispan-configuration" value="conf/standalone/test-infinispan.xml" />
+ <property name="infinispan-cache-name" value="lockCache" />
<property name="infinispan-cl-cache.jdbc.table.name" value="jcrlocks_db1_ws3" />
<property name="infinispan-cl-cache.jdbc.table.create" value="true" />
<property name="infinispan-cl-cache.jdbc.table.drop" value="false" />
<property name="infinispan-cl-cache.jdbc.id.column" value="id" />
<property name="infinispan-cl-cache.jdbc.data.column" value="data" />
- <property name="infinispan-cl-cache.jdbc.timestamp.column" value="time_stamp" />
+ <property name="infinispan-cl-cache.jdbc.timestamp.column" value="timestamp" />
<property name="infinispan-cl-cache.jdbc.datasource" value="jdbcjcr3" />
+ <property name="infinispan-cl-cache.jdbc.connectionFactory" value="org.infinispan.loaders.jdbc.connectionfactory.ManagedConnectionFactory" />
</properties>
</lock-manager>
</workspace>
@@ -335,14 +343,16 @@
<lock-manager class="org.exoplatform.services.jcr.impl.core.lock.infinispan.InfinispanLockManagerImpl">
<properties>
<property name="time-out" value="15m" />
- <property name="infinispan-configuration" value="conf/standalone/test-infinispan-lock.xml" />
+ <property name="infinispan-configuration" value="conf/standalone/test-infinispan.xml" />
+ <property name="infinispan-cache-name" value="lockCache" />
<property name="infinispan-cl-cache.jdbc.table.name" value="jcrlocks_db1tck_ws" />
<property name="infinispan-cl-cache.jdbc.table.create" value="true" />
<property name="infinispan-cl-cache.jdbc.table.drop" value="false" />
<property name="infinispan-cl-cache.jdbc.id.column" value="id" />
<property name="infinispan-cl-cache.jdbc.data.column" value="data" />
- <property name="infinispan-cl-cache.jdbc.timestamp.column" value="time_stamp" />
+ <property name="infinispan-cl-cache.jdbc.timestamp.column" value="timestamp" />
<property name="infinispan-cl-cache.jdbc.datasource" value="jdbcjcrtck" />
+ <property name="infinispan-cl-cache.jdbc.connectionFactory" value="org.infinispan.loaders.jdbc.connectionfactory.ManagedConnectionFactory" />
</properties>
</lock-manager>
</workspace>
@@ -393,14 +403,16 @@
<lock-manager class="org.exoplatform.services.jcr.impl.core.lock.infinispan.InfinispanLockManagerImpl">
<properties>
<property name="time-out" value="15m" />
- <property name="infinispan-configuration" value="conf/standalone/test-infinispan-lock.xml" />
+ <property name="infinispan-configuration" value="conf/standalone/test-infinispan.xml" />
+ <property name="infinispan-cache-name" value="lockCache" />
<property name="infinispan-cl-cache.jdbc.table.name" value="jcrlocks_db1tck_ws1" />
<property name="infinispan-cl-cache.jdbc.table.create" value="true" />
<property name="infinispan-cl-cache.jdbc.table.drop" value="false" />
<property name="infinispan-cl-cache.jdbc.id.column" value="id" />
<property name="infinispan-cl-cache.jdbc.data.column" value="data" />
- <property name="infinispan-cl-cache.jdbc.timestamp.column" value="time_stamp" />
+ <property name="infinispan-cl-cache.jdbc.timestamp.column" value="timestamp" />
<property name="infinispan-cl-cache.jdbc.datasource" value="jdbcjcr1tck" />
+ <property name="infinispan-cl-cache.jdbc.connectionFactory" value="org.infinispan.loaders.jdbc.connectionfactory.ManagedConnectionFactory" />
</properties>
</lock-manager>
</workspace>
@@ -454,14 +466,16 @@
<lock-manager class="org.exoplatform.services.jcr.impl.core.lock.infinispan.InfinispanLockManagerImpl">
<properties>
<property name="time-out" value="15m" />
- <property name="infinispan-configuration" value="conf/standalone/test-infinispan-lock.xml" />
+ <property name="infinispan-configuration" value="conf/standalone/test-infinispan.xml" />
+ <property name="infinispan-cache-name" value="lockCache" />
<property name="infinispan-cl-cache.jdbc.table.name" value="jcrlocks_db1tck_ws2" />
<property name="infinispan-cl-cache.jdbc.table.create" value="true" />
<property name="infinispan-cl-cache.jdbc.table.drop" value="false" />
<property name="infinispan-cl-cache.jdbc.id.column" value="id" />
<property name="infinispan-cl-cache.jdbc.data.column" value="data" />
- <property name="infinispan-cl-cache.jdbc.timestamp.column" value="time_stamp" />
+ <property name="infinispan-cl-cache.jdbc.timestamp.column" value="timestamp" />
<property name="infinispan-cl-cache.jdbc.datasource" value="jdbcjcr2tck" />
+ <property name="infinispan-cl-cache.jdbc.connectionFactory" value="org.infinispan.loaders.jdbc.connectionfactory.ManagedConnectionFactory" />
</properties>
</lock-manager>
</workspace>
14 years, 2 months
exo-jcr SVN: r2800 - in jcr/branches/1.14-ISPN/exo.jcr.component.core/src: main/java/org/exoplatform/services/jcr/config and 4 other directories.
by do-not-reply@jboss.org
Author: tolusha
Date: 2010-07-20 04:15:54 -0400 (Tue, 20 Jul 2010)
New Revision: 2800
Added:
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/infinispan/
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-infinispan-lock.xml
Modified:
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/config/TemplateConfigurationHelper.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/PrivilegedCacheHelper.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/lab/infinispan/TestISPNCache.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-jcr-config.xml
Log:
EXOJCR-831: first lock impl on Infinispan Test passed.
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/config/TemplateConfigurationHelper.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/config/TemplateConfigurationHelper.java 2010-07-19 14:39:08 UTC (rev 2799)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/config/TemplateConfigurationHelper.java 2010-07-20 08:15:54 UTC (rev 2800)
@@ -22,7 +22,6 @@
import org.exoplatform.services.jcr.impl.util.io.PrivilegedFileHelper;
import java.io.ByteArrayInputStream;
-import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
@@ -89,8 +88,9 @@
*/
public static TemplateConfigurationHelper createJBossCacheHelper(ConfigurationManager cfm)
{
- return new TemplateConfigurationHelper(new String[]{"^jbosscache-.*", "^jgroups-configuration"},
- new String[]{"^jbosscache-configuration"}, cfm);
+ return new TemplateConfigurationHelper(
+ new String[]{"^jbosscache-.*", "^jgroups-configuration", "^infinispan-.*"}, new String[]{
+ "^jbosscache-configuration", "^infinispan-configuration"}, cfm);
}
/**
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/PrivilegedCacheHelper.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/PrivilegedCacheHelper.java 2010-07-19 14:39:08 UTC (rev 2799)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/PrivilegedCacheHelper.java 2010-07-20 08:15:54 UTC (rev 2800)
@@ -36,7 +36,7 @@
public class PrivilegedCacheHelper
{
/**
- * Start cache in privileged mode.
+ * Start JBoss cache in privileged mode.
*
* @param cache
*/
@@ -54,7 +54,7 @@
}
/**
- * Stop cache in privileged mode.
+ * Stop JBoss cache in privileged mode.
*
* @param cache
*/
@@ -72,7 +72,7 @@
}
/**
- * Create cache in privileged mode.
+ * Create JBoss cache in privileged mode.
*
* @param cache
*/
@@ -90,7 +90,7 @@
}
/**
- * Put in cache in privileged mode.
+ * Put in JBoss cache in privileged mode.
*
* @param cache
*/
@@ -128,7 +128,7 @@
}
/**
- * Put in cache in privileged mode.
+ * Put in JBoss cache in privileged mode.
*
* @param cache
*/
@@ -163,4 +163,77 @@
}
}
}
+
+ /**
+ * Start Infinispan cache in privileged mode.
+ *
+ * @param cache
+ */
+ public static void start(final org.infinispan.Cache<Serializable, Object> cache)
+ {
+ PrivilegedAction<Object> action = new PrivilegedAction<Object>()
+ {
+ public Object run()
+ {
+ cache.start();
+ return null;
+ }
+ };
+ AccessController.doPrivileged(action);
+ }
+
+ /**
+ * Stop Infinispan cache in privileged mode.
+ *
+ * @param cache
+ */
+ public static void stop(final org.infinispan.Cache<Serializable, Object> cache)
+ {
+ PrivilegedAction<Object> action = new PrivilegedAction<Object>()
+ {
+ public Object run()
+ {
+ cache.stop();
+ return null;
+ }
+ };
+ AccessController.doPrivileged(action);
+ }
+
+ /**
+ * Put in Infinispan cache in privileged mode.
+ *
+ * @param cache
+ */
+ public static Object putIfAbsent(final org.infinispan.Cache<Serializable, Object> cache, final Serializable key,
+ final Object value) throws CacheException
+ {
+ PrivilegedExceptionAction<Object> action = new PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ return cache.putIfAbsent(key, value);
+ }
+ };
+ try
+ {
+ return AccessController.doPrivileged(action);
+ }
+ catch (PrivilegedActionException pae)
+ {
+ Throwable cause = pae.getCause();
+ if (cause instanceof CacheException)
+ {
+ throw (CacheException)cause;
+ }
+ else if (cause instanceof RuntimeException)
+ {
+ throw (RuntimeException)cause;
+ }
+ else
+ {
+ throw new RuntimeException(cause);
+ }
+ }
+ }
}
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/lab/infinispan/TestISPNCache.java
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/lab/infinispan/TestISPNCache.java 2010-07-19 14:39:08 UTC (rev 2799)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/lab/infinispan/TestISPNCache.java 2010-07-20 08:15:54 UTC (rev 2800)
@@ -87,7 +87,7 @@
cache.put("key", "value", 2, TimeUnit.SECONDS);
assertTrue(cache.containsKey("key"));
- Thread.sleep(2000);
+ Thread.sleep(2000 + 500);
assertFalse(cache.containsKey("key"));
}
@@ -121,7 +121,8 @@
cache.put("key", "value", 2, TimeUnit.SECONDS);
assertTrue(cache.containsKey("key"));
- Thread.sleep(2000);
+ Thread.sleep(2000 + 500);
assertFalse(cache.containsKey("key"));
}
+
}
Added: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-infinispan-lock.xml
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-infinispan-lock.xml (rev 0)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-infinispan-lock.xml 2010-07-20 08:15:54 UTC (rev 2800)
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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">
+
+ <default>
+ <loaders passivation="false" shared="true" preload="true">
+ <loader class="org.infinispan.loaders.jdbc.stringbased.JdbcStringBasedCacheStore" fetchPersistentState="false" ignoreModifications="false" purgeOnStartup="false">
+ <properties>
+ <property name="stringsTableNamePrefix" value="${infinispan-cl-cache.jdbc.table.name}"/>
+ <property name="idColumnName" value="${infinispan-cl-cache.jdbc.id.column}"/>
+ <property name="dataColumnName" value="${infinispan-cl-cache.jdbc.data.column}"/>
+ <property name="timestampColumnName" value="${infinispan-cl-cache.jdbc.timestamp.column}"/>
+ <property name="idColumnType" value="${infinispan-cl-cache.jdbc.id.type}"/>
+ <property name="dataColumnType" value="${infinispan-cl-cache.jdbc.data.type}"/>
+ <property name="timestampColumnType" value="${infinispan-cl-cache.jdbc.timestamp.type}"/>
+ <property name="dropTableOnExit" value="${infinispan-cl-cache.jdbc.table.drop}"/>
+ <property name="createTableOnStart" value="${infinispan-cl-cache.jdbc.table.create}"/>
+ <property name="connectionFactoryClass" value="org.infinispan.loaders.jdbc.connectionfactory.ManagedConnectionFactory"/>
+ <property name="datasourceJndiLocation" value="${infinispan-cl-cache.jdbc.datasource}"/>
+ </properties>
+ <async enabled="false"/>
+ </loader>
+ </loaders>
+ </default>
+</infinispan>
Modified: jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-jcr-config.xml
===================================================================
--- jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-jcr-config.xml 2010-07-19 14:39:08 UTC (rev 2799)
+++ jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/resources/conf/standalone/test-jcr-config.xml 2010-07-20 08:15:54 UTC (rev 2800)
@@ -78,18 +78,17 @@
</properties>
</query-handler>
- <lock-manager class="org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl">
+ <lock-manager class="org.exoplatform.services.jcr.impl.core.lock.infinispan.InfinispanLockManagerImpl">
<properties>
<property name="time-out" value="15m" />
- <property name="jbosscache-configuration" value="conf/standalone/test-jbosscache-lock.xml" />
- <property name="jbosscache-cl-cache.jdbc.table.name" value="jcrlocks_db1_ws" />
- <property name="jbosscache-cl-cache.jdbc.table.create" value="true" />
- <property name="jbosscache-cl-cache.jdbc.table.drop" value="false" />
- <property name="jbosscache-cl-cache.jdbc.table.primarykey" value="jcrlocks_db1_ws_pk" />
- <property name="jbosscache-cl-cache.jdbc.fqn.column" value="fqn" />
- <property name="jbosscache-cl-cache.jdbc.node.column" value="node" />
- <property name="jbosscache-cl-cache.jdbc.parent.column" value="parent" />
- <property name="jbosscache-cl-cache.jdbc.datasource" value="jdbcjcr" />
+ <property name="infinispan-configuration" value="conf/standalone/test-infinispan-lock.xml" />
+ <property name="infinispan-cl-cache.jdbc.table.name" value="jcrlocks_db1_ws" />
+ <property name="infinispan-cl-cache.jdbc.table.create" value="true" />
+ <property name="infinispan-cl-cache.jdbc.table.drop" value="false" />
+ <property name="infinispan-cl-cache.jdbc.id.column" value="id" />
+ <property name="infinispan-cl-cache.jdbc.data.column" value="data" />
+ <property name="infinispan-cl-cache.jdbc.timestamp.column" value="time_stamp" />
+ <property name="infinispan-cl-cache.jdbc.datasource" value="jdbcjcr" />
</properties>
</lock-manager>
</workspace>
@@ -131,18 +130,17 @@
<property name="spellchecker-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.spell.LuceneSpellChecker$FiveSecondsRefreshInterval" />
</properties>
</query-handler>
- <lock-manager class="org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl">
+ <lock-manager class="org.exoplatform.services.jcr.impl.core.lock.infinispan.InfinispanLockManagerImpl">
<properties>
<property name="time-out" value="15m" />
- <property name="jbosscache-configuration" value="conf/standalone/test-jbosscache-lock.xml" />
- <property name="jbosscache-cl-cache.jdbc.table.name" value="jcrlocks_db1_ws1" />
- <property name="jbosscache-cl-cache.jdbc.table.create" value="true" />
- <property name="jbosscache-cl-cache.jdbc.table.drop" value="false" />
- <property name="jbosscache-cl-cache.jdbc.table.primarykey" value="jcrlocks_db1_ws1_pk" />
- <property name="jbosscache-cl-cache.jdbc.fqn.column" value="fqn" />
- <property name="jbosscache-cl-cache.jdbc.node.column" value="node" />
- <property name="jbosscache-cl-cache.jdbc.parent.column" value="parent" />
- <property name="jbosscache-cl-cache.jdbc.datasource" value="jdbcjcr1" />
+ <property name="infinispan-configuration" value="conf/standalone/test-infinispan-lock.xml" />
+ <property name="infinispan-cl-cache.jdbc.table.name" value="jcrlocks_db1_ws1" />
+ <property name="infinispan-cl-cache.jdbc.table.create" value="true" />
+ <property name="infinispan-cl-cache.jdbc.table.drop" value="false" />
+ <property name="infinispan-cl-cache.jdbc.id.column" value="id" />
+ <property name="infinispan-cl-cache.jdbc.data.column" value="data" />
+ <property name="infinispan-cl-cache.jdbc.timestamp.column" value="time_stamp" />
+ <property name="infinispan-cl-cache.jdbc.datasource" value="jdbcjcr1" />
</properties>
</lock-manager>
</workspace>
@@ -184,18 +182,17 @@
<property name="spellchecker-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.spell.LuceneSpellChecker$FiveSecondsRefreshInterval" />
</properties>
</query-handler>
- <lock-manager class="org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl">
+ <lock-manager class="org.exoplatform.services.jcr.impl.core.lock.infinispan.InfinispanLockManagerImpl">
<properties>
<property name="time-out" value="15m" />
- <property name="jbosscache-configuration" value="conf/standalone/test-jbosscache-lock.xml" />
- <property name="jbosscache-cl-cache.jdbc.table.name" value="jcrlocks_db1_ws2" />
- <property name="jbosscache-cl-cache.jdbc.table.create" value="true" />
- <property name="jbosscache-cl-cache.jdbc.table.drop" value="false" />
- <property name="jbosscache-cl-cache.jdbc.table.primarykey" value="jcrlocks_db1_ws2_pk" />
- <property name="jbosscache-cl-cache.jdbc.fqn.column" value="fqn" />
- <property name="jbosscache-cl-cache.jdbc.node.column" value="node" />
- <property name="jbosscache-cl-cache.jdbc.parent.column" value="parent" />
- <property name="jbosscache-cl-cache.jdbc.datasource" value="jdbcjcr2" />
+ <property name="infinispan-configuration" value="conf/standalone/test-infinispan-lock.xml" />
+ <property name="infinispan-cl-cache.jdbc.table.name" value="jcrlocks_db1_ws2" />
+ <property name="infinispan-cl-cache.jdbc.table.create" value="true" />
+ <property name="infinispan-cl-cache.jdbc.table.drop" value="false" />
+ <property name="infinispan-cl-cache.jdbc.id.column" value="id" />
+ <property name="infinispan-cl-cache.jdbc.data.column" value="data" />
+ <property name="infinispan-cl-cache.jdbc.timestamp.column" value="time_stamp" />
+ <property name="infinispan-cl-cache.jdbc.datasource" value="jdbcjcr2" />
</properties>
</lock-manager>
</workspace>
@@ -253,36 +250,32 @@
<property name="jbosscache-configuration" value="conf/standalone/test-jbosscache-config.xml" />
</properties>
</cache>
- <query-handler
- class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
- <properties>
- <property name="index-dir" value="target/temp/index/db1/ws3" />
- <property name="synonymprovider-class"
- value="org.exoplatform.services.jcr.impl.core.query.lucene.PropertiesSynonymProvider" />
- <property name="synonymprovider-config-path" value="../../synonyms.properties" />
- <property name="support-highlighting" value="true" />
- <property name="indexing-configuration-path" value="../../indexing-configuration.xml" />
- <property name="query-class"
- value="org.exoplatform.services.jcr.impl.core.query.QueryImpl" />
- <property name="spellchecker-class"
- value="org.exoplatform.services.jcr.impl.core.query.lucene.spell.LuceneSpellChecker$FiveSecondsRefreshInterval" />
- </properties>
- </query-handler>
- <lock-manager class="org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl">
- <properties>
- <property name="time-out" value="15m" />
- <property name="jbosscache-configuration" value="conf/standalone/test-jbosscache-lock.xml" />
- <property name="jbosscache-cl-cache.jdbc.table.name" value="jcrlocks_db1_ws3" />
- <property name="jbosscache-cl-cache.jdbc.table.create" value="true" />
- <property name="jbosscache-cl-cache.jdbc.table.drop" value="false" />
- <property name="jbosscache-cl-cache.jdbc.table.primarykey" value="jcrlocks_db1_ws3_pk" />
- <property name="jbosscache-cl-cache.jdbc.fqn.column" value="fqn" />
- <property name="jbosscache-cl-cache.jdbc.node.column" value="node" />
- <property name="jbosscache-cl-cache.jdbc.parent.column" value="parent" />
- <property name="jbosscache-cl-cache.jdbc.datasource" value="jdbcjcr3" />
- </properties>
- </lock-manager>
-
+ <query-handler
+ class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
+ <properties>
+ <property name="index-dir" value="target/temp/index/db1/ws3" />
+ <property name="synonymprovider-class"
+ value="org.exoplatform.services.jcr.impl.core.query.lucene.PropertiesSynonymProvider" />
+ <property name="synonymprovider-config-path" value="../../synonyms.properties" />
+ <property name="support-highlighting" value="true" />
+ <property name="indexing-configuration-path" value="../../indexing-configuration.xml" />
+ <property name="query-class" value="org.exoplatform.services.jcr.impl.core.query.QueryImpl" />
+ <property name="spellchecker-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.spell.LuceneSpellChecker$FiveSecondsRefreshInterval" />
+ </properties>
+ </query-handler>
+ <lock-manager class="org.exoplatform.services.jcr.impl.core.lock.infinispan.InfinispanLockManagerImpl">
+ <properties>
+ <property name="time-out" value="15m" />
+ <property name="infinispan-configuration" value="conf/standalone/test-infinispan-lock.xml" />
+ <property name="infinispan-cl-cache.jdbc.table.name" value="jcrlocks_db1_ws3" />
+ <property name="infinispan-cl-cache.jdbc.table.create" value="true" />
+ <property name="infinispan-cl-cache.jdbc.table.drop" value="false" />
+ <property name="infinispan-cl-cache.jdbc.id.column" value="id" />
+ <property name="infinispan-cl-cache.jdbc.data.column" value="data" />
+ <property name="infinispan-cl-cache.jdbc.timestamp.column" value="time_stamp" />
+ <property name="infinispan-cl-cache.jdbc.datasource" value="jdbcjcr3" />
+ </properties>
+ </lock-manager>
</workspace>
</workspaces>
</repository>
@@ -339,18 +332,17 @@
<property name="spellchecker-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.spell.LuceneSpellChecker$FiveSecondsRefreshInterval" />
</properties>
</query-handler>
- <lock-manager class="org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl">
+ <lock-manager class="org.exoplatform.services.jcr.impl.core.lock.infinispan.InfinispanLockManagerImpl">
<properties>
<property name="time-out" value="15m" />
- <property name="jbosscache-configuration" value="conf/standalone/test-jbosscache-lock.xml" />
- <property name="jbosscache-cl-cache.jdbc.table.name" value="jcrlocks_db1tck_ws" />
- <property name="jbosscache-cl-cache.jdbc.table.create" value="true" />
- <property name="jbosscache-cl-cache.jdbc.table.drop" value="false" />
- <property name="jbosscache-cl-cache.jdbc.table.primarykey" value="jcrlocks_db1tck_ws_pk" />
- <property name="jbosscache-cl-cache.jdbc.fqn.column" value="fqn" />
- <property name="jbosscache-cl-cache.jdbc.node.column" value="node" />
- <property name="jbosscache-cl-cache.jdbc.parent.column" value="parent" />
- <property name="jbosscache-cl-cache.jdbc.datasource" value="jdbcjcrtck" />
+ <property name="infinispan-configuration" value="conf/standalone/test-infinispan-lock.xml" />
+ <property name="infinispan-cl-cache.jdbc.table.name" value="jcrlocks_db1tck_ws" />
+ <property name="infinispan-cl-cache.jdbc.table.create" value="true" />
+ <property name="infinispan-cl-cache.jdbc.table.drop" value="false" />
+ <property name="infinispan-cl-cache.jdbc.id.column" value="id" />
+ <property name="infinispan-cl-cache.jdbc.data.column" value="data" />
+ <property name="infinispan-cl-cache.jdbc.timestamp.column" value="time_stamp" />
+ <property name="infinispan-cl-cache.jdbc.datasource" value="jdbcjcrtck" />
</properties>
</lock-manager>
</workspace>
@@ -398,20 +390,19 @@
<property name="spellchecker-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.spell.LuceneSpellChecker$FiveSecondsRefreshInterval" />
</properties>
</query-handler>
- <lock-manager class="org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl">
+ <lock-manager class="org.exoplatform.services.jcr.impl.core.lock.infinispan.InfinispanLockManagerImpl">
<properties>
<property name="time-out" value="15m" />
- <property name="jbosscache-configuration" value="conf/standalone/test-jbosscache-lock.xml" />
- <property name="jbosscache-cl-cache.jdbc.table.name" value="jcrlocks_db1tck_ws1" />
- <property name="jbosscache-cl-cache.jdbc.table.create" value="true" />
- <property name="jbosscache-cl-cache.jdbc.table.drop" value="false" />
- <property name="jbosscache-cl-cache.jdbc.table.primarykey" value="jcrlocks_db1tck_ws1_pk" />
- <property name="jbosscache-cl-cache.jdbc.fqn.column" value="fqn" />
- <property name="jbosscache-cl-cache.jdbc.node.column" value="node" />
- <property name="jbosscache-cl-cache.jdbc.parent.column" value="parent" />
- <property name="jbosscache-cl-cache.jdbc.datasource" value="jdbcjcr1tck" />
+ <property name="infinispan-configuration" value="conf/standalone/test-infinispan-lock.xml" />
+ <property name="infinispan-cl-cache.jdbc.table.name" value="jcrlocks_db1tck_ws1" />
+ <property name="infinispan-cl-cache.jdbc.table.create" value="true" />
+ <property name="infinispan-cl-cache.jdbc.table.drop" value="false" />
+ <property name="infinispan-cl-cache.jdbc.id.column" value="id" />
+ <property name="infinispan-cl-cache.jdbc.data.column" value="data" />
+ <property name="infinispan-cl-cache.jdbc.timestamp.column" value="time_stamp" />
+ <property name="infinispan-cl-cache.jdbc.datasource" value="jdbcjcr1tck" />
</properties>
- </lock-manager>
+ </lock-manager>
</workspace>
<workspace name="ws2">
@@ -460,20 +451,19 @@
<property name="extractorTimeout" value="10"/>
</properties>
</query-handler>
- <lock-manager class="org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl">
+ <lock-manager class="org.exoplatform.services.jcr.impl.core.lock.infinispan.InfinispanLockManagerImpl">
<properties>
<property name="time-out" value="15m" />
- <property name="jbosscache-configuration" value="conf/standalone/test-jbosscache-lock.xml" />
- <property name="jbosscache-cl-cache.jdbc.table.name" value="jcrlocks_db1tck_ws2" />
- <property name="jbosscache-cl-cache.jdbc.table.create" value="true" />
- <property name="jbosscache-cl-cache.jdbc.table.drop" value="false" />
- <property name="jbosscache-cl-cache.jdbc.table.primarykey" value="jcrlocks_db1tck_ws2_pk" />
- <property name="jbosscache-cl-cache.jdbc.fqn.column" value="fqn" />
- <property name="jbosscache-cl-cache.jdbc.node.column" value="node" />
- <property name="jbosscache-cl-cache.jdbc.parent.column" value="parent" />
- <property name="jbosscache-cl-cache.jdbc.datasource" value="jdbcjcr2tck" />
+ <property name="infinispan-configuration" value="conf/standalone/test-infinispan-lock.xml" />
+ <property name="infinispan-cl-cache.jdbc.table.name" value="jcrlocks_db1tck_ws2" />
+ <property name="infinispan-cl-cache.jdbc.table.create" value="true" />
+ <property name="infinispan-cl-cache.jdbc.table.drop" value="false" />
+ <property name="infinispan-cl-cache.jdbc.id.column" value="id" />
+ <property name="infinispan-cl-cache.jdbc.data.column" value="data" />
+ <property name="infinispan-cl-cache.jdbc.timestamp.column" value="time_stamp" />
+ <property name="infinispan-cl-cache.jdbc.datasource" value="jdbcjcr2tck" />
</properties>
- </lock-manager>
+ </lock-manager>
</workspace>
</workspaces>
</repository>
14 years, 2 months
exo-jcr SVN: r2799 - core/trunk/exo.core.component.database/src/test/java/org/exoplatform/services/database.
by do-not-reply@jboss.org
Author: tolusha
Date: 2010-07-19 10:39:08 -0400 (Mon, 19 Jul 2010)
New Revision: 2799
Modified:
core/trunk/exo.core.component.database/src/test/java/org/exoplatform/services/database/TestDBCreator.java
Log:
EXOJCR-812: InitialContextBinder multi-thread test
Modified: core/trunk/exo.core.component.database/src/test/java/org/exoplatform/services/database/TestDBCreator.java
===================================================================
--- core/trunk/exo.core.component.database/src/test/java/org/exoplatform/services/database/TestDBCreator.java 2010-07-19 14:37:51 UTC (rev 2798)
+++ core/trunk/exo.core.component.database/src/test/java/org/exoplatform/services/database/TestDBCreator.java 2010-07-19 14:39:08 UTC (rev 2799)
@@ -42,6 +42,7 @@
private InitialContextInitializer initContext;
+ @Override
public void setUp() throws Exception
{
PortalContainer container = PortalContainer.getInstance();
@@ -62,8 +63,8 @@
refAddr.put("username", dbInfo.getUsername());
refAddr.put("password", dbInfo.getPassword());
- initContext.bind("testjdbcjcr", "javax.sql.DataSource",
- "org.apache.commons.dbcp.BasicDataSourceFactory", null, refAddr);
+ initContext.bind("testjdbcjcr", "javax.sql.DataSource", "org.apache.commons.dbcp.BasicDataSourceFactory", null,
+ refAddr);
DataSource ds = (DataSource)initContext.getInitialContext().lookup("testjdbcjcr");
assertNotNull(ds);
@@ -71,4 +72,68 @@
Connection conn = ds.getConnection();
assertNotNull(conn);
}
+
+ public void testDBCreateMultiThread() throws Exception
+ {
+ DBCreateThread[] queue = new DBCreateThread[100];
+
+ for (int i = 0; i < queue.length; i++)
+ {
+ queue[i] = new DBCreateThread(i);
+ queue[i].start();
+ }
+
+ for (int i = 0; i < queue.length; i++)
+ {
+ queue[i].join();
+ }
+
+ for (int i = 0; i < queue.length; i++)
+ {
+ DataSource ds = (DataSource)initContext.getInitialContext().lookup("testjdbcjcr_" + i);
+ assertNotNull(ds);
+
+ Connection conn = ds.getConnection();
+ assertNotNull(conn);
+ }
+
+ }
+
+ class DBCreateThread extends Thread
+ {
+
+ private final int threadNumber;
+
+ DBCreateThread(int threadNumber)
+ {
+ this.threadNumber = threadNumber;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void run()
+ {
+ try
+ {
+ DBConnectionInfo dbInfo = dbCreator.createDatabase("testdb_" + threadNumber);
+
+ Map<String, String> refAddr = new HashMap<String, String>();
+ refAddr.put("driverClassName", dbInfo.getDriver());
+ refAddr.put("url", dbInfo.getUrl());
+ refAddr.put("username", dbInfo.getUsername());
+ refAddr.put("password", dbInfo.getPassword());
+
+ initContext.bind("testjdbcjcr_" + threadNumber, "javax.sql.DataSource",
+ "org.apache.commons.dbcp.BasicDataSourceFactory", null, refAddr);
+ }
+ catch (Exception e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+
}
14 years, 2 months
exo-jcr SVN: r2798 - kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/naming.
by do-not-reply@jboss.org
Author: tolusha
Date: 2010-07-19 10:37:51 -0400 (Mon, 19 Jul 2010)
New Revision: 2798
Modified:
kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/naming/InitialContextBinder.java
Log:
EXOJCR-812: InitialContextBinder should be thread-safe
Modified: kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/naming/InitialContextBinder.java
===================================================================
--- kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/naming/InitialContextBinder.java 2010-07-16 11:39:07 UTC (rev 2797)
+++ kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/naming/InitialContextBinder.java 2010-07-19 14:37:51 UTC (rev 2798)
@@ -22,14 +22,12 @@
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
-
import java.util.HashMap;
import java.util.Iterator;
-import java.util.Stack;
-
import java.util.Map;
-
+import java.util.Stack;
import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
import javax.naming.NameAlreadyBoundException;
import javax.naming.NamingException;
@@ -105,7 +103,7 @@
{
this.initialContextInitializer = initialContextInitializer;
- this.bindings = new HashMap<String, Reference>();
+ this.bindings = new ConcurrentHashMap<String, Reference>();
this.bindingsStorePath = System.getProperty("java.io.tmpdir") + File.separator + "bind-references.xml";
if (new File(bindingsStorePath).exists())
@@ -173,7 +171,7 @@
* @throws FileNotFoundException
* if can't open output stream from file
*/
- protected void saveBindings() throws FileNotFoundException, XMLStreamException
+ protected synchronized void saveBindings() throws FileNotFoundException, XMLStreamException
{
XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
XMLStreamWriter writer = outputFactory.createXMLStreamWriter(new FileOutputStream(bindingsStorePath), "UTF-8");
14 years, 2 months
exo-jcr SVN: r2797 - in jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/resource: jcr and 1 other directory.
by do-not-reply@jboss.org
Author: aparfonov
Date: 2010-07-16 07:39:07 -0400 (Fri, 16 Jul 2010)
New Revision: 2797
Modified:
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/resource/JcrURLConnection.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/resource/jcr/Handler.java
Log:
EXOJCR-859 :
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/resource/JcrURLConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/resource/JcrURLConnection.java 2010-07-15 14:11:57 UTC (rev 2796)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/resource/JcrURLConnection.java 2010-07-16 11:39:07 UTC (rev 2797)
@@ -45,7 +45,25 @@
private Session session;
+ private boolean closeSessionProvider;
+
public JcrURLConnection(UnifiedNodeReference nodeReference, SessionProvider sessionProvider,
+ NodeRepresentationService nodeRepresentationService, boolean closeSessionProvider) throws MalformedURLException
+ {
+
+ super(nodeReference.getURL());
+ this.sessionProvider = sessionProvider;
+ this.nodeReference = nodeReference;
+ this.nodeRepresentationService = nodeRepresentationService;
+ this.closeSessionProvider = closeSessionProvider;
+
+ doOutput = false;
+ allowUserInteraction = false;
+ useCaches = false;
+ ifModifiedSince = 0;
+ }
+
+ public JcrURLConnection(UnifiedNodeReference nodeReference, SessionProvider sessionProvider,
NodeRepresentationService nodeRepresentationService) throws MalformedURLException
{
@@ -312,7 +330,10 @@
{
try
{
- sessionProvider.close();
+ if (closeSessionProvider)
+ {
+ sessionProvider.close();
+ }
}
catch (Throwable t)
{
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/resource/jcr/Handler.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/resource/jcr/Handler.java 2010-07-15 14:11:57 UTC (rev 2796)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/resource/jcr/Handler.java 2010-07-16 11:39:07 UTC (rev 2797)
@@ -105,12 +105,18 @@
// ThreadLocalSessionProvider or System SessionProvider
SessionProvider sessionProvider = threadLocalSessionProviderService.getSessionProvider(null);
+ boolean closeSessionProvider = false;
if (sessionProvider == null && ConversationState.getCurrent() != null)
+ {
sessionProvider =
(SessionProvider)ConversationState.getCurrent().getAttribute(SessionProvider.SESSION_PROVIDER);
+ }
if (sessionProvider == null)
- sessionProvider = SessionProvider.createSystemProvider();
+ {
+ sessionProvider = SessionProvider.createAnonimProvider();
+ closeSessionProvider = true;
+ }
String repositoryName = nodeReference.getRepository();
if (repositoryName != null && repositoryName.length() > 0)
@@ -125,7 +131,8 @@
sessionProvider.setCurrentWorkspace(workspaceName);
}
- JcrURLConnection conn = new JcrURLConnection(nodeReference, sessionProvider, nodeRepresentationService);
+ JcrURLConnection conn =
+ new JcrURLConnection(nodeReference, sessionProvider, nodeRepresentationService, closeSessionProvider);
return conn;
}
14 years, 2 months