Author: tolusha
Date: 2010-08-30 02:56:05 -0400 (Mon, 30 Aug 2010)
New Revision: 3001
Added:
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/AbstractCacheableLockManager.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/PrivilegedISPNCacheHelper.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/infinispan/ISPNCacheHelper.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/jbosscache/JBossCacheHelper.java
Removed:
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/config/TemplateConfigurationHelper.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNCacheableLockManagerImpl.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.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/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/jbosscache/ExoJBossCacheFactory.java
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/config/TestTemplateConfigurationHelper.java
Log:
EXOJCR-831: apply issue's remarks
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-08-30
06:26:51 UTC (rev 3000)
+++
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/config/TemplateConfigurationHelper.java 2010-08-30
06:56:05 UTC (rev 3001)
@@ -80,20 +80,6 @@
}
/**
- * Creates instance of TemplateConfigurationHelper pre-configured for JBossCache
parameters,<br>
- * including: "jbosscache-*" and "jgroups-configuration", and
excluding "jbosscache-configuration"
- *
- * @param ConfigurationManager instance for looking up resources
- * @return
- */
- public static TemplateConfigurationHelper createJBossCacheHelper(ConfigurationManager
cfm)
- {
- return new TemplateConfigurationHelper(
- new String[]{"^jbosscache-.*", "^jgroups-configuration",
"^infinispan-.*"}, new String[]{
- "^jbosscache-configuration",
"^infinispan-configuration"}, cfm);
- }
-
- /**
* Reads configuration file from a stream and replaces all the occurrences of
template-variables
* (like : "${parameter.name}") with values provided in the map.
*
Added:
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/AbstractCacheableLockManager.java
===================================================================
---
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/AbstractCacheableLockManager.java
(rev 0)
+++
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/AbstractCacheableLockManager.java 2010-08-30
06:56:05 UTC (rev 3001)
@@ -0,0 +1,776 @@
+/*
+ * 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;
+
+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.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.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: AbstractCacheableLockManagerImpl.java 2806 2010-07-21 08:00:15Z tolusha
$
+ */
+public abstract class AbstractCacheableLockManager 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.AbstractCacheableLockManager");
+
+ 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 AbstractCacheableLockManager(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;
+ }
+}
Modified:
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNCacheableLockManagerImpl.java
===================================================================
---
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNCacheableLockManagerImpl.java 2010-08-30
06:26:51 UTC (rev 3000)
+++
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNCacheableLockManagerImpl.java 2010-08-30
06:56:05 UTC (rev 3001)
@@ -24,13 +24,13 @@
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.impl.core.lock.jbosscache.AbstractCacheableLockManagerImpl;
+import org.exoplatform.services.jcr.impl.core.lock.AbstractCacheableLockManager;
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.persistent.WorkspacePersistentDataManager;
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.impl.util.io.PrivilegedISPNCacheHelper;
import org.exoplatform.services.jcr.infinispan.InfinispanCacheFactory;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
@@ -60,7 +60,7 @@
*/
@Managed
@NameTemplate(@Property(key = "service", value = "lockmanager"))
-public class ISPNCacheableLockManagerImpl extends AbstractCacheableLockManagerImpl
+public class ISPNCacheableLockManagerImpl extends AbstractCacheableLockManager
{
/**
@@ -142,12 +142,7 @@
{
public Boolean execute(String nodeId)
{
- if (cache.get(nodeId) != null)
- {
- return true;
- }
-
- return false;
+ return cache.containsKey(nodeId);
}
};
@@ -155,7 +150,7 @@
{
public Object execute(LockData newLockData) throws LockException
{
- Object oldValue = PrivilegedCacheHelper.put(cache,
newLockData.getNodeIdentifier(), newLockData);
+ Object oldValue = PrivilegedISPNCacheHelper.put(cache,
newLockData.getNodeIdentifier(), newLockData);
if (oldValue == null)
{
throw new LockException("Can't refresh lock for node " +
newLockData.getNodeIdentifier()
@@ -165,13 +160,7 @@
}
};
- this.lockExist = new LockActionNonTxAware<Boolean, String>()
- {
- public Boolean execute(String nodeId) throws LockException
- {
- return cache.get(nodeId) != null;
- }
- };
+ this.lockExist = this.isLockLive;
this.getLockDataById = new LockActionNonTxAware<LockData, String>()
{
@@ -353,7 +342,7 @@
{
super.stop();
- PrivilegedCacheHelper.stop(cache);
+ PrivilegedISPNCacheHelper.stop(cache);
}
/**
@@ -368,7 +357,7 @@
LockData lockData = session.getPendingLock(nodeIdentifier);
// this will return null if success. And old data if something exists...
- LockData oldLockData = (LockData)PrivilegedCacheHelper.put(cache,
nodeIdentifier, lockData);
+ LockData oldLockData = (LockData)PrivilegedISPNCacheHelper.putIfAbsent(cache,
nodeIdentifier, lockData);
if (oldLockData != null)
{
Deleted:
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 2010-08-30
06:26:51 UTC (rev 3000)
+++
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/AbstractCacheableLockManagerImpl.java 2010-08-30
06:56:05 UTC (rev 3001)
@@ -1,775 +0,0 @@
-/*
- * 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;
- }
-}
Modified:
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java
===================================================================
---
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java 2010-08-30
06:26:51 UTC (rev 3000)
+++
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java 2010-08-30
06:56:05 UTC (rev 3001)
@@ -18,40 +18,17 @@
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.SimpleParameterEntry;
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.core.lock.AbstractCacheableLockManager;
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.jbosscache.ExoJBossCacheFactory;
-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;
@@ -65,30 +42,21 @@
import org.jboss.cache.loader.CacheLoader;
import org.jboss.cache.loader.CacheLoaderManager;
import org.jboss.cache.lock.TimeoutException;
-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.Collections;
-import java.util.HashSet;
import java.util.List;
-import java.util.Map;
import java.util.Set;
-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;
/**
@@ -101,18 +69,9 @@
*/
@Managed
@NameTemplate(@Property(key = "service", value = "lockmanager"))
-public class CacheableLockManagerImpl implements CacheableLockManager,
ItemsPersistenceListener, Startable
+public class CacheableLockManagerImpl extends AbstractCacheableLockManager
{
- /**
- * The name to property time out.
- */
- public static final String TIME_OUT = "time-out";
- /**
- * The name to property cache configuration.
- */
- public static final String JBOSSCACCHE_CONFIG = "jbosscache-configuration";
-
public static final String JBOSSCACHE_JDBC_CL_DATASOURCE =
"jbosscache-cl-cache.jdbc.datasource";
public static final String JBOSSCACHE_JDBC_CL_NODE_COLUMN =
"jbosscache-cl-cache.jdbc.node.type";
@@ -122,11 +81,6 @@
public static final String JBOSSCACHE_JDBC_CL_AUTO = "auto";
/**
- * Default lock time out. 30min
- */
- public static final long DEFAULT_LOCK_TIMEOUT = 1000 * 60 * 30;
-
- /**
* Name of lock root in jboss-cache.
*/
public static final String LOCKS = "$LOCKS";
@@ -141,36 +95,11 @@
*/
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;
-
- /**
* Constructor.
*
* @param dataManager - workspace persistent data manager
@@ -200,7 +129,6 @@
RepositoryException
{
this(dataManager, config, context, (TransactionManager)null, cfm);
-
}
/**
@@ -217,38 +145,13 @@
InitialContextInitializer context, TransactionManager transactionManager,
ConfigurationManager cfm)
throws RepositoryConfigurationException, RepositoryException
{
+ super(dataManager, config, transactionManager);
+
lockRoot = Fqn.fromElements(LOCKS);
- List<SimpleParameterEntry> paramenerts =
config.getLockManager().getParameters();
-
- this.dataManager = dataManager;
- if (config.getLockManager() != null)
- {
- if (paramenerts != 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
ExoJBossCacheFactory<Serializable, Object> factory =
new ExoJBossCacheFactory<Serializable, Object>(cfm,
transactionManager);
@@ -274,13 +177,92 @@
{
throw new RepositoryConfigurationException("Cache configuration not
found");
}
+
+ this.getNumLocks = new LockActionNonTxAware<Integer, Object>()
+ {
+ public Integer execute(Object arg)
+ {
+ return ((CacheSPI<Serializable, Object>)cache).getNumberOfNodes() - 1;
+ }
+ };
+
+ this.hasLocks = new LockActionNonTxAware<Boolean, Object>()
+ {
+ public Boolean execute(Object arg)
+ {
+ return ((CacheSPI<Serializable,
Object>)cache).getNode(lockRoot).hasChildrenDirect();
+ }
+ };
+
+ this.isLockLive = new LockActionNonTxAware<Boolean, String>()
+ {
+ public Boolean execute(String nodeId)
+ {
+ if (cache.get(makeLockFqn(nodeId), LOCK_DATA) != null)
//pendingLocks.containsKey(nodeId) ||
+ {
+ return true;
+ }
+
+ return false;
+ }
+ };
+
+ this.refresh = new LockActionNonTxAware<Object, LockData>()
+ {
+ public Object execute(LockData newLockData) throws LockException
+ {
+ Fqn<String> fqn = makeLockFqn(newLockData.getNodeIdentifier());
+ Object oldValue = PrivilegedCacheHelper.put(cache, fqn, LOCK_DATA,
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(makeLockFqn(nodeId), LOCK_DATA) != null;
+ }
+ };
+
+ this.getLockDataById = new LockActionNonTxAware<LockData, String>()
+ {
+ public LockData execute(String nodeId) throws LockException
+ {
+ return (LockData)cache.get(makeLockFqn(nodeId), LOCK_DATA);
+ }
+ };
+
+ this.getLockList = new LockActionNonTxAware<List<LockData>, Object>()
+ {
+ public List<LockData> execute(Object arg) throws LockException
+ {
+ Set<Object> nodesId = cache.getChildrenNames(lockRoot);
+
+ List<LockData> locksData = new ArrayList<LockData>();
+ for (Object nodeId : nodesId)
+ {
+ LockData lockData = (LockData)cache.get(makeLockFqn((String)nodeId),
LOCK_DATA);
+ if (lockData != null)
+ {
+ locksData.add(lockData);
+ }
+ }
+ return locksData;
+ }
+ };
}
/**
* 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.
*/
- public void configureJDBCCacheLoader(MappedParametrizedObjectEntry parameterEntry)
throws RepositoryException
+ private void configureJDBCCacheLoader(MappedParametrizedObjectEntry parameterEntry)
throws RepositoryException
{
String dataSourceName =
parameterEntry.getParameterValue(JBOSSCACHE_JDBC_CL_DATASOURCE, null);
// if data source is defined, then inject correct data-types.
@@ -464,350 +446,10 @@
}
}
- @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 ((CacheSPI<Serializable, Object>)cache).getNumberOfNodes() - 1;
- }
- };
-
- @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 ((CacheSPI<Serializable,
Object>)cache).getNode(lockRoot).hasChildrenDirect();
- }
- };
-
/**
- * 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(makeLockFqn(nodeId), LOCK_DATA) != 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
- {
- Fqn<String> fqn = makeLockFqn(newLockData.getNodeIdentifier());
- Object oldValue = PrivilegedCacheHelper.put(cache, fqn, LOCK_DATA,
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()
- */
+ * {@inheritDoc}
+ */
+ @Override
public void stop()
{
lockRemover.halt();
@@ -818,35 +460,11 @@
}
/**
- * 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))
{
@@ -874,13 +492,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);
@@ -896,256 +511,7 @@
}
}
- private final LockActionNonTxAware<Boolean, String> lockExist = new
LockActionNonTxAware<Boolean, String>()
- {
- public Boolean execute(String nodeId) throws LockException
- {
- return cache.get(makeLockFqn(nodeId), LOCK_DATA) != 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(makeLockFqn(nodeId), LOCK_DATA);
- }
- };
-
- 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
- {
- Set<Object> nodesId = cache.getChildrenNames(lockRoot);
-
- List<LockData> locksData = new ArrayList<LockData>();
- for (Object nodeId : nodesId)
- {
- LockData lockData = (LockData)cache.get(makeLockFqn((String)nodeId),
LOCK_DATA);
- if (lockData != null)
- {
- locksData.add(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);
- }
-
- /**
* Make lock absolute Fqn, i.e. /$LOCKS/nodeID.
*
* @param itemId String
@@ -1169,57 +535,4 @@
}
node.setResident(true);
}
-
- /**
- * 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;
- }
}
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-08-30
06:26:51 UTC (rev 3000)
+++
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/PrivilegedCacheHelper.java 2010-08-30
06:56:05 UTC (rev 3001)
@@ -164,114 +164,4 @@
}
}
- /**
- * 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);
- }
- }
- }
-
- /**
- * Put in Infinispan cache in privileged mode.
- *
- * @param cache
- */
- public static Object put(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.put(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);
- }
- }
- }
-
}
Added:
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/PrivilegedISPNCacheHelper.java
===================================================================
---
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/PrivilegedISPNCacheHelper.java
(rev 0)
+++
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/PrivilegedISPNCacheHelper.java 2010-08-30
06:56:05 UTC (rev 3001)
@@ -0,0 +1,105 @@
+/*
+ * 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.impl.util.io;
+
+import org.infinispan.Cache;
+
+import java.io.Serializable;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * @author <a href="anatoliy.bazko(a)exoplatform.org">Anatoliy
Bazko</a>
+ * @version $Id: PrivilegedCacheHelper.java 111 2010-11-11 11:11:11Z tolusha $
+ *
+ */
+public class PrivilegedISPNCacheHelper
+{
+
+ /**
+ * 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 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 Cache<Serializable, Object> cache, final
Serializable key, final Object value)
+ {
+ PrivilegedAction<Object> action = new PrivilegedAction<Object>()
+ {
+ public Object run()
+ {
+ return cache.putIfAbsent(key, value);
+ }
+ };
+ return AccessController.doPrivileged(action);
+ }
+
+ /**
+ * Put in Infinispan cache in privileged mode.
+ *
+ * @param cache
+ */
+ public static Object put(final Cache<Serializable, Object> cache, final
Serializable key, final Object value)
+ {
+ PrivilegedAction<Object> action = new PrivilegedAction<Object>()
+ {
+ public Object run()
+ {
+ return cache.put(key, value);
+ }
+ };
+ return AccessController.doPrivileged(action);
+ }
+
+}
Added:
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/infinispan/ISPNCacheHelper.java
===================================================================
---
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/infinispan/ISPNCacheHelper.java
(rev 0)
+++
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/infinispan/ISPNCacheHelper.java 2010-08-30
06:56:05 UTC (rev 3001)
@@ -0,0 +1,43 @@
+/*
+ * 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.TemplateConfigurationHelper;
+
+/**
+ * @author <a href="anatoliy.bazko(a)exoplatform.org">Anatoliy
Bazko</a>
+ * @version $Id: ISPNCacheHelper.java 111 2010-11-11 11:11:11Z tolusha $
+ *
+ */
+public class ISPNCacheHelper extends TemplateConfigurationHelper
+{
+
+ /**
+ * Creates configuration cache helper with pre-configured for Infinispan cache
parameters,<br>
+ * including: "infinispan-*" and "jgroups-configuration", and
excluding "infinispan-configuration"
+ *
+ * @param cfm
+ * instance for looking up resources
+ */
+ public ISPNCacheHelper(ConfigurationManager cfm)
+ {
+ super(new String[]{"^jgroups-configuration", "^infinispan-.*"},
new String[]{"^infinispan-configuration"}, cfm);
+ }
+}
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-08-30
06:26:51 UTC (rev 3000)
+++
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/infinispan/InfinispanCacheFactory.java 2010-08-30
06:56:05 UTC (rev 3001)
@@ -62,7 +62,7 @@
*/
public InfinispanCacheFactory(ConfigurationManager configurationManager)
{
- this.configurationHelper =
TemplateConfigurationHelper.createJBossCacheHelper(configurationManager);
+ this.configurationHelper = new ISPNCacheHelper(configurationManager);
}
/**
Modified:
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/jbosscache/ExoJBossCacheFactory.java
===================================================================
---
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/jbosscache/ExoJBossCacheFactory.java 2010-08-30
06:26:51 UTC (rev 3000)
+++
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/jbosscache/ExoJBossCacheFactory.java 2010-08-30
06:56:05 UTC (rev 3001)
@@ -78,7 +78,7 @@
public ExoJBossCacheFactory(ConfigurationManager configurationManager,
TransactionManager transactionManager)
{
this.configurationManager = configurationManager;
- this.configurationHelper =
TemplateConfigurationHelper.createJBossCacheHelper(configurationManager);
+ this.configurationHelper = new JBossCacheHelper(configurationManager);
this.transactionManager = transactionManager;
}
Added:
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/jbosscache/JBossCacheHelper.java
===================================================================
---
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/jbosscache/JBossCacheHelper.java
(rev 0)
+++
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/jbosscache/JBossCacheHelper.java 2010-08-30
06:56:05 UTC (rev 3001)
@@ -0,0 +1,43 @@
+/*
+ * 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.jbosscache;
+
+import org.exoplatform.container.configuration.ConfigurationManager;
+import org.exoplatform.services.jcr.config.TemplateConfigurationHelper;
+
+/**
+ * @author <a href="anatoliy.bazko(a)exoplatform.org">Anatoliy
Bazko</a>
+ * @version $Id: ISPNCacheHelper.java 111 2010-11-11 11:11:11Z tolusha $
+ *
+ */
+public class JBossCacheHelper extends TemplateConfigurationHelper
+{
+
+ /**
+ * Creates configuration cache helper with pre-configured for JBossCache
parameters,<br>
+ * including: "jbosscache-*" and "jgroups-configuration", and
excluding "jbosscache-configuration"
+ *
+ * @param cfm
+ * instance for looking up resources
+ */
+ public JBossCacheHelper(ConfigurationManager cfm)
+ {
+ super(new String[]{"^jbosscache-.*", "^jgroups-configuration"},
new String[]{"^jbosscache-configuration"}, cfm);
+ }
+}
Modified:
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/config/TestTemplateConfigurationHelper.java
===================================================================
---
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/config/TestTemplateConfigurationHelper.java 2010-08-30
06:26:51 UTC (rev 3000)
+++
jcr/branches/1.14-ISPN/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/config/TestTemplateConfigurationHelper.java 2010-08-30
06:56:05 UTC (rev 3001)
@@ -18,10 +18,11 @@
*/
package org.exoplatform.services.jcr.config;
+import junit.framework.TestCase;
+
import org.exoplatform.container.configuration.ConfigurationManagerImpl;
+import org.exoplatform.services.jcr.jbosscache.JBossCacheHelper;
-import junit.framework.TestCase;
-
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -39,8 +40,7 @@
public void testFilters()
{
// create helper with predefined include and exclude patterns
- TemplateConfigurationHelper helper =
- TemplateConfigurationHelper.createJBossCacheHelper(new
ConfigurationManagerImpl());
+ TemplateConfigurationHelper helper = new JBossCacheHelper(new
ConfigurationManagerImpl());
Map<String, String> parameters = new HashMap<String, String>();
parameters.put("jbosscache-configuration", "");
parameters.put("jbosscache-cache.loader", "");
@@ -58,7 +58,7 @@
public void testFilters2()
{
// create helper with predefined include and exclude patterns
- TemplateConfigurationHelper helper =
TemplateConfigurationHelper.createJBossCacheHelper(new ConfigurationManagerImpl());
+ TemplateConfigurationHelper helper = new JBossCacheHelper(new
ConfigurationManagerImpl());
Map<String, String> parameters = new HashMap<String, String>();
parameters.put("jgroups-configuration", "");
parameters.put("jbosscache-cache.loader", "");
@@ -74,7 +74,7 @@
public void testTemplating() throws IOException
{
- TemplateConfigurationHelper helper =
TemplateConfigurationHelper.createJBossCacheHelper(new ConfigurationManagerImpl());
+ TemplateConfigurationHelper helper = new JBossCacheHelper(new
ConfigurationManagerImpl());
String template = "configuration in any format, containing
${jbosscache-template-variable} and many others";
String expectedConfig = "configuration in any format, containing pretty good
parameter and many others";