exo-jcr SVN: r4405 - in kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction: impl/jotm and 1 other directory.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-05-23 05:08:02 -0400 (Mon, 23 May 2011)
New Revision: 4405
Removed:
kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/ExoResource.java
kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/TransactionException.java
kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/TransactionResource.java
kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/impl/jotm/ResourceEntry.java
Log:
EXOJCR-480: Managed transactions support
Deleted: kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/ExoResource.java
===================================================================
Deleted: kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/TransactionException.java
===================================================================
Deleted: kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/TransactionResource.java
===================================================================
Deleted: kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/impl/jotm/ResourceEntry.java
===================================================================
13 years
exo-jcr SVN: r4404 - in jcr/branches/1.12.x/patch/1.12.9-GA: JCR-1632 and 1 other directory.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-05-23 04:47:38 -0400 (Mon, 23 May 2011)
New Revision: 4404
Added:
jcr/branches/1.12.x/patch/1.12.9-GA/JCR-1632/
jcr/branches/1.12.x/patch/1.12.9-GA/JCR-1632/JCR-1632.patch
Log:
JCR-1632: patch proposed
Added: jcr/branches/1.12.x/patch/1.12.9-GA/JCR-1632/JCR-1632.patch
===================================================================
--- jcr/branches/1.12.x/patch/1.12.9-GA/JCR-1632/JCR-1632.patch (rev 0)
+++ jcr/branches/1.12.x/patch/1.12.9-GA/JCR-1632/JCR-1632.patch 2011-05-23 08:47:38 UTC (rev 4404)
@@ -0,0 +1,76 @@
+Index: exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/util/TesterConfigurationHelper.java
+===================================================================
+--- exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/util/TesterConfigurationHelper.java (revision 4403)
++++ exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/util/TesterConfigurationHelper.java (working copy)
+@@ -187,7 +187,7 @@
+
+ // Indexer
+ ArrayList qParams = new ArrayList();
+- qParams.add(new SimpleParameterEntry("indexDir", "../temp/index/" + IdGenerator.generate()));
++ qParams.add(new SimpleParameterEntry("indexDir", "target/temp/index/" + IdGenerator.generate()));
+ QueryHandlerEntry qEntry =
+ new QueryHandlerEntry("org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex", qParams);
+
+@@ -211,7 +211,7 @@
+ LockPersisterEntry persisterEntry = new LockPersisterEntry();
+ persisterEntry.setType("org.exoplatform.services.jcr.impl.core.lock.FileSystemLockPersister");
+ ArrayList lpParams = new ArrayList();
+- lpParams.add(new SimpleParameterEntry("path", "../temp/lock"));
++ lpParams.add(new SimpleParameterEntry("path", "target/temp/lock"));
+ persisterEntry.setParameters(lpParams);
+ lockManagerEntry.setPersister(persisterEntry);
+ workspaceEntry.setLockManager(lockManagerEntry);
+Index: exo.jcr.component.core/src/test/resources/log4j.properties
+===================================================================
+--- exo.jcr.component.core/src/test/resources/log4j.properties (revision 4403)
++++ exo.jcr.component.core/src/test/resources/log4j.properties (working copy)
+@@ -17,8 +17,7 @@
+
+ # 'file' is set to be a FileAppender.
+ log4j.appender.file=org.apache.log4j.FileAppender
+-#log4j.appender.file.File=jcr.log
+-log4j.appender.file.File=nul
++log4j.appender.file.File=target/jcr.log
+
+ # 'file' uses PatternLayout.
+ log4j.appender.file.layout=org.apache.log4j.PatternLayout
+Index: exo.jcr.component.core/pom.xml
+===================================================================
+--- exo.jcr.component.core/pom.xml (revision 4403)
++++ exo.jcr.component.core/pom.xml (working copy)
+@@ -364,7 +364,7 @@
+ <overWrite>false</overWrite>
+ </artifactItem>
+ </artifactItems>
+- <outputDirectory>${project.build.testSourceDirectory}</outputDirectory>
++ <outputDirectory>${project.build.directory}/jackrabbit-jcr-tests</outputDirectory>
+ </configuration>
+ </execution>
+ </executions>
+@@ -373,7 +373,7 @@
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+- <argLine>${env.MAVEN_OPTS}</argLine>
++ <argLine>${env.MAVEN_OPTS} -Dcom.arjuna.ats.arjuna.objectstore.objectStoreDir=${project.build.directory}</argLine>
+ <systemProperties>
+ <property>
+ <name>jcr.test.configuration.file</name>
+@@ -558,7 +558,7 @@
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <!-- TAKE CARE TO UPDATE ALSO run-all PROFILE -->
+- <argLine>${env.MAVEN_OPTS}</argLine>
++ <argLine>${env.MAVEN_OPTS} -Dcom.arjuna.ats.arjuna.objectstore.objectStoreDir=${project.build.directory}</argLine>
+ <systemProperties>
+ <property>
+ <name>jcr.test.configuration.file</name>
+@@ -645,7 +645,7 @@
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <!-- TAKE CARE TO UPDATE ALSO run-tck PROFILE -->
+- <argLine>${env.MAVEN_OPTS}</argLine>
++ <argLine>${env.MAVEN_OPTS} -Dcom.arjuna.ats.arjuna.objectstore.objectStoreDir=${project.build.directory}</argLine>
+ <systemProperties>
+ <property>
+ <name>jcr.test.configuration.file</name>
13 years
exo-jcr SVN: r4403 - in jcr/trunk: exo.jcr.component.core/src/main/java/org/exoplatform/services/transaction/infinispan and 1 other directory.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-05-23 03:41:43 -0400 (Mon, 23 May 2011)
New Revision: 4403
Added:
jcr/trunk/applications/product-patches/as/jboss/bin/run.conf
jcr/trunk/applications/product-patches/as/jboss/bin/run.conf.bat
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/transaction/infinispan/GenericTransactionService.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/transaction/infinispan/JBossTransactionsService.java
Log:
EXOJCR-480: Managed transactions support
Added: jcr/trunk/applications/product-patches/as/jboss/bin/run.conf
===================================================================
--- jcr/trunk/applications/product-patches/as/jboss/bin/run.conf (rev 0)
+++ jcr/trunk/applications/product-patches/as/jboss/bin/run.conf 2011-05-23 07:41:43 UTC (rev 4403)
@@ -0,0 +1,58 @@
+## -*- shell-script -*- ######################################################
+## ##
+## JBoss Bootstrap Script Configuration ##
+## ##
+##############################################################################
+
+### $Id: run.conf 88389 2009-05-08 02:37:00Z ispringer $
+
+#
+# This shell script is sourced by run.sh to initialize the environment
+# variables that run.sh uses. It is recommended to use this file to
+# configure these variables, rather than modifying run.sh itself.
+#
+
+#
+# Specify the maximum file descriptor limit, use "max" or "maximum" to use
+# the default, as queried by the system.
+#
+# Defaults to "maximum"
+#
+#MAX_FD="maximum"
+
+#
+# Specify the JBoss Profiler configuration file to load.
+#
+# Default is to not load a JBoss Profiler configuration file.
+#
+#PROFILER=""
+
+#
+# Specify the location of the Java home directory. If set then $JAVA will
+# be defined to $JAVA_HOME/bin/java, else $JAVA will be "java".
+#
+#JAVA_HOME="/usr/java/jdk1.6.0"
+
+#
+# Specify the exact Java VM executable to use.
+#
+#JAVA=""
+
+#
+# Specify options to pass to the Java VM.
+#
+if [ "x$JAVA_OPTS" = "x" ]; then
+ JAVA_OPTS="-Xms128m -Xmx512m -XX:MaxPermSize=256m -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000"
+fi
+
+# Sample JPDA settings for remote socket debugging
+#JAVA_OPTS="$JAVA_OPTS -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n"
+
+# Sample JPDA settings for shared memory debugging
+#JAVA_OPTS="$JAVA_OPTS -Xrunjdwp:transport=dt_shmem,address=jboss,server=y,suspend=n"
+
+# Add the eXo variables
+JAVA_OPTS="$JAVA_OPTS -Dexo.profiles=$1 -Dexo.jcr.parent.dir=../server/default/data"
+if [ "$1" = "jbc" ] || [ "$1" = "ispn" ]; then
+ shift
+fi
\ No newline at end of file
Added: jcr/trunk/applications/product-patches/as/jboss/bin/run.conf.bat
===================================================================
--- jcr/trunk/applications/product-patches/as/jboss/bin/run.conf.bat (rev 0)
+++ jcr/trunk/applications/product-patches/as/jboss/bin/run.conf.bat 2011-05-23 07:41:43 UTC (rev 4403)
@@ -0,0 +1,63 @@
+rem ### -*- batch file -*- ######################################################
+rem # ##
+rem # JBoss Bootstrap Script Configuration ##
+rem # ##
+rem #############################################################################
+
+rem # $Id: run.conf.bat 88820 2009-05-13 15:25:44Z dimitris(a)jboss.org $
+
+rem #
+rem # This batch file is executed by run.bat to initialize the environment
+rem # variables that run.bat uses. It is recommended to use this file to
+rem # configure these variables, rather than modifying run.bat itself.
+rem #
+
+if not "x%JAVA_OPTS%" == "x" goto JAVA_OPTS_SET
+
+rem #
+rem # Specify the JBoss Profiler configuration file to load.
+rem #
+rem # Default is to not load a JBoss Profiler configuration file.
+rem #
+rem set "PROFILER=%JBOSS_HOME%\bin\jboss-profiler.properties"
+
+rem #
+rem # Specify the location of the Java home directory (it is recommended that
+rem # this always be set). If set, then "%JAVA_HOME%\bin\java" will be used as
+rem # the Java VM executable; otherwise, "%JAVA%" will be used (see below).
+rem #
+rem set "JAVA_HOME=C:\opt\jdk1.6.0_13"
+
+rem #
+rem # Specify the exact Java VM executable to use - only used if JAVA_HOME is
+rem # not set. Default is "java".
+rem #
+rem set "JAVA=C:\opt\jdk1.6.0_13\bin\java"
+
+rem #
+rem # Specify options to pass to the Java VM. Note, there are some additional
+rem # options that are always passed by run.bat.
+rem #
+
+rem # JVM memory allocation pool parameters - modify as appropriate.
+set "JAVA_OPTS=-Xms128M -Xmx512M -XX:MaxPermSize=256M"
+
+rem # Reduce the RMI GCs to once per hour for Sun JVMs.
+set "JAVA_OPTS=%JAVA_OPTS% -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000"
+
+rem # Warn when resolving remote XML DTDs or schemas.
+set "JAVA_OPTS=%JAVA_OPTS% -Dorg.jboss.resolver.warning=true"
+
+rem # Sample JPDA settings for remote socket debugging
+rem set "JAVA_OPTS=%JAVA_OPTS% -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n"
+
+rem # Sample JPDA settings for shared memory debugging
+rem set "JAVA_OPTS=%JAVA_OPTS% -Xrunjdwp:transport=dt_shmem,address=jboss,server=y,suspend=n"
+
+rem # Add the eXo variables
+set "JAVA_OPTS=%JAVA_OPTS% -Dexo.profiles=%1 -Dexo.jcr.parent.dir=../server/default/data"
+
+if ""%1"" == ""jbc"" shift
+if ""%1"" == ""ispn"" shift
+
+:JAVA_OPTS_SET
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/transaction/infinispan/GenericTransactionService.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/transaction/infinispan/GenericTransactionService.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/transaction/infinispan/GenericTransactionService.java 2011-05-23 07:41:43 UTC (rev 4403)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2010 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.transaction.infinispan;
+
+import org.exoplatform.container.xml.InitParams;
+import org.exoplatform.services.transaction.impl.AbstractTransactionService;
+import org.infinispan.transaction.lookup.TransactionManagerLookup;
+
+import javax.transaction.TransactionManager;
+
+/**
+ * @author <a href="mailto:dmitry.kataev@exoplatform.com">Dmytro Katayev</a>
+ * @version $Id: GenericTransactionService.java -1 $
+ */
+public class GenericTransactionService extends AbstractTransactionService
+{
+
+ /**
+ * TransactionManagerLookup.
+ */
+ protected final TransactionManagerLookup tmLookup;
+
+ /**
+ * JBossTransactionManagerLookup constructor.
+ *
+ * @param tmLookup TransactionManagerLookup
+ */
+ public GenericTransactionService(TransactionManagerLookup tmLookup)
+ {
+ this(tmLookup, null);
+ }
+
+ public GenericTransactionService(TransactionManagerLookup tmLookup, InitParams params)
+ {
+ super(params);
+ this.tmLookup = tmLookup;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public TransactionManager findTransactionManager() throws Exception
+ {
+ return tmLookup.getTransactionManager();
+ }
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/transaction/infinispan/JBossTransactionsService.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/transaction/infinispan/JBossTransactionsService.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/transaction/infinispan/JBossTransactionsService.java 2011-05-23 07:41:43 UTC (rev 4403)
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2010 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.transaction.infinispan;
+
+import org.exoplatform.container.xml.InitParams;
+import org.infinispan.transaction.lookup.TransactionManagerLookup;
+
+import javax.transaction.UserTransaction;
+
+/**
+ * Add the specific part for Arjuna
+ *
+ * @author <a href="mailto:nicolas.filotto@exoplatform.com">Nicolas Filotto</a>
+ * @version $Id$
+ *
+ */
+public class JBossTransactionsService extends GenericTransactionService
+{
+
+ public JBossTransactionsService(TransactionManagerLookup tmLookup)
+ {
+ super(tmLookup);
+ }
+
+ public JBossTransactionsService(TransactionManagerLookup tmLookup, InitParams params)
+ {
+ super(tmLookup, params);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected UserTransaction findUserTransaction() throws Exception
+ {
+ return com.arjuna.ats.jta.UserTransaction.userTransaction();
+ }
+}
13 years
exo-jcr SVN: r4402 - in jcr/trunk: applications/product-patches/as/ear/META-INF and 23 other directories.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-05-23 03:39:32 -0400 (Mon, 23 May 2011)
New Revision: 4402
Added:
jcr/trunk/applications/product-patches/as/jboss/bin/
jcr/trunk/applications/product-patches/as/jboss/exo-readme.txt
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/TransactionableResourceManagerListener.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/transaction/ActionNonTxAware.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/transaction/infinispan/
jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/jta.xml
jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/kernel/data-source-provider.xml
Removed:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/XASessionException.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TxIsolatedOperation.java
Modified:
jcr/trunk/applications/exo.jcr.applications.jboss/pom.xml
jcr/trunk/applications/product-patches/as/ear/META-INF/weblogic-application.xml
jcr/trunk/applications/product-patches/as/jboss/exo-configuration.xml
jcr/trunk/applications/product-patches/as/jetty/exo-configuration.xml
jcr/trunk/applications/product-patches/as/jonas/apps/autoload/exoplatform.ear/META-INF/application.xml
jcr/trunk/applications/product-patches/as/jonas/exo-configuration.xml
jcr/trunk/applications/product-patches/as/tomcat/exo-configuration.xml
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/core/ExtendedSession.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/core/XASession.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/CompositeChangesLog.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/TransactionChangesLog.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionFactory.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionRegistry.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/TrackedXASession.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/XASessionImpl.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable/AbstractCacheableLockManager.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/WorkspacePersistentDataManager.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/BufferedISPNCache.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/BufferedJBossCache.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/TransactionableDataManager.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/TransactionableResourceManager.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCWorkspaceDataContainer.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/transaction/jbosscache/GenericTransactionService.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/transaction/jbosscache/JBossTransactionsService.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/xa/TestUserTransaction.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/xa/TestXATransaction.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/JDBCWDCTest.java
jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr.xml
jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/kernel.xml
jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/kernel/transaction-service.xml
Log:
EXOJCR-480: Managed transactions support
Modified: jcr/trunk/applications/exo.jcr.applications.jboss/pom.xml
===================================================================
--- jcr/trunk/applications/exo.jcr.applications.jboss/pom.xml 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/applications/exo.jcr.applications.jboss/pom.xml 2011-05-23 07:39:32 UTC (rev 4402)
@@ -115,11 +115,14 @@
</copy>
<!--copying exo-configuration.xml-->
<copy todir="${exo.projects.directory.working}/exo-jboss/" verbose="true" overwrite="true">
- <fileset dir="${basedir}/../product-patches/as/jboss/" includes="*.xml" />
+ <fileset dir="${basedir}/../product-patches/as/jboss/" includes="exo-*.*" />
</copy>
<copy todir="${exo.projects.directory.working}/exo-jboss/server/default/conf/" verbose="true" overwrite="true">
<fileset dir="${basedir}/../product-patches/as/jboss/exoplatform.sar/META-INF/" includes="login*.xml" />
</copy>
+ <copy todir="${exo.projects.directory.working}/exo-jboss/bin/" verbose="true" overwrite="true">
+ <fileset dir="${basedir}/../product-patches/as/jboss/bin/" includes="*.*" />
+ </copy>
</tasks>
</configuration>
</plugin>
Modified: jcr/trunk/applications/product-patches/as/ear/META-INF/weblogic-application.xml
===================================================================
--- jcr/trunk/applications/product-patches/as/ear/META-INF/weblogic-application.xml 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/applications/product-patches/as/ear/META-INF/weblogic-application.xml 2011-05-23 07:39:32 UTC (rev 4402)
@@ -24,7 +24,7 @@
<classloader-structure>
<classloader-structure>
<module-ref>
- <module-uri>localadapter.rar</module-uri>
+ <module-uri>exo-jcr.rar</module-uri>
</module-ref>
<module-ref>
<module-uri>browser.war</module-uri>
Modified: jcr/trunk/applications/product-patches/as/jboss/exo-configuration.xml
===================================================================
--- jcr/trunk/applications/product-patches/as/jboss/exo-configuration.xml 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/applications/product-patches/as/jboss/exo-configuration.xml 2011-05-23 07:39:32 UTC (rev 4402)
@@ -178,12 +178,12 @@
</object-param>
</init-params>
</component>
- <component profiles="ispn,jbc">
+ <component profiles="jbc">
<key>org.jboss.cache.transaction.TransactionManagerLookup</key>
<type>org.jboss.cache.transaction.JBossStandaloneJTAManagerLookup</type>
</component>
- <component profiles="ispn,jbc">
+ <component profiles="jbc">
<key>org.exoplatform.services.transaction.TransactionService</key>
<type>org.exoplatform.services.transaction.jbosscache.JBossTransactionsService</type>
<init-params>
@@ -193,6 +193,21 @@
</value-param>
</init-params>
</component>
+ <component profiles="ispn">
+ <key>org.infinispan.transaction.lookup.TransactionManagerLookup</key>
+ <type>org.infinispan.transaction.lookup.JBossStandaloneJTAManagerLookup</type>
+ </component>
+
+ <component profiles="ispn">
+ <key>org.exoplatform.services.transaction.TransactionService</key>
+ <type>org.exoplatform.services.transaction.infinispan.JBossTransactionsService</type>
+ <init-params>
+ <value-param>
+ <name>timeout</name>
+ <value>3000</value>
+ </value-param>
+ </init-params>
+ </component>
<component profiles="ispn,jbc">
<key>org.exoplatform.services.rpc.RPCService</key>
@@ -299,7 +314,7 @@
</value-param>
<value-param>
<name>cache-folder-name</name>
- <value>../temp/ftp_cache</value>
+ <value>${exo.jcr.parent.dir:..}/temp/ftp_cache</value>
</value-param>
<!-- bytes per second -->
@@ -358,7 +373,7 @@
<name>ref-addresses</name>
<description>ref-addresses</description>
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
- <property name="url" value="jdbc:hsqldb:file:../temp/data/exodb" />
+ <property name="url" value="jdbc:hsqldb:file:${exo.jcr.parent.dir:..}/temp/data/exodb" />
<property name="username" value="sa" />
<property name="password" value="" />
</properties-param>
Added: jcr/trunk/applications/product-patches/as/jboss/exo-readme.txt
===================================================================
--- jcr/trunk/applications/product-patches/as/jboss/exo-readme.txt (rev 0)
+++ jcr/trunk/applications/product-patches/as/jboss/exo-readme.txt 2011-05-23 07:39:32 UTC (rev 4402)
@@ -0,0 +1,15 @@
+Thank you for your interest in eXo JCR
+
+To launch it, go to the bin directory and execute the following command:
+
+In Unix environment
+
+* "./run.sh" to launch eXo JCR with the default configuration
+* "./run.sh ispn" to launch eXo JCR with the configuration for Infinispan
+* "./run.sh jbc" to launch eXo JCR with the configuration for JBoss Cache
+
+In Windows environment
+
+* "run.bat" to launch eXo JCR with the default configuration
+* "run.bat ispn" to launch eXo JCR with the configuration for Infinispan
+* "run.bat jbc" to launch eXo JCR with the configuration for JBoss Cache
Modified: jcr/trunk/applications/product-patches/as/jetty/exo-configuration.xml
===================================================================
--- jcr/trunk/applications/product-patches/as/jetty/exo-configuration.xml 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/applications/product-patches/as/jetty/exo-configuration.xml 2011-05-23 07:39:32 UTC (rev 4402)
@@ -178,12 +178,12 @@
</object-param>
</init-params>
</component>
- <component profiles="ispn,jbc">
+ <component profiles="jbc">
<key>org.jboss.cache.transaction.TransactionManagerLookup</key>
<type>org.jboss.cache.transaction.JBossStandaloneJTAManagerLookup</type>
</component>
- <component profiles="ispn,jbc">
+ <component profiles="jbc">
<key>org.exoplatform.services.transaction.TransactionService</key>
<type>org.exoplatform.services.transaction.jbosscache.JBossTransactionsService</type>
<init-params>
@@ -193,6 +193,21 @@
</value-param>
</init-params>
</component>
+ <component profiles="ispn">
+ <key>org.infinispan.transaction.lookup.TransactionManagerLookup</key>
+ <type>org.infinispan.transaction.lookup.JBossStandaloneJTAManagerLookup</type>
+ </component>
+
+ <component profiles="ispn">
+ <key>org.exoplatform.services.transaction.TransactionService</key>
+ <type>org.exoplatform.services.transaction.infinispan.JBossTransactionsService</type>
+ <init-params>
+ <value-param>
+ <name>timeout</name>
+ <value>3000</value>
+ </value-param>
+ </init-params>
+ </component>
<component profiles="ispn,jbc">
<key>org.exoplatform.services.rpc.RPCService</key>
Modified: jcr/trunk/applications/product-patches/as/jonas/apps/autoload/exoplatform.ear/META-INF/application.xml
===================================================================
--- jcr/trunk/applications/product-patches/as/jonas/apps/autoload/exoplatform.ear/META-INF/application.xml 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/applications/product-patches/as/jonas/apps/autoload/exoplatform.ear/META-INF/application.xml 2011-05-23 07:39:32 UTC (rev 4402)
@@ -41,6 +41,6 @@
</web>
</module>
<module>
- <connector>localadapter.rar</connector>
+ <connector>exo-jcr.rar</connector>
</module>
</application>
Modified: jcr/trunk/applications/product-patches/as/jonas/exo-configuration.xml
===================================================================
--- jcr/trunk/applications/product-patches/as/jonas/exo-configuration.xml 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/applications/product-patches/as/jonas/exo-configuration.xml 2011-05-23 07:39:32 UTC (rev 4402)
@@ -178,12 +178,12 @@
</object-param>
</init-params>
</component>
- <component profiles="ispn,jbc">
+ <component profiles="jbc">
<key>org.jboss.cache.transaction.TransactionManagerLookup</key>
<type>org.jboss.cache.transaction.JBossStandaloneJTAManagerLookup</type>
</component>
- <component profiles="ispn,jbc">
+ <component profiles="jbc">
<key>org.exoplatform.services.transaction.TransactionService</key>
<type>org.exoplatform.services.transaction.jbosscache.JBossTransactionsService</type>
<init-params>
@@ -193,6 +193,21 @@
</value-param>
</init-params>
</component>
+ <component profiles="ispn">
+ <key>org.infinispan.transaction.lookup.TransactionManagerLookup</key>
+ <type>org.infinispan.transaction.lookup.JBossStandaloneJTAManagerLookup</type>
+ </component>
+
+ <component profiles="ispn">
+ <key>org.exoplatform.services.transaction.TransactionService</key>
+ <type>org.exoplatform.services.transaction.infinispan.JBossTransactionsService</type>
+ <init-params>
+ <value-param>
+ <name>timeout</name>
+ <value>3000</value>
+ </value-param>
+ </init-params>
+ </component>
<component profiles="ispn,jbc">
<key>org.exoplatform.services.rpc.RPCService</key>
Modified: jcr/trunk/applications/product-patches/as/tomcat/exo-configuration.xml
===================================================================
--- jcr/trunk/applications/product-patches/as/tomcat/exo-configuration.xml 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/applications/product-patches/as/tomcat/exo-configuration.xml 2011-05-23 07:39:32 UTC (rev 4402)
@@ -178,12 +178,12 @@
</object-param>
</init-params>
</component>
- <component profiles="ispn,jbc">
+ <component profiles="jbc">
<key>org.jboss.cache.transaction.TransactionManagerLookup</key>
<type>org.jboss.cache.transaction.JBossStandaloneJTAManagerLookup</type>
</component>
- <component profiles="ispn,jbc">
+ <component profiles="jbc">
<key>org.exoplatform.services.transaction.TransactionService</key>
<type>org.exoplatform.services.transaction.jbosscache.JBossTransactionsService</type>
<init-params>
@@ -193,6 +193,21 @@
</value-param>
</init-params>
</component>
+ <component profiles="ispn">
+ <key>org.infinispan.transaction.lookup.TransactionManagerLookup</key>
+ <type>org.infinispan.transaction.lookup.JBossStandaloneJTAManagerLookup</type>
+ </component>
+
+ <component profiles="ispn">
+ <key>org.exoplatform.services.transaction.TransactionService</key>
+ <type>org.exoplatform.services.transaction.infinispan.JBossTransactionsService</type>
+ <init-params>
+ <value-param>
+ <name>timeout</name>
+ <value>3000</value>
+ </value-param>
+ </init-params>
+ </component>
<component profiles="ispn,jbc">
<key>org.exoplatform.services.rpc.RPCService</key>
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/core/ExtendedSession.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/core/ExtendedSession.java 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/core/ExtendedSession.java 2011-05-23 07:39:32 UTC (rev 4402)
@@ -33,6 +33,7 @@
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.nodetype.ConstraintViolationException;
+import javax.transaction.xa.XAResource;
/**
* Created by The eXo Platform SAS.
@@ -147,4 +148,31 @@
*/
void registerLifecycleListener(SessionLifecycleListener listener);
+ /**
+ * Gives the local timeout of the session
+ *
+ * @return the timeout the local timeout expressed in milliseconds
+ */
+ long getTimeout();
+
+ /**
+ * Sets the local timeout of the session
+ *
+ * @param timeout the new local timeout any value lower or equals to 0 will disable the timeout,
+ * the expected value is expressed in milliseconds
+ */
+ void setTimeout(long timeout);
+
+ /**
+ * Indicates whether the session has expired or not. A session expired when it has not
+ * been modified since an amount of time bigger than the timeout
+ * @return <code>true</code> if it has expired, <code>false</code> otherwise.
+ */
+ boolean hasExpired();
+
+ /**
+ * Gives the XA representation of the session
+ * @return the {@link XAResource} corresponding to the session
+ */
+ XAResource getXAResource();
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/core/XASession.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/core/XASession.java 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/core/XASession.java 2011-05-23 07:39:32 UTC (rev 4402)
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2009 eXo Platform SAS.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.exoplatform.services.jcr.core;
-
-import org.exoplatform.services.transaction.TransactionException;
-
-import javax.jcr.Session;
-import javax.transaction.xa.XAException;
-import javax.transaction.xa.XAResource;
-
-/**
- * Created by The eXo Platform SAS.<br/> XASession
- *
- * @author <a href="mailto:gennady.azarenkov@exoplatform.com">Gennady Azarenkov</a>
- * @version $Id: XASession.java 11907 2008-03-13 15:36:21Z ksm $
- */
-
-public interface XASession extends Session
-{
-
- /**
- * @return XAResource
- */
- XAResource getXAResource();
-
- /**
- * Enlists XAResource in TM.
- *
- * @throws XAException
- */
- void enlistResource() throws XAException;
-
- /**
- * Delists XAResource in TM.
- *
- * @throws XAException
- */
- void delistResource() throws XAException;
-
- /**
- * Returns TransactionException of a last commit XA intransaction context. Can be null. For information purpose.
- *
- * @return TransactionException commit exception
- */
- TransactionException getCommitException();
-}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/CompositeChangesLog.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/CompositeChangesLog.java 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/CompositeChangesLog.java 2011-05-23 07:39:32 UTC (rev 4402)
@@ -43,6 +43,13 @@
void addLog(PlainChangesLog log);
/**
+ * Removes a given PlainChangesLog
+ *
+ * @param log
+ */
+ void removeLog(PlainChangesLog log);
+
+ /**
* @return systemId
*/
String getSystemId();
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/TransactionChangesLog.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/TransactionChangesLog.java 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/TransactionChangesLog.java 2011-05-23 07:39:32 UTC (rev 4402)
@@ -66,6 +66,14 @@
changesLogs.add(log);
}
+ /**
+ * {@inheritDoc}
+ */
+ public void removeLog(PlainChangesLog log)
+ {
+ changesLogs.remove(log);
+ }
+
/*
* (non-Javadoc)
*
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java 2011-05-23 07:39:32 UTC (rev 4402)
@@ -59,6 +59,7 @@
import org.exoplatform.services.jcr.impl.dataflow.persistent.CacheableWorkspaceDataManager;
import org.exoplatform.services.jcr.impl.dataflow.persistent.LinkedWorkspaceStorageCacheImpl;
import org.exoplatform.services.jcr.impl.dataflow.persistent.LocalWorkspaceDataManagerStub;
+import org.exoplatform.services.jcr.impl.dataflow.session.TransactionableResourceManager;
import org.exoplatform.services.jcr.impl.storage.SystemDataContainerHolder;
import org.exoplatform.services.jcr.impl.storage.value.StandaloneStoragePluginProvider;
import org.exoplatform.services.jcr.impl.util.io.FileCleanerHolder;
@@ -459,6 +460,7 @@
public Void run()
{
workspaceContainer.registerComponentImplementation(initilizerType);
+ workspaceContainer.registerComponentImplementation(TransactionableResourceManager.class);
workspaceContainer.registerComponentImplementation(SessionFactory.class);
return null;
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionFactory.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionFactory.java 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionFactory.java 2011-05-23 07:39:32 UTC (rev 4402)
@@ -24,12 +24,10 @@
import org.exoplatform.services.jcr.access.DynamicIdentity;
import org.exoplatform.services.jcr.config.WorkspaceEntry;
import org.exoplatform.services.jcr.core.security.JCRRuntimePermissions;
-import org.exoplatform.services.jcr.impl.dataflow.session.TransactionableResourceManager;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.security.ConversationState;
import org.exoplatform.services.security.IdentityConstants;
-import org.exoplatform.services.transaction.TransactionService;
import javax.jcr.LoginException;
import javax.jcr.RepositoryException;
@@ -48,25 +46,18 @@
private final ExoContainer container;
- private final TransactionService tService;
-
private final String workspaceName;
- private final TransactionableResourceManager txResourceManager;
-
/**
* JCR Session factory.
*
- * @param tService TransactionService
* @param config WorkspaceEntry
* @param containerContext ExoContainerContext
*/
- public SessionFactory(TransactionService tService, WorkspaceEntry config, ExoContainerContext containerContext)
+ public SessionFactory(WorkspaceEntry config, ExoContainerContext containerContext)
{
this.container = containerContext.getContainer();
this.workspaceName = config.getName();
- this.tService = tService;
- this.txResourceManager = new TransactionableResourceManager();
boolean tracking =
"true".equalsIgnoreCase(PrivilegedSystemHelper.getProperty("exo.jcr.session.tracking.active", "false"));
@@ -105,21 +96,10 @@
}
/**
- * JCR Session factory.
- *
- * @param config WorkspaceEntry
- * @param containerContext ExoContainerContext
- */
- public SessionFactory(WorkspaceEntry config, ExoContainerContext containerContext)
- {
- this((TransactionService)null, config, containerContext);
- }
-
- /**
* Creates Session object by given Credentials
*
* @param credentials
- * @return XASessionImpl if TransactionService present or SessionImpl otherwise
+ * @return the SessionImpl corresponding to the given {@link ConversationState}
* @throws RepositoryException
*/
SessionImpl createSession(ConversationState user) throws RepositoryException, LoginException
@@ -142,26 +122,13 @@
security.checkPermission(JCRRuntimePermissions.CREATE_DYNAMIC_SESSION_PERMISSION);
}
}
- if (tService == null)
- {
- if (SessionReference.isStarted())
- {
- return new TrackedSession(workspaceName, user, container);
- }
- else
- {
- return new SessionImpl(workspaceName, user, container);
- }
- }
-
if (SessionReference.isStarted())
{
- return new TrackedXASession(workspaceName, user, container, tService, txResourceManager);
+ return new TrackedSession(workspaceName, user, container);
}
else
{
- return new XASessionImpl(workspaceName, user, container, tService, txResourceManager);
+ return new SessionImpl(workspaceName, user, container);
}
}
-
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java 2011-05-23 07:39:32 UTC (rev 4402)
@@ -28,6 +28,7 @@
import org.exoplatform.services.jcr.core.NamespaceAccessor;
import org.exoplatform.services.jcr.core.SessionLifecycleListener;
import org.exoplatform.services.jcr.core.nodetype.NodeTypeDataManager;
+import org.exoplatform.services.jcr.dataflow.PlainChangesLog;
import org.exoplatform.services.jcr.datamodel.ItemData;
import org.exoplatform.services.jcr.datamodel.ItemType;
import org.exoplatform.services.jcr.datamodel.NodeData;
@@ -41,6 +42,7 @@
import org.exoplatform.services.jcr.impl.core.value.ValueFactoryImpl;
import org.exoplatform.services.jcr.impl.dataflow.ItemDataMoveVisitor;
import org.exoplatform.services.jcr.impl.dataflow.persistent.LocalWorkspaceDataManagerStub;
+import org.exoplatform.services.jcr.impl.dataflow.session.TransactionableResourceManager;
import org.exoplatform.services.jcr.impl.ext.action.SessionActionCatalog;
import org.exoplatform.services.jcr.impl.ext.action.SessionActionInterceptor;
import org.exoplatform.services.jcr.impl.util.io.FileCleanerHolder;
@@ -92,6 +94,7 @@
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.observation.ObservationManager;
import javax.jcr.version.VersionException;
+import javax.transaction.xa.XAResource;
import javax.xml.stream.XMLStreamException;
/**
@@ -150,6 +153,8 @@
private boolean live;
+ private boolean expired;
+
private Exception closedByCallStack;
private final List<SessionLifecycleListener> lifecycleListeners;
@@ -170,6 +175,16 @@
protected final NodeTypeDataManager nodeTypeManager;
+ /**
+ * Transaction resources manager.
+ */
+ private final TransactionableResourceManager txResourceManager;
+
+ /**
+ * The local timeout of the session, by default it will use the global timeout defined at repository configuration level
+ */
+ private long timeout;
+
public SessionImpl(String workspaceName, ConversationState userState, ExoContainer container)
throws RepositoryException
{
@@ -178,6 +193,7 @@
this.live = true;
this.id = IdGenerator.generate();
this.userState = userState;
+ this.txResourceManager = (TransactionableResourceManager)container.getComponentInstanceOfType(TransactionableResourceManager.class);
this.repository = (RepositoryImpl)container.getComponentInstanceOfType(RepositoryImpl.class);
this.systemLocationFactory = (LocationFactory)container.getComponentInstanceOfType(LocationFactory.class);
@@ -947,6 +963,16 @@
}
/**
+ * Makes the current session expired. This will automatically logout the session and set the expired
+ * flag to true.
+ */
+ public void expire()
+ {
+ this.expired = true;
+ logout();
+ }
+
+ /**
* {@inheritDoc}
*/
public void move(String srcAbsPath, String destAbsPath) throws ItemExistsException, PathNotFoundException,
@@ -1097,4 +1123,51 @@
repository.getName(), workspaceName, live);
}
+ /**
+ * Checks if a global Tx has been started if so the session and its change will be dynamically enrolled
+ * @param statesLog the changes to enlist in case a Global Tx has been started
+ * @return <code>true</code> if a global Tx has been started and the session could
+ * be enrolled successfully, <code>false</code> otherwise
+ */
+ public boolean canEnrollChangeToGlobalTx(PlainChangesLog statesLog)
+ {
+ return txResourceManager.canEnrollChangeToGlobalTx(this, statesLog);
+ }
+
+ /**
+ * Gives the local timeout of the session
+ *
+ * @return the timeout the local timeout expressed in milliseconds
+ */
+ public long getTimeout()
+ {
+ return timeout;
+ }
+
+ /**
+ * Sets the local timeout of the session
+ *
+ * @param timeout the new local timeout any value lower or equals to 0 will disable the timeout,
+ * the expected value is expressed in milliseconds
+ */
+ public void setTimeout(long timeout)
+ {
+ this.timeout = (timeout <= 0 ? 0 : timeout);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public XAResource getXAResource()
+ {
+ return txResourceManager;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean hasExpired()
+ {
+ return expired;
+ }
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionRegistry.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionRegistry.java 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionRegistry.java 2011-05-23 07:39:32 UTC (rev 4402)
@@ -226,11 +226,21 @@
{
for (SessionImpl session : sessionsMap.values())
{
- if (session.getLastAccessTime() + sessionTimeOut < System.currentTimeMillis())
+ if (session.getLastAccessTime() + getTimeout(session) < System.currentTimeMillis())
{
- session.logout();
+ session.expire();
}
}
}
+
+ /**
+ * Checks if the session has a local timeout if so it will use it otherwise it will use the
+ * global timeout
+ */
+ private long getTimeout(SessionImpl session)
+ {
+ long localSessionTimeout = session.getTimeout();
+ return localSessionTimeout == 0 ? sessionTimeOut : localSessionTimeout;
+ }
}
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/TrackedXASession.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/TrackedXASession.java 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/TrackedXASession.java 2011-05-23 07:39:32 UTC (rev 4402)
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2009 eXo Platform SAS.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.exoplatform.services.jcr.impl.core;
-
-import org.exoplatform.container.ExoContainer;
-import org.exoplatform.services.jcr.impl.dataflow.session.TransactionableResourceManager;
-import org.exoplatform.services.security.ConversationState;
-import org.exoplatform.services.transaction.TransactionService;
-
-import javax.jcr.RepositoryException;
-
-/**
- * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
- * @version $Revision$
- */
-public class TrackedXASession extends XASessionImpl
-{
-
- private final SessionReference ref = new SessionReference(this);
-
- public TrackedXASession(String workspaceName, ConversationState userState, ExoContainer container,
- TransactionService tService, TransactionableResourceManager txResourceManager) throws RepositoryException
- {
- super(workspaceName, userState, container, tService, txResourceManager);
- }
-
- @Override
- public void logout()
- {
- ref.closed = true;
- super.logout();
- }
-}
\ No newline at end of file
Deleted: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/XASessionException.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/XASessionException.java 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/XASessionException.java 2011-05-23 07:39:32 UTC (rev 4402)
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2010 eXo Platform SAS.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.exoplatform.services.jcr.impl.core;
-
-import javax.transaction.xa.XAException;
-
-/**
- * Provides XAException functionality with constructor for errorcode and message.
- *
- * @author <a href="mailto:peter.nedonosko@exoplatform.com">Peter Nedonosko</a>
- * @version $Id$
- * */
-public class XASessionException extends XAException
-{
-
- /**
- * serialVersionUID.
- */
- private static final long serialVersionUID = -1853702973389878895L;
-
- public XASessionException()
- {
- super();
- }
-
- public XASessionException(int errcode)
- {
- super(errcode);
- }
-
- public XASessionException(String s)
- {
- super(s);
- }
-
- public XASessionException(String s, int errorCode)
- {
- super(s);
- this.errorCode = errorCode;
- }
-}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/XASessionImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/XASessionImpl.java 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/XASessionImpl.java 2011-05-23 07:39:32 UTC (rev 4402)
@@ -1,425 +0,0 @@
-/*
- * Copyright (C) 2009 eXo Platform SAS.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.exoplatform.services.jcr.impl.core;
-
-import org.exoplatform.container.ExoContainer;
-import org.exoplatform.services.jcr.core.XASession;
-import org.exoplatform.services.jcr.impl.dataflow.session.TransactionableResourceManager;
-import org.exoplatform.services.log.ExoLogger;
-import org.exoplatform.services.log.Log;
-import org.exoplatform.services.security.ConversationState;
-import org.exoplatform.services.transaction.ExoResource;
-import org.exoplatform.services.transaction.TransactionException;
-import org.exoplatform.services.transaction.TransactionService;
-
-import javax.jcr.RepositoryException;
-import javax.transaction.RollbackException;
-import javax.transaction.SystemException;
-import javax.transaction.xa.XAException;
-import javax.transaction.xa.XAResource;
-import javax.transaction.xa.Xid;
-
-/**
- * Created by The eXo Platform SAS.
- *
- * @author <a href="mailto:gennady.azarenkov@exoplatform.com">Gennady Azarenkov</a>
- * @version $Id: XASessionImpl.java 34801 2009-07-31 15:44:50Z dkatayev $
- */
-public class XASessionImpl extends SessionImpl implements XASession, XAResource, ExoResource
-{
-
- /**
- * Session logger.
- */
- private static final Log LOG = ExoLogger.getLogger("exo.jcr.component.core.XASessionImpl");
-
- /**
- * Transaction service.
- */
- private final TransactionService tService;
-
- /**
- * Transaction resources manager.
- */
- private final TransactionableResourceManager txResourceManager;
-
- /**
- * Start flags.
- */
- private int startFlags = TMNOFLAGS;
-
- /**
- * Transaction timeout.
- */
- private int txTimeout;
-
- /**
- * An arbitrary payload required by the ExoResource implementation.
- */
- private Object payload;
-
- /**
- * TransactionException of a last commit in context of a transaction.
- * Can be set on commit and will be restet on enlist/delist resource or rollback.
- */
- private TransactionException commitException = null;
-
- /**
- * XASessionImpl constructor.
- *
- * @param workspaceName
- * workspace name
- * @param userState
- * user ConversationState
- * @param container
- * ExoContainer
- * @param tService
- * Transaction service
- * @param txResourceManager
- * Transaction resources manager.
- * @throws RepositoryException
- * Repository error
- */
- XASessionImpl(String workspaceName, ConversationState userState, ExoContainer container,
- TransactionService tService, TransactionableResourceManager txResourceManager) throws RepositoryException
- {
- super(workspaceName, userState, container);
- this.txTimeout = tService.getDefaultTimeout();
- this.tService = tService;
- this.txResourceManager = txResourceManager;
-
- // enlist on login instead of this.txResourceManager.add(this);
- try
- {
- this.enlistResource();
- }
- catch (XAException e)
- {
- throw new RepositoryException(e);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public XAResource getXAResource()
- {
- return this;
- }
-
- /**
- * {@inheritDoc}
- */
- public void delistResource() throws XAException
- {
- // TODO if session is dead? can we delist it?
- try
- {
- if (LOG.isDebugEnabled())
- {
- LOG.debug("Delist session: " + getSessionInfo() + ", " + this);
- }
-
- commitException = null;
- txResourceManager.remove(this);
- tService.delistResource(this);
- }
- catch (RollbackException e)
- {
- if (LOG.isDebugEnabled())
- {
- LOG.debug("Delist error, session: " + getSessionInfo() + ", " + this, e);
- }
-
- throw new XASessionException("Cannot delist resource XASession " + getSessionInfo() + ". " + e);
- }
- catch (SystemException e)
- {
- if (LOG.isDebugEnabled())
- {
- LOG.debug("Delist error, session: " + getSessionInfo() + ", " + this, e);
- }
-
- throw new XASessionException("Cannot delist resource XASession " + getSessionInfo() + ". " + e);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void enlistResource() throws XAException
- {
- // TODO if session is dead? can we enlist it?
- try
- {
- if (LOG.isDebugEnabled())
- {
- LOG.debug("Enlist session: " + getSessionInfo() + ", " + this);
- }
-
- commitException = null;
- txResourceManager.add(this);
- tService.enlistResource(this);
- }
- catch (RollbackException e)
- {
- if (LOG.isDebugEnabled())
- {
- LOG.debug("Enlist error, session: " + getSessionInfo() + ", " + this, e);
- }
-
- throw new XASessionException("Cannot enlist resource XASession " + getSessionInfo() + ". " + e);
- }
- catch (SystemException e)
- {
- if (LOG.isDebugEnabled())
- {
- LOG.debug("Enlist error, session: " + getSessionInfo() + ", " + this, e);
- }
-
- throw new XASessionException("Cannot enlist resource XASession " + getSessionInfo() + ". " + e);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void commit(Xid xid, boolean onePhase) throws XAException
- {
- try
- {
- txResourceManager.commit(this, onePhase);
- }
- catch (TransactionException e)
- {
- commitException = e;
- if (LOG.isDebugEnabled())
- {
- LOG.debug("Commit Error. Xid:" + xid + ", session: " + getSessionInfo() + ", " + this, e);
- }
-
- throw new XASessionException(e.toString(), e.getErrorCode());
- }
-
- if (LOG.isDebugEnabled())
- {
- LOG.debug("Commit. Xid:" + xid + ", session: " + getSessionInfo() + ", " + this);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void start(Xid xid, int flags) throws XAException
- {
- txResourceManager.start(this);
- startFlags = flags;
-
- if (LOG.isDebugEnabled())
- {
- LOG.debug("Start. Xid:" + xid + ", " + flags + ", session: " + getSessionInfo() + ", " + this);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void end(Xid xid, int flags) throws XAException
- {
- startFlags = flags;
-
- if (LOG.isDebugEnabled())
- {
- LOG.debug("End. Xid:" + xid + ", " + flags + ", session: " + getSessionInfo() + ", " + this);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void forget(Xid xid) throws XAException
- {
- // TODO forget = rollback?
- //txResourceManager.rollback(this);
-
- //if (LOG.isDebugEnabled())
- //{
- // LOG.debug("Forget. Xid:" + xid + ", session: " + getSessionInfo() + ", " + this);
- //}
- }
-
- /**
- * {@inheritDoc}
- */
- public int getTransactionTimeout() throws XAException
- {
- return txTimeout;
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean isSameRM(XAResource resource) throws XAException
- {
- if (resource instanceof XASessionImpl)
- {
- XASessionImpl session = (XASessionImpl)resource;
- boolean isSame =
- getUserID().equals(session.getUserID())
- && getWorkspace().getName().equals(session.getWorkspace().getName())
- && ((RepositoryImpl)getRepository()).getName().equals(
- ((RepositoryImpl)session.getRepository()).getName());
-
- if (LOG.isDebugEnabled())
- {
- LOG.debug("isSameRM: " + getSessionInfo() + " -- " + session.getSessionInfo() + " : " + isSame + ", "
- + this + " -- " + session + ", Flags:" + startFlags);
- }
-
- return isSame;
- }
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- public int prepare(Xid xid) throws XAException
- {
- if (LOG.isDebugEnabled())
- {
- LOG.debug("Prepare. Xid:" + xid + ", session: " + getSessionInfo() + ", " + this);
- }
-
- return XA_OK;
- }
-
- /**
- * {@inheritDoc}
- */
- public Xid[] recover(int xid) throws XAException
- {
- return null;
- }
-
- /**
- * {@inheritDoc}
- */
- public void rollback(Xid xid) throws XAException
- {
- txResourceManager.rollback(this);
- commitException = null;
-
- if (LOG.isDebugEnabled())
- {
- LOG.debug("Rollback. Xid:" + xid + ", session: " + getSessionInfo() + ", " + this);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean setTransactionTimeout(int seconds) throws XAException
- {
- try
- {
- tService.setTransactionTimeout(seconds);
- }
- catch (SystemException e)
- {
- if (LOG.isDebugEnabled())
- {
- LOG.debug("Cannot set transaction timeout " + seconds + "sec via XASession " + getSessionInfo() + ". ", e);
- }
-
- throw new XASessionException("Cannot set transaction timeout " + seconds + "sec via XASession "
- + getSessionInfo() + ". " + e);
- }
- this.txTimeout = seconds;
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void logout()
- {
- if (LOG.isDebugEnabled())
- {
- LOG.debug("Logout. Session: " + getSessionInfo() + ", " + this);
- }
-
- try
- {
- // Rolling back this session only
- getTransientNodesManager().getTransactManager().rollback();
-
- super.logout();
- }
- finally
- {
- // Delist and remove session from this user sessions list in TransactionableDataManager
- // txResourceManager.remove(this) will be called in delistResource()
- try
- {
- delistResource();
- startFlags = TMNOFLAGS;
- }
- catch (XAException e)
- {
- LOG.error("Logout error " + e, e);
- }
- }
- }
-
- /**
- * Get XASession info string.
- *
- * @return info string
- */
- private String getSessionInfo()
- {
- return getUserID() + "@" + workspaceName;
- }
-
- /**
- * {@inheritDoc}
- */
- public Object getPayload()
- {
- return payload;
- }
-
- /**
- * {@inheritDoc}
- */
- public void setPayload(Object payload)
- {
- this.payload = payload;
- }
-
- /**
- * {@inheritDoc}
- */
- public TransactionException getCommitException()
- {
- return commitException;
- }
-}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable/AbstractCacheableLockManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable/AbstractCacheableLockManager.java 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/cacheable/AbstractCacheableLockManager.java 2011-05-23 07:39:32 UTC (rev 4402)
@@ -53,9 +53,7 @@
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.security.IdentityConstants;
-import org.jboss.cache.Cache;
-import org.jboss.cache.Node;
-import org.jboss.cache.loader.CacheLoader;
+import org.exoplatform.services.transaction.ActionNonTxAware;
import org.picocontainer.Startable;
import java.io.BufferedOutputStream;
@@ -76,7 +74,6 @@
import javax.jcr.RepositoryException;
import javax.jcr.lock.LockException;
-import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
/**
@@ -198,7 +195,7 @@
{
try
{
- return executeLockActionNonTxAware(getNumLocks, null);
+ return getNumLocks.run();
}
catch (LockException e)
{
@@ -214,7 +211,7 @@
{
try
{
- return executeLockActionNonTxAware(hasLocks, null);
+ return hasLocks.run();
}
catch (LockException e)
{
@@ -230,7 +227,7 @@
{
try
{
- return executeLockActionNonTxAware(isLockLive, nodeId);
+ return isLockLive.run(nodeId);
}
catch (LockException e)
{
@@ -244,7 +241,7 @@
*/
public void refreshLockData(LockData newLockData) throws LockException
{
- executeLockActionNonTxAware(refresh, newLockData);
+ refresh.run(newLockData);
}
/**
@@ -254,7 +251,7 @@
{
try
{
- return executeLockActionNonTxAware(lockExist, nodeId);
+ return lockExist.run(nodeId);
}
catch (LockException e)
{
@@ -270,7 +267,7 @@
{
try
{
- return executeLockActionNonTxAware(getLockDataById, nodeId);
+ return getLockDataById.run(nodeId);
}
catch (LockException e)
{
@@ -286,7 +283,7 @@
{
try
{
- return executeLockActionNonTxAware(getLockList, null);
+ return getLockList.run();
}
catch (LockException e)
{
@@ -757,47 +754,6 @@
}
/**
- * Execute the given action outside a transaction. This is needed since the {@link Cache} used by implementation
- * of {@link CacheableLockManager}
- * to manage the persistence of its locks thanks to a {@link CacheLoader} and a {@link CacheLoader} lock the cache {@link Node}
- * even for read operations which cause deadlock issue when a XA {@link Transaction} is already opened
- * @throws LockException when a exception occurs
- */
- private <R, A> R executeLockActionNonTxAware(LockActionNonTxAware<R, A> action, A arg) throws LockException
- {
- Transaction tx = null;
- try
- {
- if (tm != null)
- {
- try
- {
- tx = tm.suspend();
- }
- catch (Exception e)
- {
- LOG.warn("Cannot suspend the current transaction", e);
- }
- }
- return action.execute(arg);
- }
- finally
- {
- if (tx != null)
- {
- try
- {
- tm.resume(tx);
- }
- catch (Exception e)
- {
- LOG.warn("Cannot resume the current transaction", e);
- }
- }
- }
- }
-
- /**
* Actions that are not supposed to be called within a transaction
*
* Created by The eXo Platform SAS
@@ -805,9 +761,15 @@
* nicolas.filotto(a)exoplatform.com
* 21 janv. 2010
*/
- protected static interface LockActionNonTxAware<R, A>
+ protected abstract class LockActionNonTxAware<R, A> extends ActionNonTxAware<R, A, LockException>
{
- R execute(A arg) throws LockException;
+ /**
+ * @see org.exoplatform.services.transaction.ActionNonTxAware#getTransactionManager()
+ */
+ protected TransactionManager getTransactionManager()
+ {
+ return tm;
+ }
}
/**
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java 2011-05-23 07:39:32 UTC (rev 4402)
@@ -18,6 +18,7 @@
*/
package org.exoplatform.services.jcr.impl.dataflow.persistent;
+import org.exoplatform.commons.utils.SecurityHelper;
import org.exoplatform.services.jcr.dataflow.ItemStateChangesLog;
import org.exoplatform.services.jcr.dataflow.persistent.MandatoryItemsPersistenceListener;
import org.exoplatform.services.jcr.dataflow.persistent.WorkspaceStorageCache;
@@ -34,7 +35,8 @@
import org.exoplatform.services.jcr.impl.backup.ResumeException;
import org.exoplatform.services.jcr.impl.backup.SuspendException;
import org.exoplatform.services.jcr.impl.backup.Suspendable;
-import org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.JBossCacheWorkspaceStorageCache;
+import org.exoplatform.services.jcr.impl.dataflow.session.TransactionableResourceManager;
+import org.exoplatform.services.jcr.impl.dataflow.session.TransactionableResourceManagerListener;
import org.exoplatform.services.jcr.impl.storage.SystemDataContainerHolder;
import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCStorageConnection;
import org.exoplatform.services.jcr.storage.WorkspaceDataContainer;
@@ -46,6 +48,8 @@
import org.exoplatform.services.transaction.TransactionService;
import java.io.Serializable;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
@@ -54,6 +58,7 @@
import java.util.concurrent.atomic.AtomicInteger;
import javax.jcr.RepositoryException;
+import javax.transaction.Status;
import javax.transaction.TransactionManager;
/**
@@ -79,6 +84,11 @@
*/
protected final ConcurrentMap<Integer, DataRequest> requestCache;
+ /**
+ * The resource manager
+ */
+ private final TransactionableResourceManager txResourceManager;
+
private TransactionManager transactionManager;
/**
@@ -300,40 +310,6 @@
}
}
- protected class SaveInTransaction extends TxIsolatedOperation
- {
- final ItemStateChangesLog changes;
-
- SaveInTransaction(ItemStateChangesLog changes)
- {
- super(transactionManager);
- this.changes = changes;
- }
-
- @Override
- protected void action() throws RepositoryException
- {
- CacheableWorkspaceDataManager.super.save(changes);
- }
-
- @Override
- protected void txAction() throws RepositoryException
- {
- super.txAction();
-
- // notify listeners after transaction commit but before the current resume!
- try
- {
- notifySaveItems(changes, false);
- }
- catch (Throwable th)
- {
- // TODO XA layer can throws runtime exceptions
- throw new RepositoryException(th);
- }
- }
- }
-
/**
* This class is a decorator on the top of the {@link WorkspaceStorageCache} to manage the case
* where the cache is disabled at the beginning then potentially enabled later
@@ -369,15 +345,18 @@
* Items cache
* @param systemDataContainerHolder
* System Workspace data container (persistent level)
+ * @param txResourceManager
+ * the resource manager used to manage the whole tx
* @param transactionService
* TransactionService
* @param rpcService
* the service for executing commands on all nodes of cluster
*/
public CacheableWorkspaceDataManager(WorkspaceDataContainer dataContainer, WorkspaceStorageCache cache,
- SystemDataContainerHolder systemDataContainerHolder, TransactionService transactionService, RPCService rpcService)
+ SystemDataContainerHolder systemDataContainerHolder, TransactionableResourceManager txResourceManager,
+ TransactionService transactionService, RPCService rpcService)
{
- super(dataContainer, systemDataContainerHolder);
+ super(dataContainer, systemDataContainerHolder, txResourceManager);
this.cache = cache;
this.requestCache = new ConcurrentHashMap<Integer, DataRequest>();
@@ -386,6 +365,7 @@
transactionManager = transactionService.getTransactionManager();
this.rpcService = rpcService;
+ this.txResourceManager = txResourceManager;
doInitRemoteCommands();
}
@@ -398,12 +378,15 @@
* Items cache
* @param systemDataContainerHolder
* System Workspace data container (persistent level)
+ * @param txResourceManager
+ * the resource manager used to manage the whole tx
* @param transactionService TransactionService
*/
public CacheableWorkspaceDataManager(WorkspaceDataContainer dataContainer, WorkspaceStorageCache cache,
- SystemDataContainerHolder systemDataContainerHolder, TransactionService transactionService)
+ SystemDataContainerHolder systemDataContainerHolder, TransactionableResourceManager txResourceManager,
+ TransactionService transactionService)
{
- this(dataContainer, cache, systemDataContainerHolder, transactionService, null);
+ this(dataContainer, cache, systemDataContainerHolder, txResourceManager, transactionService, null);
}
/**
@@ -415,26 +398,31 @@
* Items cache
* @param systemDataContainerHolder
* System Workspace data container (persistent level)
+ * @param txResourceManager
+ * the resource manager used to manage the whole tx
*/
public CacheableWorkspaceDataManager(WorkspaceDataContainer dataContainer, WorkspaceStorageCache cache,
- SystemDataContainerHolder systemDataContainerHolder, RPCService rpcService)
+ SystemDataContainerHolder systemDataContainerHolder, TransactionableResourceManager txResourceManager,
+ RPCService rpcService)
{
- super(dataContainer, systemDataContainerHolder);
+ super(dataContainer, systemDataContainerHolder, txResourceManager);
this.cache = cache;
this.requestCache = new ConcurrentHashMap<Integer, DataRequest>();
addItemPersistenceListener(new CacheItemsPersistenceListener());
- if (cache instanceof JBossCacheWorkspaceStorageCache)
+ try
{
- transactionManager = ((JBossCacheWorkspaceStorageCache)cache).getTransactionManager();
+ transactionManager = (TransactionManager)cache.getClass().getMethod("getTransactionManager", null).invoke(null, null);
}
- else
+ catch (Exception e)
{
+ LOG.debug("Could not get the transaction manager from the cache", e);
transactionManager = null;
}
this.rpcService = rpcService;
+ this.txResourceManager = txResourceManager;
doInitRemoteCommands();
}
@@ -447,26 +435,29 @@
* Items cache
* @param systemDataContainerHolder
* System Workspace data container (persistent level)
+ * @param txResourceManager
+ * the resource manager used to manage the whole tx
*/
public CacheableWorkspaceDataManager(WorkspaceDataContainer dataContainer, WorkspaceStorageCache cache,
+ SystemDataContainerHolder systemDataContainerHolder, TransactionableResourceManager txResourceManager)
+ {
+ this(dataContainer, cache, systemDataContainerHolder, txResourceManager, (RPCService)null);
+ }
+
+ /**
+ * CacheableWorkspaceDataManager constructor.
+ *
+ * @param dataContainer
+ * Workspace data container (persistent level)
+ * @param cache
+ * Items cache
+ * @param systemDataContainerHolder
+ * System Workspace data container (persistent level)
+ */
+ protected CacheableWorkspaceDataManager(WorkspaceDataContainer dataContainer, WorkspaceStorageCache cache,
SystemDataContainerHolder systemDataContainerHolder)
{
- super(dataContainer, systemDataContainerHolder);
- this.cache = cache;
-
- this.requestCache = new ConcurrentHashMap<Integer, DataRequest>();
- addItemPersistenceListener(new CacheItemsPersistenceListener());
-
- if (cache instanceof JBossCacheWorkspaceStorageCache)
- {
- transactionManager = ((JBossCacheWorkspaceStorageCache)cache).getTransactionManager();
- }
- else
- {
- transactionManager = null;
- }
-
- this.rpcService = null;
+ this(dataContainer, cache, systemDataContainerHolder, null, (RPCService)null);
}
/**
@@ -687,31 +678,187 @@
}
workingThreads.incrementAndGet();
-
try
{
- if (isTxAware())
+ SecurityHelper.doPrivilegedExceptionAction(new PrivilegedExceptionAction<Void>()
{
- // save in dedicated XA transaction
- new SaveInTransaction(changesLog).perform();
+ public Void run() throws Exception
+ {
+ doSave(changesLog);
+ return null;
+ }
+ });
+ }
+ catch (PrivilegedActionException e)
+ {
+ Throwable cause = e.getCause();
+ if (cause instanceof RepositoryException)
+ {
+ throw (RepositoryException)cause;
}
+ else if (cause instanceof RuntimeException)
+ {
+ throw (RuntimeException)cause;
+ }
else
{
+ throw new RuntimeException(cause);
+ }
+ }
+ finally
+ {
+ workingThreads.decrementAndGet();
+ }
+ }
- // save normaly
+ private void doSave(final ItemStateChangesLog changesLog) throws RepositoryException
+ {
+ if (isTxAware())
+ {
+ if (txResourceManager != null && txResourceManager.isGlobalTxActive())
+ {
super.save(changesLog);
-
+ registerListener(changesLog);
+ }
+ else
+ {
+ doBegin();
+ try
+ {
+ super.save(changesLog);
+ }
+ catch (Exception e)
+ {
+ doRollback();
+ if (e instanceof RepositoryException)
+ {
+ throw (RepositoryException)e;
+ }
+ else
+ {
+ throw new RepositoryException("Could not save the changes", e);
+ }
+ }
+ doCommit();
// notify listeners after storage commit
notifySaveItems(changesLog, false);
}
}
- finally
+ else
{
- workingThreads.decrementAndGet();
+ // save normally
+ super.save(changesLog);
+
+ // notify listeners after storage commit
+ notifySaveItems(changesLog, false);
+ }
+ }
+
+ /**
+ * Commits the tx
+ * @throws RepositoryException if the tx could not be committed.
+ */
+ private void doCommit() throws RepositoryException
+ {
+ try
+ {
+ transactionManager.commit();
}
+ catch (Exception e)
+ {
+ throw new RepositoryException("Could not commit the changes", e);
+ }
}
/**
+ * Starts a new Tx
+ * @throws RepositoryException if the tx could not be created
+ */
+ private void doBegin() throws RepositoryException
+ {
+ try
+ {
+ transactionManager.begin();
+ }
+ catch (Exception e)
+ {
+ throw new RepositoryException("Could not create a new Tx", e);
+ }
+ }
+
+ /**
+ * Performs rollback of the action.
+ */
+ private void doRollback()
+ {
+ try
+ {
+ transactionManager.rollback();
+ }
+ catch (Exception e)
+ {
+ LOG.error("Rollback error ", e);
+ }
+ }
+
+ /**
+ * This will allow to notify listeners that are not TxAware once the Tx is committed
+ * @param changesLog
+ * @throws RepositoryException if any error occurs
+ */
+ private void registerListener(final ItemStateChangesLog changesLog) throws RepositoryException
+ {
+ try
+ {
+ // Why calling the listeners non tx aware has been done like this:
+ // 1. If we call them in the commit phase and we use Arjuna with ISPN, we get:
+ // ActionStatus.COMMITTING > is not in a valid state to be invoking cache operations on.
+ // at org.infinispan.interceptors.TxInterceptor.enlist(TxInterceptor.java:195)
+ // at org.infinispan.interceptors.TxInterceptor.enlistReadAndInvokeNext(TxInterceptor.java:167)
+ // at org.infinispan.interceptors.TxInterceptor.visitGetKeyValueCommand(TxInterceptor.java:162)
+ // at org.infinispan.commands.read.GetKeyValueCommand.acceptVisitor(GetKeyValueCommand.java:64)
+ // This is due to the fact that ISPN enlist the cache even for a read access and enlistments are not
+ // allowed in the commit phase
+ // 2. If we call them in the commit phase, we use Arjuna with ISPN and we suspend the current tx, we get deadlocks because we
+ // try to acquire locks on cache entries that have been locked by the main tx.
+ // 3. If we call them in the afterComplete, we use JOTM with ISPN and we suspend and resume the current tx, we get:
+ // jotm: resume: Invalid Transaction Status:STATUS_COMMITTED (Current.java, line 743)
+ // javax.transaction.InvalidTransactionException: Invalid resume org.objectweb.jotm.TransactionImpl
+ // at org.objectweb.jotm.Current.resume(Current.java:744)
+ // This is due to the fact that it is not allowed to resume a tx when its status is STATUS_COMMITED
+
+ txResourceManager.addListener(new TransactionableResourceManagerListener()
+ {
+ public void onCommit(boolean onePhase) throws Exception
+ {
+ }
+
+ public void onAfterCompletion(int status) throws Exception
+ {
+ if (status == Status.STATUS_COMMITTED)
+ {
+ // Since the tx is successfully committed we can call components non tx aware
+
+ // The listeners will need to be executed outside the current tx so we suspend
+ // the current tx we can face enlistment issues on product like ISPN
+ transactionManager.suspend();
+ notifySaveItems(changesLog, false);
+ // Since the resume method could cause issue with some TM at this stage, we don't resume the tx
+ }
+ }
+
+ public void onAbort() throws Exception
+ {
+ }
+ });
+ }
+ catch (Exception e)
+ {
+ throw new RepositoryException("The listener for the components not tx aware could not be added", e);
+ }
+ }
+
+ /**
* Get cached ItemData.
*
* @param parentData
Deleted: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TxIsolatedOperation.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TxIsolatedOperation.java 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TxIsolatedOperation.java 2011-05-23 07:39:32 UTC (rev 4402)
@@ -1,376 +0,0 @@
-package org.exoplatform.services.jcr.impl.dataflow.persistent;
-
-import org.exoplatform.services.jcr.impl.storage.JCRInvalidItemStateException;
-import org.exoplatform.services.log.ExoLogger;
-import org.exoplatform.services.log.Log;
-
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-
-import javax.jcr.InvalidItemStateException;
-import javax.jcr.ItemExistsException;
-import javax.jcr.RepositoryException;
-import javax.transaction.HeuristicMixedException;
-import javax.transaction.HeuristicRollbackException;
-import javax.transaction.InvalidTransactionException;
-import javax.transaction.NotSupportedException;
-import javax.transaction.RollbackException;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-
-/**
- * Handles XA transactionaly isolated operation. I.e. Action of this operation will be executed in dedicated global transaction.
- * If another current transaction exists, the one will be suspended and resumed after the execution.
- * At other hand if nested isolated operations perform they will use same (current, active) transaction.
- */
-public abstract class TxIsolatedOperation
-{
- protected static final Log LOG = ExoLogger.getLogger("exo.jcr.component.core.TxIsolatedOperation");
-
- protected final TransactionManager txManager;
-
- protected final static ThreadLocal<Transaction> currentIsolated = new ThreadLocal<Transaction>();
-
- public TxIsolatedOperation(TransactionManager txManager)
- {
- this.txManager = txManager;
- }
-
- /**
- * Action body for a final implementation.
- *
- * @throws RepositoryException
- */
- protected abstract void action() throws RepositoryException;
-
- protected void beginTx() throws NotSupportedException, SystemException
- {
- txManager.begin(); // start new global tx
- }
-
- protected void commitTx() throws SecurityException, IllegalStateException, RollbackException,
- HeuristicMixedException, HeuristicRollbackException, SystemException
- {
- PrivilegedExceptionAction<Object> action = new PrivilegedExceptionAction<Object>()
- {
- public Object run() throws Exception
- {
- txManager.commit(); // commit global tx
- return null;
- }
- };
- try
- {
- AccessController.doPrivileged(action);
- }
- catch (PrivilegedActionException pae)
- {
- Throwable cause = pae.getCause();
- if (cause instanceof RollbackException)
- {
- throw (RollbackException)cause;
- }
- else if (cause instanceof HeuristicMixedException)
- {
- throw (HeuristicMixedException)cause;
- }
- else if (cause instanceof HeuristicRollbackException)
- {
- throw (HeuristicRollbackException)cause;
- }
- else if (cause instanceof SecurityException)
- {
- throw (SecurityException)cause;
- }
- else if (cause instanceof IllegalStateException)
- {
- throw (IllegalStateException)cause;
- }
- else if (cause instanceof SystemException)
- {
- throw (SystemException)cause;
- }
- else if (cause instanceof RuntimeException)
- {
- throw (RuntimeException)cause;
- }
- else
- {
- throw new RuntimeException(cause);
- }
- }
- }
-
- protected void rollbackTx() throws NotSupportedException, SystemException
- {
- PrivilegedExceptionAction<Object> action = new PrivilegedExceptionAction<Object>()
- {
- public Object run() throws Exception
- {
- txManager.rollback(); // rollback global tx
- return null;
- }
- };
- try
- {
- AccessController.doPrivileged(action);
- }
- catch (PrivilegedActionException pae)
- {
- Throwable cause = pae.getCause();
- if (cause instanceof SecurityException)
- {
- throw (SecurityException)cause;
- }
- else if (cause instanceof IllegalStateException)
- {
- throw (IllegalStateException)cause;
- }
- else if (cause instanceof SystemException)
- {
- throw (SystemException)cause;
- }
- else if (cause instanceof RuntimeException)
- {
- throw (RuntimeException)cause;
- }
- else
- {
- throw new RuntimeException(cause);
- }
- }
- }
-
- /**
- * Apply action in new XA transaction (begin then commit or rollback).
- * Action will runs in dedicated XA transaction, i.e. only JCR storage stuff will be involved to.
- * But if it's a nested isolated operation it will run the action assuming the same (current, active) transaction.
- *
- * @throws RepositoryException if error occurs
- */
- // * @throws SystemException if XA unexpected error
- // * @throws NotSupportedException if unsupported XA operation
- // * @throws HeuristicRollbackException if all relevant updates have been rolled back on commit
- // * @throws HeuristicMixedException if some relevant updates have been committed and others have been rolled back on commit
- // * @throws RollbackException rollback performed
- // * @throws IllegalStateException if thread is not associated with a transaction
- // * @throws SecurityException if thread is not allowed to commit the transaction
- protected void txAction() throws RepositoryException
- {
- final boolean actInTx = currentIsolated.get() == null;
- if (actInTx)
- {
- // it's rooted isolated operation
- boolean rollback = true;
- try
- {
- beginTx();
-
- // remember current isolated transaction for this thread
- Transaction current = txManager.getTransaction();
- if (current != null)
- {
- currentIsolated.set(current);
- }
-
- action();
-
- try
- {
- commitTx();
- }
- catch (RollbackException e)
- {
- // Indicate that the transaction has been rolled back rather than committed.
- // TODO throw new RepositoryException(e);
- LOG.error("Transaction has been rolled back", e);
- }
- catch (HeuristicRollbackException e)
- {
- // if all relevant updates have been rolled back on commit
- // TODO throw new RepositoryException(e);
- LOG.error("Relevant updates have been rolled back", e);
- }
- catch (HeuristicMixedException e)
- {
- // if some relevant updates have been committed and others have been rolled back on commit
- // TODO partial commit - got inconsistency. rollback not possible?
- // doRollback();
- // TODO throw new RepositoryException(e);
- LOG.error("Some relevant updates have been committed and others have been rolled back", e);
- }
- catch (IllegalStateException e)
- {
- // if thread is not associated with a transaction
- // TODO can we do rollback if not in the tx thread?
- // doRollback();
- // TODO throw new RepositoryException(e);
- LOG.error("Commit impossible, thread is not associated with the transaction", e);
- }
- catch (SecurityException e)
- {
- // if thread is not allowed to commit the transaction
- // TODO can we do the rollback, will it have a rights?
- // doRollback();
- // TODO throw new RepositoryException(e);
- LOG.error("Commit impossible, thread is not allowed to commit the transaction", e);
- }
- catch (SystemException e)
- {
- // if XA unexpected error
- // TODO rollback not possible?
- // doRollback();
- // TODO throw new RepositoryException(e);
- LOG.error("Commit impossible dur to unexpected XA error", e);
- }
- finally
- {
- rollback = false;
- }
- }
- catch (NotSupportedException e)
- {
- // if unsupported XA operation: nested transaction
- rollback = false;
- doRollback();
- throw new RepositoryException(e);
- }
- catch (SystemException e)
- {
- // if XA unexpected error on begin or get transaction
- rollback = false;
- doRollback();
- throw new RepositoryException("Unexpected error on begin or get of a transaction", e);
- }
- finally
- {
- if (rollback)
- {
- doRollback();
- }
-
- // remove current isolated transaction from this thread
- currentIsolated.remove();
- }
- }
- else
- {
- // it's nested isolated operation
- action();
- }
- }
-
- /**
- * Performs rollback of the action.
- */
- private void doRollback()
- {
- try
- {
- rollbackTx();
- }
- catch (Exception e1)
- {
- LOG.error("Rollback error ", e1);
- }
- }
-
- /**
- * Apply the action in new XA transaction. Action should run in dedicated XA transaction,
- * i.e. only JCR storage stuff should be involved to.
- */
- public void perform() throws RepositoryException
- {
- try
- {
- // Care about dedicated XA transaction for storage save:
- // suspend current ransaction and create one new for the JCR storage (cache etc.)
- // after the new transaction done we'll resume the current.
-
- Transaction current = txManager.suspend();
- Throwable actionError = null; // used for resume errors handling
- try
- {
- txAction();
- }
- // catch (RollbackException e)
- // {
- // // Indicate that the transaction has been rolled back rather than committed.
- // throw new RepositoryException(actionError = e);
- // }
- catch (JCRInvalidItemStateException e)
- {
- throw new JCRInvalidItemStateException(e.getMessage(), e.getIdentifier(), e.getState(), actionError = e);
- }
- catch (InvalidItemStateException e)
- {
- throw new InvalidItemStateException(actionError = e);
- }
- catch (ItemExistsException e)
- {
- throw new ItemExistsException(actionError = e);
- }
- catch (ReadOnlyWorkspaceException e)
- {
- throw new ReadOnlyWorkspaceException(actionError = e);
- }
- catch (RepositoryException e)
- {
- throw new RepositoryException(actionError = e);
- }
- catch (Throwable e)
- {
- throw new RepositoryException(actionError = e);
- }
- finally
- {
- if (current != null)
- {
- try
- {
- txManager.resume(current);
- }
- catch (InvalidTransactionException e)
- {
- if (actionError == null)
- {
- throw new RepositoryException("Error of Transaction resume", e);
- }
- else
- {
- LOG.error("Error of Transaction resume", e);
- }
- }
- catch (IllegalStateException e)
- {
- if (actionError == null)
- {
- throw new RepositoryException("Error of Transaction resume", e);
- }
- else
- {
- LOG.error("Error of Transaction resume", e);
- }
- }
- catch (SystemException e)
- {
- if (actionError == null)
- {
- throw new RepositoryException("Error of Transaction resume", e);
- }
- else
- {
- LOG.error("Error of Transaction resume", e);
- }
- }
- }
- }
- }
- catch (SystemException e)
- {
- throw new RepositoryException("Error of Transaction suspend", e);
- }
- }
-}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/WorkspacePersistentDataManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/WorkspacePersistentDataManager.java 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/WorkspacePersistentDataManager.java 2011-05-23 07:39:32 UTC (rev 4402)
@@ -41,6 +41,8 @@
import org.exoplatform.services.jcr.datamodel.ValueData;
import org.exoplatform.services.jcr.impl.Constants;
import org.exoplatform.services.jcr.impl.dataflow.TransientValueData;
+import org.exoplatform.services.jcr.impl.dataflow.session.TransactionableResourceManager;
+import org.exoplatform.services.jcr.impl.dataflow.session.TransactionableResourceManagerListener;
import org.exoplatform.services.jcr.impl.storage.SystemDataContainerHolder;
import org.exoplatform.services.jcr.storage.WorkspaceDataContainer;
import org.exoplatform.services.jcr.storage.WorkspaceStorageConnection;
@@ -105,8 +107,13 @@
* Read-only status.
*/
protected boolean readOnly = false;
-
+
/**
+ * The resource manager
+ */
+ private final TransactionableResourceManager txResourceManager;
+
+ /**
* WorkspacePersistentDataManager constructor.
*
* @param dataContainer
@@ -114,15 +121,32 @@
* @param systemDataContainerHolder
* holder of system workspace data container
*/
- public WorkspacePersistentDataManager(WorkspaceDataContainer dataContainer,
+ protected WorkspacePersistentDataManager(WorkspaceDataContainer dataContainer,
SystemDataContainerHolder systemDataContainerHolder)
{
+ this(dataContainer, systemDataContainerHolder, null);
+ }
+
+ /**
+ * WorkspacePersistentDataManager constructor.
+ *
+ * @param dataContainer
+ * workspace data container
+ * @param systemDataContainerHolder
+ * holder of system workspace data container
+ * @param txResourceManager
+ * the resource manager used to manage the whole tx
+ */
+ public WorkspacePersistentDataManager(WorkspaceDataContainer dataContainer,
+ SystemDataContainerHolder systemDataContainerHolder, TransactionableResourceManager txResourceManager)
+ {
this.dataContainer = dataContainer;
this.systemDataContainer = systemDataContainerHolder.getContainer();
this.listeners = new ArrayList<ItemsPersistenceListener>();
this.mandatoryListeners = new ArrayList<MandatoryItemsPersistenceListener>();
this.liestenerFilters = new ArrayList<ItemsPersistenceListenerFilter>();
+ this.txResourceManager = txResourceManager;
}
/**
@@ -140,7 +164,8 @@
// whole log will be reconstructed with persisted data
ItemStateChangesLog persistedLog;
-
+ boolean failed = true;
+ ConnectionMode mode = getMode();
try
{
if (changesLog instanceof PlainChangesLogImpl)
@@ -166,7 +191,9 @@
// we don't support other types now... i.e. add else-if for that type here
throw new RepositoryException("Unsupported changes log class " + changesLog.getClass());
}
- persister.commit();
+ notifySaveItems(persistedLog, true);
+ onCommit(persister, mode);
+ failed = false;
}
catch (IOException e)
{
@@ -174,12 +201,79 @@
}
finally
{
+ persister.clear();
+ if (failed)
+ {
+ onRollback(persister, mode);
+ }
+ }
+ }
+
+ /**
+ * @return the current tx mode
+ */
+ private ConnectionMode getMode()
+ {
+ if (txResourceManager != null && txResourceManager.isGlobalTxActive())
+ {
+ return ConnectionMode.PARTIALLY_MANAGED;
+ }
+ return ConnectionMode.NORMAL;
+ }
+
+ /**
+ * @param persister
+ * @throws RepositoryException
+ */
+ private void onRollback(final ChangesLogPersister persister, ConnectionMode mode) throws RepositoryException
+ {
+ if (mode == ConnectionMode.NORMAL || mode == ConnectionMode.PARTIALLY_MANAGED)
+ {
+ // The rollback is done normally
persister.rollback();
+ }
+ }
+
+ /**
+ * @param persister
+ * @throws RepositoryException
+ */
+ private void onCommit(final ChangesLogPersister persister, ConnectionMode mode) throws RepositoryException
+ {
+ if (mode == ConnectionMode.NORMAL)
+ {
+ // The commit is done normally
+ persister.commit();
}
+ else if (mode == ConnectionMode.PARTIALLY_MANAGED)
+ {
+ // The commit or rollback will be done by callback once the tx will be completed since it could
+ // fail later in the tx
+ txResourceManager.addListener(new TransactionableResourceManagerListener()
+ {
+
+ public void onCommit(boolean onePhase) throws Exception
+ {
+ persister.commit();
+ }
+
+ public void onAfterCompletion(int status) throws Exception
+ {
+ }
+
+ public void onAbort() throws Exception
+ {
+ persister.rollback();
+ }
+ });
+ }
+ }
- notifySaveItems(persistedLog, true);
+ private enum ConnectionMode
+ {
+ NORMAL, PARTIALLY_MANAGED
}
-
+
class ChangesLogPersister
{
@@ -201,6 +295,12 @@
}
}
+ protected void clear()
+ {
+ // help to GC
+ addedNodes.clear();
+ }
+
protected void rollback() throws IllegalStateException, RepositoryException
{
if (thisConnection != null && thisConnection.isOpened())
@@ -211,9 +311,6 @@
{
systemConnection.rollback();
}
-
- // help to GC
- addedNodes.clear();
}
protected WorkspaceStorageConnection getSystemConnection() throws RepositoryException
@@ -471,7 +568,6 @@
/**
* {@inheritDoc}
*/
- @Override
public int getLastOrderNumber(final NodeData nodeData) throws RepositoryException
{
final WorkspaceStorageConnection con = dataContainer.openConnection();
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/BufferedISPNCache.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/BufferedISPNCache.java 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/BufferedISPNCache.java 2011-05-23 07:39:32 UTC (rev 4402)
@@ -910,69 +910,86 @@
public void commitTransaction()
{
CompressedISPNChangesBuffer changesContainer = getChangesBufferSafe();
- TransactionManager tm = getTransactionManager();
+ final TransactionManager tm = getTransactionManager();
try
{
- List<ChangesContainer> containers = changesContainer.getSortedList();
- for (ChangesContainer cacheChange : containers)
+ final List<ChangesContainer> containers = changesContainer.getSortedList();
+ PrivilegedAction<Void> action = new PrivilegedAction<Void>()
{
- boolean isTxCreated = false;
- try
+ public Void run()
{
- if (cacheChange.isTxRequired() && tm != null && tm.getStatus() == Status.STATUS_NO_TRANSACTION)
- {
- // No tx exists so we create a new tx
- if (LOG.isTraceEnabled())
- LOG.trace("No Tx is active we then create a new tx");
- tm.begin();
- isTxCreated = true;
- }
+ commitChanges(tm, containers);
+ return null;
}
- catch (Exception e)
+ };
+ AccessController.doPrivileged(action);
+ }
+ finally
+ {
+ changesList.set(null);
+ changesContainer = null;
+ }
+ }
+
+ /**
+ * @param tm
+ * @param containers
+ */
+ private void commitChanges(TransactionManager tm, List<ChangesContainer> containers)
+ {
+ for (ChangesContainer cacheChange : containers)
+ {
+ boolean isTxCreated = false;
+ try
+ {
+ if (cacheChange.isTxRequired() && tm != null && tm.getStatus() == Status.STATUS_NO_TRANSACTION)
{
- LOG.warn("Could not create a new tx", e);
+ // No tx exists so we create a new tx
+ if (LOG.isTraceEnabled())
+ LOG.trace("No Tx is active we then create a new tx");
+ tm.begin();
+ isTxCreated = true;
}
- try
- {
- cacheChange.apply();
- }
- catch (RuntimeException e)
- {
- if (isTxCreated)
- {
- try
- {
- if (LOG.isTraceEnabled())
- LOG.trace("An error occurs the tx will be rollbacked");
- tm.rollback();
- }
- catch (Exception e1)
- {
- LOG.warn("Could not rollback the tx", e1);
- }
- }
- throw e;
- }
+ }
+ catch (Exception e)
+ {
+ LOG.warn("Could not create a new tx", e);
+ }
+ try
+ {
+ cacheChange.apply();
+ }
+ catch (RuntimeException e)
+ {
if (isTxCreated)
{
try
{
if (LOG.isTraceEnabled())
- LOG.trace("The tx will be committed");
- tm.commit();
+ LOG.trace("An error occurs the tx will be rollbacked");
+ tm.rollback();
}
- catch (Exception e)
+ catch (Exception e1)
{
- LOG.warn("Could not commit the tx", e);
+ LOG.warn("Could not rollback the tx", e1);
}
}
+ throw e;
}
+ if (isTxCreated)
+ {
+ try
+ {
+ if (LOG.isTraceEnabled())
+ LOG.trace("The tx will be committed");
+ tm.commit();
+ }
+ catch (Exception e)
+ {
+ LOG.warn("Could not commit the tx", e);
+ }
+ }
}
- finally
- {
- changesList.set(null);
- changesContainer = null;
- }
}
/**
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java 2011-05-23 07:39:32 UTC (rev 4402)
@@ -18,7 +18,6 @@
*/
package org.exoplatform.services.jcr.impl.dataflow.persistent.infinispan;
-import org.exoplatform.commons.utils.SecurityHelper;
import org.exoplatform.container.configuration.ConfigurationManager;
import org.exoplatform.management.annotations.Managed;
import org.exoplatform.management.annotations.ManagedDescription;
@@ -50,12 +49,12 @@
import org.exoplatform.services.jcr.infinispan.ISPNCacheFactory;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
+import org.exoplatform.services.transaction.ActionNonTxAware;
import org.infinispan.Cache;
import org.infinispan.lifecycle.ComponentStatus;
import java.io.File;
import java.io.IOException;
-import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -67,7 +66,6 @@
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
-import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
/**
@@ -100,6 +98,228 @@
protected final BufferedISPNCache cache;
+ private final CacheActionNonTxAware<Void, Void> commitTransaction = new CacheActionNonTxAware<Void, Void>()
+ {
+ @Override
+ protected Void execute(Void arg) throws RuntimeException
+ {
+ cache.commitTransaction();
+ return null;
+ }
+ };
+
+ private final CacheActionNonTxAware<ItemData, String> getFromCacheById =
+ new CacheActionNonTxAware<ItemData, String>()
+ {
+ @Override
+ protected ItemData execute(String id) throws RuntimeException
+ {
+ return id == null ? null : (ItemData)cache.get(new CacheId(id));
+ }
+ };
+
+ private final CacheActionNonTxAware<List<NodeData>, NodeData> getChildNodes =
+ new CacheActionNonTxAware<List<NodeData>, NodeData>()
+ {
+ @Override
+ protected List<NodeData> execute(NodeData parent) throws RuntimeException
+ {
+ // get list of children uuids
+ final Set<String> set = (Set<String>)cache.get(new CacheNodesId(parent.getIdentifier()));
+
+ if (set != null)
+ {
+ final List<NodeData> childs = new ArrayList<NodeData>();
+
+ for (String childId : set)
+ {
+ NodeData child = (NodeData)cache.get(new CacheId(childId));
+ if (child == null)
+ {
+ return null;
+ }
+
+ childs.add(child);
+ }
+
+ // order children by orderNumber, as HashSet returns children in other order
+ Collections.sort(childs, new NodesOrderComparator<NodeData>());
+ return childs;
+ }
+ else
+ {
+ return null;
+ }
+ }
+ };
+
+ private final CacheActionNonTxAware<ItemData, Object> getFromCacheByPath =
+ new CacheActionNonTxAware<ItemData, Object>()
+ {
+ @Override
+ protected ItemData execute(Object... args) throws RuntimeException
+ {
+ String parentIdentifier = (String)args[0];
+ QPathEntry name = (QPathEntry)args[1];
+ ItemType itemType = (ItemType)args[2];
+ String itemId = null;
+
+ if (itemType == ItemType.UNKNOWN)
+ {
+ // Try as node first.
+ itemId = (String)cache.get(new CacheQPath(parentIdentifier, name, ItemType.NODE));
+
+ if (itemId == null || itemId.equals(NullItemData.NULL_ID))
+ {
+ // node with such a name is not found or marked as not-exist, so check the properties
+ String propId = (String)cache.get(new CacheQPath(parentIdentifier, name, ItemType.PROPERTY));
+ if (propId != null)
+ {
+ itemId = propId;
+ }
+ }
+ }
+ else if (itemType == ItemType.NODE)
+ {
+ itemId = (String)cache.get(new CacheQPath(parentIdentifier, name, ItemType.NODE));;
+ }
+ else
+ {
+ itemId = (String)cache.get(new CacheQPath(parentIdentifier, name, ItemType.PROPERTY));;
+ }
+
+ if (itemId != null)
+ {
+ if (itemId.equals(NullItemData.NULL_ID))
+ {
+ if (itemType == ItemType.UNKNOWN || itemType == ItemType.NODE)
+ {
+ return new NullNodeData();
+ }
+ else
+ {
+ return new NullPropertyData();
+ }
+ }
+ else
+ {
+ return get(itemId);
+ }
+ }
+ return null;
+ }
+ };
+
+ private final CacheActionNonTxAware<Integer, NodeData> getChildNodesCount =
+ new CacheActionNonTxAware<Integer, NodeData>()
+ {
+ @Override
+ protected Integer execute(NodeData parent) throws RuntimeException
+ {
+ Set<String> list = (Set<String>)cache.get(new CacheNodesId(parent.getIdentifier()));
+ return list != null ? list.size() : -1;
+ }
+ };
+
+ private final CacheActionNonTxAware<List<PropertyData>, Object> getChildProps =
+ new CacheActionNonTxAware<List<PropertyData>, Object>()
+ {
+ @Override
+ protected List<PropertyData> execute(Object... args) throws RuntimeException
+ {
+ String parentId = (String)args[0];
+ boolean withValue = (Boolean)args[1];
+ // get list of children uuids
+ final Set<String> set = (Set<String>)cache.get(new CachePropsId(parentId));
+ if (set != null)
+ {
+ final List<PropertyData> childs = new ArrayList<PropertyData>();
+
+ for (String childId : set)
+ {
+ PropertyData child = (PropertyData)cache.get(new CacheId(childId));
+
+ if (child == null)
+ {
+ return null;
+ }
+ if (withValue && child.getValues().size() <= 0)
+ {
+ return null;
+ }
+ childs.add(child);
+ }
+ return childs;
+ }
+ else
+ {
+ return null;
+ }
+ }
+ };
+
+ private final CacheActionNonTxAware<List<PropertyData>, String> getReferencedProperties =
+ new CacheActionNonTxAware<List<PropertyData>, String>()
+ {
+ @Override
+ protected List<PropertyData> execute(String identifier) throws RuntimeException
+ {
+ // get list of children uuids
+ final Set<String> set = (Set<String>)cache.get(new CacheRefsId(identifier));
+ if (set != null)
+ {
+ final List<PropertyData> props = new ArrayList<PropertyData>();
+
+ for (String childId : set)
+ {
+ PropertyData prop = (PropertyData)cache.get(new CacheId(childId));
+
+ if (prop == null || prop instanceof NullItemData)
+ {
+ return null;
+ }
+ // add property as many times as has referenced values
+ List<ValueData> lData = prop.getValues();
+ for (int i = 0, length = lData.size(); i < length; i++)
+ {
+ ValueData vdata = lData.get(i);
+ try
+ {
+ if (new String(vdata.getAsByteArray(), Constants.DEFAULT_ENCODING).equals(identifier))
+ {
+ props.add(prop);
+ }
+ }
+ catch (IllegalStateException e)
+ {
+ // property was not added, force read from lower layer
+ return null;
+ }
+ catch (IOException e)
+ {
+ // property was not added, force read from lower layer
+ return null;
+ }
+ }
+ }
+ return props;
+ }
+ else
+ {
+ return null;
+ }
+ }
+ };
+
+ private final CacheActionNonTxAware<Long, Void> getSize = new CacheActionNonTxAware<Long, Void>()
+ {
+ @Override
+ protected Long execute(Void arg) throws RuntimeException
+ {
+ return (long)cache.size();
+ }
+ };
+
/**
* Node order comparator for getChildNodes().
*/
@@ -243,6 +463,16 @@
}
/**
+ * Return TransactionManager used by ISPN backing the JCR cache.
+ *
+ * @return TransactionManager
+ */
+ public TransactionManager getTransactionManager()
+ {
+ return cache.getTransactionManager();
+ }
+
+ /**
* {@inheritDoc}
*/
public void put(ItemData item)
@@ -457,51 +687,7 @@
*/
public ItemData get(String parentIdentifier, QPathEntry name, ItemType itemType)
{
- String itemId = null;
-
- if (itemType == ItemType.UNKNOWN)
- {
- // Try as node first.
- itemId = (String)cache.get(new CacheQPath(parentIdentifier, name, ItemType.NODE));
-
- if (itemId == null || itemId.equals(NullItemData.NULL_ID))
- {
- // node with such a name is not found or marked as not-exist, so check the properties
- String propId = (String)cache.get(new CacheQPath(parentIdentifier, name, ItemType.PROPERTY));
- if (propId != null)
- {
- itemId = propId;
- }
- }
- }
- else if (itemType == ItemType.NODE)
- {
- itemId = (String)cache.get(new CacheQPath(parentIdentifier, name, ItemType.NODE));;
- }
- else
- {
- itemId = (String)cache.get(new CacheQPath(parentIdentifier, name, ItemType.PROPERTY));;
- }
-
- if (itemId != null)
- {
- if (itemId.equals(NullItemData.NULL_ID))
- {
- if (itemType == ItemType.UNKNOWN || itemType == ItemType.NODE)
- {
- return new NullNodeData();
- }
- else
- {
- return new NullPropertyData();
- }
- }
- else
- {
- return get(itemId);
- }
- }
- return null;
+ return getFromCacheByPath.run(parentIdentifier, name, itemType);
}
/**
@@ -509,7 +695,7 @@
*/
public ItemData get(String id)
{
- return id == null ? null : (ItemData)cache.get(new CacheId(id));
+ return getFromCacheById.run(id);
}
/**
@@ -517,32 +703,7 @@
*/
public List<NodeData> getChildNodes(final NodeData parent)
{
- // get list of children uuids
- final Set<String> set = (Set<String>)cache.get(new CacheNodesId(parent.getIdentifier()));
-
- if (set != null)
- {
- final List<NodeData> childs = new ArrayList<NodeData>();
-
- for (String childId : set)
- {
- NodeData child = (NodeData)cache.get(new CacheId(childId));
- if (child == null)
- {
- return null;
- }
-
- childs.add(child);
- }
-
- // order children by orderNumber, as HashSet returns children in other order
- Collections.sort(childs, new NodesOrderComparator<NodeData>());
- return childs;
- }
- else
- {
- return null;
- }
+ return getChildNodes.run(parent);
}
/**
@@ -550,8 +711,7 @@
*/
public int getChildNodesCount(NodeData parent)
{
- Set<String> list = (Set<String>)cache.get(new CacheNodesId(parent.getIdentifier()));
- return list != null ? list.size() : -1;
+ return getChildNodesCount.run(parent);
}
/**
@@ -579,32 +739,7 @@
*/
protected List<PropertyData> getChildProps(String parentId, boolean withValue)
{
- // get list of children uuids
- final Set<String> set = (Set<String>)cache.get(new CachePropsId(parentId));
- if (set != null)
- {
- final List<PropertyData> childs = new ArrayList<PropertyData>();
-
- for (String childId : set)
- {
- PropertyData child = (PropertyData)cache.get(new CacheId(childId));
-
- if (child == null)
- {
- return null;
- }
- if (withValue && child.getValues().size() <= 0)
- {
- return null;
- }
- childs.add(child);
- }
- return childs;
- }
- else
- {
- return null;
- }
+ return getChildProps.run(parentId, withValue);
}
/**
@@ -612,7 +747,7 @@
*/
public long getSize()
{
- return cache.size();
+ return getSize.run();
}
/**
@@ -1039,53 +1174,7 @@
*/
private void dedicatedTxCommit()
{
- // Ensure that the commit is done in a dedicated tx to avoid deadlock due
- // to global XA Tx
- final TransactionManager tm = cache.getTransactionManager();
- Transaction tx = null;
- try
- {
- if (tm != null)
- {
- try
- {
- tx = SecurityHelper.doPrivilegedExceptionAction(new PrivilegedExceptionAction<Transaction>()
- {
- public Transaction run() throws Exception
- {
- return tm.suspend();
- }
- });
- }
- catch (Exception e)
- {
- LOG.warn("Cannot suspend the current transaction", e);
- }
- }
- cache.commitTransaction();
- }
- finally
- {
- if (tx != null)
- {
- try
- {
- final Transaction privilegedTx = tx;
- SecurityHelper.doPrivilegedExceptionAction(new PrivilegedExceptionAction<Object>()
- {
- public Object run() throws Exception
- {
- tm.resume(privilegedTx);
- return null;
- }
- });
- }
- catch (Exception e)
- {
- LOG.warn("Cannot resume the current transaction", e);
- }
- }
- }
+ commitTransaction.run();
}
/**
@@ -1121,54 +1210,11 @@
}
/**
- * @see org.exoplatform.services.jcr.dataflow.persistent.WorkspaceStorageCache#getReferencedProperties(java.lang.String)
+ * {@inheritDoc}
*/
public List<PropertyData> getReferencedProperties(String identifier)
{
- // get list of children uuids
- final Set<String> set = (Set<String>)cache.get(new CacheRefsId(identifier));
- if (set != null)
- {
- final List<PropertyData> props = new ArrayList<PropertyData>();
-
- for (String childId : set)
- {
- PropertyData prop = (PropertyData)cache.get(new CacheId(childId));
-
- if (prop == null || prop instanceof NullItemData)
- {
- return null;
- }
- // add property as many times as has referenced values
- List<ValueData> lData = prop.getValues();
- for (int i = 0, length = lData.size(); i < length; i++)
- {
- ValueData vdata = lData.get(i);
- try
- {
- if (new String(vdata.getAsByteArray(), Constants.DEFAULT_ENCODING).equals(identifier))
- {
- props.add(prop);
- }
- }
- catch (IllegalStateException e)
- {
- // property was not added, force read from lower layer
- return null;
- }
- catch (IOException e)
- {
- // property was not added, force read from lower layer
- return null;
- }
- }
- }
- return props;
- }
- else
- {
- return null;
- }
+ return getReferencedProperties.run(identifier);
}
/**
@@ -1236,4 +1282,23 @@
}
};
}
+
+ /**
+ * Actions that are not supposed to be called within a transaction
+ *
+ * Created by The eXo Platform SAS
+ * Author : Nicolas Filotto
+ * nicolas.filotto(a)exoplatform.com
+ * 21 janv. 2010
+ */
+ protected abstract class CacheActionNonTxAware<R, A> extends ActionNonTxAware<R, A, RuntimeException>
+ {
+ /**
+ * {@inheritDoc}
+ */
+ protected TransactionManager getTransactionManager()
+ {
+ return ISPNCacheWorkspaceStorageCache.this.getTransactionManager();
+ }
+ }
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/BufferedJBossCache.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/BufferedJBossCache.java 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/BufferedJBossCache.java 2011-05-23 07:39:32 UTC (rev 4402)
@@ -110,68 +110,84 @@
CompressedChangesBuffer changesContainer = getChangesBufferSafe();
try
{
- //log.info("Before=" + changesContainer.toString());
- //Collections.sort(changesContainer);
- List<ChangesContainer> containers = changesContainer.getSortedList();
- //log.info("After=" + changesContainer.toString());
- for (ChangesContainer cacheChange : containers)
+ final List<ChangesContainer> containers = changesContainer.getSortedList();
+ PrivilegedAction<Void> action = new PrivilegedAction<Void>()
{
- boolean isTxCreated = false;
- try
+ public Void run()
{
- if (cacheChange.isTxRequired() && tm != null && tm.getStatus() == Status.STATUS_NO_TRANSACTION)
- {
- // No tx exists so we create a new tx
- if (LOG.isTraceEnabled()) LOG.trace("No Tx is active we then create a new tx");
- tm.begin();
- isTxCreated = true;
- }
+ commitChanges(containers);
+ return null;
}
- catch (Exception e)
+ };
+ AccessController.doPrivileged(action);
+ }
+ finally
+ {
+ changesList.set(null);
+ changesContainer = null;
+ }
+ }
+
+ /**
+ * @param containers
+ */
+ private void commitChanges(List<ChangesContainer> containers)
+ {
+ for (ChangesContainer cacheChange : containers)
+ {
+ boolean isTxCreated = false;
+ try
+ {
+ if (cacheChange.isTxRequired() && tm != null && tm.getStatus() == Status.STATUS_NO_TRANSACTION)
{
- LOG.warn("Could not create a new tx", e);
+ // No tx exists so we create a new tx
+ if (LOG.isTraceEnabled())
+ LOG.trace("No Tx is active we then create a new tx");
+ tm.begin();
+ isTxCreated = true;
}
- try
- {
- cacheChange.apply();
- }
- catch (RuntimeException e)
- {
- if (isTxCreated)
- {
- try
- {
- if (LOG.isTraceEnabled()) LOG.trace("An error occurs the tx will be rollbacked");
- tm.rollback();
- }
- catch (Exception e1)
- {
- LOG.warn("Could not rollback the tx", e1);
- }
- }
- throw e;
- }
+ }
+ catch (Exception e)
+ {
+ LOG.warn("Could not create a new tx", e);
+ }
+ try
+ {
+ cacheChange.apply();
+ }
+ catch (RuntimeException e)
+ {
if (isTxCreated)
{
try
{
- if (LOG.isTraceEnabled()) LOG.trace("The tx will be committed");
- tm.commit();
+ if (LOG.isTraceEnabled())
+ LOG.trace("An error occurs the tx will be rollbacked");
+ tm.rollback();
}
- catch (Exception e)
+ catch (Exception e1)
{
- LOG.warn("Could not commit the tx", e);
+ LOG.warn("Could not rollback the tx", e1);
}
}
+ throw e;
}
+ if (isTxCreated)
+ {
+ try
+ {
+ if (LOG.isTraceEnabled())
+ LOG.trace("The tx will be committed");
+ tm.commit();
+ }
+ catch (Exception e)
+ {
+ LOG.warn("Could not commit the tx", e);
+ }
+ }
}
- finally
- {
- changesList.set(null);
- changesContainer = null;
- }
}
-
+
/**
* Tries to get buffer and if it is null throws an exception otherwise returns buffer.
*
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java 2011-05-23 07:39:32 UTC (rev 4402)
@@ -49,6 +49,7 @@
import org.exoplatform.services.jcr.jbosscache.ExoJBossCacheFactory.CacheType;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
+import org.exoplatform.services.transaction.ActionNonTxAware;
import org.exoplatform.services.transaction.TransactionService;
import org.jboss.cache.Cache;
import org.jboss.cache.CacheStatus;
@@ -73,7 +74,6 @@
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
-import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
/**
@@ -165,7 +165,234 @@
protected final Fqn<String> childPropsList;
protected final Fqn<String> rootFqn;
+
+ private final CacheActionNonTxAware<Void, Void> commitTransaction = new CacheActionNonTxAware<Void, Void>()
+ {
+ @Override
+ protected Void execute(Void arg) throws RuntimeException
+ {
+ cache.commitTransaction();
+ return null;
+ }
+ };
+ private final CacheActionNonTxAware<ItemData, String> getFromCacheById =
+ new CacheActionNonTxAware<ItemData, String>()
+ {
+ @Override
+ protected ItemData execute(String id) throws RuntimeException
+ {
+ return getFromCacheById(id);
+ }
+ };
+
+ private final CacheActionNonTxAware<List<NodeData>, NodeData> getChildNodes =
+ new CacheActionNonTxAware<List<NodeData>, NodeData>()
+ {
+ @Override
+ protected List<NodeData> execute(NodeData parent) throws RuntimeException
+ {
+ // empty Set<Object> marks that there is no child nodes
+ // get list of children uuids
+ final Set<Object> set =
+ (Set<Object>)cache.get(makeChildListFqn(childNodesList, parent.getIdentifier()), ITEM_LIST);
+ if (set != null)
+ {
+ final List<NodeData> childs = new ArrayList<NodeData>();
+
+ for (Object child : set)
+ {
+ NodeData node = (NodeData)cache.get(makeItemFqn((String)child), ITEM_DATA);
+
+ if (node == null || node instanceof NullItemData)
+ {
+ return null;
+ }
+
+ childs.add(node);
+ }
+
+ // order children by orderNumber, as HashSet returns children in other order
+ Collections.sort(childs, new NodesOrderComparator<NodeData>());
+
+ return childs;
+ }
+ else
+ {
+ return null;
+ }
+ }
+ };
+
+ private final CacheActionNonTxAware<ItemData, Object> getFromCacheByPath =
+ new CacheActionNonTxAware<ItemData, Object>()
+ {
+ @Override
+ protected ItemData execute(Object... args) throws RuntimeException
+ {
+ String parentId = (String)args[0];
+ QPathEntry name = (QPathEntry)args[1];
+ ItemType itemType = (ItemType)args[2];
+ String itemId = null;
+
+ if (itemType == ItemType.UNKNOWN)
+ {
+ // Try as node first.
+ itemId = (String)cache.get(makeChildFqn(childNodes, parentId, name), ITEM_ID);
+
+ if (itemId == null || itemId.equals(NullItemData.NULL_ID))
+ {
+ // node with such a name is not found or marked as not-exist, so check the properties
+ String propId = (String)cache.get(makeChildFqn(childProps, parentId, name), ITEM_ID);
+ if (propId != null)
+ {
+ itemId = propId;
+ }
+ }
+ }
+ else if (itemType == ItemType.NODE)
+ {
+ itemId = (String)cache.get(makeChildFqn(childNodes, parentId, name), ITEM_ID);
+ }
+ else
+ {
+ itemId = (String)cache.get(makeChildFqn(childProps, parentId, name), ITEM_ID);
+ }
+
+ if (itemId != null)
+ {
+ if (itemId.equals(NullItemData.NULL_ID))
+ {
+ if (itemType == ItemType.UNKNOWN || itemType == ItemType.NODE)
+ {
+ return new NullNodeData();
+ }
+ else
+ {
+ return new NullPropertyData();
+ }
+ }
+ else
+ {
+ return get(itemId);
+ }
+ }
+ return null;
+ }
+ };
+
+ private final CacheActionNonTxAware<Integer, NodeData> getChildNodesCount =
+ new CacheActionNonTxAware<Integer, NodeData>()
+ {
+ @Override
+ protected Integer execute(NodeData parent) throws RuntimeException
+ {
+ // get list of children uuids
+ final Set<Object> set =
+ (Set<Object>)cache.get(makeChildListFqn(childNodesList, parent.getIdentifier()), ITEM_LIST);
+
+ return set != null ? set.size() : -1;
+ }
+ };
+
+ private final CacheActionNonTxAware<List<PropertyData>, Object> getChildProps =
+ new CacheActionNonTxAware<List<PropertyData>, Object>()
+ {
+ @Override
+ protected List<PropertyData> execute(Object... args) throws RuntimeException
+ {
+ String parentId = (String)args[0];
+ boolean withValue = (Boolean)args[1];
+ // get set of property uuids
+ final Set<Object> set = (Set<Object>)cache.get(makeChildListFqn(childPropsList, parentId), ITEM_LIST);
+ if (set != null)
+ {
+ final List<PropertyData> childs = new ArrayList<PropertyData>();
+
+ for (Object child : set)
+ {
+ PropertyData prop = (PropertyData)cache.get(makeItemFqn((String)child), ITEM_DATA);
+ if (prop == null || prop instanceof NullItemData)
+ {
+ return null;
+ }
+ if (withValue && prop.getValues().size() <= 0)
+ {
+ // don't return list of empty-valued props (but listChildProperties() can)
+ return null;
+ }
+ childs.add(prop);
+ }
+ return childs;
+ }
+ else
+ {
+ return null;
+ }
+ }
+ };
+
+ private final CacheActionNonTxAware<List<PropertyData>, String> getReferencedProperties =
+ new CacheActionNonTxAware<List<PropertyData>, String>()
+ {
+ @Override
+ protected List<PropertyData> execute(String identifier) throws RuntimeException
+ {
+ // get set of property uuids
+ final Set<String> set = (Set<String>)cache.get(makeRefFqn(identifier), ITEM_LIST);
+ if (set != null)
+ {
+ final List<PropertyData> props = new ArrayList<PropertyData>();
+
+ for (String propId : set)
+ {
+ PropertyData prop = (PropertyData)cache.get(makeItemFqn(propId), ITEM_DATA);
+ if (prop == null || prop instanceof NullItemData)
+ {
+ return null;
+ }
+
+ // add property as many times as has referenced values
+ List<ValueData> lData = prop.getValues();
+ for (int i = 0, length = lData.size(); i < length; i++)
+ {
+ ValueData vdata = lData.get(i);
+ try
+ {
+ if (new String(vdata.getAsByteArray(), Constants.DEFAULT_ENCODING).equals(identifier))
+ {
+ props.add(prop);
+ }
+ }
+ catch (IllegalStateException e)
+ {
+ // Do not nothing.
+ }
+ catch (IOException e)
+ {
+ // Do not nothing.
+ }
+ }
+ }
+ return props;
+ }
+ else
+ {
+ return null;
+ }
+ }
+ };
+
+ private final CacheActionNonTxAware<Long, Void> getSize = new CacheActionNonTxAware<Long, Void>()
+ {
+ @Override
+ protected Long execute(Void arg) throws RuntimeException
+ {
+ // Total number of JBC nodes in the cache - the total amount of resident nodes
+ return numNodes(cache.getNode(rootFqn)) - 7;
+ }
+ };
+
/**
* Indicates whether the cache has already been initialized or not
*/
@@ -683,60 +910,15 @@
*/
public ItemData get(String parentId, QPathEntry name, ItemType itemType)
{
- String itemId = null;
-
- if (itemType == ItemType.UNKNOWN)
- {
- // Try as node first.
- itemId = (String)cache.get(makeChildFqn(childNodes, parentId, name), ITEM_ID);
-
- if (itemId == null || itemId.equals(NullItemData.NULL_ID))
- {
- // node with such a name is not found or marked as not-exist, so check the properties
- String propId = (String)cache.get(makeChildFqn(childProps, parentId, name), ITEM_ID);
- if (propId != null)
- {
- itemId = propId;
- }
- }
- }
- else if (itemType == ItemType.NODE)
- {
- itemId = (String)cache.get(makeChildFqn(childNodes, parentId, name), ITEM_ID);
- }
- else
- {
- itemId = (String)cache.get(makeChildFqn(childProps, parentId, name), ITEM_ID);
- }
-
- if (itemId != null)
- {
- if (itemId.equals(NullItemData.NULL_ID))
- {
- if (itemType == ItemType.UNKNOWN || itemType == ItemType.NODE)
- {
- return new NullNodeData();
- }
- else
- {
- return new NullPropertyData();
- }
- }
- else
- {
- return get(itemId);
- }
- }
-
- return null;
+ return getFromCacheByPath.run(parentId, name, itemType);
}
-
+
/**
* {@inheritDoc}
*/
public ItemData get(String id)
{
- return getFromCacheById(id);
+ return getFromCacheById.run(id);
}
/**
@@ -744,47 +926,15 @@
*/
public List<NodeData> getChildNodes(final NodeData parent)
{
- // empty Set<Object> marks that there is no child nodes
- // get list of children uuids
- final Set<Object> set =
- (Set<Object>)cache.get(makeChildListFqn(childNodesList, parent.getIdentifier()), ITEM_LIST);
- if (set != null)
- {
- final List<NodeData> childs = new ArrayList<NodeData>();
-
- for (Object child : set)
- {
- NodeData node = (NodeData)cache.get(makeItemFqn((String)child), ITEM_DATA);
-
- if (node == null || node instanceof NullItemData)
- {
- return null;
- }
-
- childs.add(node);
- }
-
- // order children by orderNumber, as HashSet returns children in other order
- Collections.sort(childs, new NodesOrderComparator<NodeData>());
-
- return childs;
- }
- else
- {
- return null;
- }
+ return getChildNodes.run(parent);
}
-
+
/**
* {@inheritDoc}
*/
public int getChildNodesCount(NodeData parent)
{
- // get list of children uuids
- final Set<Object> set =
- (Set<Object>)cache.get(makeChildListFqn(childNodesList, parent.getIdentifier()), ITEM_LIST);
-
- return set != null ? set.size() : -1;
+ return getChildNodesCount.run(parent);
}
/**
@@ -802,54 +952,13 @@
{
return getChildProps(parent.getIdentifier(), false);
}
-
+
/**
* {@inheritDoc}
*/
public List<PropertyData> getReferencedProperties(String identifier)
{
- // get set of property uuids
- final Set<String> set = (Set<String>)cache.get(makeRefFqn(identifier), ITEM_LIST);
- if (set != null)
- {
- final List<PropertyData> props = new ArrayList<PropertyData>();
-
- for (String propId : set)
- {
- PropertyData prop = (PropertyData)cache.get(makeItemFqn(propId), ITEM_DATA);
- if (prop == null || prop instanceof NullItemData)
- {
- return null;
- }
-
- // add property as many times as has referenced values
- List<ValueData> lData = prop.getValues();
- for (int i = 0, length = lData.size(); i < length; i++)
- {
- ValueData vdata = lData.get(i);
- try
- {
- if (new String(vdata.getAsByteArray(), Constants.DEFAULT_ENCODING).equals(identifier))
- {
- props.add(prop);
- }
- }
- catch (IllegalStateException e)
- {
- // Do not nothing.
- }
- catch (IOException e)
- {
- // Do not nothing.
- }
- }
- }
- return props;
- }
- else
- {
- return null;
- }
+ return getReferencedProperties.run(identifier);
}
/**
@@ -894,41 +1003,15 @@
*/
protected List<PropertyData> getChildProps(String parentId, boolean withValue)
{
- // get set of property uuids
- final Set<Object> set = (Set<Object>)cache.get(makeChildListFqn(childPropsList, parentId), ITEM_LIST);
- if (set != null)
- {
- final List<PropertyData> childs = new ArrayList<PropertyData>();
-
- for (Object child : set)
- {
- PropertyData prop = (PropertyData)cache.get(makeItemFqn((String)child), ITEM_DATA);
- if (prop == null || prop instanceof NullItemData)
- {
- return null;
- }
- if (withValue && prop.getValues().size() <= 0)
- {
- // don't return list of empty-valued props (but listChildProperties() can)
- return null;
- }
- childs.add(prop);
- }
- return childs;
- }
- else
- {
- return null;
- }
+ return getChildProps.run(parentId, withValue);
}
-
+
/**
* {@inheritDoc}
*/
public long getSize()
{
- // Total number of JBC nodes in the cache - the total amount of resident nodes
- return numNodes(cache.getNode(rootFqn)) - 7;
+ return getSize.run();
}
/**
@@ -1531,7 +1614,7 @@
private enum ModifyChildOption {
NOT_MODIFY, MODIFY, FORCE_MODIFY
}
-
+
/**
* Allows to commit the cache changes in a dedicated XA Tx in order to avoid potential
* deadlocks
@@ -1540,37 +1623,7 @@
{
// Ensure that the commit is done in a dedicated tx to avoid deadlock due
// to global XA Tx
- TransactionManager tm = getTransactionManager();
- Transaction tx = null;
- try
- {
- if (tm != null)
- {
- try
- {
- tx = tm.suspend();
- }
- catch (Exception e)
- {
- LOG.warn("Cannot suspend the current transaction", e);
- }
- }
- cache.commitTransaction();
- }
- finally
- {
- if (tx != null)
- {
- try
- {
- tm.resume(tx);
- }
- catch (Exception e)
- {
- LOG.warn("Cannot resume the current transaction", e);
- }
- }
- }
+ commitTransaction.run();
}
/**
@@ -1662,4 +1715,23 @@
createResidentNode(itemsRoot);
}
}
+
+ /**
+ * Actions that are not supposed to be called within a transaction
+ *
+ * Created by The eXo Platform SAS
+ * Author : Nicolas Filotto
+ * nicolas.filotto(a)exoplatform.com
+ * 21 janv. 2010
+ */
+ protected abstract class CacheActionNonTxAware<R, A> extends ActionNonTxAware<R, A, RuntimeException>
+ {
+ /**
+ * @see org.exoplatform.services.transaction.ActionNonTxAware#getTransactionManager()
+ */
+ protected TransactionManager getTransactionManager()
+ {
+ return JBossCacheWorkspaceStorageCache.this.getTransactionManager();
+ }
+ }
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/TransactionableDataManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/TransactionableDataManager.java 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/TransactionableDataManager.java 2011-05-23 07:39:32 UTC (rev 4402)
@@ -33,8 +33,6 @@
import org.exoplatform.services.jcr.impl.dataflow.persistent.LocalWorkspaceDataManagerStub;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
-import org.exoplatform.services.transaction.TransactionException;
-import org.exoplatform.services.transaction.TransactionResource;
import java.util.ArrayList;
import java.util.Collections;
@@ -49,7 +47,7 @@
* @author Gennady Azarenkov
* @version $Id: TransactionableDataManager.java 11907 2008-03-13 15:36:21Z ksm $
*/
-public class TransactionableDataManager implements TransactionResource, DataManager
+public class TransactionableDataManager implements DataManager
{
// use LocalWorkspaceDataManagerStub, otherwise JVM will use save(ItemStateChangesLog changes) instead of
@@ -60,22 +58,14 @@
private TransactionChangesLog transactionLog;
+ private SessionImpl session;
+
public TransactionableDataManager(LocalWorkspaceDataManagerStub dataManager, SessionImpl session)
throws RepositoryException
{
super();
+ this.session = session;
this.storageDataManager = dataManager;
-
- // TODO EXOJCR-272
- // try
- // {
- // this.storageDataManager = new LocalWorkspaceStorageDataManagerProxy(dataManager, session.getValueFactory());
- // }
- // catch (Exception e1)
- // {
- // String infoString = "[Error of read value factory: " + e1.getMessage() + "]";
- // throw new RepositoryException(infoString);
- // }
}
// --------------- ItemDataConsumer --------
@@ -309,9 +299,9 @@
// --------------- --------
/**
- * {@inheritDoc}
+ * Initializes the tx changes log
*/
- public void start()
+ void start()
{
if (LOG.isDebugEnabled())
{
@@ -325,47 +315,23 @@
}
/**
- * {@inheritDoc}
+ * Re move a given changes log
*/
- public void commit() throws TransactionException
+ void removeLog(PlainChangesLog log)
{
- if (txStarted())
- {
- if (LOG.isDebugEnabled())
- {
- LOG.debug("tx commit() " + this + "\n" + transactionLog.dump());
- }
-
- try
- {
- TransactionChangesLog tl = transactionLog;
- transactionLog = null;
- storageDataManager.save(tl);
- }
- catch (InvalidItemStateException e)
- {
- throw new TransactionException(e.getMessage(), e);
- }
- catch (RepositoryException e)
- {
- throw new TransactionException(e.getMessage(), e);
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void rollback()
- {
if (LOG.isDebugEnabled())
{
- LOG.debug("tx rollback() " + this + (transactionLog != null ? "\n" + transactionLog.dump() : "[NULL]"));
+ LOG.debug("tx removeLog() " + this + (transactionLog != null ? "\n" + transactionLog.dump() : "[NULL]"));
}
if (txStarted())
{
- transactionLog = null;
+ transactionLog.removeLog(log);
+ if (transactionLog.getSize() == 0)
+ {
+ // Clear tx changes log if there is no log left
+ transactionLog = null;
+ }
}
}
@@ -388,12 +354,14 @@
+ (statesLog != null ? "\n" + statesLog.dump() : "[NULL]") + "=====================");
}
- if (txStarted())
+ if (session.canEnrollChangeToGlobalTx(statesLog))
{
+ // Save within a global tx
transactionLog.addLog(statesLog);
}
else
{
+ // Regular save
storageDataManager.save(new TransactionChangesLog(statesLog));
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/TransactionableResourceManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/TransactionableResourceManager.java 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/TransactionableResourceManager.java 2011-05-23 07:39:32 UTC (rev 4402)
@@ -18,237 +18,882 @@
*/
package org.exoplatform.services.jcr.impl.dataflow.session;
-import org.exoplatform.services.jcr.impl.core.XASessionImpl;
-import org.exoplatform.services.transaction.TransactionException;
+import org.exoplatform.commons.utils.SecurityHelper;
+import org.exoplatform.container.ExoContainer;
+import org.exoplatform.container.ExoContainerContext;
+import org.exoplatform.services.jcr.dataflow.PlainChangesLog;
+import org.exoplatform.services.jcr.dataflow.TransactionChangesLog;
+import org.exoplatform.services.jcr.impl.core.SessionImpl;
+import org.exoplatform.services.jcr.impl.dataflow.persistent.LocalWorkspaceDataManagerStub;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+import org.exoplatform.services.transaction.TransactionService;
import java.lang.ref.SoftReference;
-import java.util.Iterator;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentLinkedQueue;
+import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.WeakHashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
+import javax.jcr.RepositoryException;
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
import javax.transaction.xa.XAException;
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
/**
* Created by The eXo Platform SAS.
* <p/>
- * Manager provides consistency of transaction operations performed by same user but in different
- * Repository Sessions.
+ * Used to perform an atomic prepare/commit/rollback between all the JCR sessions tied
+ * to the current transaction
* <p/>
- * Manager stores list of XASessions involved in transaction by a user and then can be used to
- * broadcast transaction start/commit/rollback to all live Sessions of the user.
- * <p/>
- * Broadcast of operations it's an atomic operation regarding to the Sessions list. Until operation
- * broadcast request is active other requests or list modifications will wait for.
- * <p/>
*
* @author <a href="mailto:peter.nedonosko@exoplatform.com.ua">Peter Nedonosko</a>
* @version $Id: TransactionableResourceManager.java 34801 2009-07-31 15:44:50Z dkatayev $
*/
-public class TransactionableResourceManager
+public class TransactionableResourceManager implements XAResource
{
/**
- * XASessions involved in transaction. Sessions stored by userId.
+ * Logger.
*/
- private ConcurrentHashMap<String, ConcurrentLinkedQueue<SoftReference<XASessionImpl>>> txResources =
- new ConcurrentHashMap<String, ConcurrentLinkedQueue<SoftReference<XASessionImpl>>>();
+ private static Log log = ExoLogger.getLogger("exo.jcr.component.core.TransactionableResourceManager");
/**
+ * Sessions involved in transaction.
+ */
+ private final ThreadLocal<TransactionContext> contexts = new ThreadLocal<TransactionContext>();
+
+ /**
+ * Transaction manager.
+ */
+ private final TransactionManager tm;
+
+ /**
+ * The eXo container in which the TransactionableResourceManager has been registered
+ */
+ private final ExoContainer container;
+
+ /**
+ * The data manager
+ */
+ private volatile LocalWorkspaceDataManagerStub workspaceDataManager;
+
+ /**
+ * The current tx timeout in seconds
+ */
+ private int txTimeout;
+
+ /**
* TransactionableResourceManager constructor.
*/
- public TransactionableResourceManager()
+ public TransactionableResourceManager(ExoContainerContext ctx)
{
+ this(ctx, null);
}
/**
- * Add session to the transaction group.
- *
- * @param userSession
- * XASessionImpl, user XASession
+ * TransactionableResourceManager constructor.
*/
- public void add(XASessionImpl userSession)
+ public TransactionableResourceManager(ExoContainerContext ctx, TransactionService tService)
{
- final ConcurrentLinkedQueue<SoftReference<XASessionImpl>> joinedList = txResources.get(userSession.getUserID());
- if (joinedList != null)
+ this.tm = tService == null ? null : tService.getTransactionManager();
+ this.container = ctx.getContainer();
+ }
+
+ /**
+ * Lazily gets the LocalWorkspaceDataManagerStub from the eXo container. This is required to
+ * prevent cyclic dependency
+ */
+ private LocalWorkspaceDataManagerStub getWorkspaceDataManager()
+ {
+ if (workspaceDataManager == null)
{
- // remove unused session from user list and put this list at the end
- // threads of same user
- for (Iterator<SoftReference<XASessionImpl>> siter = joinedList.iterator(); siter.hasNext();)
+ synchronized (this)
{
- XASessionImpl xaSession = siter.next().get();
- if (xaSession == null || !xaSession.isLive())
+ if (workspaceDataManager == null)
{
- siter.remove();
+ LocalWorkspaceDataManagerStub workspaceDataManager =
+ (LocalWorkspaceDataManagerStub)container
+ .getComponentInstanceOfType(LocalWorkspaceDataManagerStub.class);
+ if (workspaceDataManager == null)
+ {
+ throw new IllegalStateException("The workspace data manager cannot be found");
+ }
+ this.workspaceDataManager = workspaceDataManager;
}
}
+ }
+ return workspaceDataManager;
+ }
- joinedList.add(new SoftReference<XASessionImpl>(userSession));
+ /**
+ * Indicates whether a global tx is active or not
+ * @return <code>true</code> if a global tx is active, <code>false</code> otherwise.
+ */
+ public boolean isGlobalTxActive()
+ {
+ TransactionContext ctx;
+ return (ctx = contexts.get()) != null && ctx.getXidContext() != null;
+ }
- // make sure the list is not removed by another Session of same user, see
- // remove()
- txResources.putIfAbsent(userSession.getUserID(), joinedList);
- }
- else
+ /**
+ * Checks if a global Tx has been started if so the session and its change will be dynamically enrolled
+ * @param session the session to enlist in case a Global Tx has been started
+ * @param changes the changes to enlist in case a Global Tx has been started
+ * @return <code>true</code> if a global Tx has been started and the session and its change could
+ * be enrolled successfully, <code>false</code> otherwise
+ */
+ public boolean canEnrollChangeToGlobalTx(final SessionImpl session, final PlainChangesLog changes)
+ {
+ try
{
- // sync for same userId operations
- final ConcurrentLinkedQueue<SoftReference<XASessionImpl>> newJoinedList =
- new ConcurrentLinkedQueue<SoftReference<XASessionImpl>>();
- final ConcurrentLinkedQueue<SoftReference<XASessionImpl>> previous =
- txResources.putIfAbsent(userSession.getUserID(), newJoinedList);
- if (previous != null)
+ if (tm != null && session.isLive() && tm.getStatus() == Status.STATUS_ACTIVE)
{
- previous.add(new SoftReference<XASessionImpl>(userSession));
+ SecurityHelper.doPrivilegedExceptionAction(new PrivilegedExceptionAction<Void>()
+ {
+ public Void run() throws Exception
+ {
+ add(session, changes);
+ return null;
+ }
+ });
+ return true;
}
- else
- {
- newJoinedList.add(new SoftReference<XASessionImpl>(userSession));
- }
}
+ catch (Exception e)
+ {
+ log.warn("Could not check if a global Tx has been started or register the session into the resource manager",
+ e);
+ }
+ return false;
}
/**
- * Remove session from user Sessions list.
- *
- * @param userSession
- * XASessionImpl, user XASession
+ * Add a new listener to register to the current tx
+ * @param listener the listener to add
*/
- public void remove(XASessionImpl userSession)
+ public void addListener(TransactionableResourceManagerListener listener)
{
- final ConcurrentLinkedQueue<SoftReference<XASessionImpl>> joinedList = txResources.get(userSession.getUserID());
- if (joinedList != null)
+ TransactionContext ctx = contexts.get();
+ if (ctx == null)
{
- // traverse and remove unused sessions and given one
- // threads of same user
- for (Iterator<SoftReference<XASessionImpl>> siter = joinedList.iterator(); siter.hasNext();)
- {
- XASessionImpl xaSession = siter.next().get();
- if (xaSession == null || !xaSession.isLive() || xaSession == userSession)
- {
- siter.remove();
- }
- }
-
- // if list is empty - remove mapping to the list
- if (joinedList.size() <= 0)
- {
- txResources.remove(userSession.getUserID());
- }
+ throw new IllegalStateException("There is no active transaction context");
}
+ XidContext xidCtx = ctx.getXidContext();
+ if (xidCtx == null)
+ {
+ throw new IllegalStateException("There is no active xid context");
+ }
+ xidCtx.addListener(listener);
}
/**
- * Commit all sessions.
+ * Add session to the transaction group.
*
* @param userSession
- * XASessionImpl, commit initializing session
- * @throws TransactionException
- * Transaction error
+ * SessionImpl, user Session
+ * @throws SystemException
+ * @throws RollbackException
+ * @throws IllegalStateException
*/
- public void commit(XASessionImpl userSession, boolean onePhase) throws TransactionException
+ private void add(SessionImpl session, PlainChangesLog changes) throws SystemException, IllegalStateException,
+ RollbackException
{
- ConcurrentLinkedQueue<SoftReference<XASessionImpl>> joinedList;
- if (onePhase)
+ Transaction tx = tm.getTransaction();
+ if (tx == null)
{
- joinedList = txResources.remove(userSession.getUserID());
+ // No active tx so there is no need to register the session
+ return;
}
- else
+ // Get the current TransactionContext
+ TransactionContext ctx = getOrCreateTransactionContext();
+ // Register the tx if it has not been done already
+ ctx.registerTransaction(tx);
+ // Register the given changes
+ ctx.add(session, changes);
+ }
+
+ /**
+ * Gives the current {@link TransactionContext} from the ThreadLocal and create it doesn't exist
+ */
+ private TransactionContext getOrCreateTransactionContext()
+ {
+ TransactionContext ctx = contexts.get();
+ if (ctx == null)
{
- // TODO keep session on commit to be able to rollback all via XASessions(XAResource) and TM lifecycle
- joinedList = txResources.get(userSession.getUserID());
+ // No transaction context exists so we create a new one
+ ctx = new TransactionContext();
+ contexts.set(ctx);
}
+ return ctx;
+ }
- if (joinedList != null)
+ /**
+ * This synchronization is used to apply all changes before commit phase and it is also used to execute actions once the tx is completed
+ * which is necessary in case we use non tx aware resources like the lucene indexes and the observation
+ * @author <a href="mailto:nfilotto@exoplatform.com">Nicolas Filotto</a>
+ * @version $Id$
+ *
+ */
+ private class TransactionableResourceManagerSynchronization implements Synchronization
+ {
+ private final Xid xid;
+
+ /**
+ * Indicates whether or not there is another after completion method to call
+ */
+ private final AtomicBoolean isLastAfterCompletion = new AtomicBoolean(true);
+
+ public TransactionableResourceManagerSynchronization(Xid xid)
{
- Iterator<SoftReference<XASessionImpl>> it = joinedList.iterator();
- boolean hasCommitedXASession = false;
+ this.xid = xid;
+ }
+
+ /**
+ * @see javax.transaction.Synchronization#beforeCompletion()
+ */
+ public void beforeCompletion()
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("BeforeCompletion Xid:" + xid + ": " + this);
+ }
+ TransactionContext ctx = contexts.get();
+ if (ctx == null)
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("Could not find the context");
+ }
+ return;
+ }
+ else
+ {
+ // define the current branch id
+ ctx.setXid(xid);
+ }
+ Map<PlainChangesLog, SessionImpl> changes = ctx.getChanges(xid);
+ if (changes == null || changes.isEmpty())
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("There is no change to apply");
+ }
+ return;
+ }
try
{
- while (it.hasNext())
+ TransactionChangesLog allChanges = new TransactionChangesLog();
+ for (Map.Entry<PlainChangesLog, SessionImpl> entry : changes.entrySet())
{
- SoftReference<XASessionImpl> sr = it.next();
- XASessionImpl xaSession = sr.get();
- if (xaSession != null && xaSession.isLive())
+ SessionImpl session = entry.getValue();
+ // first check if the tx was not too long
+ if (session.hasExpired())
{
- xaSession.getTransientNodesManager().getTransactManager().commit();
+ // at least one session has expired so we abort the tx
+ throw new RepositoryException("The tx was too long, at least one session has expired.");
}
- hasCommitedXASession = true;
+ // Add the change following the chronology order
+ allChanges.addLog(entry.getKey());
}
+ getWorkspaceDataManager().save(allChanges);
}
- catch (TransactionException e)
+ catch (RepositoryException e)
{
- if (onePhase)
+ log.error("Could not apply changes", e);
+ setRollbackOnly();
+ return;
+ }
+ // Since between 2 TM implementations the afterCompletion can be called in the same
+ // order as the synchronization order or in the reverse order, so we add a second synchronization
+ // such that the afterCompletion method will be called in the second call
+ try
+ {
+ tm.getTransaction().registerSynchronization(new Synchronization()
{
- // rollback now
- while (it.hasNext())
+
+ public void beforeCompletion()
{
- SoftReference<XASessionImpl> sr = it.next();
- XASessionImpl xaSession = sr.get();
- if (xaSession != null && xaSession.isLive())
- {
- xaSession.getTransientNodesManager().getTransactManager().rollback();
- }
}
- if (hasCommitedXASession)
+ public void afterCompletion(int status)
{
- // somethings were commited already
- throw new TransactionException(XAException.XA_HEURMIX, e);
+ TransactionableResourceManagerSynchronization.this.afterCompletion(status);
}
- else
+ });
+ // Indicates that there is at least one after completion method to come
+ isLastAfterCompletion.set(false);
+ }
+ catch (Exception e)
+ {
+ log.error("Could not register the second synchronization", e);
+ }
+ }
+
+ /**
+ * @see javax.transaction.Synchronization#afterCompletion(int)
+ */
+ public void afterCompletion(int status)
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("AfterCompletion Xid:" + xid + ", " + status + ", " + isLastAfterCompletion.get() + ": " + this);
+ }
+ if (!isLastAfterCompletion.get())
+ {
+ isLastAfterCompletion.set(true);
+ return;
+ }
+ TransactionContext ctx = contexts.get();
+ if (ctx == null)
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("Could not find the context");
+ }
+ return;
+ }
+ XidContext xidCtx = ctx.getXidContext(xid);
+ if (xidCtx == null)
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("Could not find the xid context");
+ }
+ return;
+ }
+ try
+ {
+ List<TransactionableResourceManagerListener> listeners = xidCtx.getListeners();
+ for (int i = 0, length = listeners.size(); i < length; i++)
+ {
+ TransactionableResourceManagerListener listener = listeners.get(i);
+ try
{
- // all things were rolled back
- throw new TransactionException(XAException.XA_HEURRB, e);
+ listener.onAfterCompletion(status);
}
+ catch (Exception e)
+ {
+ log.error("Could not execute the method onAfterCompletion for the status " + status, e);
+ }
}
- throw new TransactionException(XAException.XA_RBOTHER, e);
+ Map<PlainChangesLog, SessionImpl> changes = xidCtx.getMapChanges();
+ if (changes != null && !changes.isEmpty())
+ {
+ for (Map.Entry<PlainChangesLog, SessionImpl> entry : changes.entrySet())
+ {
+ SessionImpl session = entry.getValue();
+ TransactionableDataManager txManager = session.getTransientNodesManager().getTransactManager();
+ // Remove the change from the tx change log. Please not that a simple reset cannot
+ // be done since the session could be enrolled in several tx, so each change need to
+ // be scoped to a given xid
+ txManager.removeLog(entry.getKey());
+ }
+ }
}
+ finally
+ {
+ ctx.remove(xid);
+ }
}
}
/**
- * Start transaction on all sessions.
- *
- * @param userSession
- * XASessionImpl, start initializing session
+ * @see javax.transaction.xa.XAResource#commit(javax.transaction.xa.Xid, boolean)
*/
- public void start(XASessionImpl userSession)
+ public void commit(Xid xid, boolean onePhase) throws XAException
{
- ConcurrentLinkedQueue<SoftReference<XASessionImpl>> joinedList = txResources.get(userSession.getUserID());
- if (joinedList != null)
+ if (log.isDebugEnabled())
{
- for (SoftReference<XASessionImpl> sr : joinedList)
+ log.debug("Commit. Xid:" + xid + ", onePhase: " + onePhase + ": " + this);
+ }
+ TransactionContext ctx = contexts.get();
+ if (ctx == null)
+ {
+ if (log.isDebugEnabled())
{
- XASessionImpl xaSession = sr.get();
- if (xaSession != null && xaSession.isLive())
+ log.debug("Could not find the context");
+ }
+ return;
+ }
+ XidContext xidCtx = ctx.getXidContext(xid);
+ if (xidCtx != null)
+ {
+ boolean failed = false;
+ List<TransactionableResourceManagerListener> listeners = xidCtx.getListeners();
+ for (int i = 0, length = listeners.size(); i < length; i++)
+ {
+ TransactionableResourceManagerListener listener = listeners.get(i);
+ try
{
- TransactionableDataManager txManager = xaSession.getTransientNodesManager().getTransactManager();
- txManager.start();
+ listener.onCommit(onePhase);
}
+ catch (Exception e)
+ {
+ log.error("Could not execute the method onCommit(" + onePhase + ")", e);
+ failed = true;
+ break;
+ }
}
+ if (failed)
+ {
+ if (onePhase)
+ {
+ // In case of one phase commit, we are supposed to roll back the branch
+ abort(listeners);
+ throw new XAException(XAException.XA_RBROLLBACK);
+ }
+ throw new XAException(XAException.XAER_RMERR);
+ }
}
}
/**
- * Rollback transaction on all sessions.
+ * @see javax.transaction.xa.XAResource#end(javax.transaction.xa.Xid, int)
+ */
+ public void end(Xid xid, int flags) throws XAException
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("End. Xid:" + xid + ", " + flags + ": " + this);
+ }
+ }
+
+ /**
+ * @see javax.transaction.xa.XAResource#forget(javax.transaction.xa.Xid)
+ */
+ public void forget(Xid xid) throws XAException
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("Forget. Xid:" + xid + ": " + this);
+ }
+ abort(xid);
+ }
+
+ /**
+ * @see javax.transaction.xa.XAResource#getTransactionTimeout()
+ */
+ public int getTransactionTimeout() throws XAException
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("GetTransactionTimeout. : " + this);
+ }
+ return txTimeout;
+ }
+
+ /**
+ * @return the transaction timeout in milliseconds
+ */
+ private long getTransactionTimeoutMillis()
+ {
+ return txTimeout * 1000L;
+ }
+
+ /**
+ * @see javax.transaction.xa.XAResource#isSameRM(javax.transaction.xa.XAResource)
+ */
+ public boolean isSameRM(XAResource xares) throws XAException
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("IsSameRM. XAResource:" + xares + ": " + this);
+ }
+
+ // We have one XAResource per workspace
+ return xares == this;
+ }
+
+ /**
+ * @see javax.transaction.xa.XAResource#prepare(javax.transaction.xa.Xid)
+ */
+ public int prepare(Xid xid) throws XAException
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("Prepare. Xid:" + xid + ": " + this);
+ }
+
+ return XA_OK;
+ }
+
+ /**
+ * @see javax.transaction.xa.XAResource#recover(int)
+ */
+ public Xid[] recover(int flag) throws XAException
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("Recover. flag:" + flag + ": " + this);
+ }
+ return new Xid[0];
+ }
+
+ /**
+ * @see javax.transaction.xa.XAResource#rollback(javax.transaction.xa.Xid)
+ */
+ public void rollback(Xid xid) throws XAException
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("Rollback. Xid:" + xid + ": " + this);
+ }
+ abort(xid);
+ }
+
+ /**
+ * @param xid
+ */
+ private void abort(Xid xid) throws XAException
+ {
+ TransactionContext ctx = contexts.get();
+ if (ctx == null)
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("Could not find the context");
+ }
+ return;
+ }
+ XidContext xidCtx = ctx.getXidContext(xid);
+ if (xidCtx != null)
+ {
+ List<TransactionableResourceManagerListener> listeners = xidCtx.getListeners();
+ abort(listeners);
+ }
+ }
+
+ /**
+ * Call the method onAbort on all the given listeners
*
- * @param userSession
- * XASessionImpl, rollback initializing session
+ * @param listeners all the listeners on which we need to call the onAbort method
+ * @throws XAException if an error occurs while calling one of the onAbort methods
*/
- public void rollback(XASessionImpl userSession)
+ private void abort(List<TransactionableResourceManagerListener> listeners) throws XAException
{
- ConcurrentLinkedQueue<SoftReference<XASessionImpl>> joinedList = txResources.remove(userSession.getUserID());
- if (joinedList != null)
+ boolean exception = false;
+ for (int i = 0, length = listeners.size(); i < length; i++)
{
- for (SoftReference<XASessionImpl> sr : joinedList)
+ TransactionableResourceManagerListener listener = listeners.get(i);
+ try
{
- XASessionImpl xaSession = sr.get();
- if (xaSession != null && xaSession.isLive())
+ listener.onAbort();
+ }
+ catch (Exception e)
+ {
+ log.error("Could not execute the method onAbort", e);
+ exception = true;
+ }
+ }
+ if (exception)
+ {
+ throw new XAException(XAException.XAER_RMERR);
+ }
+ }
+
+ /**
+ * @see javax.transaction.xa.XAResource#setTransactionTimeout(int)
+ */
+ public boolean setTransactionTimeout(int txTimeout) throws XAException
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("SetTransactionTimeout. " + txTimeout + ": " + this);
+ }
+ this.txTimeout = txTimeout;
+ // Set the new timeout on the current sessions
+ TransactionContext ctx = contexts.get();
+ if (ctx == null)
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("Could not find the context");
+ }
+ return true;
+ }
+ Set<SessionImpl> sessions = ctx.getSessions();
+ if (sessions != null)
+ {
+ for (SessionImpl session : sessions)
+ {
+ session.setTimeout(getTransactionTimeoutMillis());
+ }
+ }
+ return true;
+ }
+
+ /**
+ * @see javax.transaction.xa.XAResource#start(javax.transaction.xa.Xid, int)
+ */
+ public void start(Xid xid, int flags) throws XAException
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("Start. Xid:" + xid + ", " + flags + ": " + this);
+ }
+ // Get the current TransactionContext
+ TransactionContext ctx = getOrCreateTransactionContext();
+ // define the current branch id
+ ctx.setXid(xid);
+ }
+
+ /**
+ * Change the status of the tx to 'rollback-only'
+ */
+ private void setRollbackOnly()
+ {
+ try
+ {
+ tm.getTransaction().setRollbackOnly();
+ }
+ catch (Exception e)
+ {
+ log.warn("Could not set the status of the tx to 'rollback-only'", e);
+ }
+ }
+
+ private class TransactionContext
+ {
+ /**
+ * The soft reference of the current tx
+ */
+ private SoftReference<Transaction> srTx;
+
+ /**
+ * The soft reference of the current branch id
+ */
+ private SoftReference<Xid> srXid;
+
+ /**
+ * The the current contexts stored by Xid
+ */
+ private Map<Xid, XidContext> xidContexts;
+
+ /**
+ * This method registers the current tx if it is a new one, and if so
+ * enlist the resource.
+ * @param tx the current tx
+ * @throws SystemException
+ * @throws IllegalStateException
+ * @throws RollbackException
+ */
+ public void registerTransaction(Transaction tx) throws SystemException, IllegalStateException, RollbackException
+ {
+ if (!tx.equals(getTransaction()))
+ {
+ // The current tx has changed
+ // We store the new current tx
+ setTransaction(tx);
+ // We enlist the resource to get the new branch id
+ tx.enlistResource(TransactionableResourceManager.this);
+ }
+ }
+
+ public XidContext getXidContext()
+ {
+ // Get the current Xid from context
+ Xid xid = getXid();
+ if (xid == null || xidContexts == null)
+ {
+ return null;
+ }
+ return xidContexts.get(xid);
+ }
+
+ public XidContext getXidContext(Xid xid)
+ {
+ if (xid == null || xidContexts == null)
+ {
+ return null;
+ }
+ return xidContexts.get(xid);
+ }
+
+ public Map<PlainChangesLog, SessionImpl> getChanges(Xid xid)
+ {
+ XidContext ctx = getXidContext(xid);
+ if (ctx == null)
+ {
+ return null;
+ }
+ return ctx.getMapChanges();
+ }
+
+ private void setTransaction(Transaction tx)
+ {
+ srTx = new SoftReference<Transaction>(tx);
+ }
+
+ public Transaction getTransaction()
+ {
+ return srTx == null ? null : srTx.get();
+ }
+
+ public void setXid(Xid xid)
+ {
+ srXid = new SoftReference<Xid>(xid);
+ }
+
+ private Xid getXid()
+ {
+ return srXid == null ? null : srXid.get();
+ }
+
+ public Set<SessionImpl> getSessions()
+ {
+ // Get the current Xid from context
+ Xid xid = getXid();
+ if (xid == null)
+ {
+ return null;
+ }
+ return getSessions(xid);
+ }
+
+ private Set<SessionImpl> getSessions(Xid xid)
+ {
+ Map<PlainChangesLog, SessionImpl> changes = getChanges(xid);
+ return changes == null ? null : new HashSet<SessionImpl>(changes.values());
+ }
+
+ /**
+ * Add the given session and changes to the transaction context.
+ * @param session the session to add to the transaction context
+ * @param changes the session to add to the transaction context
+ * @throws IllegalStateException
+ * @throws RollbackException
+ * @throws SystemException
+ */
+ public void add(SessionImpl session, PlainChangesLog changes) throws IllegalStateException, RollbackException,
+ SystemException
+ {
+ if (xidContexts == null)
+ {
+ // No xid context has been defined, so we create a new one
+ this.xidContexts = new WeakHashMap<Xid, XidContext>();
+ }
+ // Get the current Xid from context
+ Xid xid = getXid();
+ if (xid == null)
+ {
+ throw new IllegalStateException("Threre is no active branch");
+ }
+ // Retrieve the corresponding sub-context
+ XidContext ctx = xidContexts.get(xid);
+ if (ctx == null)
+ {
+ // No sub-context for this xid, we then create a new context
+ ctx = new XidContext();
+ xidContexts.put(xid, ctx);
+ boolean registered = false;
+ try
{
- TransactionableDataManager txManager = xaSession.getTransientNodesManager().getTransactManager();
- txManager.rollback();
+ // since it is a new branch we can register the corresponding synchronization
+ getTransaction().registerSynchronization(new TransactionableResourceManagerSynchronization(xid));
+ registered = true;
}
+ finally
+ {
+ if (!registered)
+ {
+ // if an error occurs automatically unregister the branch
+ remove(xid);
+ }
+ }
}
+ if (txTimeout > 0)
+ {
+ // Set the timeout
+ session.setTimeout(getTransactionTimeoutMillis());
+ }
+ if (changes != null)
+ {
+ // Add the changes and the session to the context
+ ctx.put(changes, session);
+ // Start the transaction mode
+ session.getTransientNodesManager().getTransactManager().start();
+ }
}
+
+ public void remove(Xid xid)
+ {
+ if (xidContexts != null)
+ {
+ xidContexts.remove(xid);
+ if (xidContexts.isEmpty())
+ {
+ // There is not xid context anymore
+ // Remove the context from the TL
+ contexts.set(null);
+ }
+ }
+ }
}
+
+ /**
+ * This class encapsulate all the information related to a given Xid
+ * @author <a href="mailto:nfilotto@exoplatform.com">Nicolas Filotto</a>
+ * @version $Id$
+ *
+ */
+ private static class XidContext
+ {
+ /**
+ * The list of all the existing listeners
+ */
+ private final List<TransactionableResourceManagerListener> listeners =
+ new ArrayList<TransactionableResourceManagerListener>();
+
+ /**
+ * The map of all changes
+ */
+ private final Map<PlainChangesLog, SessionImpl> mapChanges = new LinkedHashMap<PlainChangesLog, SessionImpl>();
+
+ /**
+ * @return the listeners
+ */
+ public List<TransactionableResourceManagerListener> getListeners()
+ {
+ return listeners;
+ }
+
+ /**
+ * @param listener the listener to add to the list of listeners
+ */
+ public void addListener(TransactionableResourceManagerListener listener)
+ {
+ listeners.add(listener);
+ }
+
+ /**
+ * @return the mapChanges
+ */
+ public Map<PlainChangesLog, SessionImpl> getMapChanges()
+ {
+ return mapChanges;
+ }
+
+ /**
+ * Register changes for a given session
+ * @param changes the changes to add
+ * @param session the session related to the changes
+ */
+ public void put(PlainChangesLog changes, SessionImpl session)
+ {
+ mapChanges.put(changes, session);
+ }
+ }
}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/TransactionableResourceManagerListener.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/TransactionableResourceManagerListener.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/TransactionableResourceManagerListener.java 2011-05-23 07:39:32 UTC (rev 4402)
@@ -0,0 +1,51 @@
+/*
+ * 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.dataflow.session;
+
+
+/**
+ * Allows to be execute actions when an event occurs at {@link TransactionableResourceManager}
+ * level
+ *
+ * @author <a href="mailto:nfilotto@exoplatform.com">Nicolas Filotto</a>
+ * @version $Id$
+ *
+ */
+public interface TransactionableResourceManagerListener
+{
+ /**
+ * This method is called within the commit method of the TransactionableResourceManager
+ * @param onePhase indicates whether it is one phase commit or not
+ * @throws Exception if an error occurs
+ */
+ void onCommit(boolean onePhase) throws Exception;
+
+ /**
+ * This method is called within the abort method of the TransactionableResourceManager
+ * @throws Exception if an error occurs
+ */
+ void onAbort() throws Exception;
+
+ /**
+ * This method is called within the afterCompletion method of the TransactionableResourceManager
+ * @param status the status of the tx
+ * @throws Exception if an error occurs
+ */
+ void onAfterCompletion(int status) throws Exception;
+}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java 2011-05-23 07:39:32 UTC (rev 4402)
@@ -62,6 +62,7 @@
import org.exoplatform.services.jcr.storage.WorkspaceDataContainer;
import org.exoplatform.services.jcr.storage.WorkspaceStorageConnection;
import org.exoplatform.services.jcr.storage.value.ValueStoragePluginProvider;
+import org.exoplatform.services.jdbc.DataSourceProvider;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.naming.InitialContextInitializer;
@@ -84,7 +85,6 @@
import java.util.Set;
import javax.jcr.RepositoryException;
-import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
@@ -153,7 +153,11 @@
protected final String dbUserName;
protected final String dbPassword;
+
+ protected final DataSourceProvider dsProvider;
+ protected final boolean isManaged;
+
protected final ValueStoragePluginProvider valueStorageProvider;
protected String storageVersion;
@@ -238,7 +242,9 @@
* @param wsConfig
* Workspace configuration
* @param valueStrorageProvider
- * External Value Stprages provider
+ * External Value Storages provider
+ * @param dsProvider
+ * The data source provider
* @throws RepositoryConfigurationException
* if Repository configuration is wrong
* @throws NamingException
@@ -246,7 +252,7 @@
*/
public JDBCWorkspaceDataContainer(WorkspaceEntry wsConfig, RepositoryEntry repConfig,
InitialContextInitializer contextInit, ValueStoragePluginProvider valueStorageProvider,
- FileCleanerHolder fileCleanerHolder) throws RepositoryConfigurationException, NamingException,
+ FileCleanerHolder fileCleanerHolder, DataSourceProvider dsProvider) throws RepositoryConfigurationException, NamingException,
RepositoryException, IOException
{
@@ -260,7 +266,8 @@
this.uniqueName = wsConfig.getUniqueName();
this.multiDb = Boolean.parseBoolean(wsConfig.getContainer().getParameterValue(MULTIDB));
this.valueStorageProvider = valueStorageProvider;
-
+ this.dsProvider = dsProvider;
+
// ------------- Database config ------------------
String pDbDialect = null;
try
@@ -304,6 +311,8 @@
this.dbUserName = pDbUserName;
this.dbPassword = pDbPassword;
this.dbSourceName = null;
+ // A managed data source is only possible when the source name is not null
+ this.isManaged = false;
LOG.info("Connect to JCR database as user '" + this.dbUserName + "'");
if (pDbDialect == DBConstants.DB_DIALECT_GENERIC || DBConstants.DB_DIALECT_AUTO.equalsIgnoreCase(pDbDialect))
@@ -360,49 +369,48 @@
// remove in rel.2.0
}
this.dbSourceName = sn;
+ if (dsProvider == null)
+ {
+ throw new IllegalArgumentException("Since a data source has been defined, the DataSourceProvider cannot be null, add it in your configuration.");
+ }
+ // the data source cannot be managed if there is no transaction manager
+ this.isManaged = dsProvider.isManaged(dbSourceName);
if (pDbDialect == DBConstants.DB_DIALECT_GENERIC)
{
// try to detect via JDBC metadata
- final DataSource ds = (DataSource)new InitialContext().lookup(dbSourceName);
- if (ds != null)
+ final DataSource ds = getDataSource();
+ Connection jdbcConn = null;
+ try
{
- Connection jdbcConn = null;
- try
+ jdbcConn = SecurityHelper.doPrivilegedSQLExceptionAction(new PrivilegedExceptionAction<Connection>()
{
- jdbcConn = SecurityHelper.doPrivilegedSQLExceptionAction(new PrivilegedExceptionAction<Connection>()
+ public Connection run() throws Exception
{
- public Connection run() throws Exception
- {
- return ds.getConnection();
- }
- });
+ return ds.getConnection();
+ }
+ });
- this.dbDialect = DialectDetecter.detect(jdbcConn.getMetaData());
- }
- catch (SQLException e)
+ this.dbDialect = DialectDetecter.detect(jdbcConn.getMetaData());
+ }
+ catch (SQLException e)
+ {
+ throw new RepositoryException(e);
+ }
+ finally
+ {
+ if (jdbcConn != null)
{
- throw new RepositoryException(e);
- }
- finally
- {
- if (jdbcConn != null)
+ try
{
- try
- {
- jdbcConn.close();
- }
- catch (SQLException e)
- {
- throw new RepositoryException(e);
- }
+ jdbcConn.close();
}
+ catch (SQLException e)
+ {
+ throw new RepositoryException(e);
+ }
}
}
- else
- {
- throw new RepositoryException("Datasource '" + dbSourceName + "' is not bound in this context.");
- }
}
else
{
@@ -475,7 +483,7 @@
}
/**
- * Prepare sefault connection factory.
+ * Prepare default connection factory.
*
* @return GenericConnectionFactory
* @throws NamingException
@@ -488,14 +496,8 @@
// by default
if (dbSourceName != null)
{
- DataSource ds = (DataSource)new InitialContext().lookup(dbSourceName);
- if (ds != null)
- {
- return new GenericConnectionFactory(ds, containerName, multiDb, valueStorageProvider, maxBufferSize,
- swapDirectory, swapCleaner);
- }
-
- throw new RepositoryException("Datasource '" + dbSourceName + "' is not bound in this context.");
+ return new GenericConnectionFactory(getDataSource(), containerName, multiDb, valueStorageProvider, maxBufferSize,
+ swapDirectory, swapCleaner);
}
return new GenericConnectionFactory(dbDriver, dbUrl, dbUserName, dbPassword, containerName, multiDb,
@@ -677,17 +679,9 @@
// [PN] 28.06.07
if (dbSourceName != null)
{
- DataSource ds = (DataSource)new InitialContext().lookup(dbSourceName);
- if (ds != null)
- {
- this.connFactory =
- new MySQLConnectionFactory(ds, containerName, multiDb, valueStorageProvider, maxBufferSize,
- swapDirectory, swapCleaner);
- }
- else
- {
- throw new RepositoryException("Datasource '" + dbSourceName + "' is not bound in this context.");
- }
+ this.connFactory =
+ new MySQLConnectionFactory(getDataSource(), containerName, multiDb, valueStorageProvider, maxBufferSize,
+ swapDirectory, swapCleaner);
}
else
{
@@ -704,17 +698,9 @@
// [PN] 13.07.08
if (dbSourceName != null)
{
- DataSource ds = (DataSource)new InitialContext().lookup(dbSourceName);
- if (ds != null)
- {
- this.connFactory =
- new MySQLConnectionFactory(ds, containerName, multiDb, valueStorageProvider, maxBufferSize,
- swapDirectory, swapCleaner);
- }
- else
- {
- throw new RepositoryException("Datasource '" + dbSourceName + "' is not bound in this context.");
- }
+ this.connFactory =
+ new MySQLConnectionFactory(getDataSource(), containerName, multiDb, valueStorageProvider, maxBufferSize,
+ swapDirectory, swapCleaner);
}
else
{
@@ -768,17 +754,9 @@
{
if (dbSourceName != null)
{
- DataSource ds = (DataSource)new InitialContext().lookup(dbSourceName);
- if (ds != null)
- {
- this.connFactory =
- new HSQLDBConnectionFactory(ds, containerName, multiDb, valueStorageProvider, maxBufferSize,
- swapDirectory, swapCleaner);
- }
- else
- {
- throw new RepositoryException("Datasource '" + dbSourceName + "' is not bound in this context.");
- }
+ this.connFactory =
+ new HSQLDBConnectionFactory(getDataSource(), containerName, multiDb, valueStorageProvider, maxBufferSize,
+ swapDirectory, swapCleaner);
}
else
{
@@ -905,7 +883,7 @@
{
String str =
"JDBC based JCR Workspace Data container \n" + "container name: " + containerName + " \n"
- + "data source JNDI name: " + dbSourceName + "\n" + "is multi database: " + multiDb + "\n"
+ + (isManaged ? "managed " : "") + "data source JNDI name: " + dbSourceName + "\n" + "is multi database: " + multiDb + "\n"
+ "storage version: " + storageVersion + "\n" + "value storage provider: " + valueStorageProvider + "\n"
+ "max buffer size (bytes): " + maxBufferSize + "\n" + "swap directory path: "
+ PrivilegedFileHelper.getAbsolutePath(swapDirectory);
@@ -1423,4 +1401,20 @@
{
return connFactory.isReindexingSupport();
}
+
+ /**
+ * Get the data source from the InitialContext and wraps it into a {@link ManagedDataSource}
+ * in case it has been configured as managed
+ */
+ protected DataSource getDataSource() throws RepositoryException
+ {
+ try
+ {
+ return dsProvider.getDataSource(dbSourceName);
+ }
+ catch (NamingException e)
+ {
+ throw new RepositoryException("Datasource '" + dbSourceName + "' is not bound in this context.", e);
+ }
+ }
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCWorkspaceDataContainer.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCWorkspaceDataContainer.java 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCWorkspaceDataContainer.java 2011-05-23 07:39:32 UTC (rev 4402)
@@ -39,15 +39,14 @@
import org.exoplatform.services.jcr.impl.util.io.FileCleanerHolder;
import org.exoplatform.services.jcr.impl.util.jdbc.DBInitializerException;
import org.exoplatform.services.jcr.storage.value.ValueStoragePluginProvider;
+import org.exoplatform.services.jdbc.DataSourceProvider;
import org.exoplatform.services.naming.InitialContextInitializer;
import org.picocontainer.Startable;
import java.io.IOException;
import javax.jcr.RepositoryException;
-import javax.naming.InitialContext;
import javax.naming.NamingException;
-import javax.sql.DataSource;
/**
* Created by The eXo Platform SAS.
@@ -64,7 +63,9 @@
* @param wsConfig
* Workspace configuration
* @param valueStrorageProvider
- * External Value Stprages provider
+ * External Value Storages provider
+ * @param dsProvider
+ * The data source provider
* @throws RepositoryConfigurationException
* if Repository configuration is wrong
* @throws NamingException
@@ -72,12 +73,11 @@
*/
public CQJDBCWorkspaceDataContainer(WorkspaceEntry wsConfig, RepositoryEntry repConfig,
InitialContextInitializer contextInit, ValueStoragePluginProvider valueStorageProvider,
- FileCleanerHolder fileCleanerHolder) throws RepositoryConfigurationException, NamingException,
+ FileCleanerHolder fileCleanerHolder, DataSourceProvider dsProvider) throws RepositoryConfigurationException, NamingException,
RepositoryException, IOException
{
- super(wsConfig, repConfig, contextInit, valueStorageProvider, fileCleanerHolder);
+ super(wsConfig, repConfig, contextInit, valueStorageProvider, fileCleanerHolder, dsProvider);
}
-
/**
* Init storage database.
*
@@ -100,13 +100,9 @@
// sample of connection factory customization
if (dbSourceName != null)
{
- DataSource ds = (DataSource)new InitialContext().lookup(dbSourceName);
- if (ds != null)
- this.connFactory =
- new DefaultOracleConnectionFactory(ds, containerName, multiDb, valueStorageProvider, maxBufferSize,
- swapDirectory, swapCleaner, useQueryHints);
- else
- throw new RepositoryException("Datasource '" + dbSourceName + "' is not bound in this context.");
+ this.connFactory =
+ new DefaultOracleConnectionFactory(getDataSource(), containerName, multiDb, valueStorageProvider, maxBufferSize,
+ swapDirectory, swapCleaner, useQueryHints);
}
else
this.connFactory =
@@ -123,13 +119,9 @@
if (dbSourceName != null)
{
- DataSource ds = (DataSource)new InitialContext().lookup(dbSourceName);
- if (ds != null)
- this.connFactory =
- new DefaultOracleConnectionFactory(ds, containerName, multiDb, valueStorageProvider, maxBufferSize,
- swapDirectory, swapCleaner, useQueryHints);
- else
- throw new RepositoryException("Datasource '" + dbSourceName + "' is not bound in this context.");
+ this.connFactory =
+ new DefaultOracleConnectionFactory(getDataSource(), containerName, multiDb, valueStorageProvider, maxBufferSize,
+ swapDirectory, swapCleaner, useQueryHints);
}
else
this.connFactory =
@@ -150,13 +142,9 @@
// [PN] 28.06.07
if (dbSourceName != null)
{
- DataSource ds = (DataSource)new InitialContext().lookup(dbSourceName);
- if (ds != null)
- this.connFactory =
- new MySQLConnectionFactory(ds, containerName, multiDb, valueStorageProvider, maxBufferSize,
- swapDirectory, swapCleaner);
- else
- throw new RepositoryException("Datasource '" + dbSourceName + "' is not bound in this context.");
+ this.connFactory =
+ new MySQLConnectionFactory(getDataSource(), containerName, multiDb, valueStorageProvider, maxBufferSize,
+ swapDirectory, swapCleaner);
}
else
this.connFactory =
@@ -171,13 +159,9 @@
// [PN] 13.07.08
if (dbSourceName != null)
{
- DataSource ds = (DataSource)new InitialContext().lookup(dbSourceName);
- if (ds != null)
- this.connFactory =
- new MySQLConnectionFactory(ds, containerName, multiDb, valueStorageProvider, maxBufferSize,
- swapDirectory, swapCleaner);
- else
- throw new RepositoryException("Datasource '" + dbSourceName + "' is not bound in this context.");
+ this.connFactory =
+ new MySQLConnectionFactory(getDataSource(), containerName, multiDb, valueStorageProvider, maxBufferSize,
+ swapDirectory, swapCleaner);
}
else
this.connFactory =
@@ -191,17 +175,9 @@
{
if (dbSourceName != null)
{
- DataSource ds = (DataSource)new InitialContext().lookup(dbSourceName);
- if (ds != null)
- {
- this.connFactory =
- new MSSQLConnectionFactory(ds, containerName, multiDb, valueStorageProvider, maxBufferSize,
- swapDirectory, swapCleaner);
- }
- else
- {
- throw new RepositoryException("Datasource '" + dbSourceName + "' is not bound in this context.");
- }
+ this.connFactory =
+ new MSSQLConnectionFactory(getDataSource(), containerName, multiDb, valueStorageProvider, maxBufferSize,
+ swapDirectory, swapCleaner);
}
else
{
@@ -223,17 +199,9 @@
{
if (dbSourceName != null)
{
- DataSource ds = (DataSource)new InitialContext().lookup(dbSourceName);
- if (ds != null)
- {
- this.connFactory =
- new DB2ConnectionFactory(ds, containerName, multiDb, valueStorageProvider, maxBufferSize,
- swapDirectory, swapCleaner);
- }
- else
- {
- throw new RepositoryException("Datasource '" + dbSourceName + "' is not bound in this context.");
- }
+ this.connFactory =
+ new DB2ConnectionFactory(getDataSource(), containerName, multiDb, valueStorageProvider, maxBufferSize,
+ swapDirectory, swapCleaner);
}
else
{
@@ -249,17 +217,9 @@
{
if (dbSourceName != null)
{
- DataSource ds = (DataSource)new InitialContext().lookup(dbSourceName);
- if (ds != null)
- {
- this.connFactory =
- new DB2ConnectionFactory(ds, containerName, multiDb, valueStorageProvider, maxBufferSize,
- swapDirectory, swapCleaner);
- }
- else
- {
- throw new RepositoryException("Datasource '" + dbSourceName + "' is not bound in this context.");
- }
+ this.connFactory =
+ new DB2ConnectionFactory(getDataSource(), containerName, multiDb, valueStorageProvider, maxBufferSize,
+ swapDirectory, swapCleaner);
}
else
{
@@ -275,17 +235,9 @@
{
if (dbSourceName != null)
{
- DataSource ds = (DataSource)new InitialContext().lookup(dbSourceName);
- if (ds != null)
- {
- this.connFactory =
- new SybaseConnectionFactory(ds, containerName, multiDb, valueStorageProvider, maxBufferSize,
- swapDirectory, swapCleaner);
- }
- else
- {
- throw new RepositoryException("Datasource '" + dbSourceName + "' is not bound in this context.");
- }
+ this.connFactory =
+ new SybaseConnectionFactory(getDataSource(), containerName, multiDb, valueStorageProvider, maxBufferSize,
+ swapDirectory, swapCleaner);
}
else
{
@@ -309,13 +261,9 @@
{
if (dbSourceName != null)
{
- DataSource ds = (DataSource)new InitialContext().lookup(dbSourceName);
- if (ds != null)
- this.connFactory =
- new HSQLDBConnectionFactory(ds, containerName, multiDb, valueStorageProvider, maxBufferSize,
- swapDirectory, swapCleaner);
- else
- throw new RepositoryException("Datasource '" + dbSourceName + "' is not bound in this context.");
+ this.connFactory =
+ new HSQLDBConnectionFactory(getDataSource(), containerName, multiDb, valueStorageProvider, maxBufferSize,
+ swapDirectory, swapCleaner);
}
else
this.connFactory =
@@ -358,12 +306,8 @@
// by default
if (dbSourceName != null)
{
- DataSource ds = (DataSource)new InitialContext().lookup(dbSourceName);
- if (ds != null)
- return new GenericCQConnectionFactory(ds, containerName, multiDb, valueStorageProvider, maxBufferSize,
- swapDirectory, swapCleaner);
-
- throw new RepositoryException("Datasource '" + dbSourceName + "' is not bound in this context.");
+ return new GenericCQConnectionFactory(getDataSource(), containerName, multiDb, valueStorageProvider, maxBufferSize,
+ swapDirectory, swapCleaner);
}
return new GenericCQConnectionFactory(dbDriver, dbUrl, dbUserName, dbPassword, containerName, multiDb,
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/transaction/ActionNonTxAware.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/transaction/ActionNonTxAware.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/transaction/ActionNonTxAware.java 2011-05-23 07:39:32 UTC (rev 4402)
@@ -0,0 +1,143 @@
+/*
+ * 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.transaction;
+
+import org.exoplatform.commons.utils.SecurityHelper;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+
+import java.security.PrivilegedExceptionAction;
+
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+/**
+ * This class describes all the actions that are not supposed to be called
+ * within a transaction
+ *
+ * @author <a href="mailto:nfilotto@exoplatform.com">Nicolas Filotto</a>
+ * @version $Id$
+ *
+ */
+public abstract class ActionNonTxAware<R, A, E extends Exception>
+{
+ /**
+ * The logger
+ */
+ protected Log LOG = ExoLogger.getLogger("exo.jcr.component.core.ActionNonTxAware");
+
+ /**
+ * Executes the action outside the context of the current tx
+ * @param arg the argument to use to execute the action
+ * @return the result of the action
+ * @throws E if an error occurs while executing the action
+ */
+ public R run(A... arg) throws E
+ {
+ final TransactionManager tm = getTransactionManager();
+ Transaction tx = null;
+ try
+ {
+ if (tm != null)
+ {
+ try
+ {
+ tx = SecurityHelper.doPrivilegedExceptionAction(new PrivilegedExceptionAction<Transaction>()
+ {
+ public Transaction run() throws Exception
+ {
+ return tm.suspend();
+ }
+ });
+ }
+ catch (Exception e)
+ {
+ LOG.warn("Cannot suspend the current transaction", e);
+ }
+ }
+ return execute(arg);
+ }
+ finally
+ {
+ if (tx != null)
+ {
+ try
+ {
+ final Transaction privilegedTx = tx;
+ SecurityHelper.doPrivilegedExceptionAction(new PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ tm.resume(privilegedTx);
+ return null;
+ }
+ });
+ }
+ catch (Exception e)
+ {
+ LOG.warn("Cannot resume the current transaction", e);
+ }
+ }
+ }
+ }
+
+ /**
+ * Executes the action outside the context of the current tx. This
+ * method is equivalent to {@link ActionNonTxAware#run(Object)} but
+ * with <tt>null</tt> as parameter.
+ * @return the result of the action
+ * @throws E if an error occurs while executing the action
+ */
+ public R run() throws E
+ {
+ return run((A[])null);
+ }
+
+ /**
+ * Executes the action
+ * @param arg the argument to use to execute the action
+ * @return the result of the action
+ * @throws E if an error occurs while executing the action
+ */
+ protected R execute(A... arg) throws E
+ {
+ if (arg == null || arg.length == 0)
+ {
+ return execute((A)null);
+ }
+ return execute(arg[0]);
+ }
+
+ /**
+ * Executes the action
+ * @param arg the argument to use to execute the action
+ * @return the result of the action
+ * @throws E if an error occurs while executing the action
+ */
+ protected R execute(A arg) throws E
+ {
+ return null;
+ }
+
+ /**
+ * Gives the Transaction Manager that will be used while executing the action
+ * @return the {@link TransactionManager} to use
+ */
+ protected abstract TransactionManager getTransactionManager();
+}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/transaction/jbosscache/GenericTransactionService.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/transaction/jbosscache/GenericTransactionService.java 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/transaction/jbosscache/GenericTransactionService.java 2011-05-23 07:39:32 UTC (rev 4402)
@@ -18,67 +18,25 @@
*/
package org.exoplatform.services.transaction.jbosscache;
-import org.exoplatform.commons.utils.SecurityHelper;
import org.exoplatform.container.xml.InitParams;
-import org.exoplatform.services.log.ExoLogger;
-import org.exoplatform.services.log.Log;
-import org.exoplatform.services.transaction.ExoResource;
-import org.exoplatform.services.transaction.TransactionService;
+import org.exoplatform.services.transaction.impl.AbstractTransactionService;
import org.jboss.cache.transaction.TransactionManagerLookup;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-
-import javax.transaction.HeuristicMixedException;
-import javax.transaction.HeuristicRollbackException;
-import javax.transaction.InvalidTransactionException;
-import javax.transaction.NotSupportedException;
-import javax.transaction.RollbackException;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
-import javax.transaction.UserTransaction;
-import javax.transaction.xa.XAResource;
-import javax.transaction.xa.Xid;
/**
* @author <a href="mailto:dmitry.kataev@exoplatform.com">Dmytro Katayev</a>
* @version $Id: GenericTransactionService.java -1 $
*/
-public class GenericTransactionService implements TransactionService
+public class GenericTransactionService extends AbstractTransactionService
{
- /**
- * The logger
- */
- private static final Log LOG = ExoLogger.getLogger("exo.jcr.component.core.GenericTransactionService");
/**
- * The default value of a transaction timeout in seconds
- */
- private static final int DEFAULT_TIME_OUT = 60;
-
- /**
* TransactionManagerLookup.
*/
protected final TransactionManagerLookup tmLookup;
/**
- * The default timeout
- */
- protected final int defaultTimeout;
-
- /**
- * Indicates if the timeout has to be enforced
- */
- protected final boolean forceTimeout;
-
- /**
- * The current Transaction Manager
- */
- private volatile TransactionManager tm;
-
- /**
* JBossTransactionManagerLookup constructor.
*
* @param tmLookup TransactionManagerLookup
@@ -90,539 +48,15 @@
public GenericTransactionService(TransactionManagerLookup tmLookup, InitParams params)
{
+ super(params);
this.tmLookup = tmLookup;
- if (params != null && params.getValueParam("timeout") != null)
- {
- this.defaultTimeout = Integer.parseInt(params.getValueParam("timeout").getValue());
- this.forceTimeout = true;
- }
- else
- {
- this.defaultTimeout = DEFAULT_TIME_OUT;
- this.forceTimeout = false;
- }
}
/**
* {@inheritDoc}
*/
- public Xid createXid()
+ public TransactionManager findTransactionManager() throws Exception
{
- throw new UnsupportedOperationException("Method createXid() not supported");
+ return tmLookup.getTransactionManager();
}
-
- /**
- * {@inheritDoc}
- */
- public void delistResource(final ExoResource exores) throws RollbackException, SystemException
- {
- TransactionManager tm = getTransactionManager();
- final Transaction tx = tm.getTransaction();
- if (tx != null)
- {
- PrivilegedExceptionAction<Object> action = new PrivilegedExceptionAction<Object>()
- {
- public Object run() throws Exception
- {
- tx.delistResource(exores.getXAResource(), XAResource.TMNOFLAGS);
- return null;
- }
- };
- try
- {
- AccessController.doPrivileged(action);
- }
- catch (PrivilegedActionException pae)
- {
- Throwable cause = pae.getCause();
-
- if (cause instanceof RollbackException)
- {
- throw (RollbackException)cause;
- }
- else if (cause instanceof IllegalStateException)
- {
- throw (IllegalStateException)cause;
- }
- else if (cause instanceof SystemException)
- {
- throw (SystemException)cause;
- }
- else if (cause instanceof RuntimeException)
- {
- throw (RuntimeException)cause;
- }
- else
- {
- throw new RuntimeException(cause);
- }
- }
- }
- else
- {
- delistResourceOnTxMissing(tm, exores);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void enlistResource(final ExoResource exores) throws RollbackException, SystemException
- {
- TransactionManager tm = getTransactionManager();
- final Transaction tx = tm.getTransaction();
- if (tx != null)
- {
- PrivilegedExceptionAction<Object> action = new PrivilegedExceptionAction<Object>()
- {
- public Object run() throws Exception
- {
- tx.enlistResource(exores.getXAResource());
- return null;
- }
- };
- try
- {
- AccessController.doPrivileged(action);
- }
- catch (PrivilegedActionException pae)
- {
- Throwable cause = pae.getCause();
-
- if (cause instanceof RollbackException)
- {
- throw (RollbackException)cause;
- }
- else if (cause instanceof IllegalStateException)
- {
- throw (IllegalStateException)cause;
- }
- else if (cause instanceof SystemException)
- {
- throw (SystemException)cause;
- }
- else if (cause instanceof RuntimeException)
- {
- throw (RuntimeException)cause;
- }
- else
- {
- throw new RuntimeException(cause);
- }
- }
- }
- else
- {
- enlistResourceOnTxMissing(tm, exores);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public int getDefaultTimeout()
- {
- return defaultTimeout;
- }
-
- /**
- * {@inheritDoc}
- */
- public TransactionManager getTransactionManager()
- {
- if (tm == null)
- {
- synchronized (this)
- {
- if (tm == null)
- {
- TransactionManager tm;
- try
- {
- tm = SecurityHelper.doPrivilegedExceptionAction(new PrivilegedExceptionAction<TransactionManager>()
- {
- public TransactionManager run() throws Exception
- {
- return tmLookup.getTransactionManager();
- }
- });
- }
- catch (Exception e)
- {
- throw new RuntimeException("Transaction manager not found", e);
- }
- if (forceTimeout)
- {
- // Only set the timeout when a timeout has been given into the
- // configuration otherwise we assume that the value will be
- // set at the AS level
- tm = new TransactionManagerTxTimeoutAware(tm, defaultTimeout);
- }
- this.tm = tm;
- }
- }
- }
- return tm;
- }
-
- /**
- * {@inheritDoc}
- */
- public UserTransaction getUserTransaction()
- {
- throw new UnsupportedOperationException("Method UserTransaction() not supported");
- }
-
- /**
- * {@inheritDoc}
- */
- public void setTransactionTimeout(int seconds) throws SystemException
- {
- TransactionManager tm = getTransactionManager();
- tm.setTransactionTimeout(seconds);
- }
-
- /**
- * Allows to execute an action when we try to enlist a resource when there is no active
- * transaction
- */
- protected void enlistResourceOnTxMissing(TransactionManager tm, ExoResource exores) throws RollbackException,
- SystemException
- {
- }
-
- /**
- * Allows to execute an action when we try to delist a resource when there is no active
- * transaction
- */
- protected void delistResourceOnTxMissing(TransactionManager tm, ExoResource exores) throws RollbackException,
- SystemException
- {
- }
-
- /**
- * This class is used to enforce the {@link Transaction} timeout when a new transaction
- * is created through the nested {@link TransactionManager}
- *
- * Created by The eXo Platform SAS
- * Author : Nicolas Filotto
- * nicolas.filotto(a)exoplatform.com
- * 1 f�vr. 2010
- */
- private static class TransactionManagerTxTimeoutAware implements TransactionManager
- {
- /**
- * The nested {@link TransactionManager}
- */
- private final TransactionManager tm;
-
- /**
- * The default timeout of the {@link Transaction}
- */
- private final int defaultTimeout;
-
- /**
- * This is used to know if a timeout has already been set for the next transaction
- */
- private final ThreadLocal<Boolean> timeoutHasBeenSet = new ThreadLocal<Boolean>();
-
- public TransactionManagerTxTimeoutAware(TransactionManager tm, int defaultTimeout)
- {
- this.tm = tm;
- this.defaultTimeout = defaultTimeout;
- }
-
- /**
- * {@inheritDoc}
- */
- public void begin() throws NotSupportedException, SystemException
- {
- if (timeoutHasBeenSet.get() != null)
- {
- // clean the ThreadLocal
- timeoutHasBeenSet.set(null);
- }
- else
- {
- try
- {
- // Set the default transaction timeout
- tm.setTransactionTimeout(defaultTimeout);
- }
- catch (Exception e)
- {
- LOG.warn("Cannot set the transaction timeout", e);
- }
- }
-
- // Start the transaction
- PrivilegedExceptionAction<Object> action = new PrivilegedExceptionAction<Object>()
- {
- public Object run() throws Exception
- {
- tm.begin();
- return null;
- }
- };
- try
- {
- AccessController.doPrivileged(action);
- }
- catch (PrivilegedActionException pae)
- {
- Throwable cause = pae.getCause();
- if (cause instanceof NotSupportedException)
- {
- throw (NotSupportedException)cause;
- }
- else if (cause instanceof SystemException)
- {
- throw (SystemException)cause;
- }
- else if (cause instanceof RuntimeException)
- {
- throw (RuntimeException)cause;
- }
- else
- {
- throw new RuntimeException(cause);
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException,
- SecurityException, IllegalStateException, SystemException
- {
- PrivilegedExceptionAction<Object> action = new PrivilegedExceptionAction<Object>()
- {
- public Object run() throws Exception
- {
- tm.commit();
- return null;
- }
- };
- try
- {
- AccessController.doPrivileged(action);
- }
- catch (PrivilegedActionException pae)
- {
- Throwable cause = pae.getCause();
- if (cause instanceof RollbackException)
- {
- throw (RollbackException)cause;
- }
- else if (cause instanceof HeuristicMixedException)
- {
- throw (HeuristicMixedException)cause;
- }
- else if (cause instanceof HeuristicRollbackException)
- {
- throw (HeuristicRollbackException)cause;
- }
- else if (cause instanceof SecurityException)
- {
- throw (SecurityException)cause;
- }
- else if (cause instanceof IllegalStateException)
- {
- throw (IllegalStateException)cause;
- }
- else if (cause instanceof SystemException)
- {
- throw (SystemException)cause;
- }
- else if (cause instanceof RuntimeException)
- {
- throw (RuntimeException)cause;
- }
- else
- {
- throw new RuntimeException(cause);
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public int getStatus() throws SystemException
- {
- return tm.getStatus();
- }
-
- /**
- * {@inheritDoc}
- */
- public Transaction getTransaction() throws SystemException
- {
- try
- {
- return SecurityHelper.doPrivilegedExceptionAction(new PrivilegedExceptionAction<Transaction>()
- {
- public Transaction run() throws Exception
- {
- return tm.getTransaction();
- }
- });
- }
- catch (PrivilegedActionException pae)
- {
- Throwable cause = pae.getCause();
- if (cause instanceof SystemException)
- {
- throw (SystemException)cause;
- }
- else if (cause instanceof RuntimeException)
- {
- throw (RuntimeException)cause;
- }
- else
- {
- throw new RuntimeException(cause);
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void resume(final Transaction tx) throws InvalidTransactionException, IllegalStateException,
- SystemException
- {
- PrivilegedExceptionAction<Object> action = new PrivilegedExceptionAction<Object>()
- {
- public Object run() throws Exception
- {
- tm.resume(tx);
- return null;
- }
- };
- try
- {
- AccessController.doPrivileged(action);
- }
- catch (PrivilegedActionException pae)
- {
- Throwable cause = pae.getCause();
- if (cause instanceof InvalidTransactionException)
- {
- throw (InvalidTransactionException)cause;
- }
- else if (cause instanceof IllegalStateException)
- {
- throw (IllegalStateException)cause;
- }
- else if (cause instanceof SystemException)
- {
- throw (SystemException)cause;
- }
- else if (cause instanceof RuntimeException)
- {
- throw (RuntimeException)cause;
- }
- else
- {
- throw new RuntimeException(cause);
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void rollback() throws IllegalStateException, SecurityException, SystemException
- {
- PrivilegedExceptionAction<Object> action = new PrivilegedExceptionAction<Object>()
- {
- public Object run() throws Exception
- {
- tm.rollback();
- return null;
- }
- };
- try
- {
- AccessController.doPrivileged(action);
- }
- catch (PrivilegedActionException pae)
- {
- Throwable cause = pae.getCause();
- if (cause instanceof IllegalStateException)
- {
- throw (IllegalStateException)cause;
- }
- else if (cause instanceof SecurityException)
- {
- throw (SecurityException)cause;
- }
- else if (cause instanceof SystemException)
- {
- throw (SystemException)cause;
- }
- else if (cause instanceof RuntimeException)
- {
- throw (RuntimeException)cause;
- }
- else
- {
- throw new RuntimeException(cause);
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void setRollbackOnly() throws IllegalStateException, SystemException
- {
- tm.setRollbackOnly();
- }
-
- /**
- * {@inheritDoc}
- */
- public void setTransactionTimeout(int timeout) throws SystemException
- {
- tm.setTransactionTimeout(timeout);
- timeoutHasBeenSet.set(true);
- }
-
- /**
- * {@inheritDoc}
- */
- public Transaction suspend() throws SystemException
- {
- PrivilegedExceptionAction<Transaction> action = new PrivilegedExceptionAction<Transaction>()
- {
- public Transaction run() throws Exception
- {
- return tm.suspend();
- }
- };
- try
- {
- return AccessController.doPrivileged(action);
- }
- catch (PrivilegedActionException pae)
- {
- Throwable cause = pae.getCause();
- if (cause instanceof SystemException)
- {
- throw (SystemException)cause;
- }
- else if (cause instanceof RuntimeException)
- {
- throw (RuntimeException)cause;
- }
- else
- {
- throw new RuntimeException(cause);
- }
- }
- }
- }
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/transaction/jbosscache/JBossTransactionsService.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/transaction/jbosscache/JBossTransactionsService.java 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/transaction/jbosscache/JBossTransactionsService.java 2011-05-23 07:39:32 UTC (rev 4402)
@@ -18,16 +18,10 @@
*/
package org.exoplatform.services.transaction.jbosscache;
-import com.arjuna.ats.jta.xa.XidImple;
-
import org.exoplatform.container.xml.InitParams;
import org.jboss.cache.transaction.TransactionManagerLookup;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
import javax.transaction.UserTransaction;
-import javax.transaction.xa.Xid;
/**
* Add the specific part for Arjuna
@@ -53,24 +47,8 @@
* {@inheritDoc}
*/
@Override
- public Xid createXid()
+ protected UserTransaction findUserTransaction() throws Exception
{
- return new XidImple();
+ return com.arjuna.ats.jta.UserTransaction.userTransaction();
}
-
- /**
- * {@inheritDoc}
- */
- @Override
- public UserTransaction getUserTransaction()
- {
- PrivilegedAction<UserTransaction> action = new PrivilegedAction<UserTransaction>()
- {
- public UserTransaction run()
- {
- return com.arjuna.ats.jta.UserTransaction.userTransaction();
- }
- };
- return AccessController.doPrivileged(action);
- }
}
Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/xa/TestUserTransaction.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/xa/TestUserTransaction.java 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/xa/TestUserTransaction.java 2011-05-23 07:39:32 UTC (rev 4402)
@@ -19,7 +19,6 @@
package org.exoplatform.services.jcr.api.xa;
import org.exoplatform.services.jcr.JcrAPIBaseTest;
-import org.exoplatform.services.jcr.core.XASession;
import org.exoplatform.services.jcr.impl.core.SessionImpl;
import org.exoplatform.services.transaction.TransactionService;
@@ -199,9 +198,6 @@
ut.begin();
- // In a case of reusing Have to enlist the resource once again!
- ((XASession)s1).enlistResource();
-
tx2.addNode("txcommit21");
s1.save();
ut.commit();
@@ -251,7 +247,6 @@
catch (Exception e)
{
// ok
- assertNotNull(((XASession) s1).getCommitException());
}
s1.logout();
Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/xa/TestXATransaction.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/xa/TestXATransaction.java 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/xa/TestXATransaction.java 2011-05-23 07:39:32 UTC (rev 4402)
@@ -19,20 +19,28 @@
package org.exoplatform.services.jcr.api.xa;
import org.exoplatform.services.jcr.JcrAPIBaseTest;
-import org.exoplatform.services.jcr.core.XASession;
import org.exoplatform.services.transaction.TransactionService;
import javax.jcr.LoginException;
import javax.jcr.NoSuchWorkspaceException;
import javax.jcr.Node;
+import javax.jcr.NodeIterator;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import javax.jcr.lock.Lock;
+import javax.jcr.query.Query;
+import javax.jcr.query.QueryManager;
+import javax.jcr.query.QueryResult;
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
import javax.transaction.xa.XAException;
-import javax.transaction.xa.XAResource;
-import javax.transaction.xa.Xid;
/**
* Created by The eXo Platform SAS. <br>
@@ -57,12 +65,11 @@
public void testSimpleGlobalTransaction() throws Exception
{
assertNotNull(ts);
- Xid id = ts.createXid();
- XAResource xares = ((XASession)session).getXAResource();
- xares.start(id, XAResource.TMNOFLAGS);
+ TransactionManager tm = ts.getTransactionManager();
+ tm.begin();
session.getRootNode().addNode("txg1");
session.save();
- xares.commit(id, true);
+ tm.commit();
Session s1 =
repository.login(new SimpleCredentials("admin", "admin".toCharArray()), session.getWorkspace().getName());
assertNotNull(s1.getItem("/txg1"));
@@ -75,13 +82,12 @@
Session s1 =
repository.login(new SimpleCredentials("admin", "admin".toCharArray()), session.getWorkspace().getName());
- Xid id1 = ts.createXid();
- XAResource xares = ((XASession)session).getXAResource();
- xares.start(id1, XAResource.TMNOFLAGS);
+ TransactionManager tm = ts.getTransactionManager();
+ tm.begin();
session.getRootNode().addNode("txg2");
session.save();
- // xares.commit(id, true);
+
try
{
s1.getItem("/txg2");
@@ -90,10 +96,9 @@
catch (PathNotFoundException e)
{
}
- xares.end(id1, XAResource.TMSUSPEND);
+ Transaction tx = tm.suspend();
- Xid id2 = ts.createXid();
- xares.start(id2, XAResource.TMNOFLAGS);
+ tm.begin();
session.getRootNode().addNode("txg3");
session.save();
@@ -107,21 +112,119 @@
}
// End work
- xares.end(id2, XAResource.TMSUCCESS);
+ tm.commit();
+ try
+ {
+ s1.getItem("/txg2");
+ fail("PathNotFoundException");
+ }
+ catch (PathNotFoundException e)
+ {
+ }
+ assertNotNull(s1.getItem("/txg3"));
// Resume work with former transaction
- xares.start(id1, XAResource.TMRESUME);
+ tm.resume(tx);
// Commit work recorded when associated with xid2
- xares.commit(id1, true);
- // xares.commit(id2, true);
+ tm.commit();
+
assertNotNull(s1.getItem("/txg2"));
assertNotNull(s1.getItem("/txg3"));
+
+ QueryManager manager = s1.getWorkspace().getQueryManager();
+ Query query = manager.createQuery("select * from nt:base where jcr:path = '/txg2'", Query.SQL);
+ QueryResult queryResult = query.execute();
+ assertNotNull(queryResult);
+ NodeIterator iter = queryResult.getNodes();
+ assertEquals(1, iter.getSize());
+
+ query = manager.createQuery("select * from nt:base where jcr:path = '/txg3'", Query.SQL);
+ queryResult = query.execute();
+ assertNotNull(queryResult);
+ iter = queryResult.getNodes();
+ assertEquals(1, iter.getSize());
+ }
+ public void test2GlobalTransactions2() throws Exception
+ {
+ assertNotNull(ts);
+ Session s1 =
+ repository.login(new SimpleCredentials("admin", "admin".toCharArray()), session.getWorkspace().getName());
+
+ TransactionManager tm = ts.getTransactionManager();
+ tm.begin();
+
+ session.getRootNode().addNode("txg2");
+ session.save();
+
+ try
+ {
+ s1.getItem("/txg2");
+ fail("PathNotFoundException");
+ }
+ catch (PathNotFoundException e)
+ {
+ }
+ Transaction tx = tm.suspend();
+
+ tm.begin();
+ session.getRootNode().addNode("txg3");
+ session.save();
+
+ try
+ {
+ s1.getItem("/txg3");
+ fail("PathNotFoundException");
+ }
+ catch (PathNotFoundException e)
+ {
+ }
+
+ // End work
+ tm.commit();
+ try
+ {
+ s1.getItem("/txg2");
+ fail("PathNotFoundException");
+ }
+ catch (PathNotFoundException e)
+ {
+ }
+ assertNotNull(s1.getItem("/txg3"));
+
+ // Resume work with former transaction
+ tm.resume(tx);
+
+ // Roll back work recorded when associated with xid2
+ tm.rollback();
+
+ try
+ {
+ s1.getItem("/txg2");
+ fail("PathNotFoundException");
+ }
+ catch (PathNotFoundException e)
+ {
+ }
+ assertNotNull(s1.getItem("/txg3"));
+
+ QueryManager manager = s1.getWorkspace().getQueryManager();
+ Query query = manager.createQuery("select * from nt:base where jcr:path = '/txg2'", Query.SQL);
+ QueryResult queryResult = query.execute();
+ assertNotNull(queryResult);
+ NodeIterator iter = queryResult.getNodes();
+ assertEquals(0, iter.getSize());
+
+ query = manager.createQuery("select * from nt:base where jcr:path = '/txg3'", Query.SQL);
+ queryResult = query.execute();
+ assertNotNull(queryResult);
+ iter = queryResult.getNodes();
+ assertEquals(1, iter.getSize());
}
-
+
public void testLockInTransactions() throws LoginException, NoSuchWorkspaceException, RepositoryException,
- XAException
+ XAException, NotSupportedException, SystemException, SecurityException, IllegalStateException, RollbackException, HeuristicMixedException, HeuristicRollbackException
{
assertNotNull(ts);
Session s1 =
@@ -133,9 +236,8 @@
n1.addMixin("mix:lockable");
session.getRootNode().save();
- Xid id1 = ts.createXid();
- XAResource xares = ((XASession)session).getXAResource();
- xares.start(id1, XAResource.TMNOFLAGS);
+ TransactionManager tm = ts.getTransactionManager();
+ tm.begin();
// lock node
Lock lock = n1.lock(false, true);
@@ -145,11 +247,8 @@
assertFalse(s2.getRootNode().getNode("testLock").isLocked());
- // End work
- xares.end(id1, XAResource.TMSUCCESS);
-
// Commit work recorded when associated with xid2
- xares.commit(id1, true);
+ tm.commit();
assertTrue(s2.getRootNode().getNode("testLock").isLocked());
n1.unlock();
Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/JDBCWDCTest.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/JDBCWDCTest.java 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/JDBCWDCTest.java 2011-05-23 07:39:32 UTC (rev 4402)
@@ -108,7 +108,7 @@
container =
new JDBCWorkspaceDataContainer(config, repositoryEntry, null, new StandaloneStoragePluginProvider(config,
- holder), holder);
+ holder), holder, null);
Properties logProps = new Properties();
logProps.put("org.apache.commons.logging.simplelog.defaultlog", "debug");
Added: jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/jta.xml
===================================================================
--- jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/jta.xml (rev 0)
+++ jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/jta.xml 2011-05-23 07:39:32 UTC (rev 4402)
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- This document was created with Syntext Serna Free. -->
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="JCR.JTA">
+ <?dbhtml filename="ch-jta.html"?>
+
+ <title>JTA</title>
+
+ <para>eXo JCR supports the Java Transaction API out of the box. If a
+ <emphasis>TransactionService</emphasis> has been defined (refer to the
+ chapter about the TransactionService for more details) at session save, it
+ checks if a global transaction is active and if so, it automatically
+ enrolles the JCR session in the global transaction. If you intend to use a
+ managed data source, you will have to configure the service
+ <emphasis>DataSourceProvider</emphasis> (for more details please refer to
+ the corresponding chapter).</para>
+</chapter>
Modified: jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr.xml
===================================================================
--- jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr.xml 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr.xml 2011-05-23 07:39:32 UTC (rev 4402)
@@ -129,6 +129,9 @@
<xi:include href="jcr/statistics.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="jcr/jta.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+
<xi:include href="jcr/other/acl.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
Added: jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/kernel/data-source-provider.xml
===================================================================
--- jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/kernel/data-source-provider.xml (rev 0)
+++ jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/kernel/data-source-provider.xml 2011-05-23 07:39:32 UTC (rev 4402)
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="Kernel.DataSourceProvider">
+ <?dbhtml filename="ch-data-source-provider.html"?>
+
+ <title>The data source provider</title>
+
+ <section>
+ <title>Description</title>
+
+ <para>The <emphasis>DataSourceProvider</emphasis> is a service used to
+ give access to a data source in an uniform manner in order to be able to
+ support data sources that are managed by the application server.</para>
+
+ <para><table>
+ <title>List methods</title>
+
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>getDataSource(String dataSourceName)</entry>
+
+ <entry>Tries to get the data source from a JNDI lookup. If it
+ can be found and the data source is defined as managed, the
+ service will wrap the original <emphasis>DataSource</emphasis>
+ instance in a new <emphasis>DataSource</emphasis> instance that
+ is aware of its <emphasis>managed</emphasis> state otherwise it
+ will return the original <emphasis>DataSource</emphasis>
+ instance.</entry>
+ </row>
+
+ <row>
+ <entry>isManaged(String dataSourceName)</entry>
+
+ <entry>Indicates whether or not the given data source is
+ managed.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table></para>
+ </section>
+
+ <section>
+ <title>Configuration</title>
+
+ <para>The configuration of the <emphasis>DataSourceProvider</emphasis>
+ should be defined only if you use managed data sources since by default
+ all the data sources are considered as not managed. See below the default
+ configuration</para>
+
+ <programlisting><configuration>
+....
+ <component>
+ <key>org.exoplatform.services.jdbc.DataSourceProvider</key>
+ <type>org.exoplatform.services.jdbc.impl.DataSourceProviderImpl</type>
+ <init-params>
+ <!-- Indicates that the data source needs to check if a tx is active
+ to decide if the provided connection needs to be managed or not.
+ If it is set to false, the data source will provide only
+ managed connections if the data source itself is managed. -->
+ <!--value-param>
+ <name>check-tx-active</name>
+ <value>true</value>
+ </value-param-->
+ <!-- Indicates that all the data sources are managed
+ If set to true the parameter never-managed and
+ managed-data-sources will be ignored -->
+ <!--value-param>
+ <name>always-managed</name>
+ <value>true</value>
+ </value-param-->
+ <!-- Indicates the list of all the data sources that are
+ managed, each value tag can contain a list of
+ data source names separated by a comma, in the
+ example below we will register ds-foo1, ds-foo2
+ and ds-foo3 as managed data source. If always-managed
+ and/or never-managed is set true this parameter is ignored -->
+ <!--values-param>
+ <name>managed-data-sources</name>
+ <value>ds-foo1, ds-foo2</value>
+ <value>ds-foo3</value>
+ </values-param-->
+ </init-params>
+ </component>
+...
+</configuration></programlisting>
+
+ <table>
+ <title>Fields description</title>
+
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry><emphasis>check-tx-active</emphasis></entry>
+
+ <entry>This parameter indicates that the data source needs to
+ check if a transaction is active to decide if the provided
+ connection needs to be managed or not. If it is set to
+ <emphasis>false</emphasis>, the data source will provide only
+ managed connections if the data source itself is managed. By
+ default, this parameter is set to <emphasis>true</emphasis>. If
+ this parameter is set to <emphasis>true</emphasis>, it will need
+ the <emphasis>TransactionService</emphasis> to work propertly, so
+ please ensure that the <emphasis>TransactionService</emphasis> is
+ defined in your configuration.</entry>
+ </row>
+
+ <row>
+ <entry><emphasis>always-managed</emphasis></entry>
+
+ <entry>This parameter indicates that all the data sources are
+ managed. If set to <emphasis>true</emphasis> the parameter
+ <emphasis>never-managed</emphasis> and
+ <emphasis>managed-data-sources</emphasis> will be ignored, so it
+ will consider all the data sources as managed. By default, this
+ parameter is set to <emphasis>false</emphasis>.</entry>
+ </row>
+
+ <row>
+ <entry><emphasis>managed-data-sources</emphasis></entry>
+
+ <entry>This parameter indicates the list of all the data sources
+ that are managed, each value tag can contain a list of data source
+ names separated by a comma. If <emphasis>always-managed</emphasis>
+ and/or <emphasis>never-managed</emphasis> is set
+ <emphasis>true</emphasis> this parameter is ignored.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+</chapter>
Modified: jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/kernel/transaction-service.xml
===================================================================
--- jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/kernel/transaction-service.xml 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/kernel/transaction-service.xml 2011-05-23 07:39:32 UTC (rev 4402)
@@ -1,65 +1,229 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
-"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<chapter id="Kernel.TransactionService">
- <?dbhtml filename="ch-tranasction-service.html"?>
-
- <title>TransactionService</title>
-
- <section>
- <title>Base information</title>
-
- <para>TransactionServices provides acces to XA TransactionManager and
- UserTransaction (See JTA specification for details).</para>
-
- <table>
- <title>List methods</title>
-
- <tgroup cols="2">
- <tbody>
- <row>
- <entry>getTransactionManager()</entry>
-
- <entry>Get used TransactionManager</entry>
- </row>
-
- <row>
- <entry>getUserTransaction()</entry>
-
- <entry>Get UserTransaction on TransactionManager</entry>
- </row>
-
- <row>
- <entry>getDefaultTimeout()</entry>
-
- <entry>Return default TimeOut</entry>
- </row>
-
- <row>
- <entry>setTransactionTimeout(int seconds)</entry>
-
- <entry>Set TimeOut in second</entry>
- </row>
-
- <row>
- <entry>enlistResource(ExoResource xares)</entry>
-
- <entry>Enlist XA resource in TransactionManager</entry>
- </row>
-
- <row>
- <entry>delistResource(ExoResource xares)</entry>
-
- <entry>Delist XA resource from TransactionManager</entry>
- </row>
-
- <row>
- <entry>createXid()</entry>
-
- <entry>Creates unique XA transaction identifier.</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- </section>
-</chapter>
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<chapter id="Kernel.TransactionService">
+ <?dbhtml filename="ch-tranasction-service.html"?>
+
+ <title>TransactionService</title>
+
+ <section>
+ <title>Base information</title>
+
+ <para>TransactionServices provides access to the TransactionManager and
+ the UserTransaction (See JTA specification for details).</para>
+
+ <table>
+ <title>List methods</title>
+
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>getTransactionManager()</entry>
+
+ <entry>Get used TransactionManager</entry>
+ </row>
+
+ <row>
+ <entry>getUserTransaction()</entry>
+
+ <entry>Get UserTransaction on TransactionManager</entry>
+ </row>
+
+ <row>
+ <entry>getDefaultTimeout()</entry>
+
+ <entry>Return default TimeOut</entry>
+ </row>
+
+ <row>
+ <entry>setTransactionTimeout(int seconds)</entry>
+
+ <entry>Set TimeOut in second</entry>
+ </row>
+
+ <row>
+ <entry>enlistResource(XAResource xares)</entry>
+
+ <entry>Enlist XA resource in TransactionManager</entry>
+ </row>
+
+ <row>
+ <entry>delistResource(XAResource xares)</entry>
+
+ <entry>Delist XA resource from TransactionManager</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+
+ <section>
+ <title>Existing TransactionService implementations</title>
+
+ <para>eXo JCR proposes out of the box several implementations, they all
+ implement the abstract class
+ <emphasis>org.exoplatform.services.transaction.impl.AbstractTransactionService</emphasis>.
+ This main class implement the biggest part of all the methods proposed by
+ the <emphasis>TransactionService</emphasis>. For each sub-class of
+ <emphasis>AbstractTransactionService</emphasis>, you can set the
+ transaction timeout by configuration using the value parameter
+ <emphasis>timeout</emphasis> that is expressed in seconds. </para>
+
+ <section>
+ <title>JOTM in standalone mode</title>
+
+ <para>To use JOTM as TransactionManager in standalone mode simply add
+ the following component configuration:</para>
+
+ <programlisting> <component>
+ <key>org.exoplatform.services.transaction.TransactionService</key>
+ <type>org.exoplatform.services.transaction.impl.jotm.TransactionServiceJotmImpl</type>
+ <!-- Uncomment the lines below if you want to set default transaction timeout that is expressed in seconds -->
+ <!--init-params>
+ <value-param>
+ <name>timeout</name>
+ <value>60</value>
+ </value-param>
+ </init-params-->
+ </component></programlisting>
+ </section>
+
+ <section>
+ <title>Generic TransactionService based on the TransactionManagerLookup
+ of JBoss Cache</title>
+
+ <para>If you intend to use JBoss Cache, you can use a generic
+ TransactionService based on its TransactionManagerLookup which is able
+ to automatically find the TransactionManager of several Application
+ Servers thanks to a set of JNDI lookups. This generic TransactionService
+ covers mainly the TransactionManager lookups, the UserTransaction is
+ actually simply the TransactionManager instance that has been wrapped.
+ See below an example of configuration:</para>
+
+ <programlisting> <!-- Configuration of the TransactionManagerLookup -->
+ <component>
+ <key>org.jboss.cache.transaction.TransactionManagerLookup</key>
+ <type>org.jboss.cache.transaction.GenericTransactionManagerLookup</type>
+ </component>
+ <!-- Configuration of the TransactionService -->
+ <component>
+ <key>org.exoplatform.services.transaction.TransactionService</key>
+ <type>org.exoplatform.services.transaction.jbosscache.GenericTransactionService</type>
+ <!-- Uncomment the lines below if you want to set default transaction timeout that is expressed in seconds -->
+ <!--init-params>
+ <value-param>
+ <name>timeout</name>
+ <value>60</value>
+ </value-param>
+ </init-params-->
+ </component></programlisting>
+ </section>
+
+ <section>
+ <title>Specific GenericTransactionService for JBoss Cache and
+ Arjuna</title>
+
+ <para>If you intend to use JBoss Cache with Arjuna, you can use a more
+ specific GenericTransactionService, it is mostly interesting in case you
+ want to use the real UserTransaction. See below an example of
+ configuration:</para>
+
+ <programlisting> <!-- Configuration of the TransactionManagerLookup -->
+ <component>
+ <key>org.jboss.cache.transaction.TransactionManagerLookup</key>
+ <type>org.jboss.cache.transaction.JBossStandaloneJTAManagerLookup</type>
+ </component>
+ <!-- Configuration of the TransactionService -->
+ <component>
+ <key>org.exoplatform.services.transaction.TransactionService</key>
+ <type>org.exoplatform.services.transaction.jbosscache.JBossTransactionsService</type>
+ <!-- Uncomment the lines below if you want to set default transaction timeout that is expressed in seconds -->
+ <!--init-params>
+ <value-param>
+ <name>timeout</name>
+ <value>60</value>
+ </value-param>
+ </init-params-->
+ </component></programlisting>
+ </section>
+
+ <section>
+ <title>Generic TransactionService based on the TransactionManagerLookup
+ of Infinispan</title>
+
+ <para>If you intend to use Infinispan, you can use a generic
+ TransactionService based on its TransactionManagerLookup which is able
+ to automatically find the TransactionManager of several Application
+ Servers thanks to a set of JNDI lookups. This generic TransactionService
+ covers mainly the TransactionManager lookups, the UserTransaction is
+ actually simply the TransactionManager instance that has been wrapped.
+ See below an example of configuration:</para>
+
+ <programlisting> <!-- Configuration of the TransactionManagerLookup -->
+ <component>
+ <key>org.infinispan.transaction.lookup.TransactionManagerLookup</key>
+ <type>org.infinispan.transaction.lookup.GenericTransactionManagerLookup</type>
+ </component>
+ <!-- Configuration of the TransactionService -->
+ <component>
+ <key>org.exoplatform.services.transaction.TransactionService</key>
+ <type>org.exoplatform.services.transaction.infinispan.GenericTransactionService</type>
+ <!-- Uncomment the lines below if you want to set default transaction timeout that is expressed in seconds -->
+ <!--init-params>
+ <value-param>
+ <name>timeout</name>
+ <value>60</value>
+ </value-param>
+ </init-params-->
+ </component></programlisting>
+ </section>
+
+ <section>
+ <title>Specific GenericTransactionService for Infinispan and
+ Arjuna</title>
+
+ <para>If you intend to use Infinispan with Arjuna, you can use a more
+ specific GenericTransactionService, it is mostly interesting in case you
+ want to use the real UserTransaction. See below an example of
+ configuration:</para>
+
+ <programlisting> <!-- Configuration of the TransactionManagerLookup -->
+ <component>
+ <key>org.infinispan.transaction.lookup.TransactionManagerLookup</key>
+ <type>org.infinispan.transaction.lookup.JBossStandaloneJTAManagerLookup</type>
+ </component>
+ <!-- Configuration of the TransactionService -->
+ <component>
+ <key>org.exoplatform.services.transaction.TransactionService</key>
+ <type>org.exoplatform.services.transaction.infinispan.JBossTransactionsService</type>
+ <!-- Uncomment the lines below if you want to set default transaction timeout that is expressed in seconds -->
+ <!--init-params>
+ <value-param>
+ <name>timeout</name>
+ <value>60</value>
+ </value-param>
+ </init-params-->
+ </component></programlisting>
+ </section>
+
+ <section>
+ <title>A very specific TransactionService for JBoss AS</title>
+
+ <para>If you intend to use JBoss AS with JBoss Cache and Infinispan, you
+ can use a very specific TransactionService for JBoss AS. See below an
+ example of configuration:</para>
+
+ <programlisting> <component>
+ <key>org.exoplatform.services.transaction.TransactionService</key>
+ <type>org.exoplatform.services.transaction.impl.jboss.JBossTransactionService</type>
+ <!-- Uncomment the lines below if you want to set default transaction timeout that is expressed in seconds -->
+ <!--init-params>
+ <value-param>
+ <name>timeout</name>
+ <value>60</value>
+ </value-param>
+ </init-params-->
+ </component></programlisting>
+ </section>
+ </section>
+</chapter>
Modified: jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/kernel.xml
===================================================================
--- jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/kernel.xml 2011-05-23 06:57:15 UTC (rev 4401)
+++ jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/kernel.xml 2011-05-23 07:39:32 UTC (rev 4402)
@@ -44,6 +44,9 @@
<xi:include href="kernel/transaction-service.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="kernel/data-source-provider.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="kernel/jndi-naming.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
13 years
exo-jcr SVN: r4401 - in kernel/trunk/exo.kernel.component.common: src/main/java/org/exoplatform/services and 13 other directories.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-05-23 02:57:15 -0400 (Mon, 23 May 2011)
New Revision: 4401
Added:
kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/jdbc/
kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/jdbc/DataSourceProvider.java
kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/jdbc/impl/
kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/jdbc/impl/DataSourceProviderImpl.java
kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/jdbc/impl/ManagedConnection.java
kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/jdbc/impl/ManagedDataSource.java
kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/impl/AbstractTransactionService.java
kernel/trunk/exo.kernel.component.common/src/test/java/org/exoplatform/services/jdbc/
kernel/trunk/exo.kernel.component.common/src/test/java/org/exoplatform/services/jdbc/impl/
kernel/trunk/exo.kernel.component.common/src/test/java/org/exoplatform/services/jdbc/impl/TestDataSourceProviderImpl.java
Modified:
kernel/trunk/exo.kernel.component.common/pom.xml
kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/ExoResource.java
kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/TransactionException.java
kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/TransactionResource.java
kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/TransactionService.java
kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/impl/jboss/JBossTransactionService.java
kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/impl/jotm/ResourceEntry.java
kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/impl/jotm/TransactionServiceJotmImpl.java
kernel/trunk/exo.kernel.component.common/src/main/resources/conf/portal/configuration.xml
kernel/trunk/exo.kernel.component.common/src/test/java/org/exoplatform/services/transaction/TransactionTest.java
kernel/trunk/exo.kernel.component.common/src/test/java/org/exoplatform/services/transaction/XAResourceTestImpl.java
kernel/trunk/exo.kernel.component.common/src/test/java/org/exoplatform/services/transaction/jcr/TestXASessionIntegration.java
kernel/trunk/exo.kernel.component.common/src/test/java/org/exoplatform/services/transaction/jcr/XASession.java
kernel/trunk/exo.kernel.component.common/src/test/resources/conf/standalone/test-configuration.xml
Log:
EXOJCR-480: Managed transactions support
Modified: kernel/trunk/exo.kernel.component.common/pom.xml
===================================================================
--- kernel/trunk/exo.kernel.component.common/pom.xml 2011-05-20 14:38:19 UTC (rev 4400)
+++ kernel/trunk/exo.kernel.component.common/pom.xml 2011-05-23 06:57:15 UTC (rev 4401)
@@ -125,10 +125,7 @@
<name>jgroups.stack</name>
<value>udp</value>
</property>
- </systemProperties>
- <excludes>
- <exclude>**/TransactionTest.java</exclude>
- </excludes>
+ </systemProperties>
</configuration>
</plugin>
<plugin>
Added: kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/jdbc/DataSourceProvider.java
===================================================================
--- kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/jdbc/DataSourceProvider.java (rev 0)
+++ kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/jdbc/DataSourceProvider.java 2011-05-23 06:57:15 UTC (rev 4401)
@@ -0,0 +1,52 @@
+/*
+ * 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.jdbc;
+
+import javax.naming.NamingException;
+import javax.sql.DataSource;
+
+/**
+ * This provider is used to get a {@link DataSource} in an uniform manner.
+ * It allows to wrap the {@link DataSource} in case it is defined as managed
+ *
+ * @author <a href="mailto:nfilotto@exoplatform.com">Nicolas Filotto</a>
+ * @version $Id$
+ *
+ */
+public interface DataSourceProvider
+{
+ /**
+ * Try to get the data source from a lookup, if it can't a {@link NamingException}
+ * will be thrown
+ * @param dataSourceName the name of the data source to lookup
+ * @return the {@link DataSource} found thanks to the lookup. The original
+ * object could be wrap to another {@link DataSource} in order to support
+ * managed data source.
+ * @throws NamingException if the data source could not be found
+ */
+ DataSource getDataSource(String dataSourceName) throws NamingException;
+
+ /**
+ * Indicates whether or not the given data source is managed
+ * @param dataSourceName the data source to check
+ * @return <code>true</code> if the data source is managed,
+ * <code>false</code> otherwise
+ */
+ boolean isManaged(String dataSourceName);
+}
Added: kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/jdbc/impl/DataSourceProviderImpl.java
===================================================================
--- kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/jdbc/impl/DataSourceProviderImpl.java (rev 0)
+++ kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/jdbc/impl/DataSourceProviderImpl.java 2011-05-23 06:57:15 UTC (rev 4401)
@@ -0,0 +1,160 @@
+/*
+ * 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.jdbc.impl;
+
+import org.exoplatform.container.xml.InitParams;
+import org.exoplatform.container.xml.ValueParam;
+import org.exoplatform.container.xml.ValuesParam;
+import org.exoplatform.services.jdbc.DataSourceProvider;
+import org.exoplatform.services.transaction.TransactionService;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.sql.DataSource;
+import javax.transaction.TransactionManager;
+
+/**
+ * The default implementation of {@link DataSourceProvider}. It allows you
+ * to define a data source as managed thanks to the configuration of this
+ * component. When the data source is declared as managed, the {@link DataSource}
+ * object will be wrap into a {@link ManagedDataSource}.
+ *
+ * @author <a href="mailto:nfilotto@exoplatform.com">Nicolas Filotto</a>
+ * @version $Id$
+ *
+ */
+public class DataSourceProviderImpl implements DataSourceProvider
+{
+
+ /**
+ * The name of the parameter to know if the tx has to be checked or not.
+ */
+ protected static final String PARAM_CHECK_TX = "check-tx-active";
+
+ /**
+ * The name of the parameter to know if the data sources are always managed.
+ */
+ protected static final String PARAM_ALWAYS_MANAGED = "always-managed";
+
+ /**
+ * The name of the parameter of all the managed data sources.
+ */
+ protected static final String PARAM_MANAGED_DS = "managed-data-sources";
+
+ /**
+ * The transaction manager
+ */
+ protected final TransactionManager tm;
+
+ /**
+ * Indicates if the data source needs to check if a tx is active
+ * to decide if the provided connection needs to be managed or not.
+ * If it is set to false, the data source will provide only
+ * managed connections if the data source itself is managed.
+ */
+ protected boolean checkIfTxActive = true;
+
+ /**
+ * Indicates that all the data sources are managed
+ */
+ protected boolean alwaysManaged;
+
+ /**
+ * A set of all the data sources that are managed
+ */
+ protected final Set<String> managedDS = new HashSet<String>();
+
+ /**
+ * The default constructor
+ */
+ public DataSourceProviderImpl(InitParams params)
+ {
+ this(params, null);
+ }
+
+ /**
+ * The default constructor
+ */
+ public DataSourceProviderImpl(InitParams params, TransactionService tService)
+ {
+ this.tm = tService == null ? null : tService.getTransactionManager();
+ if (params != null)
+ {
+ ValueParam param = params.getValueParam(PARAM_CHECK_TX);
+ if (param != null)
+ {
+ this.checkIfTxActive = Boolean.valueOf(param.getValue());
+ }
+ param = params.getValueParam(PARAM_ALWAYS_MANAGED);
+ if (param != null && Boolean.valueOf(param.getValue()))
+ {
+ this.alwaysManaged = true;
+ return;
+ }
+ ValuesParam vp = params.getValuesParam(PARAM_MANAGED_DS);
+ if (vp != null && vp.getValues() != null)
+ {
+ for (Object oValue : vp.getValues())
+ {
+ String s = (String)oValue;
+ StringTokenizer st = new StringTokenizer(s, ",");
+ while (st.hasMoreTokens())
+ {
+ String dsName = st.nextToken().trim();
+ if (!dsName.isEmpty())
+ {
+ managedDS.add(dsName);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * @throws NamingException
+ * @see org.exoplatform.services.jdbc.DataSourceProvider#getDataSource(java.lang.String)
+ */
+ public DataSource getDataSource(String dataSourceName) throws NamingException
+ {
+ DataSource ds = (DataSource)new InitialContext().lookup(dataSourceName);
+ // wrap the data source object if it is managed
+ return isManaged(dataSourceName) ? new ManagedDataSource(ds, tm, checkIfTxActive) : ds;
+ }
+
+ /**
+ * @see org.exoplatform.services.jdbc.DataSourceProvider#isManaged(java.lang.String)
+ */
+ public boolean isManaged(String dataSourceName)
+ {
+ if (alwaysManaged)
+ {
+ return true;
+ }
+ else if (managedDS.isEmpty())
+ {
+ return false;
+ }
+ return managedDS.contains(dataSourceName);
+ }
+}
Added: kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/jdbc/impl/ManagedConnection.java
===================================================================
--- kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/jdbc/impl/ManagedConnection.java (rev 0)
+++ kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/jdbc/impl/ManagedConnection.java 2011-05-23 06:57:15 UTC (rev 4401)
@@ -0,0 +1,458 @@
+/*
+ * 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.jdbc.impl;
+
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.CallableStatement;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.NClob;
+import java.sql.PreparedStatement;
+import java.sql.SQLClientInfoException;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.SQLXML;
+import java.sql.Savepoint;
+import java.sql.Statement;
+import java.sql.Struct;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * This classes wraps a jdbc connection in order to prevent any forbidden
+ * actions such as explicit commit/rollback.
+ *
+ * @author <a href="mailto:nfilotto@exoplatform.com">Nicolas Filotto</a>
+ * @version $Id$
+ *
+ */
+public class ManagedConnection implements Connection
+{
+
+ /**
+ * The nested connection
+ */
+ private final Connection con;
+
+ /**
+ * default constructor
+ */
+ public ManagedConnection(Connection con)
+ {
+ this.con = con;
+ }
+
+ /**
+ * @see java.sql.Wrapper#isWrapperFor(java.lang.Class)
+ */
+ public boolean isWrapperFor(Class<?> iface) throws SQLException
+ {
+ return con.isWrapperFor(iface);
+ }
+
+ /**
+ * @see java.sql.Wrapper#unwrap(java.lang.Class)
+ */
+ public <T> T unwrap(Class<T> iface) throws SQLException
+ {
+ return con.unwrap(iface);
+ }
+
+ /**
+ * @see java.sql.Connection#prepareStatement(java.lang.String)
+ */
+ public PreparedStatement prepareStatement(String sql) throws SQLException
+ {
+ return con.prepareStatement(sql);
+ }
+
+ /**
+ * @see java.sql.Connection#prepareCall(java.lang.String)
+ */
+ public CallableStatement prepareCall(String sql) throws SQLException
+ {
+ return con.prepareCall(sql);
+ }
+
+ /**
+ * @see java.sql.Connection#nativeSQL(java.lang.String)
+ */
+ public String nativeSQL(String sql) throws SQLException
+ {
+ return con.nativeSQL(sql);
+ }
+
+ /**
+ * @see java.sql.Connection#setAutoCommit(boolean)
+ */
+ public void setAutoCommit(boolean autoCommit) throws SQLException
+ {
+ con.setAutoCommit(autoCommit);
+ }
+
+ /**
+ * @see java.sql.Connection#commit()
+ */
+ public void commit() throws SQLException
+ {
+ // We cannot call commit explicitly, it will be done by the AS itself
+ }
+
+ /**
+ * @see java.sql.Connection#rollback()
+ */
+ public void rollback() throws SQLException
+ {
+ // We cannot call rollback explicitly, it will be done by the AS itself
+ }
+
+ /**
+ * @see java.sql.Connection#close()
+ */
+ public void close() throws SQLException
+ {
+ con.close();
+ }
+
+ /**
+ * @see java.sql.Connection#setReadOnly(boolean)
+ */
+ public void setReadOnly(boolean readOnly) throws SQLException
+ {
+ con.setReadOnly(readOnly);
+ }
+
+ /**
+ * @see java.sql.Connection#setCatalog(java.lang.String)
+ */
+ public void setCatalog(String catalog) throws SQLException
+ {
+ con.setCatalog(catalog);
+ }
+
+ /**
+ * @see java.sql.Connection#setTransactionIsolation(int)
+ */
+ public void setTransactionIsolation(int level) throws SQLException
+ {
+ con.setTransactionIsolation(level);
+ }
+
+ /**
+ * @see java.sql.Connection#clearWarnings()
+ */
+ public void clearWarnings() throws SQLException
+ {
+ con.clearWarnings();
+ }
+
+ /**
+ * @see java.sql.Connection#createArrayOf(java.lang.String, java.lang.Object[])
+ */
+ public Array createArrayOf(String typeName, Object[] elements) throws SQLException
+ {
+ return con.createArrayOf(typeName, elements);
+ }
+
+ /**
+ * @see java.sql.Connection#createBlob()
+ */
+ public Blob createBlob() throws SQLException
+ {
+ return con.createBlob();
+ }
+
+ /**
+ * @see java.sql.Connection#createClob()
+ */
+ public Clob createClob() throws SQLException
+ {
+ return con.createClob();
+ }
+
+ /**
+ * @see java.sql.Connection#createNClob()
+ */
+ public NClob createNClob() throws SQLException
+ {
+ return con.createNClob();
+ }
+
+ /**
+ * @see java.sql.Connection#createSQLXML()
+ */
+ public SQLXML createSQLXML() throws SQLException
+ {
+ return con.createSQLXML();
+ }
+
+ /**
+ * @see java.sql.Connection#createStatement()
+ */
+ public Statement createStatement() throws SQLException
+ {
+ return con.createStatement();
+ }
+
+ /**
+ * @see java.sql.Connection#createStatement(int, int)
+ */
+ public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException
+ {
+ return con.createStatement(resultSetType, resultSetConcurrency);
+ }
+
+ /**
+ * @see java.sql.Connection#prepareStatement(java.lang.String, int, int)
+ */
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)
+ throws SQLException
+ {
+ return con.prepareStatement(sql, resultSetType, resultSetConcurrency);
+ }
+
+ /**
+ * @see java.sql.Connection#prepareCall(java.lang.String, int, int)
+ */
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException
+ {
+ return con.prepareCall(sql, resultSetType, resultSetConcurrency);
+ }
+
+ /**
+ * @see java.sql.Connection#setTypeMap(java.util.Map)
+ */
+ public void setTypeMap(Map<String, Class<?>> map) throws SQLException
+ {
+ con.setTypeMap(map);
+ }
+
+ /**
+ * @see java.sql.Connection#setSavepoint()
+ */
+ public Savepoint setSavepoint() throws SQLException
+ {
+ return con.setSavepoint();
+ }
+
+ /**
+ * @see java.sql.Connection#setSavepoint(java.lang.String)
+ */
+ public Savepoint setSavepoint(String name) throws SQLException
+ {
+ return con.setSavepoint(name);
+ }
+
+ /**
+ * @see java.sql.Connection#rollback(java.sql.Savepoint)
+ */
+ public void rollback(Savepoint savepoint) throws SQLException
+ {
+ // We cannot call rollback explicitly, it will be done by the AS itself
+ }
+
+ /**
+ * @see java.sql.Connection#releaseSavepoint(java.sql.Savepoint)
+ */
+ public void releaseSavepoint(Savepoint savepoint) throws SQLException
+ {
+ con.releaseSavepoint(savepoint);
+ }
+
+ /**
+ * @see java.sql.Connection#createStatement(int, int, int)
+ */
+ public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
+ throws SQLException
+ {
+ return con.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+
+ /**
+ * @see java.sql.Connection#createStruct(java.lang.String, java.lang.Object[])
+ */
+ public Struct createStruct(String typeName, Object[] attributes) throws SQLException
+ {
+ return con.createStruct(typeName, attributes);
+ }
+
+ /**
+ * @see java.sql.Connection#getAutoCommit()
+ */
+ public boolean getAutoCommit() throws SQLException
+ {
+ return con.getAutoCommit();
+ }
+
+ /**
+ * @see java.sql.Connection#isClosed()
+ */
+ public boolean isClosed() throws SQLException
+ {
+ return con.isClosed();
+ }
+
+ /**
+ * @see java.sql.Connection#isReadOnly()
+ */
+ public boolean isReadOnly() throws SQLException
+ {
+ return con.isReadOnly();
+ }
+
+ /**
+ * @see java.sql.Connection#getCatalog()
+ */
+ public String getCatalog() throws SQLException
+ {
+ return con.getCatalog();
+ }
+
+ /**
+ * @see java.sql.Connection#getClientInfo()
+ */
+ public Properties getClientInfo() throws SQLException
+ {
+ return con.getClientInfo();
+ }
+
+ /**
+ * @see java.sql.Connection#getClientInfo(java.lang.String)
+ */
+ public String getClientInfo(String name) throws SQLException
+ {
+ return con.getClientInfo(name);
+ }
+
+ /**
+ * @see java.sql.Connection#getMetaData()
+ */
+ public DatabaseMetaData getMetaData() throws SQLException
+ {
+ return con.getMetaData();
+ }
+
+ /**
+ * @see java.sql.Connection#getTransactionIsolation()
+ */
+ public int getTransactionIsolation() throws SQLException
+ {
+ return con.getTransactionIsolation();
+ }
+
+ /**
+ * @see java.sql.Connection#getWarnings()
+ */
+ public SQLWarning getWarnings() throws SQLException
+ {
+ return con.getWarnings();
+ }
+
+ /**
+ * @see java.sql.Connection#getTypeMap()
+ */
+ public Map<String, Class<?>> getTypeMap() throws SQLException
+ {
+ return con.getTypeMap();
+ }
+
+ /**
+ * @see java.sql.Connection#getHoldability()
+ */
+ public int getHoldability() throws SQLException
+ {
+ return con.getHoldability();
+ }
+
+ /**
+ * @see java.sql.Connection#isValid(int)
+ */
+ public boolean isValid(int timeout) throws SQLException
+ {
+ return con.isValid(timeout);
+ }
+
+ /**
+ * @see java.sql.Connection#prepareStatement(java.lang.String, int, int, int)
+ */
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency,
+ int resultSetHoldability) throws SQLException
+ {
+ return con.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+
+ /**
+ * @see java.sql.Connection#prepareCall(java.lang.String, int, int, int)
+ */
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency,
+ int resultSetHoldability) throws SQLException
+ {
+ return con.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+
+ /**
+ * @see java.sql.Connection#prepareStatement(java.lang.String, int)
+ */
+ public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException
+ {
+ return con.prepareStatement(sql, autoGeneratedKeys);
+ }
+
+ /**
+ * @see java.sql.Connection#prepareStatement(java.lang.String, int[])
+ */
+ public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException
+ {
+ return con.prepareStatement(sql, columnIndexes);
+ }
+
+ /**
+ * @see java.sql.Connection#prepareStatement(java.lang.String, java.lang.String[])
+ */
+ public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException
+ {
+ return con.prepareStatement(sql, columnNames);
+ }
+
+ /**
+ * @see java.sql.Connection#setClientInfo(java.util.Properties)
+ */
+ public void setClientInfo(Properties properties) throws SQLClientInfoException
+ {
+ con.setClientInfo(properties);
+ }
+
+ /**
+ * @see java.sql.Connection#setClientInfo(java.lang.String, java.lang.String)
+ */
+ public void setClientInfo(String name, String value) throws SQLClientInfoException
+ {
+ con.setClientInfo(name, value);
+ }
+
+ /**
+ * @see java.sql.Connection#setHoldability(int)
+ */
+ public void setHoldability(int holdability) throws SQLException
+ {
+ con.setHoldability(holdability);
+ }
+}
Added: kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/jdbc/impl/ManagedDataSource.java
===================================================================
--- kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/jdbc/impl/ManagedDataSource.java (rev 0)
+++ kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/jdbc/impl/ManagedDataSource.java 2011-05-23 06:57:15 UTC (rev 4401)
@@ -0,0 +1,162 @@
+/*
+ * 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.jdbc.impl;
+
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+
+import java.io.PrintWriter;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import javax.sql.DataSource;
+import javax.transaction.Status;
+import javax.transaction.TransactionManager;
+
+/**
+ * This classes is used to wrap the original {@link DataSource}
+ * in order to be able to support the managed data sources with a limited
+ * amount of changes. A {@link DataSource} is expected to be wrapped only
+ * when a data source is defined and has been configured as managed
+ *
+ * @author <a href="mailto:nfilotto@exoplatform.com">Nicolas Filotto</a>
+ * @version $Id$
+ *
+ */
+public class ManagedDataSource implements DataSource
+{
+ private static final Log LOG = ExoLogger.getLogger("exo.jcr.component.core.ManagedDataSource");
+
+ /**
+ * The transaction manager
+ */
+ private final TransactionManager tm;
+
+ /**
+ * The wrapped {@link DataSource}
+ */
+ private final DataSource ds;
+
+ /**
+ * Indicates whether the tx status need to be check first to know
+ * if the provided connection needs to be managed or not
+ */
+ private final boolean checkIfTxActive;
+
+ /**
+ * default constructor
+ */
+ public ManagedDataSource(DataSource ds, TransactionManager tm, boolean checkIfTxActive)
+ {
+ this.tm = tm;
+ this.ds = ds;
+ this.checkIfTxActive = checkIfTxActive;
+ }
+
+ /**
+ * @see javax.sql.CommonDataSource#getLogWriter()
+ */
+ public PrintWriter getLogWriter() throws SQLException
+ {
+ return ds.getLogWriter();
+ }
+
+ /**
+ * @see javax.sql.CommonDataSource#getLoginTimeout()
+ */
+ public int getLoginTimeout() throws SQLException
+ {
+ return ds.getLoginTimeout();
+ }
+
+ /**
+ * @see javax.sql.CommonDataSource#setLogWriter(java.io.PrintWriter)
+ */
+ public void setLogWriter(PrintWriter out) throws SQLException
+ {
+ ds.setLogWriter(out);
+ }
+
+ /**
+ * @see javax.sql.CommonDataSource#setLoginTimeout(int)
+ */
+ public void setLoginTimeout(int seconds) throws SQLException
+ {
+ ds.setLoginTimeout(seconds);
+ }
+
+ /**
+ * @see java.sql.Wrapper#isWrapperFor(java.lang.Class)
+ */
+ public boolean isWrapperFor(Class<?> iface) throws SQLException
+ {
+ return ds.isWrapperFor(iface);
+ }
+
+ /**
+ * @see java.sql.Wrapper#unwrap(java.lang.Class)
+ */
+ public <T> T unwrap(Class<T> iface) throws SQLException
+ {
+ return ds.unwrap(iface);
+ }
+
+ /**
+ * @see javax.sql.DataSource#getConnection()
+ */
+ public Connection getConnection() throws SQLException
+ {
+ Connection con = ds.getConnection();
+ return providesManagedConnection() ? new ManagedConnection(con) : con;
+ }
+
+ /**
+ * @see javax.sql.DataSource#getConnection(java.lang.String, java.lang.String)
+ */
+ public Connection getConnection(String username, String password) throws SQLException
+ {
+ Connection con = ds.getConnection(username, password);
+ return providesManagedConnection() ? new ManagedConnection(con) : con;
+ }
+
+ /**
+ * Indicates whether or not a global tx is active
+ * @return <code>true</code> if a tx is active, <code>false</code> otherwise
+ */
+ private boolean isTxActive()
+ {
+ try
+ {
+ return tm != null && tm.getStatus() != Status.STATUS_NO_TRANSACTION;
+ }
+ catch (Exception e)
+ {
+ LOG.warn("We cannot know if a global tx is active", e);
+ }
+ return false;
+ }
+
+ /**
+ * Indicates whether or not the provided connection needs to be managed
+ */
+ private boolean providesManagedConnection()
+ {
+ return !checkIfTxActive || isTxActive();
+ }
+}
Modified: kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/ExoResource.java
===================================================================
--- kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/ExoResource.java 2011-05-20 14:38:19 UTC (rev 4400)
+++ kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/ExoResource.java 2011-05-23 06:57:15 UTC (rev 4401)
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2009 eXo Platform SAS.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.exoplatform.services.transaction;
-
-import javax.transaction.xa.XAException;
-import javax.transaction.xa.XAResource;
-
-/**
- * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
- * @version $Revision$
- */
-public interface ExoResource
-{
-
- /**
- * @return XAResource
- */
- XAResource getXAResource();
-
- /**
- * Enlists XAResource in TM.
- *
- * @throws javax.transaction.xa.XAException
- */
- void enlistResource() throws XAException;
-
- /**
- * Delists XAResource in TM.
- *
- * @throws XAException
- */
- void delistResource() throws XAException;
-
- /**
- * Returns the payload attached to the resource.
- *
- * @return the payload
- */
- Object getPayload();
-
- /**
- * Attach a payload to the resource.
- *
- * @param payload the payload
- */
- void setPayload(Object payload);
-
-}
Modified: kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/TransactionException.java
===================================================================
--- kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/TransactionException.java 2011-05-20 14:38:19 UTC (rev 4400)
+++ kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/TransactionException.java 2011-05-23 06:57:15 UTC (rev 4401)
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2009 eXo Platform SAS.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.exoplatform.services.transaction;
-
-import javax.transaction.xa.XAException;
-
-/**
- * Created by The eXo Platform SAS.
- *
- * @author <a href="mailto:gennady.azarenkov@exoplatform.com">Gennady
- * Azarenkov</a>
- * @version $Id: TransactionException.java 5987 2006-06-05 10:14:23Z geaz $
- */
-
-public class TransactionException extends Exception
-{
-
- private final int errcode;
-
- public TransactionException()
- {
- super();
- this.errcode = XAException.XA_RBOTHER;
- }
-
- public TransactionException(String arg0)
- {
- super(arg0);
- this.errcode = XAException.XA_RBOTHER;
- }
-
- public TransactionException(String arg0, Throwable arg1)
- {
- super(arg0, arg1);
- this.errcode = XAException.XA_RBOTHER;
- }
-
- public TransactionException(Throwable arg0)
- {
- super(arg0);
- this.errcode = XAException.XA_RBOTHER;
- }
-
- public TransactionException(int errcode, String arg0)
- {
- super(arg0);
- this.errcode = errcode;
- }
-
- public TransactionException(int errcode, Throwable arg0)
- {
- super(arg0);
- this.errcode = errcode;
- }
-
- public int getErrorCode()
- {
- return errcode;
- }
-}
Modified: kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/TransactionResource.java
===================================================================
--- kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/TransactionResource.java 2011-05-20 14:38:19 UTC (rev 4400)
+++ kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/TransactionResource.java 2011-05-23 06:57:15 UTC (rev 4401)
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2009 eXo Platform SAS.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.exoplatform.services.transaction;
-
-/**
- * Created by The eXo Platform SAS.<br/> Internal resource manager for support
- * transaction
- *
- * @author <a href="mailto:gennady.azarenkov@exoplatform.com">Gennady
- * Azarenkov</a>
- * @version $Id: TransactionResource.java 6853 2006-07-07 11:41:24Z geaz $
- */
-
-public interface TransactionResource
-{
-
- /**
- * called when transaction is starting (by
- * javax.transaction.xa.XAResource#start(javax.transaction.xa.Xid, int))
- *
- * @throws TransactionException
- */
- void start() throws TransactionException;
-
- /**
- * called when transaction is committing (by
- * javax.transaction.xa.XAResource#commit(javax.transaction.xa.Xid, boolean))
- *
- * @throws TransactionException
- */
- void commit() throws TransactionException;
-
- /**
- * called when transaction is rolling back (by
- * javax.transaction.xa.XAResource#rollback(javax.transaction.xa.Xid))
- *
- * @throws TransactionException
- */
- void rollback() throws TransactionException;
-
-}
Modified: kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/TransactionService.java
===================================================================
--- kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/TransactionService.java 2011-05-20 14:38:19 UTC (rev 4400)
+++ kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/TransactionService.java 2011-05-23 06:57:15 UTC (rev 4401)
@@ -22,7 +22,7 @@
import javax.transaction.SystemException;
import javax.transaction.TransactionManager;
import javax.transaction.UserTransaction;
-import javax.transaction.xa.Xid;
+import javax.transaction.xa.XAResource;
/**
* Created by The eXo Platform SAS.<br/> The transaction service
@@ -62,25 +62,34 @@
* Enlists XA resource in transaction manager.
*
* @param xares XAResource
- * @throws RollbackException
- * @throws SystemException
+ * @return <i>true</i> if the resource was enlisted successfully; otherwise
+ * <i>false</i>.
+ *
+ * @exception RollbackException Thrown to indicate that
+ * the transaction has been marked for rollback only.
+ *
+ * @exception IllegalStateException Thrown if the transaction in the
+ * target object is in the prepared state or the transaction is
+ * inactive.
+ *
+ * @exception SystemException Thrown if the transaction manager
+ * encounters an unexpected error condition.
*/
- void enlistResource(ExoResource xares) throws RollbackException, SystemException;
+ boolean enlistResource(XAResource xares) throws RollbackException, SystemException, IllegalStateException;
/**
* Delists XA resource from transaction manager.
*
* @param xares XAResource
- * @throws RollbackException
- * @throws SystemException
+ * @exception IllegalStateException Thrown if the transaction in the
+ * target object is inactive.
+ *
+ * @exception SystemException Thrown if the transaction manager
+ * encounters an unexpected error condition.
+ *
+ * @return <i>true</i> if the resource was delisted successfully; otherwise
+ * <i>false</i>.
*/
- void delistResource(ExoResource xares) throws RollbackException, SystemException;
+ boolean delistResource(XAResource xares) throws RollbackException, SystemException, IllegalStateException;
- /**
- * Creates unique XA transaction identifier.
- *
- * @return Xid
- */
- Xid createXid();
-
}
Added: kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/impl/AbstractTransactionService.java
===================================================================
--- kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/impl/AbstractTransactionService.java (rev 0)
+++ kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/impl/AbstractTransactionService.java 2011-05-23 06:57:15 UTC (rev 4401)
@@ -0,0 +1,845 @@
+/*
+ * 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.transaction.impl;
+
+import org.exoplatform.commons.utils.SecurityHelper;
+import org.exoplatform.container.xml.InitParams;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+import org.exoplatform.services.transaction.TransactionService;
+
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.InvalidTransactionException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import javax.transaction.UserTransaction;
+import javax.transaction.xa.XAResource;
+
+/**
+ * This abstract class implements the main logic of all the methods expected for a
+ * {@link TransactionService}. If you intend to use a {@link TransactionManager} in
+ * standalone mode (not manager by your Application Server), you can set the
+ * transaction timeout thanks to the <code>value-param</code> called <code>timeout</code>
+ * the value of this parameter is expressed in seconds.
+ *
+ * @author <a href="mailto:nicolas.filotto@exoplatform.com">Nicolas Filotto</a>
+ * @version $Id$
+ *
+ */
+public abstract class AbstractTransactionService implements TransactionService
+{
+ /**
+ * The logger
+ */
+ private static final Log LOG = ExoLogger.getLogger("exo.kernel.component.common.AbstractTransactionService");
+
+ /**
+ * The default value of a transaction timeout in seconds
+ */
+ private static final int DEFAULT_TIME_OUT = 60;
+
+ /**
+ * The default timeout
+ */
+ protected final int defaultTimeout;
+
+ /**
+ * Indicates if the timeout has to be enforced
+ */
+ protected final boolean forceTimeout;
+
+ /**
+ * The current Transaction Manager
+ */
+ private volatile TransactionManager tm;
+
+ /**
+ * The current User Transaction
+ */
+ private volatile UserTransaction ut;
+
+ public AbstractTransactionService()
+ {
+ this(null);
+ }
+
+ public AbstractTransactionService(InitParams params)
+ {
+ if (params != null && params.getValueParam("timeout") != null)
+ {
+ this.defaultTimeout = Integer.parseInt(params.getValueParam("timeout").getValue());
+ this.forceTimeout = true;
+ }
+ else
+ {
+ this.defaultTimeout = DEFAULT_TIME_OUT;
+ this.forceTimeout = false;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean delistResource(final XAResource xares) throws RollbackException, SystemException
+ {
+ TransactionManager tm = getTransactionManager();
+ final Transaction tx = tm.getTransaction();
+ if (tx != null)
+ {
+ PrivilegedExceptionAction<Boolean> action = new PrivilegedExceptionAction<Boolean>()
+ {
+ public Boolean run() throws Exception
+ {
+ int flag = XAResource.TMSUCCESS;
+ switch (tx.getStatus())
+ {
+ case Status.STATUS_MARKED_ROLLBACK:
+ case Status.STATUS_ROLLEDBACK:
+ case Status.STATUS_ROLLING_BACK: flag = XAResource.TMFAIL;
+ }
+ return tx.delistResource(xares, flag);
+ }
+ };
+ try
+ {
+ return AccessController.doPrivileged(action);
+ }
+ catch (PrivilegedActionException pae)
+ {
+ Throwable cause = pae.getCause();
+
+ if (cause instanceof RollbackException)
+ {
+ throw (RollbackException)cause;
+ }
+ else if (cause instanceof IllegalStateException)
+ {
+ throw (IllegalStateException)cause;
+ }
+ else if (cause instanceof SystemException)
+ {
+ throw (SystemException)cause;
+ }
+ else if (cause instanceof RuntimeException)
+ {
+ throw (RuntimeException)cause;
+ }
+ else
+ {
+ throw new RuntimeException(cause);
+ }
+ }
+ }
+ else
+ {
+ throw new IllegalStateException("Could not delist the XA Resource since there is no active session");
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean enlistResource(final XAResource xares) throws RollbackException, SystemException
+ {
+ TransactionManager tm = getTransactionManager();
+ final Transaction tx = tm.getTransaction();
+ if (tx != null)
+ {
+ PrivilegedExceptionAction<Boolean> action = new PrivilegedExceptionAction<Boolean>()
+ {
+ public Boolean run() throws Exception
+ {
+ return tx.enlistResource(xares);
+ }
+ };
+ try
+ {
+ return AccessController.doPrivileged(action);
+ }
+ catch (PrivilegedActionException pae)
+ {
+ Throwable cause = pae.getCause();
+
+ if (cause instanceof RollbackException)
+ {
+ throw (RollbackException)cause;
+ }
+ else if (cause instanceof IllegalStateException)
+ {
+ throw (IllegalStateException)cause;
+ }
+ else if (cause instanceof SystemException)
+ {
+ throw (SystemException)cause;
+ }
+ else if (cause instanceof RuntimeException)
+ {
+ throw (RuntimeException)cause;
+ }
+ else
+ {
+ throw new RuntimeException(cause);
+ }
+ }
+ }
+ else
+ {
+ throw new IllegalStateException("Could not enlist the XA Resource since there is no active session");
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getDefaultTimeout()
+ {
+ return defaultTimeout;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final TransactionManager getTransactionManager()
+ {
+ if (tm == null)
+ {
+ synchronized (this)
+ {
+ if (tm == null)
+ {
+ TransactionManager tm;
+ try
+ {
+ tm = SecurityHelper.doPrivilegedExceptionAction(new PrivilegedExceptionAction<TransactionManager>()
+ {
+ public TransactionManager run() throws Exception
+ {
+ return findTransactionManager();
+ }
+ });
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("Transaction manager not found", e);
+ }
+ if (forceTimeout)
+ {
+ // Only set the timeout when a timeout has been given into the
+ // configuration otherwise we assume that the value will be
+ // set at the AS level
+ tm = new TransactionManagerTxTimeoutAware(tm, defaultTimeout);
+ }
+ this.tm = tm;
+ }
+ }
+ }
+ return tm;
+ }
+
+ /**
+ * Indicates whether or not the {@link TransactionManager} has been initialized
+ */
+ protected boolean isTMInitialized()
+ {
+ return tm != null;
+ }
+
+ /**
+ * This method will try to find the current {@link TransactionManager}
+ * @return the current {@link TransactionManager}
+ * @throws Exception if an error occurs while looking for the {@link TransactionManager}
+ */
+ protected abstract TransactionManager findTransactionManager() throws Exception;
+
+ /**
+ * {@inheritDoc}
+ */
+ public final UserTransaction getUserTransaction()
+ {
+ if (ut == null)
+ {
+ synchronized (this)
+ {
+ if (ut == null)
+ {
+ UserTransaction ut;
+ try
+ {
+ ut = SecurityHelper.doPrivilegedExceptionAction(new PrivilegedExceptionAction<UserTransaction>()
+ {
+ public UserTransaction run() throws Exception
+ {
+ return findUserTransaction();
+ }
+ });
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("UserTransaction not found", e);
+ }
+ this.ut = ut;
+ }
+ }
+ }
+ return ut;
+ }
+
+
+ /**
+ * This method will try to find the current {@link UserTransaction}, by default it will
+ * simply wraps a {@link TransactionManager}
+ * @return the current {@link UserTransaction}
+ * @throws Exception if an error occurs while looking for the {@link UserTransaction}
+ */
+ protected UserTransaction findUserTransaction() throws Exception
+ {
+ return new UserTransactionWrapper(getTransactionManager());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setTransactionTimeout(int seconds) throws SystemException
+ {
+ TransactionManager tm = getTransactionManager();
+ tm.setTransactionTimeout(seconds);
+ }
+
+ /**
+ * This class is used to enforce the {@link Transaction} timeout when a new transaction is
+ * created through the nested {@link TransactionManager}
+ *
+ * Created by The eXo Platform SAS
+ * Author : Nicolas Filotto
+ * nicolas.filotto(a)exoplatform.com
+ * 1 f�vr. 2010
+ */
+ private static class TransactionManagerTxTimeoutAware implements TransactionManager
+ {
+ /**
+ * The nested {@link TransactionManager}
+ */
+ private final TransactionManager tm;
+
+ /**
+ * The default timeout of the {@link Transaction}
+ */
+ private final int defaultTimeout;
+
+ /**
+ * This is used to know if a timeout has already been set for the next transaction
+ */
+ private final ThreadLocal<Boolean> timeoutHasBeenSet = new ThreadLocal<Boolean>();
+
+ public TransactionManagerTxTimeoutAware(TransactionManager tm, int defaultTimeout)
+ {
+ this.tm = tm;
+ this.defaultTimeout = defaultTimeout;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void begin() throws NotSupportedException, SystemException
+ {
+ if (timeoutHasBeenSet.get() != null)
+ {
+ // clean the ThreadLocal
+ timeoutHasBeenSet.set(null);
+ }
+ else
+ {
+ try
+ {
+ // Set the default transaction timeout
+ tm.setTransactionTimeout(defaultTimeout);
+ }
+ catch (Exception e)
+ {
+ LOG.warn("Cannot set the transaction timeout", e);
+ }
+ }
+
+ // Start the transaction
+ PrivilegedExceptionAction<Object> action = new PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ tm.begin();
+ return null;
+ }
+ };
+ try
+ {
+ AccessController.doPrivileged(action);
+ }
+ catch (PrivilegedActionException pae)
+ {
+ Throwable cause = pae.getCause();
+ if (cause instanceof NotSupportedException)
+ {
+ throw (NotSupportedException)cause;
+ }
+ else if (cause instanceof SystemException)
+ {
+ throw (SystemException)cause;
+ }
+ else if (cause instanceof RuntimeException)
+ {
+ throw (RuntimeException)cause;
+ }
+ else
+ {
+ throw new RuntimeException(cause);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException,
+ SecurityException, IllegalStateException, SystemException
+ {
+ PrivilegedExceptionAction<Object> action = new PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ tm.commit();
+ return null;
+ }
+ };
+ try
+ {
+ AccessController.doPrivileged(action);
+ }
+ catch (PrivilegedActionException pae)
+ {
+ Throwable cause = pae.getCause();
+ if (cause instanceof RollbackException)
+ {
+ throw (RollbackException)cause;
+ }
+ else if (cause instanceof HeuristicMixedException)
+ {
+ throw (HeuristicMixedException)cause;
+ }
+ else if (cause instanceof HeuristicRollbackException)
+ {
+ throw (HeuristicRollbackException)cause;
+ }
+ else if (cause instanceof SecurityException)
+ {
+ throw (SecurityException)cause;
+ }
+ else if (cause instanceof IllegalStateException)
+ {
+ throw (IllegalStateException)cause;
+ }
+ else if (cause instanceof SystemException)
+ {
+ throw (SystemException)cause;
+ }
+ else if (cause instanceof RuntimeException)
+ {
+ throw (RuntimeException)cause;
+ }
+ else
+ {
+ throw new RuntimeException(cause);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getStatus() throws SystemException
+ {
+ return tm.getStatus();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Transaction getTransaction() throws SystemException
+ {
+ try
+ {
+ return SecurityHelper.doPrivilegedExceptionAction(new PrivilegedExceptionAction<Transaction>()
+ {
+ public Transaction run() throws Exception
+ {
+ return tm.getTransaction();
+ }
+ });
+ }
+ catch (PrivilegedActionException pae)
+ {
+ Throwable cause = pae.getCause();
+ if (cause instanceof SystemException)
+ {
+ throw (SystemException)cause;
+ }
+ else if (cause instanceof RuntimeException)
+ {
+ throw (RuntimeException)cause;
+ }
+ else
+ {
+ throw new RuntimeException(cause);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void resume(final Transaction tx) throws InvalidTransactionException, IllegalStateException,
+ SystemException
+ {
+ PrivilegedExceptionAction<Object> action = new PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ tm.resume(tx);
+ return null;
+ }
+ };
+ try
+ {
+ AccessController.doPrivileged(action);
+ }
+ catch (PrivilegedActionException pae)
+ {
+ Throwable cause = pae.getCause();
+ if (cause instanceof InvalidTransactionException)
+ {
+ throw (InvalidTransactionException)cause;
+ }
+ else if (cause instanceof IllegalStateException)
+ {
+ throw (IllegalStateException)cause;
+ }
+ else if (cause instanceof SystemException)
+ {
+ throw (SystemException)cause;
+ }
+ else if (cause instanceof RuntimeException)
+ {
+ throw (RuntimeException)cause;
+ }
+ else
+ {
+ throw new RuntimeException(cause);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void rollback() throws IllegalStateException, SecurityException, SystemException
+ {
+ PrivilegedExceptionAction<Object> action = new PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ tm.rollback();
+ return null;
+ }
+ };
+ try
+ {
+ AccessController.doPrivileged(action);
+ }
+ catch (PrivilegedActionException pae)
+ {
+ Throwable cause = pae.getCause();
+ if (cause instanceof IllegalStateException)
+ {
+ throw (IllegalStateException)cause;
+ }
+ else if (cause instanceof SecurityException)
+ {
+ throw (SecurityException)cause;
+ }
+ else if (cause instanceof SystemException)
+ {
+ throw (SystemException)cause;
+ }
+ else if (cause instanceof RuntimeException)
+ {
+ throw (RuntimeException)cause;
+ }
+ else
+ {
+ throw new RuntimeException(cause);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setRollbackOnly() throws IllegalStateException, SystemException
+ {
+ tm.setRollbackOnly();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setTransactionTimeout(int timeout) throws SystemException
+ {
+ tm.setTransactionTimeout(timeout);
+ timeoutHasBeenSet.set(true);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Transaction suspend() throws SystemException
+ {
+ PrivilegedExceptionAction<Transaction> action = new PrivilegedExceptionAction<Transaction>()
+ {
+ public Transaction run() throws Exception
+ {
+ return tm.suspend();
+ }
+ };
+ try
+ {
+ return AccessController.doPrivileged(action);
+ }
+ catch (PrivilegedActionException pae)
+ {
+ Throwable cause = pae.getCause();
+ if (cause instanceof SystemException)
+ {
+ throw (SystemException)cause;
+ }
+ else if (cause instanceof RuntimeException)
+ {
+ throw (RuntimeException)cause;
+ }
+ else
+ {
+ throw new RuntimeException(cause);
+ }
+ }
+ }
+ }
+
+ /**
+ * This class is used to propose a default implementation of a {@link UserTransaction}
+ * from the {@link TransactionManager}
+ * @author <a href="mailto:nfilotto@exoplatform.com">Nicolas Filotto</a>
+ * @version $Id$
+ *
+ */
+ private static class UserTransactionWrapper implements UserTransaction
+ {
+
+ /**
+ * The {@link TransactionManager} that we will use to simulate a {@link UserTransaction}
+ */
+ private final TransactionManager tm;
+
+ /**
+ * Default Constructor
+ * @param tm
+ */
+ public UserTransactionWrapper(TransactionManager tm)
+ {
+ this.tm = tm;
+ }
+
+ /**
+ * @see javax.transaction.UserTransaction#begin()
+ */
+ public void begin() throws NotSupportedException, SystemException
+ {
+ PrivilegedExceptionAction<Object> action = new PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ tm.begin();
+ return null;
+ }
+ };
+ try
+ {
+ AccessController.doPrivileged(action);
+ }
+ catch (PrivilegedActionException pae)
+ {
+ Throwable cause = pae.getCause();
+ if (cause instanceof NotSupportedException)
+ {
+ throw (NotSupportedException)cause;
+ }
+ else if (cause instanceof SystemException)
+ {
+ throw (SystemException)cause;
+ }
+ else if (cause instanceof RuntimeException)
+ {
+ throw (RuntimeException)cause;
+ }
+ else
+ {
+ throw new RuntimeException(cause);
+ }
+ }
+ }
+
+ /**
+ * @see javax.transaction.UserTransaction#commit()
+ */
+ public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException,
+ SecurityException, IllegalStateException, SystemException
+ {
+ PrivilegedExceptionAction<Object> action = new PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ tm.commit();
+ return null;
+ }
+ };
+ try
+ {
+ AccessController.doPrivileged(action);
+ }
+ catch (PrivilegedActionException pae)
+ {
+ Throwable cause = pae.getCause();
+ if (cause instanceof RollbackException)
+ {
+ throw (RollbackException)cause;
+ }
+ else if (cause instanceof HeuristicMixedException)
+ {
+ throw (HeuristicMixedException)cause;
+ }
+ else if (cause instanceof HeuristicRollbackException)
+ {
+ throw (HeuristicRollbackException)cause;
+ }
+ else if (cause instanceof SecurityException)
+ {
+ throw (SecurityException)cause;
+ }
+ else if (cause instanceof IllegalStateException)
+ {
+ throw (IllegalStateException)cause;
+ }
+ else if (cause instanceof SystemException)
+ {
+ throw (SystemException)cause;
+ }
+ else if (cause instanceof RuntimeException)
+ {
+ throw (RuntimeException)cause;
+ }
+ else
+ {
+ throw new RuntimeException(cause);
+ }
+ }
+ }
+
+ /**
+ * @see javax.transaction.UserTransaction#rollback()
+ */
+ public void rollback() throws IllegalStateException, SecurityException, SystemException
+ {
+ PrivilegedExceptionAction<Object> action = new PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ tm.rollback();
+ return null;
+ }
+ };
+ try
+ {
+ AccessController.doPrivileged(action);
+ }
+ catch (PrivilegedActionException pae)
+ {
+ Throwable cause = pae.getCause();
+ if (cause instanceof IllegalStateException)
+ {
+ throw (IllegalStateException)cause;
+ }
+ else if (cause instanceof SecurityException)
+ {
+ throw (SecurityException)cause;
+ }
+ else if (cause instanceof SystemException)
+ {
+ throw (SystemException)cause;
+ }
+ else if (cause instanceof RuntimeException)
+ {
+ throw (RuntimeException)cause;
+ }
+ else
+ {
+ throw new RuntimeException(cause);
+ }
+ }
+ }
+
+ /**
+ * @see javax.transaction.UserTransaction#setRollbackOnly()
+ */
+ public void setRollbackOnly() throws IllegalStateException, SystemException
+ {
+ tm.setRollbackOnly();
+ }
+
+ /**
+ * @see javax.transaction.UserTransaction#getStatus()
+ */
+ public int getStatus() throws SystemException
+ {
+ return tm.getStatus();
+ }
+
+ /**
+ * @see javax.transaction.UserTransaction#setTransactionTimeout(int)
+ */
+ public void setTransactionTimeout(int timeout) throws SystemException
+ {
+ tm.setTransactionTimeout(timeout);
+ }
+ }
+}
Modified: kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/impl/jboss/JBossTransactionService.java
===================================================================
--- kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/impl/jboss/JBossTransactionService.java 2011-05-20 14:38:19 UTC (rev 4400)
+++ kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/impl/jboss/JBossTransactionService.java 2011-05-23 06:57:15 UTC (rev 4401)
@@ -18,53 +18,47 @@
*/
package org.exoplatform.services.transaction.impl.jboss;
-import org.exoplatform.services.transaction.ExoResource;
-import org.exoplatform.services.transaction.TransactionService;
+import org.exoplatform.services.transaction.impl.AbstractTransactionService;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
import javax.naming.InitialContext;
import javax.naming.NamingException;
-import javax.transaction.RollbackException;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import javax.transaction.UserTransaction;
-import javax.transaction.xa.XAResource;
-import javax.transaction.xa.Xid;
/**
* @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
* @version $Revision$
*/
-public class JBossTransactionService implements TransactionService
+public class JBossTransactionService extends AbstractTransactionService
{
- /** . */
- private volatile TransactionManager tm;
-
- public TransactionManager getTransactionManager()
+ /**
+ * {@inheritDoc}
+ */
+ public TransactionManager findTransactionManager()
{
- if (tm == null)
+ try
{
- try
- {
- tm = (TransactionManager)new InitialContext().lookup("java:/TransactionManager");
- }
- catch (NamingException e)
- {
- throw new IllegalStateException(e);
- }
+ return (TransactionManager)new InitialContext().lookup("java:/TransactionManager");
}
- return tm;
+ catch (NamingException e)
+ {
+ throw new IllegalStateException(e);
+ }
}
- public UserTransaction getUserTransaction()
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public UserTransaction findUserTransaction()
{
try
{
- return (UserTransaction)new InitialContext().lookup("java:/TransactionManager");
+ return (UserTransaction)new InitialContext().lookup("java:comp/UserTransaction");
}
catch (NamingException e)
{
@@ -72,6 +66,10 @@
}
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public int getDefaultTimeout()
{
try
@@ -85,32 +83,4 @@
throw new IllegalStateException(e);
}
}
-
- public void setTransactionTimeout(int seconds) throws SystemException
- {
- TransactionManager tm = getTransactionManager();
- tm.setTransactionTimeout(seconds);
- }
-
- public void enlistResource(ExoResource exores) throws RollbackException, SystemException
- {
- TransactionManager tm = getTransactionManager();
- Transaction tx = tm.getTransaction();
- tx.enlistResource(exores.getXAResource());
- }
-
- public void delistResource(ExoResource exores) throws RollbackException, SystemException
- {
- TransactionManager tm = getTransactionManager();
- Transaction tx = tm.getTransaction();
- tx.delistResource(exores.getXAResource(), XAResource.TMNOFLAGS);
- }
-
- public Xid createXid()
- {
- // Convenient method used by JCR tests to manufacture an xid
- // it should be removed
- //
- throw new UnsupportedOperationException("Only used by JCR impl in tests");
- }
}
Modified: kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/impl/jotm/ResourceEntry.java
===================================================================
--- kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/impl/jotm/ResourceEntry.java 2011-05-20 14:38:19 UTC (rev 4400)
+++ kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/impl/jotm/ResourceEntry.java 2011-05-23 06:57:15 UTC (rev 4401)
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2009 eXo Platform SAS.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.exoplatform.services.transaction.impl.jotm;
-
-import org.exoplatform.services.transaction.ExoResource;
-import org.objectweb.transaction.jta.ResourceManagerEvent;
-
-import java.util.List;
-
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-import javax.transaction.xa.XAException;
-
-/**
- * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
- * @version $Revision$
- */
-public class ResourceEntry implements ResourceManagerEvent
-{
-
- List<?> jotmResourceList;
-
- final ExoResource resource;
-
- public ResourceEntry(ExoResource resource)
- {
- this.resource = resource;
- }
-
- public void enlistConnection(Transaction transaction) throws SystemException
- {
- try
- {
- /*
- if (LOG.isDebugEnabled())
- LOG.debug("Enlist connection. Session: " + getSessionInfo() + ", " + this
- + ", transaction: " + transaction);
- */
- resource.enlistResource();
- }
- catch (IllegalStateException e)
- {
- throw new SystemException(e.getMessage());
- }
- catch (XAException e)
- {
- throw new SystemException(e.getMessage());
- }
- }
-}
Modified: kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/impl/jotm/TransactionServiceJotmImpl.java
===================================================================
--- kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/impl/jotm/TransactionServiceJotmImpl.java 2011-05-20 14:38:19 UTC (rev 4400)
+++ kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/transaction/impl/jotm/TransactionServiceJotmImpl.java 2011-05-23 06:57:15 UTC (rev 4401)
@@ -23,25 +23,17 @@
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.naming.InitialContextInitializer;
-import org.exoplatform.services.transaction.ExoResource;
-import org.exoplatform.services.transaction.TransactionService;
+import org.exoplatform.services.transaction.impl.AbstractTransactionService;
import org.objectweb.jotm.Current;
import org.objectweb.jotm.TransactionFactory;
import org.objectweb.jotm.TransactionFactoryImpl;
-import org.objectweb.jotm.XidImpl;
import java.rmi.RemoteException;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
-import java.util.List;
-import javax.transaction.RollbackException;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import javax.transaction.UserTransaction;
-import javax.transaction.xa.XAResource;
-import javax.transaction.xa.Xid;
/**
* Created by The eXo Platform SAS.<br/> JOTM based implementation of
@@ -51,31 +43,47 @@
* Azarenkov</a>
* @version $Id: $
*/
-public class TransactionServiceJotmImpl implements TransactionService
+public class TransactionServiceJotmImpl extends AbstractTransactionService
{
protected static Log log = ExoLogger.getLogger("exo.kernel.component.common.TransactionServiceJotmImpl");
- public static final String TRACK_WITHOT_TRANSACTION_PARAM = "track-without-transaction";
+ private final int defaultTimeout;
+
+ /**
+ * Default constructor
+ * @param initializer we enforce a dependency with the InitialContextInitializer to
+ * ensure that the related binded resources have been defined
+ * @param params the init parameters
+ */
+ public TransactionServiceJotmImpl(InitialContextInitializer initializer, InitParams params)
+ {
+ if (params != null && params.getValueParam("timeout") != null)
+ {
+ this.defaultTimeout = Integer.parseInt(params.getValueParam("timeout").getValue());
+ }
+ else
+ {
+ this.defaultTimeout = -1;
+ }
+ }
- private boolean trackWithoutTransaction = false;
-
- private Current current;
-
- public TransactionServiceJotmImpl(InitialContextInitializer initializer, InitParams params) throws RemoteException
+ /**
+ * {@inheritDoc}
+ */
+ public TransactionManager findTransactionManager() throws Exception
{
- current = Current.getCurrent();
+ Current current = Current.getCurrent();
if (current == null)
{
try
{
- SecurityHelper.doPrivilegedExceptionAction(new PrivilegedExceptionAction<Void>()
+ current = SecurityHelper.doPrivilegedExceptionAction(new PrivilegedExceptionAction<Current>()
{
- public Void run() throws Exception
+ public Current run() throws Exception
{
TransactionFactory tm = new TransactionFactoryImpl();
- current = new Current(tm);
- return null;
+ return new Current(tm);
}
});
}
@@ -96,144 +104,33 @@
}
}
-
// Change the timeout only if JOTM is not initialized yet
- if (params != null)
+ if (defaultTimeout > 0)
{
- if (params.getValueParam("timeout") != null)
- {
-
- int t = Integer.parseInt(params.getValueParam("timeout").getValue());
- current.setDefaultTimeout(t);
- }
-
- if (params.getValueParam(TRACK_WITHOT_TRANSACTION_PARAM) != null)
- {
- trackWithoutTransaction =
- Boolean.parseBoolean(params.getValueParam(TRACK_WITHOT_TRANSACTION_PARAM).getValue());
- }
+ current.setDefaultTimeout(defaultTimeout);
}
}
else
{
log.info("Use externally initialized JOTM: " + current);
}
- }
-
- /**
- * {@inheritDoc}
- */
- public TransactionManager getTransactionManager()
- {
return current;
}
/**
* {@inheritDoc}
*/
- public UserTransaction getUserTransaction()
+ public UserTransaction findUserTransaction()
{
- return current;
+ return (UserTransaction)getTransactionManager();
}
/**
* {@inheritDoc}
*/
- public void enlistResource(ExoResource exores) throws RollbackException, SystemException
- {
- XAResource xares = exores.getXAResource();
- ResourceEntry entry = new ResourceEntry(exores);
- exores.setPayload(entry);
- Transaction tx = getTransactionManager().getTransaction();
- if (tx != null)
- {
- current.getTransaction().enlistResource(xares);
- }
- else if (trackWithoutTransaction)
- {
- current.connectionOpened(entry);
-
- // actual only if current.connectionOpened(entry);
- // otherwise NPE inside the JOTM's Current
- entry.jotmResourceList = popThreadLocalRMEventList();
- pushThreadLocalRMEventList(entry.jotmResourceList);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void delistResource(ExoResource exores) throws RollbackException, SystemException
- {
- XAResource xares = exores.getXAResource();
- ResourceEntry entry = (ResourceEntry)exores.getPayload();
- Transaction tx = getTransactionManager().getTransaction();
- if (tx != null)
- {
- current.getTransaction().delistResource(xares, XAResource.TMNOFLAGS);
- }
- else if (trackWithoutTransaction)
- {
- current.connectionClosed(entry);
-
- // actual only if current.connectionClosed(entry);
- if (entry != null && entry.jotmResourceList != null)
- {
- entry.jotmResourceList.remove(xares);
- }
- }
-
- exores.setPayload(null);
- }
-
- /**
- * {@inheritDoc}
- */
- public Xid createXid()
- {
- return new XidImpl();
- }
-
- /**
- * {@inheritDoc}
- */
+ @Override
public int getDefaultTimeout()
{
- return current.getDefaultTimeout();
+ return ((Current)getTransactionManager()).getDefaultTimeout();
}
-
- /**
- * {@inheritDoc}
- */
- public void setTransactionTimeout(int seconds) throws SystemException
- {
- current.setTransactionTimeout(seconds);
- }
-
- /**
- * Push a new event list on the stack of thread local resource event sets. The
- * list must contain only <code>ResourceManagerEvent</code> objects.
- *
- * @param eventList the possibly null list of events to store forecoming
- * <code>ResourceManagerEvent</code> events occuring in the current
- * thread.
- */
- public void pushThreadLocalRMEventList(List eventList)
- {
- current.pushThreadLocalRMEventList(eventList);
- };
-
- /**
- * Pop the current set from the stack of thread local resource event sets The
- * list contains <code>ResourceManagerEvent</code> objects.
- *
- * @return The possibly null <code>ResourceManagerEvent</code> list of events
- * that have occured in the current thread since the last call of
- * <code>pushThreadLocalRMEventList</code> or since the thread
- * started.
- */
- public List popThreadLocalRMEventList()
- {
- return current.popThreadLocalRMEventList();
- };
}
Modified: kernel/trunk/exo.kernel.component.common/src/main/resources/conf/portal/configuration.xml
===================================================================
--- kernel/trunk/exo.kernel.component.common/src/main/resources/conf/portal/configuration.xml 2011-05-20 14:38:19 UTC (rev 4400)
+++ kernel/trunk/exo.kernel.component.common/src/main/resources/conf/portal/configuration.xml 2011-05-23 06:57:15 UTC (rev 4401)
@@ -43,7 +43,39 @@
</properties-param>
</init-params>
</component>
-
+
+ <component>
+ <key>org.exoplatform.services.jdbc.DataSourceProvider</key>
+ <type>org.exoplatform.services.jdbc.impl.DataSourceProviderImpl</type>
+ <init-params>
+ <!-- Indicates that the data source needs to check if a tx is active
+ to decide if the provided connection needs to be managed or not.
+ If it is set to false, the data source will provide only
+ managed connections if the data source itself is managed. -->
+ <!--value-param>
+ <name>check-tx-active</name>
+ <value>true</value>
+ </value-param-->
+ <!-- Indicates that all the data sources are managed
+ If set to true the parameter never-managed and
+ managed-data-sources will be ignored -->
+ <!--value-param>
+ <name>always-managed</name>
+ <value>true</value>
+ </value-param-->
+ <!-- Indicates the list of all the data sources that are
+ managed, each value tag can contain a list of
+ data source names separated by a comma, in the
+ example below we will register ds-foo1, ds-foo2
+ and ds-foo3 as managed data source. If always-managed
+ and/or never-managed is set true this parameter is ignored -->
+ <!--values-param>
+ <name>managed-data-sources</name>
+ <value>ds-foo1, ds-foo2</value>
+ <value>ds-foo3</value>
+ </values-param-->
+ </init-params>
+ </component>
<!-- component>
<key>org.exoplatform.services.net.NetService</key>
<type>org.exoplatform.services.net.impl.NetServiceImpl</type>
Added: kernel/trunk/exo.kernel.component.common/src/test/java/org/exoplatform/services/jdbc/impl/TestDataSourceProviderImpl.java
===================================================================
--- kernel/trunk/exo.kernel.component.common/src/test/java/org/exoplatform/services/jdbc/impl/TestDataSourceProviderImpl.java (rev 0)
+++ kernel/trunk/exo.kernel.component.common/src/test/java/org/exoplatform/services/jdbc/impl/TestDataSourceProviderImpl.java 2011-05-23 06:57:15 UTC (rev 4401)
@@ -0,0 +1,809 @@
+/*
+ * 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.jdbc.impl;
+
+import org.exoplatform.container.xml.InitParams;
+import org.exoplatform.container.xml.ValueParam;
+import org.exoplatform.container.xml.ValuesParam;
+import org.exoplatform.services.jdbc.DataSourceProvider;
+import org.exoplatform.services.transaction.TransactionService;
+import org.exoplatform.test.BasicTestCase;
+
+import java.io.PrintWriter;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.CallableStatement;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.NClob;
+import java.sql.PreparedStatement;
+import java.sql.SQLClientInfoException;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.SQLXML;
+import java.sql.Savepoint;
+import java.sql.Statement;
+import java.sql.Struct;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.sql.DataSource;
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.InvalidTransactionException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import javax.transaction.UserTransaction;
+import javax.transaction.xa.XAResource;
+
+/**
+ * @author <a href="mailto:nfilotto@exoplatform.com">Nicolas Filotto</a>
+ * @version $Id$
+ *
+ */
+public class TestDataSourceProviderImpl extends BasicTestCase
+{
+ private static String DS_NAME = "TestDataSourceProviderImpl-DS";
+
+ private String oldFactoryName;
+
+ private MyDataSource mds;
+
+ /**
+ * @see junit.framework.TestCase#setUp()
+ */
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ oldFactoryName = System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.exoplatform.services.naming.SimpleContextFactory");
+ new InitialContext().bind(DS_NAME, mds = new MyDataSource());
+ }
+
+ /**
+ * @see junit.framework.TestCase#tearDown()
+ */
+ @Override
+ protected void tearDown() throws Exception
+ {
+ try
+ {
+ new InitialContext().unbind(DS_NAME);
+ }
+ finally
+ {
+ if (oldFactoryName == null)
+ {
+ System.clearProperty(Context.INITIAL_CONTEXT_FACTORY);
+ }
+ else
+ {
+ System.setProperty(Context.INITIAL_CONTEXT_FACTORY, oldFactoryName);
+ }
+ super.tearDown();
+ }
+ }
+
+ public void testIsManaged() throws Exception
+ {
+ DataSourceProvider dsp = new DataSourceProviderImpl(null);
+ assertFalse(dsp.isManaged(DS_NAME));
+
+ InitParams params = new InitParams();
+ dsp = new DataSourceProviderImpl(params);
+ assertFalse(dsp.isManaged(DS_NAME));
+
+ ValueParam paramConf = new ValueParam();
+ paramConf.setName(DataSourceProviderImpl.PARAM_ALWAYS_MANAGED);
+ paramConf.setValue("true");
+ params.addParameter(paramConf);
+ dsp = new DataSourceProviderImpl(params);
+ assertTrue(dsp.isManaged(DS_NAME));
+
+ paramConf.setValue("false");
+ dsp = new DataSourceProviderImpl(params);
+ assertFalse(dsp.isManaged(DS_NAME));
+
+ ValuesParam paramsConf = new ValuesParam();
+ paramsConf.setName(DataSourceProviderImpl.PARAM_MANAGED_DS);
+ ArrayList<String> values = new ArrayList<String>();
+ values.add(DS_NAME);
+ values.add(" ds-foo1, ds-foo2 ");
+ values.add("ds-foo3");
+ paramsConf.setValues(values);
+ params.addParameter(paramsConf);
+ dsp = new DataSourceProviderImpl(params);
+ assertTrue(dsp.isManaged(DS_NAME));
+ assertTrue(dsp.isManaged("ds-foo1"));
+ assertTrue(dsp.isManaged("ds-foo2"));
+ assertTrue(dsp.isManaged("ds-foo3"));
+ }
+
+ public void testGetDataSource() throws Exception
+ {
+ DataSourceProvider dsp = new DataSourceProviderImpl(null);
+ DataSource ds = dsp.getDataSource(DS_NAME);
+ assertNotNull(ds);
+ Connection con = ds.getConnection();
+ con.commit();
+ assertTrue(mds.con.committed);
+ con = ds.getConnection(null, null);
+ con.commit();
+ assertTrue(mds.con.committed);
+
+ MyTransactionService mts = new MyTransactionService();
+ mts.tm.setStatus(Status.STATUS_ACTIVE);
+ dsp = new DataSourceProviderImpl(null, mts);
+ ds = dsp.getDataSource(DS_NAME);
+ assertNotNull(ds);
+ con = ds.getConnection();
+ con.commit();
+ assertTrue(mds.con.committed);
+ con = ds.getConnection(null, null);
+ con.commit();
+ assertTrue(mds.con.committed);
+ mts.tm.setStatus(Status.STATUS_NO_TRANSACTION);
+ con = ds.getConnection();
+ con.commit();
+ assertTrue(mds.con.committed);
+ con = ds.getConnection(null, null);
+ con.commit();
+ assertTrue(mds.con.committed);
+
+ InitParams params = new InitParams();
+ ValueParam paramConf = new ValueParam();
+ paramConf.setName(DataSourceProviderImpl.PARAM_ALWAYS_MANAGED);
+ paramConf.setValue("true");
+ params.addParameter(paramConf);
+ dsp = new DataSourceProviderImpl(params, mts);
+ ds = dsp.getDataSource(DS_NAME);
+ assertNotNull(ds);
+ mts.tm.setStatus(Status.STATUS_ACTIVE);
+ con = ds.getConnection();
+ con.commit();
+ assertFalse(mds.con.committed);
+ con = ds.getConnection(null, null);
+ con.commit();
+ assertFalse(mds.con.committed);
+ mts.tm.setStatus(Status.STATUS_NO_TRANSACTION);
+ con = ds.getConnection();
+ con.commit();
+ assertTrue(mds.con.committed);
+ con = ds.getConnection(null, null);
+ con.commit();
+ assertTrue(mds.con.committed);
+
+ paramConf = new ValueParam();
+ paramConf.setName(DataSourceProviderImpl.PARAM_CHECK_TX);
+ paramConf.setValue("false");
+ params.addParameter(paramConf);
+ dsp = new DataSourceProviderImpl(params, mts);
+ ds = dsp.getDataSource(DS_NAME);
+ assertNotNull(ds);
+ mts.tm.setStatus(Status.STATUS_ACTIVE);
+ con = ds.getConnection();
+ con.commit();
+ assertFalse(mds.con.committed);
+ con = ds.getConnection(null, null);
+ con.commit();
+ assertFalse(mds.con.committed);
+ mts.tm.setStatus(Status.STATUS_NO_TRANSACTION);
+ con = ds.getConnection();
+ con.commit();
+ assertFalse(mds.con.committed);
+ con = ds.getConnection(null, null);
+ con.commit();
+ assertFalse(mds.con.committed);
+ }
+
+ private static class MyDataSource implements DataSource
+ {
+ public MyConnection con;
+
+ /**
+ * @see javax.sql.CommonDataSource#getLogWriter()
+ */
+ public PrintWriter getLogWriter() throws SQLException
+ {
+ return null;
+ }
+
+ /**
+ * @see javax.sql.CommonDataSource#getLoginTimeout()
+ */
+ public int getLoginTimeout() throws SQLException
+ {
+ return 0;
+ }
+
+ /**
+ * @see javax.sql.CommonDataSource#setLogWriter(java.io.PrintWriter)
+ */
+ public void setLogWriter(PrintWriter arg0) throws SQLException
+ {
+ }
+
+ /**
+ * @see javax.sql.CommonDataSource#setLoginTimeout(int)
+ */
+ public void setLoginTimeout(int arg0) throws SQLException
+ {
+ }
+
+ /**
+ * @see java.sql.Wrapper#isWrapperFor(java.lang.Class)
+ */
+ public boolean isWrapperFor(Class<?> arg0) throws SQLException
+ {
+ return false;
+ }
+
+ /**
+ * @see java.sql.Wrapper#unwrap(java.lang.Class)
+ */
+ public <T> T unwrap(Class<T> arg0) throws SQLException
+ {
+ return null;
+ }
+
+ /**
+ * @see javax.sql.DataSource#getConnection()
+ */
+ public Connection getConnection() throws SQLException
+ {
+ return con = new MyConnection();
+ }
+
+ /**
+ * @see javax.sql.DataSource#getConnection(java.lang.String, java.lang.String)
+ */
+ public Connection getConnection(String username, String password) throws SQLException
+ {
+ return con = new MyConnection();
+ }
+ }
+
+ private static class MyConnection implements Connection
+ {
+
+ public boolean committed;
+
+ /**
+ * @see java.sql.Wrapper#isWrapperFor(java.lang.Class)
+ */
+ public boolean isWrapperFor(Class<?> iface) throws SQLException
+ {
+ return false;
+ }
+
+ /**
+ * @see java.sql.Wrapper#unwrap(java.lang.Class)
+ */
+ public <T> T unwrap(Class<T> iface) throws SQLException
+ {
+ return null;
+ }
+
+ /**
+ * @see java.sql.Connection#prepareStatement(java.lang.String)
+ */
+ public PreparedStatement prepareStatement(String sql) throws SQLException
+ {
+ return null;
+ }
+
+ /**
+ * @see java.sql.Connection#prepareCall(java.lang.String)
+ */
+ public CallableStatement prepareCall(String sql) throws SQLException
+ {
+ return null;
+ }
+
+ /**
+ * @see java.sql.Connection#nativeSQL(java.lang.String)
+ */
+ public String nativeSQL(String sql) throws SQLException
+ {
+ return null;
+ }
+
+ /**
+ * @see java.sql.Connection#setAutoCommit(boolean)
+ */
+ public void setAutoCommit(boolean autoCommit) throws SQLException
+ {
+ }
+
+ /**
+ * @see java.sql.Connection#commit()
+ */
+ public void commit() throws SQLException
+ {
+ committed = true;
+ }
+
+ /**
+ * @see java.sql.Connection#rollback()
+ */
+ public void rollback() throws SQLException
+ {
+ }
+
+ /**
+ * @see java.sql.Connection#close()
+ */
+ public void close() throws SQLException
+ {
+ }
+
+ /**
+ * @see java.sql.Connection#setReadOnly(boolean)
+ */
+ public void setReadOnly(boolean readOnly) throws SQLException
+ {
+ }
+
+ /**
+ * @see java.sql.Connection#setCatalog(java.lang.String)
+ */
+ public void setCatalog(String catalog) throws SQLException
+ {
+ }
+
+ /**
+ * @see java.sql.Connection#setTransactionIsolation(int)
+ */
+ public void setTransactionIsolation(int level) throws SQLException
+ {
+ }
+
+ /**
+ * @see java.sql.Connection#clearWarnings()
+ */
+ public void clearWarnings() throws SQLException
+ {
+ }
+
+ /**
+ * @see java.sql.Connection#createArrayOf(java.lang.String, java.lang.Object[])
+ */
+ public Array createArrayOf(String arg0, Object[] arg1) throws SQLException
+ {
+ return null;
+ }
+
+ /**
+ * @see java.sql.Connection#createBlob()
+ */
+ public Blob createBlob() throws SQLException
+ {
+ return null;
+ }
+
+ /**
+ * @see java.sql.Connection#createClob()
+ */
+ public Clob createClob() throws SQLException
+ {
+ return null;
+ }
+
+ /**
+ * @see java.sql.Connection#createNClob()
+ */
+ public NClob createNClob() throws SQLException
+ {
+ return null;
+ }
+
+ /**
+ * @see java.sql.Connection#createSQLXML()
+ */
+ public SQLXML createSQLXML() throws SQLException
+ {
+ return null;
+ }
+
+ /**
+ * @see java.sql.Connection#createStatement()
+ */
+ public Statement createStatement() throws SQLException
+ {
+ return null;
+ }
+
+ /**
+ * @see java.sql.Connection#createStatement(int, int)
+ */
+ public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException
+ {
+ return null;
+ }
+
+ /**
+ * @see java.sql.Connection#prepareStatement(java.lang.String, int, int)
+ */
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)
+ throws SQLException
+ {
+ return null;
+ }
+
+ /**
+ * @see java.sql.Connection#prepareCall(java.lang.String, int, int)
+ */
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException
+ {
+ return null;
+ }
+
+ /**
+ * @see java.sql.Connection#setTypeMap(java.util.Map)
+ */
+ public void setTypeMap(Map<String, Class<?>> map) throws SQLException
+ {
+ }
+
+ /**
+ * @see java.sql.Connection#setSavepoint()
+ */
+ public Savepoint setSavepoint() throws SQLException
+ {
+ return null;
+ }
+
+ /**
+ * @see java.sql.Connection#setSavepoint(java.lang.String)
+ */
+ public Savepoint setSavepoint(String name) throws SQLException
+ {
+ return null;
+ }
+
+ /**
+ * @see java.sql.Connection#rollback(java.sql.Savepoint)
+ */
+ public void rollback(Savepoint savepoint) throws SQLException
+ {
+ }
+
+ /**
+ * @see java.sql.Connection#releaseSavepoint(java.sql.Savepoint)
+ */
+ public void releaseSavepoint(Savepoint savepoint) throws SQLException
+ {
+ }
+
+ /**
+ * @see java.sql.Connection#createStatement(int, int, int)
+ */
+ public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
+ throws SQLException
+ {
+ return null;
+ }
+
+ /**
+ * @see java.sql.Connection#createStruct(java.lang.String, java.lang.Object[])
+ */
+ public Struct createStruct(String arg0, Object[] arg1) throws SQLException
+ {
+ return null;
+ }
+
+ /**
+ * @see java.sql.Connection#getAutoCommit()
+ */
+ public boolean getAutoCommit() throws SQLException
+ {
+ return false;
+ }
+
+ /**
+ * @see java.sql.Connection#isClosed()
+ */
+ public boolean isClosed() throws SQLException
+ {
+ return false;
+ }
+
+ /**
+ * @see java.sql.Connection#isReadOnly()
+ */
+ public boolean isReadOnly() throws SQLException
+ {
+ return false;
+ }
+
+ /**
+ * @see java.sql.Connection#getCatalog()
+ */
+ public String getCatalog() throws SQLException
+ {
+ return null;
+ }
+
+ /**
+ * @see java.sql.Connection#getClientInfo()
+ */
+ public Properties getClientInfo() throws SQLException
+ {
+ return null;
+ }
+
+ /**
+ * @see java.sql.Connection#getClientInfo(java.lang.String)
+ */
+ public String getClientInfo(String arg0) throws SQLException
+ {
+ return null;
+ }
+
+ /**
+ * @see java.sql.Connection#getMetaData()
+ */
+ public DatabaseMetaData getMetaData() throws SQLException
+ {
+ return null;
+ }
+
+ /**
+ * @see java.sql.Connection#getTransactionIsolation()
+ */
+ public int getTransactionIsolation() throws SQLException
+ {
+ return 0;
+ }
+
+ /**
+ * @see java.sql.Connection#getWarnings()
+ */
+ public SQLWarning getWarnings() throws SQLException
+ {
+ return null;
+ }
+
+ /**
+ * @see java.sql.Connection#getTypeMap()
+ */
+ public Map<String, Class<?>> getTypeMap() throws SQLException
+ {
+ return null;
+ }
+
+ /**
+ * @see java.sql.Connection#getHoldability()
+ */
+ public int getHoldability() throws SQLException
+ {
+ return 0;
+ }
+
+ /**
+ * @see java.sql.Connection#isValid(int)
+ */
+ public boolean isValid(int arg0) throws SQLException
+ {
+ return false;
+ }
+
+ /**
+ * @see java.sql.Connection#prepareStatement(java.lang.String, int, int, int)
+ */
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency,
+ int resultSetHoldability) throws SQLException
+ {
+ return null;
+ }
+
+ /**
+ * @see java.sql.Connection#prepareCall(java.lang.String, int, int, int)
+ */
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency,
+ int resultSetHoldability) throws SQLException
+ {
+ return null;
+ }
+
+ /**
+ * @see java.sql.Connection#prepareStatement(java.lang.String, int)
+ */
+ public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException
+ {
+ return null;
+ }
+
+ /**
+ * @see java.sql.Connection#prepareStatement(java.lang.String, int[])
+ */
+ public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException
+ {
+ return null;
+ }
+
+ /**
+ * @see java.sql.Connection#prepareStatement(java.lang.String, java.lang.String[])
+ */
+ public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException
+ {
+ return null;
+ }
+
+ /**
+ * @see java.sql.Connection#setClientInfo(java.util.Properties)
+ */
+ public void setClientInfo(Properties arg0) throws SQLClientInfoException
+ {
+ }
+
+ /**
+ * @see java.sql.Connection#setClientInfo(java.lang.String, java.lang.String)
+ */
+ public void setClientInfo(String arg0, String arg1) throws SQLClientInfoException
+ {
+ }
+
+ /**
+ * @see java.sql.Connection#setHoldability(int)
+ */
+ public void setHoldability(int holdability) throws SQLException
+ {
+ }
+ }
+
+ private static class MyTransactionService implements TransactionService
+ {
+ public MyTransactionManager tm = new MyTransactionManager();
+
+ /**
+ * @see org.exoplatform.services.transaction.TransactionService#getTransactionManager()
+ */
+ public TransactionManager getTransactionManager()
+ {
+ return tm;
+ }
+
+ /**
+ * @see org.exoplatform.services.transaction.TransactionService#getUserTransaction()
+ */
+ public UserTransaction getUserTransaction()
+ {
+ return null;
+ }
+
+ /**
+ * @see org.exoplatform.services.transaction.TransactionService#getDefaultTimeout()
+ */
+ public int getDefaultTimeout()
+ {
+ return 0;
+ }
+
+ /**
+ * @see org.exoplatform.services.transaction.TransactionService#setTransactionTimeout(int)
+ */
+ public void setTransactionTimeout(int seconds) throws SystemException
+ {
+ }
+
+ /**
+ * @see org.exoplatform.services.transaction.TransactionService#enlistResource(javax.transaction.xa.XAResource)
+ */
+ public boolean enlistResource(XAResource xares) throws RollbackException, SystemException, IllegalStateException
+ {
+ return false;
+ }
+
+ /**
+ * @see org.exoplatform.services.transaction.TransactionService#delistResource(javax.transaction.xa.XAResource)
+ */
+ public boolean delistResource(XAResource xares) throws RollbackException, SystemException, IllegalStateException
+ {
+ return false;
+ }
+ }
+
+ private static class MyTransactionManager implements TransactionManager
+ {
+
+ private int status;
+
+ public void setStatus(int status)
+ {
+ this.status = status;
+ }
+
+ /**
+ * @see javax.transaction.TransactionManager#begin()
+ */
+ public void begin() throws NotSupportedException, SystemException
+ {
+ }
+
+ /**
+ * @see javax.transaction.TransactionManager#commit()
+ */
+ public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException,
+ SecurityException, IllegalStateException, SystemException
+ {
+ }
+
+ /**
+ * @see javax.transaction.TransactionManager#getStatus()
+ */
+ public int getStatus() throws SystemException
+ {
+ return status;
+ }
+
+ /**
+ * @see javax.transaction.TransactionManager#getTransaction()
+ */
+ public Transaction getTransaction() throws SystemException
+ {
+ return null;
+ }
+
+ /**
+ * @see javax.transaction.TransactionManager#resume(javax.transaction.Transaction)
+ */
+ public void resume(Transaction tobj) throws InvalidTransactionException, IllegalStateException, SystemException
+ {
+ }
+
+ /**
+ * @see javax.transaction.TransactionManager#rollback()
+ */
+ public void rollback() throws IllegalStateException, SecurityException, SystemException
+ {
+ }
+
+ /**
+ * @see javax.transaction.TransactionManager#setRollbackOnly()
+ */
+ public void setRollbackOnly() throws IllegalStateException, SystemException
+ {
+ }
+
+ /**
+ * @see javax.transaction.TransactionManager#setTransactionTimeout(int)
+ */
+ public void setTransactionTimeout(int seconds) throws SystemException
+ {
+ }
+
+ /**
+ * @see javax.transaction.TransactionManager#suspend()
+ */
+ public Transaction suspend() throws SystemException
+ {
+ return null;
+ }
+
+ }
+}
Modified: kernel/trunk/exo.kernel.component.common/src/test/java/org/exoplatform/services/transaction/TransactionTest.java
===================================================================
--- kernel/trunk/exo.kernel.component.common/src/test/java/org/exoplatform/services/transaction/TransactionTest.java 2011-05-20 14:38:19 UTC (rev 4400)
+++ kernel/trunk/exo.kernel.component.common/src/test/java/org/exoplatform/services/transaction/TransactionTest.java 2011-05-23 06:57:15 UTC (rev 4401)
@@ -21,14 +21,11 @@
import junit.framework.TestCase;
import org.exoplatform.container.StandaloneContainer;
-import org.exoplatform.services.log.ExoLogger;
-import org.exoplatform.services.log.Log;
-import org.objectweb.jotm.Current;
import javax.naming.InitialContext;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
import javax.transaction.UserTransaction;
-import javax.transaction.xa.XAResource;
-import javax.transaction.xa.Xid;
/**
* Created by The eXo Platform SAS .<br/> Prerequisites: default-context-factory
@@ -40,8 +37,6 @@
public class TransactionTest extends TestCase
{
- private static Log log = ExoLogger.getLogger("exo.kernel.component.common.TransactionTest");
-
private StandaloneContainer container;
private TransactionService ts;
@@ -49,12 +44,11 @@
public void setUp() throws Exception
{
- StandaloneContainer.setConfigurationPath("src/test/java/conf/standalone/test-configuration.xml");
+ StandaloneContainer.setConfigurationPath("src/test/resources/conf/standalone/test-configuration.xml");
container = StandaloneContainer.getInstance();
ts = (TransactionService)container.getComponentInstanceOfType(TransactionService.class);
-
}
public void testUserTransactionBeforeResource() throws Exception
@@ -63,63 +57,67 @@
UserTransaction ut = ts.getUserTransaction();
ut.begin();
- Current c = (Current)ut;
- // System.out.printf(">>>>>>>>>>>"+c.getAllTx()[0]);
- // c.getAllXid();
- // System.out.printf(">>>>>>>>>>>"+c.getAllXid());
- // fail();
-
- // c.getTransactionManager().
-
XAResourceTestImpl xares = new XAResourceTestImpl(ts);
ts.enlistResource(xares);
xares.setFlag(5);
assertEquals(0, xares.getOldFlag());
+ ts.delistResource(xares);
ut.commit();
assertEquals(5, xares.getFlag());
assertEquals(5, xares.getOldFlag());
-
- ts.delistResource(xares);
-
}
public void testUserTransactionAfterResource() throws Exception
{
XAResourceTestImpl xares = new XAResourceTestImpl(ts);
- ts.enlistResource(xares);
+ try
+ {
+ ts.enlistResource(xares);
+ fail("IllegalStateException is expected since it cannot be enlisted without an active tx");
+ }
+ catch (IllegalStateException e)
+ {
+ // OK
+ }
assertEquals(0, xares.getFlag());
UserTransaction ut = ts.getUserTransaction();
-
ut.begin();
+ ts.enlistResource(xares);
xares.setFlag(5);
assertEquals(0, xares.getOldFlag());
ut.commit();
assertEquals(5, xares.getFlag());
assertEquals(5, xares.getOldFlag());
- ts.delistResource(xares);
+ try
+ {
+ ts.delistResource(xares);
+ fail("IllegalStateException is expected since it cannot be delisted without an active tx");
+ }
+ catch (IllegalStateException e)
+ {
+ // OK
+ }
}
public void testUserTransactionRollback() throws Exception
{
-
XAResourceTestImpl xares = new XAResourceTestImpl(ts);
- ts.enlistResource(xares);
-
assertEquals(0, xares.getFlag());
UserTransaction ut = ts.getUserTransaction();
ut.begin();
+ ts.enlistResource(xares);
xares.setFlag(5);
assertEquals(5, xares.getFlag());
+ ts.delistResource(xares);
ut.rollback();
assertEquals(0, xares.getFlag());
assertEquals(0, xares.getOldFlag());
- ts.delistResource(xares);
}
public void testUserTransactionFromJndi() throws Exception
@@ -136,13 +134,10 @@
assertEquals(0, xares.getFlag());
xares.setFlag(5);
- // assertEquals(5, xares.getFlag());
+ ts.delistResource(xares);
ut.commit();
assertEquals(5, xares.getFlag());
assertEquals(5, xares.getOldFlag());
-
- ts.delistResource(xares);
-
}
public void testReuseUT() throws Exception
@@ -153,8 +148,7 @@
UserTransaction ut = (UserTransaction)obj;
ut.begin();
- XAResourceTestImpl xares = new XAResourceTestImpl(ts); //(XAResourceTestImpl)f
- // .createResoure();
+ XAResourceTestImpl xares = new XAResourceTestImpl(ts);
ts.enlistResource(xares);
xares.setFlag(5);
@@ -162,60 +156,52 @@
assertEquals(5, xares.getFlag());
assertEquals(5, xares.getOldFlag());
+ ut.begin();
// In a case of reusing Have to enlist the resource once again!
ts.enlistResource(xares);
-
- ut.begin();
xares.setFlag(2);
+ ts.delistResource(xares);
ut.commit();
assertEquals(2, xares.getFlag());
assertEquals(2, xares.getOldFlag());
-
- ts.delistResource(xares);
-
}
- public void testGenerateXid() throws Exception
- {
- Xid id = ts.createXid();
- log.info("XID ==== " + id);
- assertNotNull(id);
- }
-
public void testSimpleGlobalTransaction() throws Exception
{
- Xid id = ts.createXid();
XAResourceTestImpl xares = new XAResourceTestImpl(ts);
- xares.start(id, XAResource.TMNOFLAGS);
+ UserTransaction ut = ts.getUserTransaction();
+ ut.begin();
+ ts.enlistResource(xares);
assertEquals(0, xares.getFlag());
xares.setFlag(1);
- xares.commit(id, true);
+ ut.commit();
assertEquals(1, xares.getFlag());
assertEquals(1, xares.getOldFlag());
}
public void test2GlobalTransactions() throws Exception
{
- Xid id1 = ts.createXid();
XAResourceTestImpl xares = new XAResourceTestImpl(ts);
- xares.start(id1, XAResource.TMNOFLAGS);
+ TransactionManager tm = ts.getTransactionManager();
+ tm.begin();
+ ts.enlistResource(xares);
assertEquals(0, xares.getFlag());
xares.setFlag(1);
- xares.end(id1, XAResource.TMSUSPEND);
+ Transaction tx = tm.suspend();
assertEquals(1, xares.getFlag());
- Xid id2 = ts.createXid();
- xares.start(id2, XAResource.TMNOFLAGS);
+ tm.begin();
+ ts.enlistResource(xares);
xares.setFlag(2);
// End work
- xares.end(id2, XAResource.TMSUCCESS);
+ tm.commit();
// Resume work with former transaction
- xares.start(id1, XAResource.TMRESUME);
+ tm.resume(tx);
// Commit work recorded when associated with xid2
- xares.commit(id2, true);
+ tm.commit();
assertEquals(2, xares.getFlag());
assertEquals(2, xares.getOldFlag());
}
Modified: kernel/trunk/exo.kernel.component.common/src/test/java/org/exoplatform/services/transaction/XAResourceTestImpl.java
===================================================================
--- kernel/trunk/exo.kernel.component.common/src/test/java/org/exoplatform/services/transaction/XAResourceTestImpl.java 2011-05-20 14:38:19 UTC (rev 4400)
+++ kernel/trunk/exo.kernel.component.common/src/test/java/org/exoplatform/services/transaction/XAResourceTestImpl.java 2011-05-23 06:57:15 UTC (rev 4401)
@@ -21,9 +21,7 @@
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
-import javax.transaction.RollbackException;
import javax.transaction.Status;
-import javax.transaction.SystemException;
import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
@@ -36,39 +34,24 @@
* @version $Id: $
*/
-public class XAResourceTestImpl implements ExoResource, XAResource
+public class XAResourceTestImpl implements XAResource
{
private static Log log = ExoLogger.getLogger("exo.kernel.component.common.XAResourceTestImpl");
private int timeout = 5;
- // private transient TransactionService ts;
-
private int oldFlag;
private int flag = oldFlag = 0;
private final TransactionService ts;
- private Object payload;
-
public XAResourceTestImpl(TransactionService ts)
{
this.ts = ts;
}
- // public XAResourceTestImpl(TransactionService ts)
- // throws RollbackException, SystemException {
- // this.ts = ts;
- // ts.enlistResource(this);
- // }
-
- public XAResource getXAResource()
- {
- return this;
- }
-
public void commit(Xid arg0, boolean arg1) throws XAException
{
oldFlag = flag;
@@ -134,45 +117,8 @@
this.flag = flag;
}
- public void enlistResource() throws XAException
- {
- try
- {
- ts.enlistResource(this);
- }
- catch (IllegalStateException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- catch (RollbackException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- catch (SystemException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
-
- public void delistResource() throws XAException
- {
- }
-
public int getOldFlag()
{
return oldFlag;
}
-
- public Object getPayload()
- {
- return payload;
- }
-
- public void setPayload(Object payload)
- {
- this.payload = payload;
- }
}
Modified: kernel/trunk/exo.kernel.component.common/src/test/java/org/exoplatform/services/transaction/jcr/TestXASessionIntegration.java
===================================================================
--- kernel/trunk/exo.kernel.component.common/src/test/java/org/exoplatform/services/transaction/jcr/TestXASessionIntegration.java 2011-05-20 14:38:19 UTC (rev 4400)
+++ kernel/trunk/exo.kernel.component.common/src/test/java/org/exoplatform/services/transaction/jcr/TestXASessionIntegration.java 2011-05-23 06:57:15 UTC (rev 4401)
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2009 eXo Platform SAS.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.exoplatform.services.transaction.jcr;
-
-import junit.framework.TestCase;
-
-import org.exoplatform.services.transaction.TransactionService;
-import org.exoplatform.services.transaction.impl.jotm.TransactionServiceJotmImpl;
-
-/**
- * Integration test between the behavior of an XASession implementing the ExoResource interface
- * and the JOTM implementation.
- *
- * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
- * @version $Revision$
- */
-public class TestXASessionIntegration extends TestCase
-{
-
- /** . */
- private TransactionService txservice;
-
- @Override
- protected void setUp() throws Exception
- {
- txservice = new TransactionServiceJotmImpl(null, null);
- }
-
- public void testLoginLogout() throws Exception
- {
- XASession session = new XASession(txservice);
- txservice.enlistResource(session);
- txservice.delistResource(session);
- }
-
- public void testLogout() throws Exception
- {
- XASession session = new XASession(txservice);
- txservice.delistResource(session);
- }
-}
Modified: kernel/trunk/exo.kernel.component.common/src/test/java/org/exoplatform/services/transaction/jcr/XASession.java
===================================================================
--- kernel/trunk/exo.kernel.component.common/src/test/java/org/exoplatform/services/transaction/jcr/XASession.java 2011-05-20 14:38:19 UTC (rev 4400)
+++ kernel/trunk/exo.kernel.component.common/src/test/java/org/exoplatform/services/transaction/jcr/XASession.java 2011-05-23 06:57:15 UTC (rev 4401)
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2009 eXo Platform SAS.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.exoplatform.services.transaction.jcr;
-
-import org.exoplatform.services.transaction.ExoResource;
-import org.exoplatform.services.transaction.TransactionService;
-
-import javax.transaction.HeuristicMixedException;
-import javax.transaction.HeuristicRollbackException;
-import javax.transaction.RollbackException;
-import javax.transaction.SystemException;
-import javax.transaction.xa.XAException;
-import javax.transaction.xa.XAResource;
-import javax.transaction.xa.Xid;
-
-/**
- * Simulate an xa resource.
- *
- * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
- * @version $Revision$
- */
-public class XASession implements XAResource, ExoResource
-{
-
- /** Transaction service. */
- private final TransactionService tService;
-
- /** Start flags. */
- private int startFlags;
-
- /** . */
- private Object payload;
-
- /** . */
- private int txTimeout;
-
- public XASession(TransactionService tService)
- {
- this.tService = tService;
- this.txTimeout = tService.getDefaultTimeout();
- this.payload = null;
- this.startFlags = TMNOFLAGS;
- }
-
- // ExoResource implementation
-
- public XAResource getXAResource()
- {
- return this;
- }
-
- public void enlistResource() throws XAException
- {
- try
- {
- tService.enlistResource(this);
- }
- catch (RollbackException e)
- {
- throw new XAException(e.getMessage());
- }
- catch (SystemException e)
- {
- throw new XAException(e.getMessage());
- }
- }
-
- public void delistResource() throws XAException
- {
- try
- {
- tService.delistResource(this);
- }
- catch (RollbackException e)
- {
- throw new XAException(e.getMessage());
- }
- catch (SystemException e)
- {
- throw new XAException(e.getMessage());
- }
- }
-
- public Object getPayload()
- {
- return payload;
- }
-
- public void setPayload(Object payload)
- {
- this.payload = payload;
- }
-
- // XAResource implementation
-
- public void commit(Xid xid, boolean b) throws XAException
- {
- try
- {
- tService.getTransactionManager().commit();
- }
- catch (RollbackException e)
- {
- throw new XAException(XAException.XA_RBOTHER);
- }
- catch (HeuristicRollbackException e)
- {
- throw new XAException(XAException.XA_RBOTHER);
- }
- catch (HeuristicMixedException e)
- {
- throw new XAException(XAException.XA_RBOTHER);
- }
- catch (SystemException e)
- {
- throw new XAException(XAException.XA_RBOTHER);
- }
- }
-
- public void end(Xid xid, int flags) throws XAException
- {
- startFlags = flags;
- }
-
- public void forget(Xid xid) throws XAException
- {
- }
-
- public int getTransactionTimeout() throws XAException
- {
- return txTimeout;
- }
-
- public boolean isSameRM(XAResource resource) throws XAException
- {
- return resource == this;
- }
-
- public int prepare(Xid xid) throws XAException
- {
- return XA_OK;
- }
-
- public Xid[] recover(int i) throws XAException
- {
- return null;
- }
-
- public void rollback(Xid xid) throws XAException
- {
- }
-
- public void start(Xid xid, int flags) throws XAException
- {
- startFlags = flags;
- }
-
- public boolean setTransactionTimeout(int seconds) throws XAException
- {
- try
- {
- tService.setTransactionTimeout(seconds);
- }
- catch (SystemException e)
- {
- throw new XAException(e.getMessage());
- }
- this.txTimeout = seconds;
- return true;
- }
-}
Modified: kernel/trunk/exo.kernel.component.common/src/test/resources/conf/standalone/test-configuration.xml
===================================================================
--- kernel/trunk/exo.kernel.component.common/src/test/resources/conf/standalone/test-configuration.xml 2011-05-20 14:38:19 UTC (rev 4400)
+++ kernel/trunk/exo.kernel.component.common/src/test/resources/conf/standalone/test-configuration.xml 2011-05-23 06:57:15 UTC (rev 4401)
@@ -21,67 +21,7 @@
-->
<configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">
- <!--
- <component>
- <key>org.exoplatform.services.log.LogConfigurationInitializer</key>
- <type>org.exoplatform.services.log.LogConfigurationInitializer</type>
- <init-params>
- <value-param>
- <name>configurator</name>
- <value>org.exoplatform.services.log.impl.Log4JConfigurator</value>
- </value-param>
- <properties-param>
- <name>properties</name>
- <description>Log4J properties</description>
- <property name="log4j.rootLogger" value="INFO, stdout, file" />
- <property name="log4j.appender.stdout" value="org.apache.log4j.ConsoleAppender" />
-
- <property name="log4j.appender.stdout.layout" value="org.apache.log4j.PatternLayout" />
- <property name="log4j.appender.stdout.layout.ConversionPattern" value="%d{dd.MM.yyyy HH:mm:ss} *%-5p* [%t] %c{1}: %m (%F, line %L) %n" />
- <property name="log4j.appender.stdout.threshold" value="INFO" />
-
- <property name="log4j.appender.file" value="org.apache.log4j.FileAppender" />
- <property name="log4j.appender.file.File" value="target/jcr.log" />
-
- <property name="log4j.appender.file.layout" value="org.apache.log4j.PatternLayout" />
- <property name="log4j.appender.file.layout.ConversionPattern" value="%d{dd.MM.yyyy HH:mm:ss} *%-5p* [%t] %c{1}: %m (%F, line %L) %n" />
- </properties-param>
-
- <!-- value-param>
- <name>logger</name>
- <value>org.exoplatform.services.log.impl.BufferedSimpleLog</value>
- </value-param>
- <value-param>
- <name>configurator</name>
- <value>org.exoplatform.services.log.impl.SimpleLogConfigurator</value>
- </value-param>
- <properties-param>
- <name>properties</name>
- <description>SimpleLog properties</description>
- <property name="org.apache.commons.logging.simplelog.defaultlog" value="debug" />
- <property name="org.apache.commons.logging.simplelog.showdatetime" value="true" />
- </properties-param -->
-
- <!-- value-param>
- <name>logger</name>
- <value>org.exoplatform.services.log.impl.BufferedJdk14Logger</value>
- </value-param>
- <value-param>
- <name>configurator</name>
- <value>org.exoplatform.services.log.impl.Jdk14Configurator</value>
- </value-param>
- <properties-param>
- <name>properties</name>
- <description>jdk1.4 Logger properties</description>
- <property name="handlers" value="java.util.logging.ConsoleHandler" />
- <property name=".level" value="FINE" />
- <property name="java.util.logging.ConsoleHandler.level" value="FINE" />
- </properties-param>
-
- </init-params>
- </component -->
-
<component>
<key>org.exoplatform.services.naming.InitialContextInitializer</key>
<type>org.exoplatform.services.naming.InitialContextInitializer</type>
@@ -146,12 +86,6 @@
<description>Default initial context properties</description>
<property name="java.naming.factory.initial" value="org.exoplatform.services.naming.SimpleContextFactory" />
</properties-param>
- <!-- properties-param>
- <name>mandatory-properties</name>
- <description>Mandatory initial context properties</description>
- <property name="java.naming.factory.initial" value="org.exoplatform.services.naming.SimpleContextFactory" />
- <property name="java.naming.provider.url" value="rmi://localhost:9999" />
- </properties-param -->
</init-params>
</component>
@@ -163,10 +97,6 @@
<name>timeout</name>
<value>5</value>
</value-param>
- <!-- value-param>
- <name>track-without-transaction</name>
- <value>true</value>
- </value-param -->
</init-params>
</component>
13 years
exo-jcr SVN: r4400 - jcr/trunk/exo.jcr.component.core.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-05-20 10:38:19 -0400 (Fri, 20 May 2011)
New Revision: 4400
Modified:
jcr/trunk/exo.jcr.component.core/pom.xml
Log:
EXOJCR-945: Cleanup build
Modified: jcr/trunk/exo.jcr.component.core/pom.xml
===================================================================
--- jcr/trunk/exo.jcr.component.core/pom.xml 2011-05-20 11:07:34 UTC (rev 4399)
+++ jcr/trunk/exo.jcr.component.core/pom.xml 2011-05-20 14:38:19 UTC (rev 4400)
@@ -433,7 +433,32 @@
</execution>
</executions>
</plugin>
- <plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>unpack</id>
+ <phase>generate-test-sources</phase>
+ <goals>
+ <goal>unpack</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+ <artifactItem>
+ <groupId>org.apache.jackrabbit</groupId>
+ <artifactId>jackrabbit-jcr-tests</artifactId>
+ <classifier>sources</classifier>
+ <type>jar</type>
+ <overWrite>false</overWrite>
+ </artifactItem>
+ </artifactItems>
+ <outputDirectory>${project.build.directory}/jackrabbit-jcr-tests</outputDirectory>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
13 years
exo-jcr SVN: r4399 - in jcr/trunk/exo.jcr.component.core: src/test/java/org/exoplatform/services/jcr/util and 1 other directories.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-05-20 07:07:34 -0400 (Fri, 20 May 2011)
New Revision: 4399
Modified:
jcr/trunk/exo.jcr.component.core/pom.xml
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/util/TesterConfigurationHelper.java
jcr/trunk/exo.jcr.component.core/src/test/resources/log4j.properties
Log:
EXOJCR-945: Cleanup build
Modified: jcr/trunk/exo.jcr.component.core/pom.xml
===================================================================
--- jcr/trunk/exo.jcr.component.core/pom.xml 2011-05-19 17:04:04 UTC (rev 4398)
+++ jcr/trunk/exo.jcr.component.core/pom.xml 2011-05-20 11:07:34 UTC (rev 4399)
@@ -355,34 +355,9 @@
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-dependency-plugin</artifactId>
- <executions>
- <execution>
- <id>unpack</id>
- <phase>generate-test-sources</phase>
- <goals>
- <goal>unpack</goal>
- </goals>
- <configuration>
- <artifactItems>
- <artifactItem>
- <groupId>org.apache.jackrabbit</groupId>
- <artifactId>jackrabbit-jcr-tests</artifactId>
- <classifier>sources</classifier>
- <type>jar</type>
- <overWrite>false</overWrite>
- </artifactItem>
- </artifactItems>
- <outputDirectory>${project.build.testSourceDirectory}</outputDirectory>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
- <argLine>${env.MAVEN_OPTS} -Djava.security.manager=org.exoplatform.commons.test.TestSecurityManager -Djava.security.policy=${project.build.directory}/test-classes/test.policy</argLine>
+ <argLine>${env.MAVEN_OPTS} -Dcom.arjuna.ats.arjuna.objectstore.objectStoreDir=${project.build.directory} -Djava.security.manager=org.exoplatform.commons.test.TestSecurityManager -Djava.security.policy=${project.build.directory}/test-classes/test.policy</argLine>
<systemProperties>
<property>
<name>jcr.test.configuration.file</name>
@@ -584,7 +559,7 @@
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<!-- TAKE CARE TO UPDATE ALSO run-all PROFILE -->
- <argLine>${env.MAVEN_OPTS} -Djava.security.manager=org.exoplatform.commons.test.TestSecurityManager -Djava.security.policy=${project.build.directory}/test-classes/test.policy</argLine>
+ <argLine>${env.MAVEN_OPTS} -Dcom.arjuna.ats.arjuna.objectstore.objectStoreDir=${project.build.directory} -Djava.security.manager=org.exoplatform.commons.test.TestSecurityManager -Djava.security.policy=${project.build.directory}/test-classes/test.policy</argLine>
<systemProperties>
<property>
<name>jcr.test.configuration.file</name>
@@ -676,7 +651,7 @@
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<!-- TAKE CARE TO UPDATE ALSO run-tck PROFILE -->
- <argLine>${env.MAVEN_OPTS} -Djava.security.manager=org.exoplatform.commons.test.TestSecurityManager -Djava.security.policy=${project.build.directory}/test-classes/test.policy</argLine>
+ <argLine>${env.MAVEN_OPTS} -Dcom.arjuna.ats.arjuna.objectstore.objectStoreDir=${project.build.directory} -Djava.security.manager=org.exoplatform.commons.test.TestSecurityManager -Djava.security.policy=${project.build.directory}/test-classes/test.policy</argLine>
<systemProperties>
<property>
<name>jcr.test.configuration.file</name>
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 2011-05-19 17:04:04 UTC (rev 4398)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/util/TesterConfigurationHelper.java 2011-05-20 11:07:34 UTC (rev 4399)
@@ -187,7 +187,7 @@
// Indexer
ArrayList qParams = new ArrayList();
- qParams.add(new SimpleParameterEntry("indexDir", "../temp/index/" + IdGenerator.generate()));
+ qParams.add(new SimpleParameterEntry("indexDir", "target/temp/index/" + IdGenerator.generate()));
QueryHandlerEntry qEntry =
new QueryHandlerEntry("org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex", qParams);
@@ -211,7 +211,7 @@
LockPersisterEntry persisterEntry = new LockPersisterEntry();
persisterEntry.setType("org.exoplatform.services.jcr.impl.core.lock.FileSystemLockPersister");
ArrayList lpParams = new ArrayList();
- lpParams.add(new SimpleParameterEntry("path", "../temp/lock"));
+ lpParams.add(new SimpleParameterEntry("path", "target/temp/lock"));
persisterEntry.setParameters(lpParams);
lockManagerEntry.setPersister(persisterEntry);
workspaceEntry.setLockManager(lockManagerEntry);
Modified: jcr/trunk/exo.jcr.component.core/src/test/resources/log4j.properties
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/resources/log4j.properties 2011-05-19 17:04:04 UTC (rev 4398)
+++ jcr/trunk/exo.jcr.component.core/src/test/resources/log4j.properties 2011-05-20 11:07:34 UTC (rev 4399)
@@ -17,8 +17,7 @@
# 'file' is set to be a FileAppender.
log4j.appender.file=org.apache.log4j.FileAppender
-#log4j.appender.file.File=jcr.log
-log4j.appender.file.File=nul
+log4j.appender.file.File=target/jcr.log
# 'file' uses PatternLayout.
log4j.appender.file.layout=org.apache.log4j.PatternLayout
13 years
exo-jcr SVN: r4398 - in kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/scheduler: impl and 1 other directory.
by do-not-reply@jboss.org
Author: nfilotto
Date: 2011-05-19 13:04:04 -0400 (Thu, 19 May 2011)
New Revision: 4398
Modified:
kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/scheduler/JobSchedulerService.java
kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/scheduler/impl/JobSchedulerServiceImpl.java
Log:
EXOJCR-1355: Allow to suspend and resume the JobSchedulerService thanks to JMX and/or Rest
Modified: kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/scheduler/JobSchedulerService.java
===================================================================
--- kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/scheduler/JobSchedulerService.java 2011-05-19 12:05:52 UTC (rev 4397)
+++ kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/scheduler/JobSchedulerService.java 2011-05-19 17:04:04 UTC (rev 4398)
@@ -19,6 +19,10 @@
package org.exoplatform.services.scheduler;
import org.exoplatform.container.component.ComponentPlugin;
+import org.exoplatform.management.annotations.Managed;
+import org.exoplatform.management.jmx.annotations.NameTemplate;
+import org.exoplatform.management.jmx.annotations.Property;
+import org.exoplatform.management.rest.annotations.RESTEndpoint;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobListener;
@@ -32,6 +36,9 @@
* Created by The eXo Platform SAS Author : Hoa Pham hoapham(a)exoplatform.com Oct
* 5, 2005
*/
+@Managed
+@NameTemplate(@Property(key = "service", value = "JobSchedulerService"))
+@RESTEndpoint(path = "JobSchedulerService")
public interface JobSchedulerService
{
public void addJob(JobInfo jinfo, Date date) throws Exception;
@@ -101,4 +108,16 @@
public Date rescheduleJob(String triggerName, String groupName, Trigger newTrigger) throws Exception;
public JobDetail getJob(JobInfo jobInfo) throws Exception;
+
+ /**
+ * Suspends all the registered jobs
+ * @return <code>true</code> if the jobs could be suspended, <code>false</code> otherwise
+ */
+ public boolean suspend();
+
+ /**
+ * Resumes all the registered jobs
+ * @return <code>true</code> if the jobs could be resumed, <code>false</code> otherwise
+ */
+ public boolean resume();
}
Modified: kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/scheduler/impl/JobSchedulerServiceImpl.java
===================================================================
--- kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/scheduler/impl/JobSchedulerServiceImpl.java 2011-05-19 12:05:52 UTC (rev 4397)
+++ kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/scheduler/impl/JobSchedulerServiceImpl.java 2011-05-19 17:04:04 UTC (rev 4398)
@@ -20,6 +20,8 @@
import org.exoplatform.container.component.ComponentPlugin;
import org.exoplatform.container.xml.PortalContainerInfo;
+import org.exoplatform.management.annotations.Managed;
+import org.exoplatform.management.annotations.ManagedDescription;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.scheduler.CronJob;
@@ -394,6 +396,38 @@
return scheduler_.rescheduleJob(triggerName, groupName, newTrigger);
}
+ @Managed
+ @ManagedDescription("Suspend all the existing jobs")
+ public boolean suspend()
+ {
+ try
+ {
+ scheduler_.standby();
+ return true;
+ }
+ catch (SchedulerException e)
+ {
+ log.error("Could not suspend the scheduler", e);
+ }
+ return false;
+ }
+
+ @Managed
+ @ManagedDescription("Resume all the existing jobs")
+ public boolean resume()
+ {
+ try
+ {
+ scheduler_.start();
+ return true;
+ }
+ catch (SchedulerException e)
+ {
+ log.error("Could not resume the scheduler", e);
+ }
+ return false;
+ }
+
public void start()
{
try
13 years
exo-jcr SVN: r4397 - jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-05-19 08:05:52 -0400 (Thu, 19 May 2011)
New Revision: 4397
Modified:
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/BackupManagerImpl.java
Log:
EXOJCR-1353: NPE during incremental restore
Modified: jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/BackupManagerImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/BackupManagerImpl.java 2011-05-19 10:45:49 UTC (rev 4396)
+++ jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/BackupManagerImpl.java 2011-05-19 12:05:52 UTC (rev 4397)
@@ -473,21 +473,6 @@
currentRepositoryBackups = Collections.synchronizedSet(new HashSet<RepositoryBackupChain>());
- // get FileCleaner from container's component FileCleanerHolder
- try
- {
- ManageableRepository repository = repoService.getCurrentRepository();
- String workspaceName = repository.getConfiguration().getSystemWorkspaceName();
-
- this.fileCleaner =
- ((FileCleanerHolder)repository.getWorkspaceContainer(workspaceName).getComponent(FileCleanerHolder.class))
- .getFileCleaner();
- }
- catch (RepositoryException e)
- {
- // do nothing. should not happens
- }
-
messages = new BackupMessagesLog(MESSAGES_MAXSIZE);
scheduler = new BackupScheduler(this, messages);
@@ -848,6 +833,21 @@
*/
public void start()
{
+ // get FileCleaner from container's component FileCleanerHolder
+ try
+ {
+ ManageableRepository repository = repoService.getCurrentRepository();
+ String workspaceName = repository.getConfiguration().getSystemWorkspaceName();
+
+ this.fileCleaner =
+ ((FileCleanerHolder)repository.getWorkspaceContainer(workspaceName).getComponent(FileCleanerHolder.class))
+ .getFileCleaner();
+ }
+ catch (RepositoryException e)
+ {
+ // do nothing. should not happens
+ }
+
//remove if exists all old jcrrestorewi*.tmp files.
File[] files = PrivilegedFileHelper.listFiles(tempDir, new JcrRestoreWiFilter());
for (int i = 0; i < files.length; i++)
@@ -856,7 +856,6 @@
}
// start all scheduled before tasks
-
if (registryService != null && !registryService.getForceXMLConfigurationValue(initParams))
{
SessionProvider sessionProvider = SessionProvider.createSystemProvider();
13 years
exo-jcr SVN: r4396 - core/trunk/exo.core.component.organization.jdbc/src/test/java/org/exoplatform/services/organization.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-05-19 06:45:49 -0400 (Thu, 19 May 2011)
New Revision: 4396
Modified:
core/trunk/exo.core.component.organization.jdbc/src/test/java/org/exoplatform/services/organization/TestOrganizationService.java
Log:
EXOJCR-1009: fix test
Modified: core/trunk/exo.core.component.organization.jdbc/src/test/java/org/exoplatform/services/organization/TestOrganizationService.java
===================================================================
--- core/trunk/exo.core.component.organization.jdbc/src/test/java/org/exoplatform/services/organization/TestOrganizationService.java 2011-05-19 10:07:48 UTC (rev 4395)
+++ core/trunk/exo.core.component.organization.jdbc/src/test/java/org/exoplatform/services/organization/TestOrganizationService.java 2011-05-19 10:45:49 UTC (rev 4396)
@@ -289,11 +289,17 @@
try
{
membershipHandler_.linkMembership(userBenj, group2, mt, true);
+ fail("Exception should be thrown");
}
catch (InvalidNameException e)
{
}
+ mt = mtHandler_.createMembershipTypeInstance();
+ mt.setName("membershipType3");
+ mtHandler_.createMembershipType(mt, true);
+ membershipHandler_.linkMembership(userBenj, group2, mt, true);
+
/*
* find all memberships in group2 Expect result: 4 membership: 3 for
* Benj(testmebership, membershipType2, membershipType3) : 1 for
13 years