exo-jcr SVN: r1505 - jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/lab/cluster/prepare.
by do-not-reply@jboss.org
Author: nzamosenchuk
Date: 2010-01-20 08:30:57 -0500 (Wed, 20 Jan 2010)
New Revision: 1505
Modified:
jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/lab/cluster/prepare/TestLoadIndexerWriterWithModes.java
Log:
EXOJCR-396: added session.refresh(false) if exception occurs on session.save().
Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/lab/cluster/prepare/TestLoadIndexerWriterWithModes.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/lab/cluster/prepare/TestLoadIndexerWriterWithModes.java 2010-01-20 12:46:45 UTC (rev 1504)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/lab/cluster/prepare/TestLoadIndexerWriterWithModes.java 2010-01-20 13:30:57 UTC (rev 1505)
@@ -46,7 +46,7 @@
public static final String STATISTIC = "Statistic";
private volatile boolean stop = false;
-
+
private AtomicBoolean makeThemWait = new AtomicBoolean();
private int threadCount = 10;
@@ -56,9 +56,9 @@
private final CountDownLatch doneSignal = new CountDownLatch(threadCount);
private final CyclicBarrier barrier = new CyclicBarrier(threadCount);
-
+
private volatile CountDownLatch goSignal;
-
+
private static final String[] words =
new String[]{"private", "branch", "final", "string", "logging", "bottle", "property", "node", "repository",
"exception", "cycle", "value", "index", "meaning", "strange", "words", "hello", "outline", "finest",
@@ -95,7 +95,7 @@
else
{
goSignal = new CountDownLatch(1);
- makeThemWait.set(true);
+ makeThemWait.set(true);
}
}
@@ -163,7 +163,9 @@
}
catch (Exception e1)
{
- log.error("An error occurs", e1);
+ // discard session changes
+ sessionLocal.refresh(false);
+ log.error("An error occurs", e1);
}
try
@@ -175,7 +177,7 @@
goSignal.await();
}
else
- {
+ {
Thread.sleep(300);
}
}
16 years, 3 months
exo-jcr SVN: r1504 - in jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl: storage/jdbc and 2 other directories.
by do-not-reply@jboss.org
Author: pnedonosko
Date: 2010-01-20 07:46:45 -0500 (Wed, 20 Jan 2010)
New Revision: 1504
Modified:
jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java
jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/FilePersistedValueData.java
jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/DBConstants.java
jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java
jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MultiDbJDBCConnection.java
jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/SingleDbJDBCConnection.java
jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/HSQLDBConnectionFactory.java
jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/HSQLDBMultiDbJDBCConnection.java
jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/HSQLDBSingleDbJDBCConnection.java
jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java
jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java
Log:
EXOJCR-404 impl of Value will null file load (swap file actually)
Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java 2010-01-20 12:41:55 UTC (rev 1503)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java 2010-01-20 12:46:45 UTC (rev 1504)
@@ -24,8 +24,10 @@
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.datamodel.ValueData;
import org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.JBossCacheWorkspaceStorageCache;
import org.exoplatform.services.jcr.impl.storage.SystemDataContainerHolder;
+import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCStorageConnection;
import org.exoplatform.services.jcr.storage.WorkspaceDataContainer;
import org.exoplatform.services.transaction.TransactionService;
@@ -433,12 +435,37 @@
{
data = getPersistedItemData(parentData, name);
}
- // else if (!data.isNode() && ((PropertyData)data).getValues() == null)
- // {
- // // refill the property data if values invalid (null)
- // data = fillPropertyValue((PropertyData)data);
- // }
+ else if (!data.isNode())
+ {
+ PropertyData prop = (PropertyData)data;
+ List<ValueData> vals = prop.getValues();
+ for (int i = 0; i < vals.size(); i++)
+ {
+ ValueData vd = vals.get(i);
+ if (!vd.isByteArray())
+ {
+ // check if file is correct
+ FilePersistedValueData fpvd = (FilePersistedValueData)vd;
+ if (fpvd.getFile() == null)
+ {
+ // need read from storage
+ ValueData svd =
+ getPropertyValue(prop.getIdentifier(), vd.getOrderNumber(), prop.getPersistedVersion());
+ if (svd == null)
+ {
+ // error, value not found
+ throw new RepositoryException("Value cannot be found in storage for cached Property "
+ + prop.getQPath().getAsString() + ", orderNumb:" + vd.getOrderNumber() + ", pversion:"
+ + prop.getPersistedVersion());
+ }
+
+ vals.set(i, vd);
+ }
+ }
+ }
+ }
+
return data;
}
@@ -739,27 +766,26 @@
return transactionManager != null;
}
- // /**
- // * Fill Property Value from persistent storage.
- // *
- // * @param prop PropertyData, original Property data
- // * @return PropertyData
- // * @throws IllegalStateException
- // * @throws RepositoryException
- // */
- // protected PropertyData fillPropertyValue(PropertyData prop) throws IllegalStateException, RepositoryException
- // {
- // // TODO use interface not JDBC
- // JDBCStorageConnection conn = (JDBCStorageConnection)dataContainer.openConnection();
- // try
- // {
- // return new PersistedPropertyData(prop.getIdentifier(), prop.getQPath(), prop.getParentIdentifier(), prop
- // .getPersistedVersion(), prop.getType(), prop.isMultiValued(), conn.getPropertyValues(prop.getIdentifier(),
- // prop.getPersistedVersion()));
- // }
- // finally
- // {
- // conn.close();
- // }
- // }
+ /**
+ * Fill Property Value from persistent storage.
+ *
+ * @param prop PropertyData, original Property data
+ * @return PropertyData
+ * @throws IllegalStateException
+ * @throws RepositoryException
+ */
+ protected ValueData getPropertyValue(String propertyId, int orderNumb, int persistedVersion)
+ throws IllegalStateException, RepositoryException
+ {
+ // TODO use interface not JDBC
+ JDBCStorageConnection conn = (JDBCStorageConnection)dataContainer.openConnection();
+ try
+ {
+ return conn.getValue(propertyId, orderNumb, persistedVersion);
+ }
+ finally
+ {
+ conn.close();
+ }
+ }
}
\ No newline at end of file
Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/FilePersistedValueData.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/FilePersistedValueData.java 2010-01-20 12:41:55 UTC (rev 1503)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/FilePersistedValueData.java 2010-01-20 12:46:45 UTC (rev 1504)
@@ -21,6 +21,7 @@
import org.exoplatform.services.jcr.datamodel.ValueData;
import org.exoplatform.services.jcr.impl.dataflow.AbstractPersistedValueData;
import org.exoplatform.services.jcr.impl.dataflow.TransientValueData;
+import org.exoplatform.services.jcr.impl.util.io.SwapFile;
import java.io.Externalizable;
import java.io.File;
@@ -76,7 +77,7 @@
this.file = file;
}
- public File getFile() throws IOException
+ public File getFile()
{
return file;
}
@@ -165,23 +166,15 @@
if (!isByteArray() && !another.isByteArray())
{
// compare files
- try
+ if (another instanceof TransientValueData)
{
- if (another instanceof TransientValueData)
- {
- // if another transient
- return file.equals(((TransientValueData)another).getSpoolFile());
- }
- else if (another instanceof FilePersistedValueData)
- {
- // both from peristent layer
- return file.equals(((FilePersistedValueData)another).getFile());
- }
+ // if another transient
+ return file.equals(((TransientValueData)another).getSpoolFile());
}
- catch (IOException e)
+ else if (another instanceof FilePersistedValueData)
{
- LOG.error("Read error", e);
- return false;
+ // both from peristent layer
+ return file.equals(((FilePersistedValueData)another).getFile());
}
}
return false;
@@ -244,11 +237,21 @@
byte[] buf = new byte[size];
in.readFully(buf);
- file = new File(new String(buf, "UTF-8"));
+ File f = new File(new String(buf, "UTF-8"));
+ // validate if exists
+ if (f.exists())
+ {
+ file = f;
+ }
+ else
+ {
+ file = null;
+ }
}
else
{
- throw new IOException("Persisted ValueData with null file found");
+ // should not occurs
+ throw new IOException("readExternal: Persisted ValueData with null file found");
}
}
@@ -268,7 +271,7 @@
}
else
{
- throw new IOException("Persisted ValueData with null file found");
+ throw new IOException("writeExternal: Persisted ValueData with null file found");
}
}
}
Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/DBConstants.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/DBConstants.java 2010-01-20 12:41:55 UTC (rev 1503)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/DBConstants.java 2010-01-20 12:46:45 UTC (rev 1504)
@@ -119,7 +119,9 @@
*/
protected String FIND_VALUES_VSTORAGE_DESC_BY_PROPERTYID;
- @Deprecated
+ /**
+ * FIND_VALUE_BY_PROPERTYID_OREDERNUMB.
+ */
protected String FIND_VALUE_BY_PROPERTYID_OREDERNUMB;
/**
Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java 2010-01-20 12:41:55 UTC (rev 1503)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java 2010-01-20 12:46:45 UTC (rev 1504)
@@ -71,7 +71,7 @@
* @author <a href="mailto:gennady.azarenkov@exoplatform.com">Gennady Azarenkov</a>
* @version $Id: JDBCStorageConnection.java 34801 2009-07-31 15:44:50Z dkatayev $
*/
-abstract public class JDBCStorageConnection extends DBConstants implements WorkspaceStorageConnection
+public abstract class JDBCStorageConnection extends DBConstants implements WorkspaceStorageConnection
{
/**
@@ -783,6 +783,47 @@
}
}
+ /**
+ * Reads Property Value from persistent storage.
+ *
+ * @param propertyId String, Property id
+ * @param orderNumb int, Value order number (in list of values)
+ * @param persistedVersion int
+ * @return ValueData
+ * @throws RepositoryException if read error occurs
+ */
+ public ValueData getValue(String propertyId, int orderNumb, int persistedVersion) throws RepositoryException
+ {
+ try
+ {
+ final String cid = getInternalId(propertyId);
+ final ResultSet valueRecord = findValueByPropertyIdOrderNumber(cid, orderNumb);
+ try
+ {
+ if (valueRecord.next())
+ {
+ final String storageId = valueRecord.getString(COLUMN_VSTORAGE_DESC);
+ return valueRecord.wasNull() ? readValueData(cid, orderNumb, persistedVersion, valueRecord
+ .getBinaryStream(COLUMN_VDATA)) : readValueData(propertyId, orderNumb, storageId);
+ }
+ }
+ finally
+ {
+ valueRecord.close();
+ }
+
+ return null;
+ }
+ catch (SQLException e)
+ {
+ throw new RepositoryException(e);
+ }
+ catch (IOException e)
+ {
+ throw new RepositoryException(e);
+ }
+ }
+
// ------------------ Private methods ---------------
/**
@@ -2016,6 +2057,5 @@
protected abstract ResultSet findValuesStorageDescriptorsByPropertyId(String cid) throws SQLException;
- @Deprecated
protected abstract ResultSet findValueByPropertyIdOrderNumber(String cid, int orderNumb) throws SQLException;
}
Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MultiDbJDBCConnection.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MultiDbJDBCConnection.java 2010-01-20 12:41:55 UTC (rev 1503)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MultiDbJDBCConnection.java 2010-01-20 12:46:45 UTC (rev 1504)
@@ -73,7 +73,6 @@
protected PreparedStatement findValuesStorageDescriptorsByPropertyId;
- @Deprecated
protected PreparedStatement findValueByPropertyIdOrderNumber;
protected PreparedStatement findNodesByParentId;
Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/SingleDbJDBCConnection.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/SingleDbJDBCConnection.java 2010-01-20 12:41:55 UTC (rev 1503)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/SingleDbJDBCConnection.java 2010-01-20 12:46:45 UTC (rev 1504)
@@ -551,13 +551,16 @@
/**
* {@inheritDoc}
*/
- @Deprecated
protected ResultSet findValueByPropertyIdOrderNumber(String cid, int orderNumb) throws SQLException
{
if (findValueByPropertyIdOrderNumber == null)
+ {
findValueByPropertyIdOrderNumber = dbConnection.prepareStatement(FIND_VALUE_BY_PROPERTYID_OREDERNUMB);
+ }
else
+ {
findValueByPropertyIdOrderNumber.clearParameters();
+ }
findValueByPropertyIdOrderNumber.setString(1, cid);
findValueByPropertyIdOrderNumber.setInt(2, orderNumb);
@@ -571,9 +574,13 @@
protected int renameNode(NodeData data) throws SQLException
{
if (renameNode == null)
+ {
renameNode = dbConnection.prepareStatement(RENAME_NODE);
+ }
else
+ {
renameNode.clearParameters();
+ }
renameNode.setString(1, data.getParentIdentifier() == null ? Constants.ROOT_PARENT_UUID : getInternalId(data
.getParentIdentifier()));
Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/HSQLDBConnectionFactory.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/HSQLDBConnectionFactory.java 2010-01-20 12:41:55 UTC (rev 1503)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/HSQLDBConnectionFactory.java 2010-01-20 12:46:45 UTC (rev 1504)
@@ -32,7 +32,7 @@
* 26.08.2009
*
* @author <a href="mailto:dezder@bk.ru">Denis Grebenyuk</a>
- * @version $Id:$
+ * @version $Id$
*/
public class HSQLDBConnectionFactory extends GenericCQConnectionFactory
{
Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/HSQLDBMultiDbJDBCConnection.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/HSQLDBMultiDbJDBCConnection.java 2010-01-20 12:41:55 UTC (rev 1503)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/HSQLDBMultiDbJDBCConnection.java 2010-01-20 12:46:45 UTC (rev 1504)
@@ -29,7 +29,7 @@
* 26.08.2009
*
* @author <a href="mailto:dezder@bk.ru">Denis Grebenyuk</a>
- * @version $Id:$
+ * @version $Id$
*/
public class HSQLDBMultiDbJDBCConnection extends MultiDbJDBCConnection
{
Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/HSQLDBSingleDbJDBCConnection.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/HSQLDBSingleDbJDBCConnection.java 2010-01-20 12:41:55 UTC (rev 1503)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/HSQLDBSingleDbJDBCConnection.java 2010-01-20 12:46:45 UTC (rev 1504)
@@ -30,7 +30,7 @@
* 26.08.2009
*
* @author <a href="mailto:dezder@bk.ru">Denis Grebenyuk</a>
- * @version $Id:$
+ * @version $Id$
*/
public class HSQLDBSingleDbJDBCConnection extends SingleDbJDBCConnection
{
Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java 2010-01-20 12:41:55 UTC (rev 1503)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java 2010-01-20 12:46:45 UTC (rev 1504)
@@ -75,7 +75,6 @@
protected PreparedStatement findValuesStorageDescriptorsByPropertyId;
- @Deprecated
protected PreparedStatement findValueByPropertyIdOrderNumber;
protected PreparedStatement findNodesByParentId;
Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java 2010-01-20 12:41:55 UTC (rev 1503)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java 2010-01-20 12:46:45 UTC (rev 1504)
@@ -587,13 +587,16 @@
/**
* {@inheritDoc}
*/
- @Deprecated
protected ResultSet findValueByPropertyIdOrderNumber(String cid, int orderNumb) throws SQLException
{
if (findValueByPropertyIdOrderNumber == null)
+ {
findValueByPropertyIdOrderNumber = dbConnection.prepareStatement(FIND_VALUE_BY_PROPERTYID_OREDERNUMB);
+ }
else
+ {
findValueByPropertyIdOrderNumber.clearParameters();
+ }
findValueByPropertyIdOrderNumber.setString(1, cid);
findValueByPropertyIdOrderNumber.setInt(2, orderNumb);
16 years, 3 months
exo-jcr SVN: r1503 - jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache.
by do-not-reply@jboss.org
Author: nzamosenchuk
Date: 2010-01-20 07:41:55 -0500 (Wed, 20 Jan 2010)
New Revision: 1503
Modified:
jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java
Log:
EXOJCR-423: Partially applied recommendations from issue#423. with checks if node exists. Initial structure creation is done without transactions and locally only now.
EXOJCR-396: Partially applied recommendations from issue#423. with checks if node exists. Initial structure creation is done without transactions and locally only now.
Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java 2010-01-20 11:37:11 UTC (rev 1502)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java 2010-01-20 12:41:55 UTC (rev 1503)
@@ -41,6 +41,7 @@
import org.jboss.cache.DefaultCacheFactory;
import org.jboss.cache.Fqn;
import org.jboss.cache.Node;
+import org.jboss.cache.UnversionedNode;
import java.io.Serializable;
import java.util.ArrayList;
@@ -106,8 +107,6 @@
public static final String LOCKS = "$LOCKS".intern();
- public static final String REFS = "$REFS".intern();
-
public static final String ITEM_DATA = "$data".intern();
public static final String ITEM_ID = "$id".intern();
@@ -126,8 +125,6 @@
protected final Fqn<String> childPropsList;
- protected final Fqn<String> refsRoot;
-
/**
* Node order comparator for getChildNodes().
*/
@@ -290,39 +287,34 @@
cache.getConfiguration().getRuntimeConfig().setTransactionManager(transactionManager);
}
- this.cache.create();
- this.cache.start();
-
this.itemsRoot = Fqn.fromElements(ITEMS);
this.childNodes = Fqn.fromElements(CHILD_NODES);
this.childProps = Fqn.fromElements(CHILD_PROPS);
this.childNodesList = Fqn.fromElements(CHILD_NODES_LIST);
this.childPropsList = Fqn.fromElements(CHILD_PROPS_LIST);
- this.refsRoot = Fqn.fromElements(REFS);
- // prepare cache structures
- prepareCache();
+ this.cache.create();
+ this.cache.start();
+
+ createResidentNode(childNodes);
+ createResidentNode(childNodesList);
+ createResidentNode(childProps);
+ createResidentNode(childPropsList);
+ createResidentNode(itemsRoot);
}
- protected void prepareCache() throws RepositoryException
+ /**
+ * Checks if node with give FQN not exists and creates resident node.
+ * @param fqn
+ */
+ protected void createResidentNode(Fqn fqn)
{
- TransactionManager txm = cache.getTransactionManager();
- final Node<Serializable, Object> cacheRoot = cache.getRoot();
- TxIsolatedOperation prepare = new TxIsolatedOperation(txm)
+ Node<Serializable, Object> cacheRoot = cache.getRoot();
+ if (!cacheRoot.hasChild(fqn))
{
- @Override
- protected void action() throws RepositoryException
- {
- cacheRoot.addChild(itemsRoot).setResident(true);
- cacheRoot.addChild(childNodes).setResident(true);
- cacheRoot.addChild(childNodesList).setResident(true);
- cacheRoot.addChild(childProps).setResident(true);
- cacheRoot.addChild(childPropsList).setResident(true);
- cacheRoot.addChild(refsRoot).setResident(true);
- }
- };
-
- prepare.perform();
+ cache.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
+ cacheRoot.addChild(fqn).setResident(true);
+ }
}
protected static String readJBCConfig(final WorkspaceEntry wsConfig) throws RepositoryConfigurationException
16 years, 3 months
exo-jcr SVN: r1502 - core/trunk.
by do-not-reply@jboss.org
Author: dkatayev
Date: 2010-01-20 06:37:11 -0500 (Wed, 20 Jan 2010)
New Revision: 1502
Modified:
core/trunk/pom.xml
Log:
EXOJCR-388 dependencies versions updated according to EAP
Modified: core/trunk/pom.xml
===================================================================
--- core/trunk/pom.xml 2010-01-20 11:30:02 UTC (rev 1501)
+++ core/trunk/pom.xml 2010-01-20 11:37:11 UTC (rev 1502)
@@ -194,13 +194,13 @@
<dependency>
<groupId>xdoclet</groupId>
<artifactId>xdoclet-xdoclet-module</artifactId>
- <version>1.2</version>
+ <version>1.2.3</version>
</dependency>
<dependency>
<groupId>xdoclet</groupId>
<artifactId>xjavadoc</artifactId>
- <version>1.0.3</version>
+ <version>1.2.3</version>
</dependency>
<dependency>
16 years, 3 months
exo-jcr SVN: r1501 - kernel/trunk.
by do-not-reply@jboss.org
Author: dkatayev
Date: 2010-01-20 06:30:02 -0500 (Wed, 20 Jan 2010)
New Revision: 1501
Modified:
kernel/trunk/pom.xml
Log:
EXOJCR-388 dependencies versions updated according to EAP
Modified: kernel/trunk/pom.xml
===================================================================
--- kernel/trunk/pom.xml 2010-01-20 11:13:42 UTC (rev 1500)
+++ kernel/trunk/pom.xml 2010-01-20 11:30:02 UTC (rev 1501)
@@ -94,12 +94,12 @@
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
- <version>1.0.4</version>
+ <version>1.1</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
- <version>1.6</version>
+ <version>1.8.0</version>
</dependency>
<dependency>
<groupId>commons-chain</groupId>
@@ -109,17 +109,17 @@
<dependency>
<groupId>commons-digester</groupId>
<artifactId>commons-digester</artifactId>
- <version>1.6</version>
+ <version>1.8.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
- <version>1.5.6</version>
+ <version>1.5.8</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
- <version>1.5.6</version>
+ <version>1.5.8</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
@@ -139,7 +139,7 @@
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
- <version>1.4</version>
+ <version>1.4.2</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
16 years, 3 months
exo-jcr SVN: r1500 - junit.framework/trunk.
by do-not-reply@jboss.org
Author: dkatayev
Date: 2010-01-20 06:13:42 -0500 (Wed, 20 Jan 2010)
New Revision: 1500
Modified:
junit.framework/trunk/pom.xml
Log:
EXOJCR-388 javax.faces:jsf-api dependency version updated
Modified: junit.framework/trunk/pom.xml
===================================================================
--- junit.framework/trunk/pom.xml 2010-01-20 10:51:57 UTC (rev 1499)
+++ junit.framework/trunk/pom.xml 2010-01-20 11:13:42 UTC (rev 1500)
@@ -67,7 +67,7 @@
<dependency>
<groupId>javax.faces</groupId>
<artifactId>jsf-api</artifactId>
- <version>1.2</version>
+ <version>1.2_13</version>
</dependency>
<dependency>
16 years, 3 months
exo-jcr SVN: r1499 - jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache.
by do-not-reply@jboss.org
Author: areshetnyak
Date: 2010-01-20 05:51:57 -0500 (Wed, 20 Jan 2010)
New Revision: 1499
Modified:
jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManager.java
Log:
EXOJCR-332 : The CacheableLockManaget was changed to direct get/put nodes witout keeping JBossCache node.
Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManager.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManager.java 2010-01-20 10:17:48 UTC (rev 1498)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManager.java 2010-01-20 10:51:57 UTC (rev 1499)
@@ -1,748 +1,765 @@
-/*
- * 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.management.jmx.annotations.NameTemplate;
-import org.exoplatform.management.jmx.annotations.Property;
-import org.exoplatform.services.jcr.access.SystemIdentity;
-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.NodeImpl;
-import org.exoplatform.services.jcr.impl.core.lock.AbstractLockManager;
-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.naming.InitialContextInitializer;
-import org.jboss.cache.Cache;
-import org.jboss.cache.CacheFactory;
-import org.jboss.cache.DefaultCacheFactory;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.Node;
-import org.picocontainer.Startable;
-
-import java.io.Serializable;
-import java.math.BigInteger;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.jcr.RepositoryException;
-import javax.jcr.lock.LockException;
-
-/**
- * Created by The eXo Platform SAS.
- *
- * <br/>Date:
- *
- * @author <a href="karpenko.sergiy(a)gmail.com">Karpenko Sergiy</a>
- * @version $Id: CacheableLockManager.java 111 2008-11-11 11:11:11Z serg $
- */
-@Managed
-@NameTemplate(@Property(key = "service", value = "lockmanager"))
-public class CacheableLockManager extends AbstractLockManager implements 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 JBOSSCACCHE_CONFIG = "jbosscache-configuration";
-
- /**
- * Default lock time out. 30min
- */
- public static final long DEFAULT_LOCK_TIMEOUT = 1000 * 60 * 30;
-
- // Search constants
- /**
- * The exact lock token.
- */
- protected static final int SEARCH_EXECMATCH = 1;
-
- /**
- * Lock token of closed parent
- */
- protected static final int SEARCH_CLOSEDPARENT = 2;
-
- /**
- * Lock token of closed child
- */
- protected static final int SEARCH_CLOSEDCHILD = 4;
-
- /**
- * Name of lock root in jboss-cache.
- */
- public static final String LOCKS = "$LOCKS";
-
- /**
- * Attribute name where LockData will be stored.
- */
- public static final String LOCK_DATA = "$LOCK_DATA";
-
- /**
- * Logger
- */
- private final Log log = ExoLogger.getLogger("jcr.lock.CacheableLockManager");
-
- /**
- * Data manager.
- */
- private final DataManager dataManager;
-
- /**
- * Map NodeIdentifier -- lockData
- */
- private final Map<String, LockData> pendingLocks;
-
- /**
- * Context recall is a workaround of JDBCCacheLoader starting.
- */
- private final InitialContextInitializer context;
-
- /**
- * Run time lock time out.
- */
- private long lockTimeOut;
-
- /**
- * Lock remover thread.
- */
- private LockRemover lockRemover;
-
- private Cache<Serializable, Object> cache;
-
- private Node<Serializable, Object> lockRoot;
-
- private Map<String, CacheableSessionLockManager> sessionLockManagers;
-
- /**
- * Constructor.
- *
- * @param dataManager - workspace persistent data manager
- * @param config - workspace entry
- * @param context InitialContextInitializer, needed to reload context after JBoss cache creation
- * @throws RepositoryConfigurationException
- */
- public CacheableLockManager(WorkspacePersistentDataManager dataManager, WorkspaceEntry config,
- InitialContextInitializer context) throws RepositoryConfigurationException
- {
- 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;
-
- pendingLocks = new HashMap<String, LockData>();
- sessionLockManagers = new HashMap<String, CacheableSessionLockManager>();
- this.context = context;
-
- dataManager.addItemPersistenceListener(this);
-
- // make cache
- if (config.getLockManager() != null
- && (config.getLockManager().getCacheConfig() != null || (paramenerts != null && config.getLockManager()
- .getParameterValue(JBOSSCACCHE_CONFIG, null) != null)))
- {
- String pathToConfig =
- (paramenerts != null && config.getLockManager().getParameterValue(JBOSSCACCHE_CONFIG, null) != null)
- ? config.getLockManager().getParameterValue(JBOSSCACCHE_CONFIG) : config.getLockManager()
- .getCacheConfig();
- CacheFactory<Serializable, Object> factory = new DefaultCacheFactory<Serializable, Object>();
- cache = factory.createCache(pathToConfig, false);
- cache.create();
- }
- else
- {
- throw new RepositoryConfigurationException("Cache configuration not found");
- }
- }
-
- /*
- * (non-Javadoc)
- * @see
- * org.exoplatform.services.jcr.impl.core.lock.LockManager#addPendingLock(org.exoplatform.services
- * .jcr.impl.core.NodeImpl, boolean, boolean, long)
- */
- public synchronized void addPendingLock(String nodeIdentifier, LockData lData)
- {
- pendingLocks.put(nodeIdentifier, lData);
- }
-
- @Managed
- @ManagedDescription("Remove the expired locks")
- public void cleanExpiredLocks()
- {
- removeExpired();
- }
-
- public long getDefaultLockTimeOut()
- {
- return lockTimeOut;
- }
-
- /*
- * (non-Javadoc)
- * @see
- * org.exoplatform.services.jcr.impl.core.lock.LockManager#getLock(org.exoplatform.services.jcr
- * .impl.core.NodeImpl)
- */
- public LockData getLockData(NodeImpl node) throws LockException, RepositoryException
- {
-
- LockData lData = getLockData((NodeData)node.getData(), SEARCH_EXECMATCH | SEARCH_CLOSEDPARENT);
-
- if (lData == null || (!node.getInternalIdentifier().equals(lData.getNodeIdentifier()) && !lData.isDeep()))
- {
- throw new LockException("Node not locked: " + node.getData().getQPath());
- }
- return lData;
- }
-
- @Managed
- @ManagedDescription("The number of active locks")
- public int getNumLocks()
- {
- return lockRoot.getChildrenNames().size();
- }
-
- /**
- * Return new instance of session lock manager.
- */
- public SessionLockManager getSessionLockManager(String sessionId)
- {
- CacheableSessionLockManager sessionManager = new CacheableSessionLockManager(sessionId, this);
- 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)
- {
- if (pendingLocks.containsKey(nodeId) || lockRoot.hasChild(Fqn.fromString(nodeId)))
- {
- return true;
- }
-
- 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());
- }
- }
-
- for (PlainChangesLog currChangesLog : chengesLogList)
- {
- 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();
-
- if (pendingLocks.containsKey(nodeIdentifier))
- {
- internalLock(nodeIdentifier);
- }
- else
- {
- throw new LockException("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;
- }
-
- internalUnLock(currChangesLog.getSessionId(), currChangesLog.getAllStates().get(0).getData()
- .getParentIdentifier());
- 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)
- {
- internalUnLock(currChangesLog.getSessionId(), identifier);
- }
- break;
- }
- }
- catch (LockException e)
- {
- log.error(e.getLocalizedMessage(), e);
- }
- catch (IllegalStateException e)
- {
- log.error(e.getLocalizedMessage(), e);
- }
- }
- }
-
- /**
- * Refreshed lock data in cache
- *
- * @param newLockData
- */
- public void refresh(LockData newLockData) throws LockException
- {
- //first look pending locks
- if (pendingLocks.containsKey(newLockData.getNodeIdentifier()))
- {
- pendingLocks.put(newLockData.getNodeIdentifier(), newLockData);
- }
- else
- {
- Fqn<String> id = Fqn.fromString(newLockData.getNodeIdentifier());
- if (lockRoot.hasChild(id))
- {
- lockRoot.addChild(id);
- }
- else
- {
- throw new LockException("Can't refresh lock for node " + newLockData.getNodeIdentifier()
- + " since lock is not exist");
- }
- }
- }
-
- /**
- * 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());
- }
- }
-
- for (String rLock : removeLockList)
- {
- removeLock(rLock);
- }
- }
-
- public void removePendingLock(String nodeId)
- {
- pendingLocks.remove(nodeId);
- }
-
- /*
- * (non-Javadoc)
- * @see org.picocontainer.Startable#start()
- */
- public void start()
- {
- cache.start();
- // Context recall is a workaround of JDBCCacheLoader starting.
- context.recall();
- lockRoot = cache.getRoot().addChild(Fqn.fromString(LOCKS));
- lockRoot.setResident(true);
- lockRemover = new LockRemover(this);
- }
-
- /*
- * (non-Javadoc)
- * @see org.picocontainer.Startable#stop()
- */
- public void stop()
- {
- lockRemover.halt();
- lockRemover.interrupt();
- pendingLocks.clear();
- sessionLockManagers.clear();
- cache.stop();
- }
-
- /**
- * 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 nodeIdentifier) throws LockException
- {
- LockData lockData = pendingLocks.get(nodeIdentifier);
- if (lockData != null)
- {
- Fqn<String> lockPath = Fqn.fromString(lockData.getNodeIdentifier());
-
- // addChild will add if absent or return old if present
- Node<Serializable, Object> node = lockRoot.addChild(lockPath);
-
- // this will prevent from deleting by eviction.
- node.setResident(true);
-
- // this will return null if success. And old data if something exists...
- LockData oldLockData = (LockData)node.putIfAbsent(LOCK_DATA, lockData);
-
- if (oldLockData != null)
- {
- throw new LockException("Unable to write LockData. Node [" + lockData.getNodeIdentifier()
- + "] already has LockData!");
- }
- pendingLocks.remove(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)
- {
- lockRoot.removeChild(Fqn.fromString(nodeIdentifier));
-
- CacheableSessionLockManager sessMgr = sessionLockManagers.get(sessionId);
- if (sessMgr != null)
- {
- sessMgr.notifyLockRemoved(nodeIdentifier);
- }
- }
- }
-
- private boolean lockExist(String nodeId)
- {
- return lockRoot.hasChild(Fqn.fromString(nodeId));
- }
-
- /**
- * Calculates md5 hash of string.
- *
- * @param token
- * @return
- */
- protected String getHash(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;
- }
-
- /**
- * Search lock in maps.
- *
- * @param data
- * @param searchType
- * @return
- */
- protected LockData getLockData(NodeData data, int searchType)
- {
- if (data == null)
- return null;
- LockData retval = null;
- try
- {
- if ((searchType & SEARCH_EXECMATCH) != 0)
- {
- retval = getLockDataById(data.getIdentifier());
- }
- if (retval == null && (searchType & SEARCH_CLOSEDPARENT) != 0)
- {
-
- NodeData parentData = (NodeData)dataManager.getItemData(data.getParentIdentifier());
- if (parentData != null)
- {
- retval = getLockDataById(parentData.getIdentifier());
- // parent not found try to fo upper
- if (retval == null)
- {
- retval = getLockData(parentData, SEARCH_CLOSEDPARENT);
- }
- }
- }
- if (retval == null && (searchType & SEARCH_CLOSEDCHILD) != 0)
- {
-
- List<NodeData> childData = dataManager.getChildNodesData(data);
- for (NodeData nodeData : childData)
- {
- retval = getLockDataById(nodeData.getIdentifier());
- if (retval != null)
- break;
- }
- if (retval == null)
- {
- // child not found try to find diper
- for (NodeData nodeData : childData)
- {
- retval = getLockData(nodeData, SEARCH_CLOSEDCHILD);
- if (retval != null)
- break;
- }
- }
- }
- }
- catch (RepositoryException e)
- {
- return null;
- }
-
- return retval;
- }
-
- protected LockData getLockDataById(String nodeId)
- {
- LockData lockData = null;
- Node<Serializable, Object> node = lockRoot.getChild(Fqn.fromString(nodeId));
- if (node != null)
- {
- lockData = (LockData)node.get(LOCK_DATA);
- }
- return lockData;
- }
-
- protected synchronized List<LockData> getLockList()
- {
- Set<Node<Serializable, Object>> lockSet = lockRoot.getChildren();
-
- List<LockData> locksData = new ArrayList<LockData>();
- for (Node<Serializable, Object> node : lockSet)
- {
- if (node != null)
- {
- LockData lockData = (LockData)node.get(LOCK_DATA);
- if (lockData != null)
- {
- locksData.add(lockData);
- }
- }
- }
- return locksData;
- }
-
- /**
- * Remove lock, used by Lock remover.
- *
- * @param nodeIdentifier String
- */
- protected void removeLock(String nodeIdentifier)
- {
- try
- {
- NodeData nData = (NodeData)dataManager.getItemData(nodeIdentifier);
- 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);
- }
- }
-
- /**
- * Release all resources associated with CacheableSessionLockManager.
- *
- * @param sessionID - session identifier
- */
- protected void closeSession(String sessionID)
- {
- sessionLockManagers.remove(sessionID);
- }
-}
+/*
+ * 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.management.jmx.annotations.NameTemplate;
+import org.exoplatform.management.jmx.annotations.Property;
+import org.exoplatform.services.jcr.access.SystemIdentity;
+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.NodeImpl;
+import org.exoplatform.services.jcr.impl.core.lock.AbstractLockManager;
+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.naming.InitialContextInitializer;
+import org.jboss.cache.Cache;
+import org.jboss.cache.CacheFactory;
+import org.jboss.cache.DefaultCacheFactory;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.Node;
+import org.picocontainer.Startable;
+
+import java.io.Serializable;
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.lock.LockException;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * <br/>Date:
+ *
+ * @author <a href="karpenko.sergiy(a)gmail.com">Karpenko Sergiy</a>
+ * @version $Id: CacheableLockManager.java 111 2008-11-11 11:11:11Z serg $
+ */
+@Managed
+@NameTemplate(@Property(key = "service", value = "lockmanager"))
+public class CacheableLockManager extends AbstractLockManager implements 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 JBOSSCACCHE_CONFIG = "jbosscache-configuration";
+
+ /**
+ * Default lock time out. 30min
+ */
+ public static final long DEFAULT_LOCK_TIMEOUT = 1000 * 60 * 30;
+
+ // Search constants
+ /**
+ * The exact lock token.
+ */
+ protected static final int SEARCH_EXECMATCH = 1;
+
+ /**
+ * Lock token of closed parent
+ */
+ protected static final int SEARCH_CLOSEDPARENT = 2;
+
+ /**
+ * Lock token of closed child
+ */
+ protected static final int SEARCH_CLOSEDCHILD = 4;
+
+ /**
+ * Name of lock root in jboss-cache.
+ */
+ public static final String LOCKS = "$LOCKS";
+
+ /**
+ * Attribute name where LockData will be stored.
+ */
+ public static final String LOCK_DATA = "$LOCK_DATA";
+
+ /**
+ * Logger
+ */
+ private final Log log = ExoLogger.getLogger("jcr.lock.CacheableLockManager");
+
+ /**
+ * Data manager.
+ */
+ private final DataManager dataManager;
+
+ /**
+ * Map NodeIdentifier -- lockData
+ */
+ private final Map<String, LockData> pendingLocks;
+
+ /**
+ * Context recall is a workaround of JDBCCacheLoader starting.
+ */
+ private final InitialContextInitializer context;
+
+ /**
+ * Run time lock time out.
+ */
+ private long lockTimeOut;
+
+ /**
+ * Lock remover thread.
+ */
+ private LockRemover lockRemover;
+
+ private Cache<Serializable, Object> cache;
+
+ private final Fqn<String> lockRoot;
+
+ private Map<String, CacheableSessionLockManager> sessionLockManagers;
+
+ /**
+ * Constructor.
+ *
+ * @param dataManager - workspace persistent data manager
+ * @param config - workspace entry
+ * @param context InitialContextInitializer, needed to reload context after JBoss cache creation
+ * @throws RepositoryConfigurationException
+ */
+ public CacheableLockManager(WorkspacePersistentDataManager dataManager, WorkspaceEntry config,
+ InitialContextInitializer context) throws RepositoryConfigurationException
+ {
+ 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;
+
+ pendingLocks = new HashMap<String, LockData>();
+ sessionLockManagers = new HashMap<String, CacheableSessionLockManager>();
+ this.context = context;
+
+ dataManager.addItemPersistenceListener(this);
+
+ // make cache
+ if (config.getLockManager() != null
+ && (config.getLockManager().getCacheConfig() != null || (paramenerts != null && config.getLockManager()
+ .getParameterValue(JBOSSCACCHE_CONFIG, null) != null)))
+ {
+ String pathToConfig =
+ (paramenerts != null && config.getLockManager().getParameterValue(JBOSSCACCHE_CONFIG, null) != null)
+ ? config.getLockManager().getParameterValue(JBOSSCACCHE_CONFIG) : config.getLockManager()
+ .getCacheConfig();
+ CacheFactory<Serializable, Object> factory = new DefaultCacheFactory<Serializable, Object>();
+
+ // Context recall is a workaround of JDBCCacheLoader starting.
+ context.recall();
+
+ cache = factory.createCache(pathToConfig, false);
+ cache.create();
+ }
+ else
+ {
+ throw new RepositoryConfigurationException("Cache configuration not found");
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see
+ * org.exoplatform.services.jcr.impl.core.lock.LockManager#addPendingLock(org.exoplatform.services
+ * .jcr.impl.core.NodeImpl, boolean, boolean, long)
+ */
+ public synchronized void addPendingLock(String nodeIdentifier, LockData lData)
+ {
+ pendingLocks.put(nodeIdentifier, lData);
+ }
+
+ @Managed
+ @ManagedDescription("Remove the expired locks")
+ public void cleanExpiredLocks()
+ {
+ removeExpired();
+ }
+
+ public long getDefaultLockTimeOut()
+ {
+ return lockTimeOut;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see
+ * org.exoplatform.services.jcr.impl.core.lock.LockManager#getLock(org.exoplatform.services.jcr
+ * .impl.core.NodeImpl)
+ */
+ public LockData getLockData(NodeImpl node) throws LockException, RepositoryException
+ {
+
+ LockData lData = getLockData((NodeData)node.getData(), SEARCH_EXECMATCH | SEARCH_CLOSEDPARENT);
+
+ if (lData == null || (!node.getInternalIdentifier().equals(lData.getNodeIdentifier()) && !lData.isDeep()))
+ {
+ throw new LockException("Node not locked: " + node.getData().getQPath());
+ }
+ return lData;
+ }
+
+ @Managed
+ @ManagedDescription("The number of active locks")
+ public int getNumLocks()
+ {
+ return cache.getChildrenNames(lockRoot).size();
+ }
+
+ /**
+ * Return new instance of session lock manager.
+ */
+ public SessionLockManager getSessionLockManager(String sessionId)
+ {
+ CacheableSessionLockManager sessionManager = new CacheableSessionLockManager(sessionId, this);
+ 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)
+ {
+ if (pendingLocks.containsKey(nodeId) || cache.getRoot().hasChild(makeLockFqn(nodeId)))
+ {
+ return true;
+ }
+
+ 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());
+ }
+ }
+
+ for (PlainChangesLog currChangesLog : chengesLogList)
+ {
+ 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();
+
+ if (pendingLocks.containsKey(nodeIdentifier))
+ {
+ internalLock(nodeIdentifier);
+ }
+ else
+ {
+ throw new LockException("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;
+ }
+
+ internalUnLock(currChangesLog.getSessionId(), currChangesLog.getAllStates().get(0).getData()
+ .getParentIdentifier());
+ 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)
+ {
+ internalUnLock(currChangesLog.getSessionId(), identifier);
+ }
+ break;
+ }
+ }
+ catch (LockException e)
+ {
+ log.error(e.getLocalizedMessage(), e);
+ }
+ catch (IllegalStateException e)
+ {
+ log.error(e.getLocalizedMessage(), e);
+ }
+ }
+ }
+
+ /**
+ * Refreshed lock data in cache
+ *
+ * @param newLockData
+ */
+ public void refresh(LockData newLockData) throws LockException
+ {
+ //first look pending locks
+ if (pendingLocks.containsKey(newLockData.getNodeIdentifier()))
+ {
+ pendingLocks.put(newLockData.getNodeIdentifier(), newLockData);
+ }
+ else
+ {
+ Fqn<String> fqn = makeLockFqn(newLockData.getNodeIdentifier());
+ if (cache.getRoot().hasChild(fqn))
+ {
+ cache.getRoot().addChild(fqn);
+ }
+ else
+ {
+ throw new LockException("Can't refresh lock for node " + newLockData.getNodeIdentifier()
+ + " since lock is not exist");
+ }
+ }
+ }
+
+ /**
+ * 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());
+ }
+ }
+
+ for (String rLock : removeLockList)
+ {
+ removeLock(rLock);
+ }
+ }
+
+ public void removePendingLock(String nodeId)
+ {
+ pendingLocks.remove(nodeId);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.picocontainer.Startable#start()
+ */
+ public void start()
+ {
+ cache.start();
+
+ if (!cache.getRoot().hasChild(lockRoot))
+ {
+ cache.getRoot().addChild(lockRoot);
+ }
+
+ // Context recall is a workaround of JDBCCacheLoader starting.
+ context.recall();
+ lockRemover = new LockRemover(this);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.picocontainer.Startable#stop()
+ */
+ public void stop()
+ {
+ lockRemover.halt();
+ lockRemover.interrupt();
+ pendingLocks.clear();
+ sessionLockManagers.clear();
+ cache.stop();
+ }
+
+ /**
+ * 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 nodeIdentifier) throws LockException
+ {
+ LockData lockData = pendingLocks.get(nodeIdentifier);
+ if (lockData != null)
+ {
+ Fqn<String> lockPath = makeLockFqn(lockData.getNodeIdentifier());
+
+ // addChild will add if absent or return old if present
+ Node<Serializable, Object> node = cache.getRoot().addChild(lockPath);
+
+ // this will return null if success. And old data if something exists...
+ LockData oldLockData = (LockData)node.putIfAbsent(LOCK_DATA, lockData);
+
+ if (oldLockData != null)
+ {
+ throw new LockException("Unable to write LockData. Node [" + lockData.getNodeIdentifier()
+ + "] already has LockData!");
+ }
+ pendingLocks.remove(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.removeNode(makeLockFqn(nodeIdentifier));
+
+ CacheableSessionLockManager sessMgr = sessionLockManagers.get(sessionId);
+ if (sessMgr != null)
+ {
+ sessMgr.notifyLockRemoved(nodeIdentifier);
+ }
+ }
+ }
+
+ private boolean lockExist(String nodeId)
+ {
+ return cache.getRoot().hasChild(makeLockFqn(nodeId));
+ }
+
+ /**
+ * Calculates md5 hash of string.
+ *
+ * @param token
+ * @return
+ */
+ protected String getHash(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;
+ }
+
+ /**
+ * Search lock in maps.
+ *
+ * @param data
+ * @param searchType
+ * @return
+ */
+ protected LockData getLockData(NodeData data, int searchType)
+ {
+ if (data == null)
+ return null;
+ LockData retval = null;
+ try
+ {
+ if ((searchType & SEARCH_EXECMATCH) != 0)
+ {
+ retval = getLockDataById(data.getIdentifier());
+ }
+ if (retval == null && (searchType & SEARCH_CLOSEDPARENT) != 0)
+ {
+
+ NodeData parentData = (NodeData)dataManager.getItemData(data.getParentIdentifier());
+ if (parentData != null)
+ {
+ retval = getLockDataById(parentData.getIdentifier());
+ // parent not found try to fo upper
+ if (retval == null)
+ {
+ retval = getLockData(parentData, SEARCH_CLOSEDPARENT);
+ }
+ }
+ }
+ if (retval == null && (searchType & SEARCH_CLOSEDCHILD) != 0)
+ {
+
+ List<NodeData> childData = dataManager.getChildNodesData(data);
+ for (NodeData nodeData : childData)
+ {
+ retval = getLockDataById(nodeData.getIdentifier());
+ if (retval != null)
+ break;
+ }
+ if (retval == null)
+ {
+ // child not found try to find diper
+ for (NodeData nodeData : childData)
+ {
+ retval = getLockData(nodeData, SEARCH_CLOSEDCHILD);
+ if (retval != null)
+ break;
+ }
+ }
+ }
+ }
+ catch (RepositoryException e)
+ {
+ return null;
+ }
+
+ return retval;
+ }
+
+ protected LockData getLockDataById(String nodeId)
+ {
+ return (LockData) cache.get(makeLockFqn(nodeId), LOCK_DATA);
+ }
+
+ protected synchronized List<LockData> getLockList()
+ {
+ 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;
+ }
+
+ /**
+ * 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);
+ }
+ }
+
+ /**
+ * Release all resources associated with CacheableSessionLockManager.
+ *
+ * @param sessionID - session identifier
+ */
+ protected void closeSession(String sessionID)
+ {
+ sessionLockManagers.remove(sessionID);
+ }
+
+ /**
+ * Make lock absolute Fqn, i.e. /$LOCKS/nodeID.
+ *
+ * @param itemId String
+ * @return Fqn
+ */
+ private Fqn<String> makeLockFqn(String nodeId)
+ {
+ return Fqn.fromRelativeElements(lockRoot, nodeId);
+ }
+}
16 years, 3 months
exo-jcr SVN: r1498 - jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent.
by do-not-reply@jboss.org
Author: skabashnyuk
Date: 2010-01-20 05:17:48 -0500 (Wed, 20 Jan 2010)
New Revision: 1498
Modified:
jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/WorkspaceStorageCacheBaseCase.java
Log:
EXOJCR-390 : cache.beginTransaction() is colled in JBossCache
Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/WorkspaceStorageCacheBaseCase.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/WorkspaceStorageCacheBaseCase.java 2010-01-20 10:12:01 UTC (rev 1497)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/WorkspaceStorageCacheBaseCase.java 2010-01-20 10:17:48 UTC (rev 1498)
@@ -561,7 +561,6 @@
properties2.add(propertyData22);
try
{
- cache.beginTransaction();
cache.addChildProperties(nodeData2, properties2);
List<NodeData> nodes2 = new ArrayList<NodeData>();
@@ -588,7 +587,7 @@
chlog.add(ItemState.createDeletedState(nodeData2));
// cache.remove(nodeData2); // remove node2 and its childs and properties (21, 22)
cache.onSaveItems(chlog);
- cache.commitTransaction();
+
}
catch (Exception e)
{
16 years, 3 months
exo-jcr SVN: r1497 - jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache.
by do-not-reply@jboss.org
Author: sergiykarpenko
Date: 2010-01-20 05:12:01 -0500 (Wed, 20 Jan 2010)
New Revision: 1497
Modified:
jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManager.java
Log:
EXOJCR-418: InitialContextInitializer recall moved to start()
Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManager.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManager.java 2010-01-20 09:31:06 UTC (rev 1496)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManager.java 2010-01-20 10:12:01 UTC (rev 1497)
@@ -140,6 +140,11 @@
private final Map<String, LockData> pendingLocks;
/**
+ * Context recall is a workaround of JDBCCacheLoader starting.
+ */
+ private final InitialContextInitializer context;
+
+ /**
* Run time lock time out.
*/
private long lockTimeOut;
@@ -188,6 +193,7 @@
pendingLocks = new HashMap<String, LockData>();
sessionLockManagers = new HashMap<String, CacheableSessionLockManager>();
+ this.context = context;
dataManager.addItemPersistenceListener(this);
@@ -201,10 +207,6 @@
? config.getLockManager().getParameterValue(JBOSSCACCHE_CONFIG) : config.getLockManager()
.getCacheConfig();
CacheFactory<Serializable, Object> factory = new DefaultCacheFactory<Serializable, Object>();
-
- // Context recall is a workaround of JDBCCacheLoader starting.
- context.recall();
-
cache = factory.createCache(pathToConfig, false);
cache.create();
}
@@ -457,6 +459,8 @@
public void start()
{
cache.start();
+ // Context recall is a workaround of JDBCCacheLoader starting.
+ context.recall();
lockRoot = cache.getRoot().addChild(Fqn.fromString(LOCKS));
lockRoot.setResident(true);
lockRemover = new LockRemover(this);
@@ -716,7 +720,7 @@
dataManager.save(new TransactionChangesLog(changesLog));
}
- catch (JCRInvalidItemStateException e)
+ 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.
@@ -724,7 +728,7 @@
{
log.debug("The propperty was removed in other node of cluster.", e);
}
-
+
}
catch (RepositoryException e)
{
16 years, 3 months
exo-jcr SVN: r1496 - jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/cluster.
by do-not-reply@jboss.org
Author: skabashnyuk
Date: 2010-01-20 04:31:06 -0500 (Wed, 20 Jan 2010)
New Revision: 1496
Modified:
jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/cluster/test-jbosscache-config-ws.xml
jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/cluster/test-jbosscache-config-ws1.xml
jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/cluster/test-jbosscache-indexer-config-exoloader_db1_ws.xml
jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/cluster/test-jbosscache-indexer-config-exoloader_db1_ws1.xml
jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/cluster/test-jbosscache-lock-config_db1_ws.xml
jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/cluster/test-jbosscache-lock-config_db1_ws1.xml
Log:
EXOJCR-390 : remove multiplexerStack="fc-fast-minimalthreads"
Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/cluster/test-jbosscache-config-ws.xml
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/cluster/test-jbosscache-config-ws.xml 2010-01-20 01:37:35 UTC (rev 1495)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/cluster/test-jbosscache-config-ws.xml 2010-01-20 09:31:06 UTC (rev 1496)
@@ -14,8 +14,9 @@
This JGroups configuration is taken from JBC branch, but
"enable_bundling" is set to false, because of notice, that appeared
during running
+ multiplexerStack="fc-fast-minimalthreads"
-->
- <jgroupsConfig multiplexerStack="fc-fast-minimalthreads">
+ <jgroupsConfig>
<!--
UDP discard_incompatible_packets="true" enable_bundling="false"
enable_diagnostics="false" ip_ttl="2" loopback="false"
Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/cluster/test-jbosscache-config-ws1.xml
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/cluster/test-jbosscache-config-ws1.xml 2010-01-20 01:37:35 UTC (rev 1495)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/cluster/test-jbosscache-config-ws1.xml 2010-01-20 09:31:06 UTC (rev 1496)
@@ -14,8 +14,9 @@
This JGroups configuration is taken from JBC branch, but
"enable_bundling" is set to false, because of notice, that appeared
during running
+ multiplexerStack="fc-fast-minimalthreads"
-->
- <jgroupsConfig multiplexerStack="fc-fast-minimalthreads" >
+ <jgroupsConfig >
<!--
UDP discard_incompatible_packets="true" enable_bundling="false"
enable_diagnostics="false" ip_ttl="2" loopback="false"
Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/cluster/test-jbosscache-indexer-config-exoloader_db1_ws.xml
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/cluster/test-jbosscache-indexer-config-exoloader_db1_ws.xml 2010-01-20 01:37:35 UTC (rev 1495)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/cluster/test-jbosscache-indexer-config-exoloader_db1_ws.xml 2010-01-20 09:31:06 UTC (rev 1496)
@@ -9,7 +9,7 @@
<clustering mode="replication" clusterName="JBoss-Cache-Indexer-Cluster_db1_ws">
<stateRetrieval timeout="20000" fetchInMemoryState="false" nonBlocking="true"/>
- <jgroupsConfig multiplexerStack="fc-fast-minimalthreads">
+ <jgroupsConfig>
<TCP bind_addr="127.0.0.1" start_port="9700" loopback="true"
recv_buf_size="20000000" send_buf_size="640000"
discard_incompatible_packets="true" max_bundle_size="64000"
Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/cluster/test-jbosscache-indexer-config-exoloader_db1_ws1.xml
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/cluster/test-jbosscache-indexer-config-exoloader_db1_ws1.xml 2010-01-20 01:37:35 UTC (rev 1495)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/cluster/test-jbosscache-indexer-config-exoloader_db1_ws1.xml 2010-01-20 09:31:06 UTC (rev 1496)
@@ -9,7 +9,7 @@
<clustering mode="replication" clusterName="JBoss-Cache-Indexer-Cluster_db1_ws1">
<stateRetrieval timeout="20000" fetchInMemoryState="false" nonBlocking="true"/>
- <jgroupsConfig multiplexerStack="fc-fast-minimalthreads">
+ <jgroupsConfig>
<TCP bind_addr="127.0.0.1" start_port="9750" loopback="true"
recv_buf_size="20000000" send_buf_size="640000"
discard_incompatible_packets="true" max_bundle_size="64000"
Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/cluster/test-jbosscache-lock-config_db1_ws.xml
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/cluster/test-jbosscache-lock-config_db1_ws.xml 2010-01-20 01:37:35 UTC (rev 1495)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/cluster/test-jbosscache-lock-config_db1_ws.xml 2010-01-20 09:31:06 UTC (rev 1496)
@@ -5,7 +5,7 @@
<clustering mode="replication" clusterName="JBoss-Cache-Lock-Cluster_db1_ws">
<stateRetrieval timeout="20000" fetchInMemoryState="false" nonBlocking="true"/>
- <jgroupsConfig multiplexerStack="fc-fast-minimalthreads">
+ <jgroupsConfig >
<TCP bind_addr="127.0.0.1" start_port="9800" loopback="true"
recv_buf_size="20000000" send_buf_size="640000"
Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/cluster/test-jbosscache-lock-config_db1_ws1.xml
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/cluster/test-jbosscache-lock-config_db1_ws1.xml 2010-01-20 01:37:35 UTC (rev 1495)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/cluster/test-jbosscache-lock-config_db1_ws1.xml 2010-01-20 09:31:06 UTC (rev 1496)
@@ -5,7 +5,7 @@
<clustering mode="replication" clusterName="JBoss-Cache-Lock-Cluster_db1_ws1">
<stateRetrieval timeout="20000" fetchInMemoryState="false" nonBlocking="true"/>
- <jgroupsConfig multiplexerStack="fc-fast-minimalthreads">
+ <jgroupsConfig>
<TCP bind_addr="127.0.0.1" start_port="9850" loopback="true"
recv_buf_size="20000000" send_buf_size="640000"
16 years, 3 months