Author: dkuleshov
Date: 2012-02-27 09:19:58 -0500 (Mon, 27 Feb 2012)
New Revision: 5700
Added:
jcr/trunk/exo.jcr.component.core.impl.infinispan.v5/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNLockTableHandler.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockTableHandler.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockTableHandlerFactory.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/JBCLockTableHandler.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/JBCShareableLockTableHandler.java
Modified:
jcr/trunk/exo.jcr.component.core.impl.infinispan.v5/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNCacheableLockManagerImpl.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryCheckController.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/InspectionQuery.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainerChecker.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TestRepositoryCheckController.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/util/TesterConfigurationHelper.java
Log:
EXOJCR-1755: added lock consistency check utility
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryCheckController.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryCheckController.java 2012-02-27
11:05:12 UTC (rev 5699)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryCheckController.java 2012-02-27
14:19:58 UTC (rev 5700)
@@ -23,6 +23,7 @@
import org.exoplatform.management.jmx.annotations.NameTemplate;
import org.exoplatform.management.jmx.annotations.Property;
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.config.WorkspaceEntry;
import org.exoplatform.services.jcr.core.ManageableRepository;
import org.exoplatform.services.jcr.impl.core.query.SearchManager;
import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer;
@@ -124,6 +125,7 @@
}
protected String checkRepositoryDataConsistency(DataStorage[] storages)
+
{
try
{
@@ -273,6 +275,8 @@
(JDBCWorkspaceDataContainer)getComponent(JDBCWorkspaceDataContainer.class,
wsName);
JDBCWorkspaceDataContainerChecker.checkDataBase(dataContainer, lastReport);
+ JDBCWorkspaceDataContainerChecker.checkLocksInDataBase(dataContainer,
+ (WorkspaceEntry)getComponent(WorkspaceEntry.class, wsName), lastReport);
}
}
Added:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockTableHandler.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockTableHandler.java
(rev 0)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockTableHandler.java 2012-02-27
14:19:58 UTC (rev 5700)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2011 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.core.lock;
+
+import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+
+import java.sql.SQLException;
+import java.util.Set;
+
+import javax.naming.NamingException;
+
+/**
+ * Provides method for extraction of set of locked nodes' IDs from
+ * {@link LockManager} persistant layer (database lock table),
+ * which can be further used for consistency check.
+ *
+ * @author <a href="mailto:dkuleshov@exoplatform.com">Dmitry
Kuleshov</a>
+ */
+public interface LockTableHandler
+{
+ /**
+ * Get a set of locked jcr nodes IDs contained in {@link LockManager} persistent layer
(database table).
+ *
+ * @return {@link Set} of node IDs
+ * @throws NamingException
+ * @throws RepositoryConfigurationException
+ * @throws SQLException
+ */
+ Set<String> getLockedNodesIds() throws NamingException,
RepositoryConfigurationException, SQLException;
+}
Added:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockTableHandlerFactory.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockTableHandlerFactory.java
(rev 0)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/LockTableHandlerFactory.java 2012-02-27
14:19:58 UTC (rev 5700)
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2011 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.core.lock;
+
+import org.exoplatform.services.jcr.config.WorkspaceEntry;
+import org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl;
+import org.exoplatform.services.jcr.impl.core.lock.jbosscache.JBCLockTableHandler;
+import
org.exoplatform.services.jcr.impl.core.lock.jbosscache.JBCShareableLockTableHandler;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+
+/**
+ *
+ * @author <a href="mailto:dkuleshov@exoplatform.com">Dmitry
Kuleshov</a>
+ * @version $Id: LockTableHandlerFactory.java 34360 27.02.2012 11:55:03 dkuleshov $
+ *
+ */
+public class LockTableHandlerFactory
+{
+ protected static final Log LOG =
ExoLogger.getExoLogger("exo.jcr.component.core.LockTableHandlerFactory");
+
+ /**
+ * Provides {@link LockTableHandler} instance according to preconfigured {@link
LockManager}
+ *
+ * @param workspaceEntry
+ * @return {@link LockTableHandler}
+ */
+ public static LockTableHandler getHandler(WorkspaceEntry workspaceEntry)
+ {
+ String lockManagerFqn = workspaceEntry.getLockManager().getType();
+ String jbcLockManagerFqn =
"org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl";
+ String ispnLockManagerFqn =
"org.exoplatform.services.jcr.impl.core.lock.infinispan.ISPNCacheableLockManagerImpl";
+
+ String ispnLockTableHandlerFqn =
"org.exoplatform.services.jcr.impl.core.lock.infinispan.ISPNLockTableHandler";
+
+ if (jbcLockManagerFqn.equals(lockManagerFqn))
+ {
+ if (isJbcCacheShareable(workspaceEntry))
+ {
+ return new JBCShareableLockTableHandler(workspaceEntry);
+ }
+ return new JBCLockTableHandler(workspaceEntry);
+ }
+ else if(ispnLockManagerFqn.equals(lockManagerFqn))
+ {
+ // we're using reflection to create IspnLockTableHandler instance
+ // such aproach allows to avoid addition of jcr.component.core.infinispan.v5 as
a dependency
+ // (ispnLockTableHandler is located in jcr.component.core.infinispan.v5)
+ // for jcr.component.core module, while it is needed only for compilation
+ // and at the same time we can use IspnLockTableHandler for
+ // jcr.component.core.infinispan.v5 module
+ try
+ {
+ Class<?> ispnLockTableHandlerClass =
Class.forName(ispnLockTableHandlerFqn);
+ Constructor<?>[] ispnLockTableHandlerClassConstructors =
+ ispnLockTableHandlerClass.getDeclaredConstructors();
+
+ for (Constructor<?> constructor :
ispnLockTableHandlerClassConstructors)
+ {
+ Class<?>[] parameterTypes = constructor.getParameterTypes();
+ if (parameterTypes.length == 1 && parameterTypes[0] ==
WorkspaceEntry.class)
+ {
+ return (LockTableHandler)constructor.newInstance(workspaceEntry);
+ }
+ }
+ }
+ catch (ClassNotFoundException e)
+ {
+ LOG.error(e.getMessage(), e);
+ }
+ catch (IllegalArgumentException e)
+ {
+ LOG.error(e.getMessage(), e);
+ }
+ catch (InstantiationException e)
+ {
+ LOG.error(e.getMessage(), e);
+ }
+ catch (IllegalAccessException e)
+ {
+ LOG.error(e.getMessage(), e);
+ }
+ catch (InvocationTargetException e)
+ {
+ LOG.error(e.getMessage(), e);
+ }
+ }
+
+ throw new UnsupportedOperationException(
+ "Currently supported only CacheableLockManagerImpl and
ISPNCacheableLockManagerImpl");
+ }
+
+ private static Boolean isJbcCacheShareable(WorkspaceEntry workspaceEntry)
+ {
+ return
workspaceEntry.getLockManager().getParameterBoolean(CacheableLockManagerImpl.JBOSSCACHE_SHAREABLE,
+ CacheableLockManagerImpl.JBOSSCACHE_SHAREABLE_DEFAULT);
+ }
+}
Added:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/JBCLockTableHandler.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/JBCLockTableHandler.java
(rev 0)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/JBCLockTableHandler.java 2012-02-27
14:19:58 UTC (rev 5700)
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2011 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.core.lock.jbosscache;
+
+import org.exoplatform.commons.utils.SecurityHelper;
+import org.exoplatform.services.jcr.config.LockManagerEntry;
+import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.config.WorkspaceEntry;
+import org.exoplatform.services.jcr.impl.core.lock.LockTableHandler;
+import org.exoplatform.services.jcr.impl.storage.jdbc.InspectionQuery;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+
+import java.security.PrivilegedExceptionAction;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.sql.DataSource;
+
+/**
+ * Provides means for nodes' IDs extraction in case we use {@link
CacheableLockManagerImpl}
+ * as {@link LockManager} based on non shareable JBoss Cache instance.
+ * Equally applicable for single and multi db configurations.
+ *
+ * @author <a href="mailto:dkuleshov@exoplatform.com">Dmitry
Kuleshov</a>
+ * @version $Id: JBCLockTableHandler.java 34360 2009-07-22 23:58:59Z dkuleshov $
+ */
+public class JBCLockTableHandler implements LockTableHandler
+{
+ protected static final Log LOG =
ExoLogger.getLogger("exo.jcr.component.core.JBCLockTableHandler");
+
+ protected final WorkspaceEntry workspaceEntry;
+
+ protected final LockManagerEntry lockManagerEntry;
+
+ /**
+ * JBCLockTableHandler constructor.
+ */
+ public JBCLockTableHandler(final WorkspaceEntry workspaceEntry)
+ {
+ this.workspaceEntry = workspaceEntry;
+ this.lockManagerEntry = workspaceEntry.getLockManager();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Set<String> getLockedNodesIds() throws NamingException,
RepositoryConfigurationException, SQLException
+ {
+ String fqnColumn =
lockManagerEntry.getParameterValue("jbosscache-cl-cache.jdbc.fqn.column");
+
+ Set<String> lockedNodesIds = new HashSet<String>();
+
+ ResultSet resultSet = null;
+ PreparedStatement preparedStatement = null;
+
+ Connection jdbcConnection = openConnection();
+ try
+ {
+ InspectionQuery inspectionQuery = getQuery();
+
+ preparedStatement = inspectionQuery.prepareStatement(jdbcConnection);
+ resultSet = preparedStatement.executeQuery();
+
+ while (resultSet.next())
+ {
+ String fqn = resultSet.getString(fqnColumn);
+
+ lockedNodesIds.add(fqn.substring(fqn.lastIndexOf("/") + 1));
+ }
+ }
+ finally
+ {
+ if (resultSet != null)
+ {
+ try
+ {
+ resultSet.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.error(e.getMessage(), e);
+ }
+ }
+ if (preparedStatement != null)
+ {
+ try
+ {
+ preparedStatement.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.error(e.getMessage(), e);
+ }
+ }
+ if (jdbcConnection != null)
+ {
+ try
+ {
+ jdbcConnection.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.error(e.getMessage(), e);
+ }
+ }
+ }
+
+ return lockedNodesIds;
+ }
+
+ protected InspectionQuery getQuery() throws RepositoryConfigurationException
+ {
+ return new InspectionQuery("SELECT * FROM "
+ +
lockManagerEntry.getParameterValue(CacheableLockManagerImpl.JBOSSCACHE_JDBC_TABLE_NAME) +
" WHERE PARENT='/"
+ + CacheableLockManagerImpl.LOCKS + "'", new String[]{},
"Locks table match");
+ }
+
+ private Connection openConnection() throws NamingException,
RepositoryConfigurationException, SQLException
+ {
+ final DataSource ds =
+ (DataSource)new InitialContext().lookup(lockManagerEntry
+ .getParameterValue(CacheableLockManagerImpl.JBOSSCACHE_JDBC_CL_DATASOURCE));
+
+ return SecurityHelper.doPrivilegedSQLExceptionAction(new
PrivilegedExceptionAction<Connection>()
+ {
+ public Connection run() throws SQLException
+ {
+ return ds.getConnection();
+ }
+ });
+ }
+}
Added:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/JBCShareableLockTableHandler.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/JBCShareableLockTableHandler.java
(rev 0)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/JBCShareableLockTableHandler.java 2012-02-27
14:19:58 UTC (rev 5700)
@@ -0,0 +1,55 @@
+/*
+ * 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.services.jcr.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.config.WorkspaceEntry;
+import org.exoplatform.services.jcr.impl.core.lock.LockTableHandler;
+import org.exoplatform.services.jcr.impl.storage.jdbc.InspectionQuery;
+
+/**
+ * Provides means for nodes' IDs extraction in case we use {@link
CacheableLockManagerImpl}
+ * as {@link LockManager} based on shareable JBoss Cache instance.
+ * Equally applicable for single and multi db configurations.
+ *
+ * @author <a href="mailto:dkuleshov@exoplatform.com">Dmitry
Kuleshov</a>
+ * @version $Id: JBCShareableLockTableHandler.java 34360 2009-07-22 23:58:59Z dkuleshov
$
+ *
+ */
+public class JBCShareableLockTableHandler extends JBCLockTableHandler implements
LockTableHandler
+{
+
+ /**
+ * JBCShareableLockTableHandler constructor.
+ */
+ public JBCShareableLockTableHandler(WorkspaceEntry workspaceEntry)
+ {
+ super(workspaceEntry);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected InspectionQuery getQuery() throws RepositoryConfigurationException
+ {
+ return new InspectionQuery("SELECT * FROM "
+ +
lockManagerEntry.getParameterValue(CacheableLockManagerImpl.JBOSSCACHE_JDBC_TABLE_NAME) +
" WHERE PARENT='/"
+ + workspaceEntry.getUniqueName() + "/" +
CacheableLockManagerImpl.LOCKS + "'", new String[]{},
+ "Locks table match");
+ }
+
+}
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/InspectionQuery.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/InspectionQuery.java 2012-02-27
11:05:12 UTC (rev 5699)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/InspectionQuery.java 2012-02-27
14:19:58 UTC (rev 5700)
@@ -26,7 +26,7 @@
* @author <a href="mailto:aplotnikov@exoplatform.com">Andrey
Plotnikov</a>
* @version $Id: InspectionQuery.java 34360 16.02.2012 andrew.plotnikov $
*/
-class InspectionQuery
+public class InspectionQuery
{
/**
* Data class, contains a combination of SQL states, description, field names and
status
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainerChecker.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainerChecker.java 2012-02-27
11:05:12 UTC (rev 5699)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainerChecker.java 2012-02-27
14:19:58 UTC (rev 5700)
@@ -19,8 +19,11 @@
package org.exoplatform.services.jcr.impl.storage.jdbc;
import org.exoplatform.commons.utils.SecurityHelper;
+import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.config.WorkspaceEntry;
import org.exoplatform.services.jcr.impl.Constants;
import org.exoplatform.services.jcr.impl.InspectionReport;
+import org.exoplatform.services.jcr.impl.core.lock.LockTableHandlerFactory;
import org.exoplatform.services.jcr.impl.storage.value.ValueDataNotFoundException;
import org.exoplatform.services.jcr.impl.storage.value.ValueStorageNotFoundException;
import org.exoplatform.services.jcr.storage.value.ValueIOChannel;
@@ -39,6 +42,7 @@
import java.util.Set;
import javax.jcr.RepositoryException;
+import javax.naming.NamingException;
/**
* @author <a href="mailto:skarpenko@exoplatform.com">Sergiy
Karpenko</a>
@@ -50,6 +54,141 @@
protected static final Log LOG =
ExoLogger.getLogger("exo.jcr.component.core.JDBCWorkspaceDataContainerChecker");
/**
+ * Checks jcr locks for consistency. Defines if there is a node with lockIsDeep or
lockOwner property
+ * (basically means that the node is to be locked)
+ * and has no corresponding record in LockManager persistant layer ( db table);
+ * or the opposite.
+ */
+ public static void checkLocksInDataBase(JDBCWorkspaceDataContainer jdbcDataContainer,
WorkspaceEntry workspaceEntry,
+ InspectionReport report) throws RepositoryException, IOException
+ {
+ String multiDbQueryStatement =
+ "SELECT DISTINCT PARENT_ID from JCR_MITEM WHERE I_CLASS=2 "
+ + "AND (
NAME='[http://www.jcp.org/jcr/1.0]lockOwner' OR
NAME='[http://www.jcp.org/jcr/1.0]lockIsDeep')";
+
+ String singleDbQueryStatement =
+ "SELECT DISTINCT PARENT_ID from JCR_SITEM WHERE CONTAINER_NAME='"
+ + jdbcDataContainer.containerName
+ + "' AND I_CLASS=2 and
(
NAME='[http://www.jcp.org/jcr/1.0]lockOwner' OR
NAME='[http://www.jcp.org/jcr/1.0]lockIsDeep')";
+
+ InspectionQuery itemTableQuery =
+ new InspectionQuery(jdbcDataContainer.multiDb ? multiDbQueryStatement :
singleDbQueryStatement,
+ new String[]{DBConstants.COLUMN_PARENTID}, "Items which have
jcr:lockOwner and jcr:lockIsDeep properties");
+
+ ResultSet resultSet = null;
+ PreparedStatement preparedStatement = null;
+
+ // using existing DataSource to get a JDBC Connection.
+ Connection jdbcConnection =
jdbcDataContainer.getConnectionFactory().getJdbcConnection();
+ try
+ {
+ preparedStatement = itemTableQuery.prepareStatement(jdbcConnection);
+ resultSet = preparedStatement.executeQuery();
+
+ Set<String> itemTableIds = new HashSet<String>();
+ while (resultSet.next())
+ {
+ itemTableIds.add(jdbcDataContainer.multiDb ?
resultSet.getString(DBConstants.COLUMN_PARENTID) : resultSet
+
.getString(DBConstants.COLUMN_PARENTID).substring(workspaceEntry.getName().length()));
+ }
+
+ Set<String> lockTableIds =
LockTableHandlerFactory.getHandler(workspaceEntry).getLockedNodesIds();
+
+ checkIdSetsConsistency(report, itemTableIds, lockTableIds);
+ }
+ catch (SQLException e)
+ {
+ report.logExceptionAndSetInconsistency("Exception during Lock DB
inspection.", e);
+ }
+ catch (NamingException e)
+ {
+ report.logExceptionAndSetInconsistency("Exception during Lock DB
inspection.", e);
+ }
+ catch (RepositoryConfigurationException e)
+ {
+ report.logExceptionAndSetInconsistency("Exception during Lock DB
inspection.", e);
+ }
+ finally
+ {
+ if (resultSet != null)
+ {
+ try
+ {
+ resultSet.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.error(e.getMessage(), e);
+ }
+ }
+ if (preparedStatement != null)
+ {
+ try
+ {
+ preparedStatement.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.error(e.getMessage(), e);
+ }
+ }
+
+ if (jdbcConnection != null)
+ {
+ try
+ {
+ jdbcConnection.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.error(e.getMessage(), e);
+ }
+ }
+ }
+ }
+
+ private static void checkIdSetsConsistency(InspectionReport report,
+ Set<String> itemTableIds, Set<String> lockTableIds) throws IOException
+ {
+ // let us make a set to contain all the consistent node IDs
+ // which obviously is an interection of
+ // itemTableIds set and lockTableIds set
+ Set<String> consistentIds = new HashSet<String>(itemTableIds);
+ consistentIds.retainAll(lockTableIds);
+
+ // simply remove consistent node IDs
+ // and we will have inconsistent nodes left
+ itemTableIds.removeAll(consistentIds);
+ lockTableIds.removeAll(consistentIds);
+
+ if (!itemTableIds.isEmpty())
+ {
+ StringBuffer record = new StringBuffer();
+
+ record.append("Items listed in JCR_XITEM table have lock
inconsistency:\n");
+ for (String id : itemTableIds)
+ {
+ record.append("Node UUID: " + id + "\n");
+ }
+
+ report.logBrokenObjectAndSetInconsistency(record.toString(), "");
+ }
+
+ if (!lockTableIds.isEmpty())
+ {
+ StringBuffer record = new StringBuffer();
+
+ record.append("Items listed in LockManager's table have lock
inconsistency:\n");
+ for (String id : lockTableIds)
+ {
+ record.append("Node UUID: " + id + "\n");
+ }
+
+ report.logBrokenObjectAndSetInconsistency(record.toString(), "");
+ }
+ }
+
+ /**
* Check database.
* <p>
* Check that database is not broken, and all base relation between jcr-items are not
corrupted.
Modified:
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TestRepositoryCheckController.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TestRepositoryCheckController.java 2012-02-27
11:05:12 UTC (rev 5699)
+++
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/TestRepositoryCheckController.java 2012-02-27
14:19:58 UTC (rev 5700)
@@ -20,6 +20,7 @@
import org.exoplatform.services.jcr.BaseStandaloneTest;
import org.exoplatform.services.jcr.access.AccessControlList;
+import org.exoplatform.services.jcr.config.LockManagerEntry;
import org.exoplatform.services.jcr.config.WorkspaceEntry;
import org.exoplatform.services.jcr.core.ManageableRepository;
import org.exoplatform.services.jcr.dataflow.ItemState;
@@ -32,6 +33,7 @@
import org.exoplatform.services.jcr.impl.core.NodeImpl;
import org.exoplatform.services.jcr.impl.core.PropertyImpl;
import org.exoplatform.services.jcr.impl.core.SessionImpl;
+import org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl;
import org.exoplatform.services.jcr.impl.core.query.SearchManager;
import org.exoplatform.services.jcr.impl.core.query.SystemSearchManager;
import org.exoplatform.services.jcr.impl.dataflow.TransientNodeData;
@@ -64,6 +66,16 @@
private TesterRepositoryCheckController checkController;
+ private static boolean SHARED_CACHE = true;
+
+ private static boolean NOT_SHARED_CACHE = false;
+
+ private static boolean MULTI_DB = true;
+
+ private static boolean SINGLE_DB = false;
+
+ private static boolean CACHE_ENABLED = true;
+
private final TesterConfigurationHelper helper =
TesterConfigurationHelper.getInstance();
/**
@@ -98,6 +110,169 @@
result.startsWith(RepositoryCheckController.REPORT_CONSISTENT_MESSAGE));
}
+ public void testConsistentLocksInDataBase() throws Exception
+ {
+ checkConsistentLocksInDataBase(NOT_SHARED_CACHE, SINGLE_DB);
+ checkConsistentLocksInDataBase(NOT_SHARED_CACHE, MULTI_DB);
+ }
+
+ public void testConsistentLocksInDataBaseSharedCache() throws Exception
+ {
+ checkConsistentLocksInDataBase(SHARED_CACHE, SINGLE_DB);
+ checkConsistentLocksInDataBase(SHARED_CACHE, MULTI_DB);
+ }
+
+ private void checkConsistentLocksInDataBase(boolean isCacheShared, boolean isMultiDb)
throws Exception
+ {
+ ManageableRepository repository = helper.createRepository(container, isMultiDb,
CACHE_ENABLED, isCacheShared);
+ SessionImpl session =
+ (SessionImpl)repository.login(credentials,
repository.getConfiguration().getSystemWorkspaceName());
+ NodeImpl node = (NodeImpl)session.getRootNode().addNode("testNode");
+ node.addMixin("mix:lockable");
+ session.save();
+ node.lock(false, false);
+
+ checkController = new TesterRepositoryCheckController(repository);
+ String result = checkController.checkRepositoryDataConsistency(new
DataStorage[]{DataStorage.DB});
+ assertNotNull(result);
+
+ assertTrue("Repository data is not consistent, result: " + result,
+ result.startsWith(RepositoryCheckController.REPORT_CONSISTENT_MESSAGE));
+ checkController.getLastLogFile().delete();
+ }
+
+ public void testInconsistentLocksInDataBase() throws Exception
+ {
+ checkInconsistentLocksInItemTable(NOT_SHARED_CACHE, SINGLE_DB);
+ checkInconsistentLocksInItemTable(NOT_SHARED_CACHE, MULTI_DB);
+
+ checkInconsistentLocksInLockTable(NOT_SHARED_CACHE, SINGLE_DB);
+ checkInconsistentLocksInLockTable(NOT_SHARED_CACHE, MULTI_DB);
+ }
+
+ public void testInconsistentLocksInDataBaseWithSharedCache() throws Exception
+ {
+ checkInconsistentLocksInItemTable(SHARED_CACHE, SINGLE_DB);
+ checkInconsistentLocksInItemTable(SHARED_CACHE, MULTI_DB);
+
+ checkInconsistentLocksInLockTable(SHARED_CACHE, SINGLE_DB);
+ checkInconsistentLocksInLockTable(SHARED_CACHE, MULTI_DB);
+ }
+
+ private void checkInconsistentLocksInItemTable(boolean cacheShared, boolean isMultiDb)
throws Exception
+ {
+ ManageableRepository repository = helper.createRepository(container, isMultiDb,
CACHE_ENABLED, cacheShared);
+ SessionImpl session =
+ (SessionImpl)repository.login(credentials,
repository.getConfiguration().getSystemWorkspaceName());
+ NodeImpl node = (NodeImpl)session.getRootNode().addNode("testNode");
+ node.addMixin("mix:lockable");
+ session.save();
+ node.lock(false, false);
+
+ WorkspaceEntry workspaceEntry =
repository.getConfiguration().getWorkspaceEntries().get(0);
+ String sourceName =
workspaceEntry.getContainer().getParameterValue(JDBCWorkspaceDataContainer.SOURCE_NAME);
+
+ String multiDbQueryStatement =
+ "DELETE FROM JCR_MITEM WHERE I_CLASS=2 "
+ + "AND (
NAME='[http://www.jcp.org/jcr/1.0]lockOwner' OR
NAME='[http://www.jcp.org/jcr/1.0]lockIsDeep')";
+ String singleDbQueryStatement =
+ "DELETE FROM JCR_SITEM WHERE CONTAINER_NAME='"
+ + workspaceEntry.getName()
+ + "' AND I_CLASS=2 AND
(
NAME='[http://www.jcp.org/jcr/1.0]lockOwner' OR
NAME='[http://www.jcp.org/jcr/1.0]lockIsDeep')";
+
+ Connection conn = ((DataSource)new
InitialContext().lookup(sourceName)).getConnection();
+
+ // remove constraint
+ conn.prepareStatement(
+ "ALTER TABLE JCR_" + (isMultiDb ? "M" : "S") +
"ITEM DROP CONSTRAINT JCR_FK_" + (isMultiDb ? "M" : "S")
+ + "VALUE_PROPERTY").execute();
+ // delete properties (this should cause inconsistency)
+ conn.prepareStatement(isMultiDb ? multiDbQueryStatement :
singleDbQueryStatement).execute();
+
+ // remove constriant
+ conn.prepareStatement(
+ "ALTER TABLE JCR_" + (isMultiDb ? "M" : "S") +
"VALUE DROP CONSTRAINT JCR_PK_" + (isMultiDb ? "M" : "S")
+ + "VALUE").execute();
+
+ // clean up properties value to avoid another (except needed) cause of
inconsistency
+ String lockOwnerPropertyId =
+ (isMultiDb ? "" : workspaceEntry.getName())
+ +
((PropertyImpl)node.getProperty("jcr:lockIsDeep")).getInternalIdentifier();
+ String lockIsDeepPropertyId =
+ (isMultiDb ? "" : workspaceEntry.getName())
+ +
((PropertyImpl)node.getProperty("jcr:lockOwner")).getInternalIdentifier();
+
+ conn.prepareStatement(
+ "DELETE FROM JCR_" + (isMultiDb ? "M" : "S") +
"VALUE WHERE PROPERTY_ID = '" + lockOwnerPropertyId
+ + "' OR PROPERTY_ID = '" + lockIsDeepPropertyId +
"'").execute();
+ conn.commit();
+ conn.close();
+
+ checkController = new TesterRepositoryCheckController(repository);
+ String result = checkController.checkRepositoryDataConsistency(new
DataStorage[]{DataStorage.DB});
+ assertNotNull(result);
+ assertTrue("Repository data is consistent, result: " + result,
+ result.startsWith(RepositoryCheckController.REPORT_NOT_CONSISTENT_MESSAGE));
+ // checkController.getLastLogFile().delete();
+ }
+
+ private void checkInconsistentLocksInLockTable(boolean cacheShared, boolean isMultiDb)
throws Exception
+ {
+ ManageableRepository repository = helper.createRepository(container, isMultiDb,
true, cacheShared);
+ SessionImpl session =
+ (SessionImpl)repository.login(credentials,
repository.getConfiguration().getSystemWorkspaceName());
+ NodeImpl node = (NodeImpl)session.getRootNode().addNode("testNode");
+ node.addMixin("mix:lockable");
+ session.save();
+ node.lock(false, false);
+
+ WorkspaceEntry workspaceEntry =
repository.getConfiguration().getWorkspaceEntries().get(0);
+ LockManagerEntry lockManagerEntry = workspaceEntry.getLockManager();
+
+ String sourceName = null;
+ String queryStatement = null;
+
+ if (helper.ispnCacheEnabled())
+ {
+ sourceName =
lockManagerEntry.getParameterValue("infinispan-cl-cache.jdbc.datasource");
+
+ queryStatement =
+ "DELETE FROM " +
lockManagerEntry.getParameterValue("infinispan-cl-cache.jdbc.table.name") +
"_" + "L"
+ + workspaceEntry.getUniqueName().replace("_",
"").replace("-", "_");
+ }
+ else
+ {
+ sourceName =
lockManagerEntry.getParameterValue(CacheableLockManagerImpl.JBOSSCACHE_JDBC_CL_DATASOURCE);
+
+ if (cacheShared)
+ {
+ queryStatement =
+ "DELETE FROM " +
lockManagerEntry.getParameterValue(CacheableLockManagerImpl.JBOSSCACHE_JDBC_TABLE_NAME)
+ + " WHERE PARENT='/" + workspaceEntry.getUniqueName() +
"/" + CacheableLockManagerImpl.LOCKS + "'";
+ }
+ else
+ {
+ queryStatement =
+ "DELETE FROM " +
lockManagerEntry.getParameterValue(CacheableLockManagerImpl.JBOSSCACHE_JDBC_TABLE_NAME)
+ + " WHERE PARENT='/" + CacheableLockManagerImpl.LOCKS +
"'";
+ }
+
+ }
+
+ Connection conn = ((DataSource)new
InitialContext().lookup(sourceName)).getConnection();
+
+ conn.prepareStatement(queryStatement).execute();
+ conn.commit();
+ conn.close();
+
+ checkController = new TesterRepositoryCheckController(repository);
+ String result = checkController.checkRepositoryDataConsistency(new
DataStorage[]{DataStorage.DB});
+ assertNotNull(result);
+ assertTrue("Repository data is consistent, result: " + result,
+ result.startsWith(RepositoryCheckController.REPORT_NOT_CONSISTENT_MESSAGE));
+ // checkController.getLastLogFile().delete();
+ }
+
public void testValueStorage() throws Exception
{
checkController = new
TesterRepositoryCheckController(repositoryService.getRepository("db1"));
Modified:
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/util/TesterConfigurationHelper.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/util/TesterConfigurationHelper.java 2012-02-27
11:05:12 UTC (rev 5699)
+++
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/util/TesterConfigurationHelper.java 2012-02-27
14:19:58 UTC (rev 5700)
@@ -110,17 +110,23 @@
return service.getRepository(repoEntry.getName());
}
- public ManageableRepository createRepository(ExoContainer container, boolean
isMultiDb, boolean cacheEnabled)
- throws Exception
+ public ManageableRepository createRepository(ExoContainer container, boolean
isMultiDb, boolean cacheEnabled,
+ boolean cacheShared) throws Exception
{
RepositoryService service =
(RepositoryService)container.getComponentInstanceOfType(RepositoryService.class);
- RepositoryEntry repoEntry = createRepositoryEntry(isMultiDb, null, null,
cacheEnabled);
+ RepositoryEntry repoEntry = createRepositoryEntry(isMultiDb, null, null,
cacheEnabled, cacheShared);
service.createRepository(repoEntry);
service.getConfig().retain();
return service.getRepository(repoEntry.getName());
}
+ public ManageableRepository createRepository(ExoContainer container, boolean
isMultiDb, boolean cacheEnabled)
+ throws Exception
+ {
+ return createRepository(container, isMultiDb, cacheEnabled, false);
+ }
+
public ManageableRepository createRepository(ExoContainer container, RepositoryEntry
repoEntry) throws Exception
{
RepositoryService service =
(RepositoryService)container.getComponentInstanceOfType(RepositoryService.class);
@@ -130,15 +136,24 @@
}
/**
+ * Create workspace entry.
+ */
+ public RepositoryEntry createRepositoryEntry(boolean isMultiDb, String systemWSName,
String dsName,
+ boolean cacheEnabled) throws Exception
+ {
+ return createRepositoryEntry(isMultiDb, systemWSName, dsName, cacheEnabled,
false);
+ }
+
+ /**
* Create workspace entry.
*/
public RepositoryEntry createRepositoryEntry(boolean isMultiDb, String systemWSName,
String dsName,
- boolean cacheEnabled) throws Exception
+ boolean cacheEnabled, boolean cacheShared) throws Exception
{
// create system workspace entry
List<String> ids = new ArrayList<String>();
ids.add("id");
- WorkspaceEntry wsEntry = createWorkspaceEntry(isMultiDb, dsName, ids,
cacheEnabled);
+ WorkspaceEntry wsEntry = createWorkspaceEntry(isMultiDb, dsName, ids, cacheEnabled,
cacheShared);
if (systemWSName != null)
{
@@ -174,6 +189,15 @@
public WorkspaceEntry createWorkspaceEntry(boolean isMultiDb, String dsName,
List<String> valueStorageIds,
boolean cacheEnabled) throws Exception
{
+ return createWorkspaceEntry(isMultiDb, dsName, valueStorageIds, cacheEnabled,
false);
+ }
+
+ /**
+ * Create workspace entry.
+ */
+ public WorkspaceEntry createWorkspaceEntry(boolean isMultiDb, String dsName,
List<String> valueStorageIds,
+ boolean cacheEnabled, boolean cacheShared) throws Exception
+ {
if (dsName == null)
{
dsName = createDatasource();
@@ -239,13 +263,37 @@
// Lock
LockManagerEntry lockManagerEntry = new LockManagerEntry();
- lockManagerEntry.setTimeout(900000);
- LockPersisterEntry lockPersisterEntry = new LockPersisterEntry();
-
lockPersisterEntry.setType("org.exoplatform.services.jcr.impl.core.lock.FileSystemLockPersister");
- ArrayList<SimpleParameterEntry> lockPersisterParameters = new
ArrayList<SimpleParameterEntry>();
- lockPersisterParameters.add(new SimpleParameterEntry("path",
"target/temp/lock/" + wsName));
- lockPersisterEntry.setParameters(lockPersisterParameters);
- lockManagerEntry.setPersister(lockPersisterEntry);
+ lockManagerEntry.putParameterValue("time-out", "15m");
+ if (ispnCacheEnabled())
+ {
+ lockManagerEntry
+
.setType("org.exoplatform.services.jcr.impl.core.lock.infinispan.ISPNCacheableLockManagerImpl");
+ lockManagerEntry.putParameterValue("infinispan-configuration",
"conf/standalone/test-infinispan-lock.xml");
+
lockManagerEntry.putParameterValue("infinispan-cl-cache.jdbc.table.name",
"lk");
+
lockManagerEntry.putParameterValue("infinispan-cl-cache.jdbc.table.create",
"true");
+
lockManagerEntry.putParameterValue("infinispan-cl-cache.jdbc.table.drop",
"false");
+
lockManagerEntry.putParameterValue("infinispan-cl-cache.jdbc.id.column",
"id");
+
lockManagerEntry.putParameterValue("infinispan-cl-cache.jdbc.data.column",
"data");
+
lockManagerEntry.putParameterValue("infinispan-cl-cache.jdbc.timestamp.column",
"timestamp");
+
lockManagerEntry.putParameterValue("infinispan-cl-cache.jdbc.datasource",
dsName);
+
lockManagerEntry.putParameterValue("infinispan-cl-cache.jdbc.connectionFactory",
+
"org.infinispan.loaders.jdbc.connectionfactory.ManagedConnectionFactory");
+ }
+ else
+ {
+
lockManagerEntry.setType("org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl");
+ lockManagerEntry.putParameterValue("jbosscache-configuration",
"conf/standalone/test-jbosscache-lock.xml");
+
lockManagerEntry.putParameterValue("jbosscache-cl-cache.jdbc.table.name",
"jcrlocks");
+
lockManagerEntry.putParameterValue("jbosscache-cl-cache.jdbc.table.create",
"true");
+
lockManagerEntry.putParameterValue("jbosscache-cl-cache.jdbc.table.drop",
"false");
+
lockManagerEntry.putParameterValue("jbosscache-cl-cache.jdbc.table.primarykey",
+ "jcrlocks_" + IdGenerator.generate());
+
lockManagerEntry.putParameterValue("jbosscache-cl-cache.jdbc.fqn.column",
"fqn");
+
lockManagerEntry.putParameterValue("jbosscache-cl-cache.jdbc.node.column",
"node");
+
lockManagerEntry.putParameterValue("jbosscache-cl-cache.jdbc.parent.column",
"parent");
+
lockManagerEntry.putParameterValue("jbosscache-cl-cache.jdbc.datasource",
dsName);
+ lockManagerEntry.putParameterValue("jbosscache-shareable",
String.valueOf(cacheShared));
+ }
WorkspaceEntry workspaceEntry = new WorkspaceEntry();
workspaceEntry.setContainer(containerEntry);
@@ -258,6 +306,20 @@
return workspaceEntry;
}
+ public boolean ispnCacheEnabled()
+ {
+ try
+ {
+
Class.forName("org.exoplatform.services.jcr.impl.core.lock.infinispan.ISPNCacheableLockManagerImpl");
+ return true;
+ }
+ catch (ClassNotFoundException e)
+ {
+ return false;
+ }
+
+ }
+
public List<String> getValueStorageIds(ArrayList<ValueStorageEntry>
entries)
{
List<String> ids = new ArrayList<String>();
Modified:
jcr/trunk/exo.jcr.component.core.impl.infinispan.v5/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNCacheableLockManagerImpl.java
===================================================================
---
jcr/trunk/exo.jcr.component.core.impl.infinispan.v5/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNCacheableLockManagerImpl.java 2012-02-27
11:05:12 UTC (rev 5699)
+++
jcr/trunk/exo.jcr.component.core.impl.infinispan.v5/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNCacheableLockManagerImpl.java 2012-02-27
14:19:58 UTC (rev 5700)
@@ -76,6 +76,8 @@
public static final String INFINISPAN_JDBC_CL_ID_COLUMN =
"infinispan-cl-cache.jdbc.id.type";
+ public static final String INFINISPAN_JDBC_CL_ID_COLUMN_NAME =
"infinispan-cl-cache.jdbc.id.column";
+
public static final String INFINISPAN_JDBC_TABLE_NAME =
"infinispan-cl-cache.jdbc.table.name";
public static final String INFINISPAN_JDBC_CL_AUTO = "auto";
Added:
jcr/trunk/exo.jcr.component.core.impl.infinispan.v5/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNLockTableHandler.java
===================================================================
---
jcr/trunk/exo.jcr.component.core.impl.infinispan.v5/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNLockTableHandler.java
(rev 0)
+++
jcr/trunk/exo.jcr.component.core.impl.infinispan.v5/src/main/java/org/exoplatform/services/jcr/impl/core/lock/infinispan/ISPNLockTableHandler.java 2012-02-27
14:19:58 UTC (rev 5700)
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2011 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.core.lock.infinispan;
+
+import org.exoplatform.commons.utils.SecurityHelper;
+import org.exoplatform.services.jcr.config.LockManagerEntry;
+import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.config.WorkspaceEntry;
+import org.exoplatform.services.jcr.impl.core.lock.LockTableHandler;
+import org.exoplatform.services.jcr.impl.storage.jdbc.InspectionQuery;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+
+import java.security.PrivilegedExceptionAction;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.sql.DataSource;
+
+/**
+ * Provides means for nodes' IDs extraction in case we use {@link
ISPNCacheableLockManagerImpl}
+ * as {@link LockManager} based on ISPN Cache instance.
+ *
+ * @author <a href="mailto:dkuleshov@exoplatform.com">Dmitry
Kuleshov</a>
+ * @version $Id: ISPNLockTableHandler.java 34360 27.02.2012 12:41:39 dkuleshov $
+ *
+ */
+public class ISPNLockTableHandler implements LockTableHandler
+{
+
+ protected static final Log LOG = ExoLogger
+
.getLogger("exo.jcr.component.core.impl.infinispan.v5.ISPNLockTableHandler");
+
+ protected final WorkspaceEntry workspaceEntry;
+
+ protected final LockManagerEntry lockManagerEntry;
+
+ public ISPNLockTableHandler(WorkspaceEntry workspaceEntry)
+ {
+ this.workspaceEntry = workspaceEntry;
+ this.lockManagerEntry = workspaceEntry.getLockManager();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Set<String> getLockedNodesIds() throws RepositoryConfigurationException,
SQLException, NamingException
+ {
+ Set<String> lockedNodesIds = new HashSet<String>();
+
+ ResultSet resultSet = null;
+ PreparedStatement preparedStatement = null;
+
+ Connection jdbcConnection = openConnection();
+ try
+ {
+ InspectionQuery inspectionQuery = getQuery();
+
+ preparedStatement = inspectionQuery.prepareStatement(jdbcConnection);
+ resultSet = preparedStatement.executeQuery();
+
+ String idColumn =
+
lockManagerEntry.getParameterValue(ISPNCacheableLockManagerImpl.INFINISPAN_JDBC_CL_ID_COLUMN_NAME);
+
+ while (resultSet.next())
+ {
+ lockedNodesIds.add(resultSet.getString(idColumn));
+ }
+ }
+ finally
+ {
+ if (resultSet != null)
+ {
+ try
+ {
+ resultSet.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.error(e.getMessage(), e);
+ }
+ }
+ if (preparedStatement != null)
+ {
+ try
+ {
+ preparedStatement.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.error(e.getMessage(), e);
+ }
+ }
+ if (jdbcConnection != null)
+ {
+ try
+ {
+ jdbcConnection.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.error(e.getMessage(), e);
+ }
+ }
+ }
+
+ return lockedNodesIds;
+ }
+
+ protected InspectionQuery getQuery() throws RepositoryConfigurationException
+ {
+ String tableName =
+
lockManagerEntry.getParameterValue(ISPNCacheableLockManagerImpl.INFINISPAN_JDBC_TABLE_NAME)
+ "_" + "L"
+ + workspaceEntry.getUniqueName().replace("_",
"").replace("-", "_");
+
+ return new InspectionQuery("SELECT * FROM " + tableName, new String[]{},
"Locks table match");
+ }
+
+ private Connection openConnection() throws NamingException,
RepositoryConfigurationException, SQLException
+ {
+ final DataSource ds =
+ (DataSource)new InitialContext().lookup(lockManagerEntry
+
.getParameterValue(ISPNCacheableLockManagerImpl.INFINISPAN_JDBC_CL_DATASOURCE));
+
+ return SecurityHelper.doPrivilegedSQLExceptionAction(new
PrivilegedExceptionAction<Connection>()
+ {
+ public Connection run() throws SQLException
+ {
+ return ds.getConnection();
+ }
+ });
+ }
+
+}
\ No newline at end of file