You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pp...@apache.org on 2009/10/11 03:52:35 UTC
svn commit: r823997 - in
/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jta:
./ ContainerTest.java JTAManagedRuntime.java SimpleTransaction.java
SimpleTransactionManager.java
Author: ppoddar
Date: Sun Oct 11 01:52:34 2009
New Revision: 823997
URL: http://svn.apache.org/viewvc?rev=823997&view=rev
Log:
OPENJOA-1342: Support simple/basic container test harness for managed transaction
Added:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jta/
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jta/ContainerTest.java (with props)
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jta/JTAManagedRuntime.java (with props)
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jta/SimpleTransaction.java (with props)
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jta/SimpleTransactionManager.java (with props)
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jta/ContainerTest.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jta/ContainerTest.java?rev=823997&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jta/ContainerTest.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jta/ContainerTest.java Sun Oct 11 01:52:34 2009
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.jta;
+
+import javax.transaction.TransactionManager;
+
+import org.apache.openjpa.ee.ManagedRuntime;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Simulates a container transaction around a test method.
+ *
+ * The concrete tests derived from this class must adhere to the following guidelines:
+ * <LI>They must configure openjpa.ManagedRuntime in setUp() properties as
+ * to <code>org.apache.openjpa.jta.JTAManagedRuntime</code>
+ *
+ * <LI>The tests themselves must not try to access the transaction directly
+ * i.e. not call EntityManager.getTransaction(). Attempt to do so will raise
+ * exception.
+ *
+ * <LI>The test methods must use EntityManager.joinTransaction() to use a transaction.
+ * This test harness ensures that a transaction is active before running each
+ * test method.
+ *
+ * <LI>The test methods may call commit() and rollback() methods of this class
+ * to demarcate transaction.
+ *
+ * @author Pinaki Poddar
+ *
+ */
+public abstract class ContainerTest extends SingleEMFTestCase {
+ ManagedRuntime runtime;
+
+ @Override
+ public void setUp(Object...props) {
+ super.setUp(props);
+ runtime = emf.getConfiguration().getManagedRuntimeInstance();
+ assertNotNull(runtime);
+ }
+
+ @Override
+ public void runTest() throws Throwable {
+ TransactionManager txm = runtime.getTransactionManager();
+ txm.begin();
+ try {
+ super.runTest();
+ } catch (Throwable t) {
+ t.printStackTrace();
+ throw t;
+ }
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ }
+
+ protected void commit() {
+ try {
+ runtime.getTransactionManager().commit();
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+
+ protected void rollback() {
+ try {
+ runtime.getTransactionManager().rollback();
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+
+
+}
Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jta/ContainerTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jta/JTAManagedRuntime.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jta/JTAManagedRuntime.java?rev=823997&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jta/JTAManagedRuntime.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jta/JTAManagedRuntime.java Sun Oct 11 01:52:34 2009
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.jta;
+
+import javax.transaction.NotSupportedException;
+import javax.transaction.SystemException;
+import javax.transaction.TransactionManager;
+
+import org.apache.openjpa.ee.ManagedRuntime;
+/**
+ * An implementation of {@linkplain ManagedRuntime managed runtime} for testing
+ * JTA resources in a JSE environment without a <em>real</em> and often heavy
+ * container. Uses a {@linkplain simple} (or basic) TransactionManager.
+ *
+ * @author Pinaki Poddar
+ *
+ */
+public class JTAManagedRuntime implements ManagedRuntime {
+ private SimpleTransactionManager txm = new SimpleTransactionManager();
+
+ public void doNonTransactionalWork(Runnable runnable) throws NotSupportedException {
+ throw new NotSupportedException();
+ }
+
+ public Throwable getRollbackCause() throws Exception {
+ return txm.getTransaction().getRollbackCause();
+ }
+
+ public Object getTransactionKey() throws Exception, SystemException {
+ return getTransactionManager().getTransaction().hashCode();
+ }
+
+ public TransactionManager getTransactionManager() throws Exception {
+ return txm;
+ }
+
+ public void setRollbackOnly(Throwable cause) throws Exception {
+ txm.getTransaction().setRollbackOnly(cause);
+ }
+
+}
Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jta/JTAManagedRuntime.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jta/SimpleTransaction.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jta/SimpleTransaction.java?rev=823997&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jta/SimpleTransaction.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jta/SimpleTransaction.java Sun Oct 11 01:52:34 2009
@@ -0,0 +1,175 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.jta;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.xa.XAResource;
+
+/**
+ * A transaction for testing.
+ *
+ * @author Pinaki Poddar
+ *
+ */
+public class SimpleTransaction implements Transaction {
+ private final Set<Synchronization> synchs = new HashSet<Synchronization>();
+ private Throwable rollbackCause;
+ private volatile int status = Status.STATUS_UNKNOWN;
+
+ /**
+ * Commits this transaction.
+ */
+ public void commit() throws HeuristicMixedException, HeuristicRollbackException, RollbackException,
+ SecurityException, SystemException {
+ if (status == Status.STATUS_MARKED_ROLLBACK)
+ throw new RuntimeException(this + " can not commit. Marked for rollback");
+ status = Status.STATUS_COMMITTING;
+ List<Throwable> errors = new ArrayList<Throwable>();
+ for (Synchronization synch : synchs) {
+ try {
+ synch.beforeCompletion();
+ } catch (Throwable t) {
+ errors.add(t);
+ }
+ }
+ // do nothing
+ for (Synchronization synch : synchs) {
+ try {
+ synch.afterCompletion(Status.STATUS_COMMITTED);
+ } catch (Throwable t) {
+ errors.add(t);
+ }
+ }
+ status = errors.isEmpty() ? Status.STATUS_COMMITTED : Status.STATUS_UNKNOWN;
+ }
+
+ /**
+ * Not implemented.
+ * Raises UnsupportedOperationException.
+ */
+ public boolean delistResource(XAResource arg0, int arg1) throws IllegalStateException, SystemException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Not implemented.
+ * Raises UnsupportedOperationException.
+ */
+ public boolean enlistResource(XAResource arg0) throws IllegalStateException, RollbackException, SystemException {
+ return false;
+ }
+
+ /**
+ * Gets the status of this transaction.
+ * Raises UnsupportedOperationException.
+ */
+ public int getStatus() throws SystemException {
+ return status;
+ }
+
+ void setStatus(int newStatus) throws SystemException {
+ status = newStatus;
+ }
+
+
+ /**
+ * Registers the given synchronization element.
+ */
+ public void registerSynchronization(Synchronization synch) throws IllegalStateException, RollbackException,
+ SystemException {
+ synchs.add(synch);
+ }
+
+ /**
+ * Rolls back this transaction.
+ */
+ public void rollback() throws IllegalStateException, SystemException {
+ status = Status.STATUS_ROLLING_BACK;
+ List<Throwable> errors = new ArrayList<Throwable>();
+ for (Synchronization synch : synchs) {
+ try {
+ synch.beforeCompletion();
+ } catch (Throwable t) {
+ errors.add(t);
+ }
+ }
+
+ for (Synchronization synch : synchs) {
+ try {
+ synch.afterCompletion(Status.STATUS_ROLLEDBACK);
+ } catch (Throwable t) {
+ errors.add(t);
+ }
+ }
+ status = errors.isEmpty() ? Status.STATUS_ROLLEDBACK : Status.STATUS_UNKNOWN;
+ if (!errors.isEmpty())
+ throw new RuntimeException(errors.get(0));
+ }
+
+ /**
+ * Marks this transaction for rollback only.
+ */
+ public void setRollbackOnly() throws IllegalStateException, SystemException {
+ setRollbackOnly(null);
+ }
+
+ /**
+ * Marks this transaction for rollback only with the given underlying cause.
+ */
+ void setRollbackOnly(Throwable cause) throws IllegalStateException, SystemException {
+ rollbackCause = cause;
+ status = Status.STATUS_MARKED_ROLLBACK;
+ }
+
+ Throwable getRollbackCause() {
+ return rollbackCause;
+ }
+
+ public String toString() {
+ return "TXN:"+hashCode() +"["+statusCode()+"]";
+ }
+
+ String statusCode() {
+ switch (status) {
+ case Status.STATUS_ACTIVE : return "active";
+ case Status.STATUS_COMMITTED : return "committed";
+ case Status.STATUS_COMMITTING : return "committing";
+ case Status.STATUS_MARKED_ROLLBACK : return "marked rollback";
+ case Status.STATUS_NO_TRANSACTION : return "none";
+ case Status.STATUS_PREPARED : return "prepared";
+ case Status.STATUS_PREPARING : return "preparing";
+ case Status.STATUS_ROLLEDBACK : return "rolled back";
+ case Status.STATUS_ROLLING_BACK : return "rolling back";
+ case Status.STATUS_UNKNOWN : return "unknown";
+ default : return "error";
+ }
+ }
+
+}
Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jta/SimpleTransaction.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jta/SimpleTransactionManager.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jta/SimpleTransactionManager.java?rev=823997&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jta/SimpleTransactionManager.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jta/SimpleTransactionManager.java Sun Oct 11 01:52:34 2009
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.jta;
+
+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;
+
+/**
+ * A very very simple Transaction Manager for testing JTA resource
+ * without a container.
+ * <br>
+ * Provides a single transaction per-thread model.
+ *
+ * @author Pinaki Poddar
+ *
+ */
+public class SimpleTransactionManager implements TransactionManager {
+ private static ThreadLocal<SimpleTransaction> txns = new ThreadLocal<SimpleTransaction>();
+
+ /**
+ * Begins a new transaction associated with the current thread.
+ *
+ */
+ public void begin() throws NotSupportedException, SystemException {
+ SimpleTransaction txn = getTransaction();
+ int status = txn.getStatus();
+ if (status == Status.STATUS_COMMITTED || status == Status.STATUS_ROLLEDBACK || status == Status.STATUS_UNKNOWN
+ || status == Status.STATUS_ACTIVE)
+ txn.setStatus(Status.STATUS_ACTIVE);
+ else
+ throw new IllegalStateException("Can not begin " + txn);
+ }
+
+ /**
+ * Commits a transaction associated with the current thread.
+ * Raises IllegalStateException if no transaction is associated with the current thread.
+ *
+ */
+ public void commit() throws HeuristicMixedException, HeuristicRollbackException, IllegalStateException,
+ RollbackException, SecurityException, SystemException {
+ assertActiveTransaction();
+ try {
+ getTransaction().commit();
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ txns.set(null);
+ }
+
+ }
+
+ /**
+ * Gets the status of the transaction associated with the current thread.
+ */
+ public int getStatus() throws SystemException {
+ if (txns.get() == null)
+ return Status.STATUS_NO_TRANSACTION;
+ return getTransaction().getStatus();
+ }
+
+ /**
+ * Gets the transaction associated with the current thread.
+ * If no transaction is associated then creates a transaction and
+ * associates with the current thread.
+ */
+ public SimpleTransaction getTransaction() throws SystemException {
+ SimpleTransaction txn = txns.get();
+ if (txn == null) {
+ txn = new SimpleTransaction();
+ txn.setStatus(Status.STATUS_ACTIVE);
+ txns.set(txn);
+ }
+ return txn;
+ }
+
+ /**
+ * Not implemented.
+ * Raises UnsupportedOperationException.
+ */
+ public void resume(Transaction arg0) throws IllegalStateException, InvalidTransactionException, SystemException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Rolls back a transaction associated with the current thread.
+ * Raises IllegalStateException if no transaction is associated with the current thread.
+ *
+ */
+ public void rollback() throws IllegalStateException, SecurityException, SystemException {
+ assertActiveTransaction();
+ try {
+ getTransaction().rollback();
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ txns.set(null);
+ }
+ }
+
+ /**
+ * Marks a transaction associated with the current thread for rollback.
+ * Raises IllegalStateException if no transaction is associated with the current thread.
+ *
+ */
+ public void setRollbackOnly() throws IllegalStateException, SystemException {
+ assertActiveTransaction();
+ getTransaction().setRollbackOnly();
+ }
+
+ /**
+ * Not implemented.
+ * Raises UnsupportedOperationException.
+ */
+ public void setTransactionTimeout(int arg0) throws SystemException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Not implemented.
+ * Raises UnsupportedOperationException.
+ */
+ public Transaction suspend() throws SystemException {
+ throw new UnsupportedOperationException();
+ }
+
+ void assertActiveTransaction() throws IllegalStateException, SystemException {
+ if (getStatus() == Status.STATUS_NO_TRANSACTION)
+ throw new IllegalStateException("No transaction on " + Thread.currentThread());
+ }
+
+}
Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jta/SimpleTransactionManager.java
------------------------------------------------------------------------------
svn:eol-style = native