openjpa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From p..@apache.org
Subject svn commit: r627979 [12/39] - in /openjpa/trunk: openjpa-lib/src/test/java/org/apache/openjpa/lib/test/ openjpa-persistence-jdbc/ openjpa-persistence-jdbc/src/test/java/ openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/ openjpa-per...
Date Fri, 15 Feb 2008 09:20:40 GMT
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestLocalRemoteEvents.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestLocalRemoteEvents.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestLocalRemoteEvents.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestLocalRemoteEvents.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,40 @@
+/*
+ * 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.persistence.event;
+
+
+import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
+
+import org.apache.openjpa.event.SingleJVMRemoteCommitProvider;
+
+public class TestLocalRemoteEvents
+    extends RemoteEventBase {
+
+    public TestLocalRemoteEvents(String s) {
+        super(s);
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+    }
+
+    public void testLocalEvents() {
+        doTest(SingleJVMRemoteCommitProvider.class, "", "");
+    }
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestOrphanedKeyAction.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestOrphanedKeyAction.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestOrphanedKeyAction.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestOrphanedKeyAction.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,136 @@
+/*
+ * 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.persistence.event;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import org.apache.openjpa.persistence.common.utils.BufferedLogFactory;
+
+import org.apache.openjpa.event.OrphanedKeyAction;
+import org.apache.openjpa.persistence.EntityNotFoundException;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
+import org.apache.openjpa.util.OpenJPAException;
+
+/**
+ * <p>Test the {@link OrphanedKeyAction} plugin.</p>
+ *
+ * @author Abe White
+ */
+public class TestOrphanedKeyAction
+    extends AbstractTestCase {
+
+    private Object _oid = null;
+
+    public TestOrphanedKeyAction(String s) {
+        super(s, "eventcactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+
+        RuntimeTest1 pc = new RuntimeTest1();
+        pc.setIntField(1);
+        RuntimeTest1 pc2 = new RuntimeTest1();
+        pc2.setIntField(2);
+        pc.setSelfOneOne(pc2);
+
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(pm);
+        pm.persist(pc);
+        endTx(pm);
+        _oid = pm.getObjectId(pc);
+
+        startTx(pm);
+        pm.remove(pc2);
+        endTx(pm);
+        endEm(pm);
+    }
+
+    public void testLog() {
+        Map map = getOrphanedKeyConfiguration("log(Level=FATAL)");
+
+        OpenJPAEntityManagerFactory pmf = getEmf(map);
+        OpenJPAEntityManager pm = pmf.createEntityManager();
+
+        BufferedLogFactory logFactory = (BufferedLogFactory)
+            ((OpenJPAEntityManagerSPI) pm).getConfiguration().getLogFactory();
+        logFactory.clear();
+
+        RuntimeTest1 pc = (RuntimeTest1) pm.find(RuntimeTest1.class, _oid);
+        logFactory.assertNoLogMessage("*orphan*");
+        assertNull(pc.getSelfOneOne());
+        logFactory.assertLogMessage("*orphan*");
+        endEm(pm);
+        pmf.close();
+    }
+
+    public void testException() {
+        Map map = getOrphanedKeyConfiguration("exception");
+        OpenJPAEntityManagerFactory pmf = getEmf(map);
+
+        OpenJPAEntityManager pm = pmf.createEntityManager();
+
+        BufferedLogFactory logFactory = (BufferedLogFactory)
+            ((OpenJPAEntityManagerSPI) pm).getConfiguration().getLogFactory();
+        logFactory.clear();
+
+        RuntimeTest1 pc = (RuntimeTest1) pm.find(RuntimeTest1.class, _oid);
+        try {
+            pc.getSelfOneOne();
+            fail("Did not throw expected exception for orphaned key.");
+        } catch (EntityNotFoundException onfe) {
+            logFactory.assertNoLogMessage("*orphan*");
+        } catch (OpenJPAException ke) {
+            bug(1138, ke, "Wrong exception type.");
+        }
+        endEm(pm);
+        pmf.close();
+    }
+
+    public void testNone() {
+        Map map = getOrphanedKeyConfiguration("none");
+        OpenJPAEntityManagerFactory pmf = getEmf(map);
+        OpenJPAEntityManager pm = pmf.createEntityManager();
+
+        BufferedLogFactory logFactory = (BufferedLogFactory)
+            ((OpenJPAEntityManagerSPI) pm).getConfiguration().getLogFactory();
+        logFactory.clear();
+
+        RuntimeTest1 pc = (RuntimeTest1) pm.find(RuntimeTest1.class, _oid);
+        assertNull(pc.getSelfOneOne());
+        logFactory.assertNoLogMessage("*orphan*");
+        endEm(pm);
+        pmf.close();
+    }
+
+    Map getOrphanedKeyConfiguration(String orphanKeyAction) {
+        Map map = new HashMap();
+        map.put("openjpa.Log", BufferedLogFactory.class.getName());
+        if (orphanKeyAction != null)
+            map.put("openjpa.OrphanedKeyAction", orphanKeyAction);
+        return map;
+    }
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteClassChanges.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteClassChanges.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteClassChanges.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteClassChanges.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,273 @@
+/*
+ * 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.persistence.event;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.EntityManager;
+
+
+import org.apache.openjpa.persistence.event.common.apps.Duration;
+import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+import org.apache.openjpa.event.RemoteCommitEvent;
+import org.apache.openjpa.event.RemoteCommitListener;
+import org.apache.openjpa.event.TCPRemoteCommitProvider;
+import org.apache.openjpa.lib.conf.Configurations;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+
+public class TestTCPRemoteClassChanges
+    extends AbstractTestCase {
+
+    public TestTCPRemoteClassChanges(String s) {
+        super(s, "eventcactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+    }
+
+    public void tearDownTestClass()
+        throws Exception {
+        //super.tearDownTestClass();
+    }
+
+    private static final int NUM_OBJECTS = 4;
+
+    private void pause(double seconds) {
+        try {
+            Thread.currentThread().yield();
+            Thread.currentThread().sleep((int) seconds * 1000);
+        } catch (Exception e) {
+        }
+    }
+
+    public void testAddedClasses() {
+        // Create two pmfs in a cluster that are using RCPTCP.
+        OpenJPAEntityManagerFactory pmfSender = createDistinctFactory(
+            TCPRemoteCommitProvider.class,
+            "Port=5636, Addresses=127.0.0.1:5636;127.0.0.1:6636");
+        OpenJPAEntityManagerFactory pmfReceiver = createDistinctFactory(
+            TCPRemoteCommitProvider.class,
+            "Port=6636, Addresses=127.0.0.1:6636;127.0.0.1:5636");
+
+        // Register a RCEListener with the RCEM. Our RCEListener will
+        // record the total number of a,d, and u recevied from each
+        // RCE as the sending PM performs commits.
+        RemoteCommitListenerTestImpl listenerAtReceiver
+            = new RemoteCommitListenerTestImpl();
+        ((OpenJPAEntityManagerFactorySPI) pmfReceiver).getConfiguration()
+            .getRemoteCommitEventManager().
+            addListener(listenerAtReceiver);
+
+        OpenJPAEntityManager pmSender = (OpenJPAEntityManager)
+            pmfSender.createEntityManager();
+
+        System.out.println("-------------------");
+        System.out.println(
+            "2 PMFs created, acting as a cluster using ports 5636 and 6636");
+        System.out.println(
+            "Testing scenario:");
+        System.out.println(
+            "  - tx of inserts (normal trans)\n" +
+                "  - tx of inserts (large trans)\n" +
+                "  - tx of inserts,updates, dels (large trans)");
+        System.out.println(
+            "Remote commit event will transmit classes.");
+
+        // Perform transaction that adds objects.
+        // Noraml transaction
+        performAdds(pmSender, NUM_OBJECTS);
+
+        // Wait for a bit so the receiver can get the event.
+        pause(1);
+        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalAddedClasses);
+
+        // largeTransaction
+        //pmSender.setLargeTransaction(true);
+        pmSender.setTrackChangesByType(true);
+        performAdds(pmSender, NUM_OBJECTS);
+        pause(1);
+        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalAddedClasses);
+        assertEquals(0, listenerAtReceiver.totalUpdatedClasses);
+        assertEquals(0, listenerAtReceiver.totalDeletedClasses);
+        assertEquals(NUM_OBJECTS, listenerAtReceiver.receivedExtentEvCount);
+
+        // Still in large trans mode, perform updates and deletes of
+        // check that class names are communicated
+
+        //pmSender.setLargeTransaction(true);
+        pmSender.setTrackChangesByType(true);
+        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
+        pause(1);
+        assertEquals(3 * NUM_OBJECTS, listenerAtReceiver.totalAddedClasses);
+        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalUpdatedClasses);
+        // all deletes then a commit
+        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalDeletedClasses);
+        assertEquals(4 * NUM_OBJECTS,
+            listenerAtReceiver.receivedExtentEvCount);
+        assertEquals(0, listenerAtReceiver.totalOidUpdated);
+        assertEquals(0, listenerAtReceiver.totalOidDeleted);
+        assertEquals(0, listenerAtReceiver.totalOidAdded);
+
+        // shutdown
+        pmSender.close();
+        pmfSender.close();
+        pmfReceiver.close();
+    }
+
+    protected double performAdds(EntityManager pm,
+        int numObjects) {
+        // Perform a transaction that will trigger adds
+        Duration timeToAMD = new Duration(
+            "Adds, " + numObjects + " objects.");
+        timeToAMD.start();
+
+        // create objects
+        RuntimeTest1[] persistables = new RuntimeTest1[numObjects];
+        for (int i = 0; i < persistables.length; i++) {
+            persistables[i] = new RuntimeTest1("foo #" + i, i);
+        }
+
+        // add them, a commit per object
+        for (int i = 0; i < persistables.length; i++) {
+            startTx(pm);
+            pm.persist(persistables[i]);
+            endTx(pm);
+        }
+
+        timeToAMD.stop();
+        return timeToAMD.getDurationAsSeconds();
+    }
+
+    protected void performAddsModifiesDeletes(EntityManager pm,
+        int numObjects) {
+        // Perform a series of transactions that will trigger adds,
+        // deletes, and udpates
+
+        // create objects
+        RuntimeTest1[] persistables = new RuntimeTest1[numObjects];
+        for (int i = 0; i < persistables.length; i++) {
+            persistables[i] = new RuntimeTest1("foo #" + i, i);
+        }
+
+        // add them
+        for (int i = 0; i < persistables.length; i++) {
+            startTx(pm);
+            pm.persist(persistables[i]);
+            endTx(pm);
+        }
+
+        // modify them
+        for (int i = 0; i < persistables.length; i++) {
+            startTx(pm);
+            persistables[i].setStringField("bazzed" + i);
+            endTx(pm);
+        }
+
+        // delete them
+        for (int i = 0; i < persistables.length; i++) {
+            startTx(pm);
+            pm.remove(persistables[i]);
+            endTx(pm);
+        }
+    }
+
+    static int _fetchGroupSerial = 0;
+
+    protected OpenJPAEntityManagerFactory createDistinctFactory(
+        Class providerClass, String classProps1) {
+        Map propsMap;
+
+        if (providerClass != null) {
+
+            propsMap = new HashMap();
+            propsMap.put("openjpa.RemoteCommitProvider", Configurations.
+                getPlugin(providerClass.getName(), classProps1));
+            propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup" +
+                _fetchGroupSerial);
+        } else {
+            // No RCP
+            propsMap = new HashMap();
+            propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
+            propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup" +
+                _fetchGroupSerial);
+        }
+        _fetchGroupSerial += 1;
+
+        return (OpenJPAEntityManagerFactory) getEmf(propsMap);
+    }
+
+    protected static class RemoteCommitListenerTestImpl
+        implements RemoteCommitListener {
+
+        Collection updated;
+        Collection deleted;
+        int totalAddedClasses = 0;
+        int totalUpdatedClasses = 0;
+        int totalDeletedClasses = 0;
+
+        int totalOidAdded = 0;
+        int totalOidUpdated = 0;
+        int totalOidDeleted = 0;
+
+        int receivedExtentEvCount = 0;
+
+        public synchronized void afterCommit(RemoteCommitEvent event) {
+            totalAddedClasses += event.getPersistedTypeNames().size();
+            if (event.getPayloadType() == RemoteCommitEvent.PAYLOAD_EXTENTS) {
+                receivedExtentEvCount += 1;
+                totalUpdatedClasses += event.getUpdatedTypeNames().size();
+                totalDeletedClasses += event.getDeletedTypeNames().size();
+            } else {
+                if (event.getPayloadType() ==
+                    RemoteCommitEvent.PAYLOAD_OIDS_WITH_ADDS)
+                    totalOidAdded = event.getPersistedObjectIds().size();
+                this.updated = event.getUpdatedObjectIds();
+                this.deleted = event.getDeletedObjectIds();
+                totalOidUpdated += updated.size();
+                totalOidDeleted += deleted.size();
+            }
+        }
+
+        public void resetCounts() {
+            totalAddedClasses = 0;
+            totalUpdatedClasses = 0;
+            totalDeletedClasses = 0;
+            totalOidAdded = 0;
+            totalOidUpdated = 0;
+            totalOidDeleted = 0;
+        }
+
+        public void close() {
+        }
+
+        public String toString() {
+            String returnString = "Clsses add=" + totalAddedClasses + " dels=" +
+                totalDeletedClasses + " ups=" + totalUpdatedClasses;
+            returnString = returnString + "Oids add=" + totalAddedClasses +
+                " dels=" + totalDeletedClasses + " ups=" + totalUpdatedClasses;
+            return returnString;
+        }
+    }
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteEvents.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteEvents.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteEvents.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteEvents.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,42 @@
+/*
+ * 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.persistence.event;
+
+
+import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
+
+import org.apache.openjpa.event.TCPRemoteCommitProvider;
+
+public class TestTCPRemoteEvents
+    extends RemoteEventBase {
+
+    public TestTCPRemoteEvents(String s) {
+        super(s);
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+    }
+
+    public void testEvents() {
+        doTest(TCPRemoteCommitProvider.class,
+            "Port=5636, Addresses=127.0.0.1:5636;127.0.0.1:6636",
+            "Port=6636, Addresses=127.0.0.1:5636;127.0.0.1:6636");
+    }
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteEventsDuration.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteEventsDuration.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteEventsDuration.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteEventsDuration.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,278 @@
+/*
+ * 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.persistence.event;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.EntityManager;
+
+
+import org.apache.openjpa.persistence.event.common.apps.Duration;
+import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+import org.apache.openjpa.event.RemoteCommitEvent;
+import org.apache.openjpa.event.RemoteCommitListener;
+import org.apache.openjpa.event.TCPRemoteCommitProvider;
+import org.apache.openjpa.lib.conf.Configurations;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+
+public class TestTCPRemoteEventsDuration
+    extends AbstractTestCase {
+
+    public TestTCPRemoteEventsDuration(String s) {
+        super(s, "eventcactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+    }
+
+    public void tearDownTestClass()
+        throws Exception {
+        //super.tearDownTestClass();
+    }
+
+    // FYI For 1000 objects with MySQL -- 1005 transactions,
+    // doTransactions () takes 45 seconds
+    private static final int NUM_OBJECTS = 200;
+    private static final int NUM_TO_AVERAGE = 3;
+    private static final int NUM_CONCURRENT = 3;
+
+    public void testDurationDifference() {
+        // create a non-cluserted, single pmf
+        OpenJPAEntityManagerFactory factorySingle = createDistinctFactory(
+            null, "");
+        EntityManager pmSingle = factorySingle.createEntityManager();
+
+        // Create 2 pmfs that are using RCPTCP. run same benachmark of
+        // transactions
+        OpenJPAEntityManagerFactory senderFactory1TCP =
+            createDistinctFactory(TCPRemoteCommitProvider.class,
+                "MaxActive=4, RecoveryTimeMillis=1000, Port=5636, " +
+                    "Addresses=127.0.0.1:5636;127.0.0.1:6636");
+        OpenJPAEntityManagerFactory factory2TCP = createDistinctFactory(
+            TCPRemoteCommitProvider.class,
+            "Port=6636, Addresses=127.0.0.1:6636;127.0.0.1:5636");
+
+        // Register a RCEListener with the RCEM. The RCEListener
+        // will record the number of
+        // a,d, and u recevied when the sender PM performs commits.
+        RemoteCommitListenerTestImpl listenerAtReceiver
+            = new RemoteCommitListenerTestImpl();
+        ((OpenJPAEntityManagerFactorySPI) factory2TCP).getConfiguration()
+            .getRemoteCommitEventManager().
+            addListener(listenerAtReceiver);
+
+        System.out.println("-------------------");
+        System.out.println("3 PMFs created, 1 as standalone, and 2 acting " +
+            "as a cluster using ports 5636 and 6636");
+        // This call is a "throw away" run to seed caches, etc.
+        doTransactions(pmSingle, NUM_OBJECTS);
+
+        double benchmarkSingle = 0.0;
+        for (int i = 0; i < NUM_TO_AVERAGE; i++) {
+            benchmarkSingle += doTransactions(pmSingle, NUM_OBJECTS);
+        }
+        benchmarkSingle /= NUM_TO_AVERAGE;
+
+        EntityManager pmOneThread =
+            senderFactory1TCP.createEntityManager();
+        double benchmarkClusterOneThread = doTransactions(pmOneThread,
+            NUM_OBJECTS);
+        pmOneThread.close();
+
+        Duration timeThreaded = new Duration("For " + NUM_CONCURRENT +
+            " concurrent threads performing Adds, removes, and dletes for " +
+            NUM_OBJECTS + " objects.");
+
+        Thread[] concurrentThreads = new Thread[NUM_CONCURRENT];
+        timeThreaded.start();
+        for (int i = 0; i < NUM_CONCURRENT; i++) {
+            Worker worker = new Worker
+                (senderFactory1TCP.createEntityManager());
+            concurrentThreads[i] = new Thread(worker);
+            concurrentThreads[i].start();
+        }
+        // Wait for all threads to finish
+        for (int i = 0; i < NUM_CONCURRENT; i++) {
+            try {
+                concurrentThreads[i].join();
+            } catch (Exception e) {
+                assertTrue(false);
+                break;
+            }
+        }
+        timeThreaded.stop();
+        double benchmarkCluster = timeThreaded.getDurationAsSeconds();
+
+        System.out.println("For " + NUM_OBJECTS + " objects, and " +
+            NUM_CONCURRENT + " concurrent threads, the receiving pmf of the " +
+            "cluster received :" +
+            listenerAtReceiver.totalAddedClasses + " claases adds, " +
+            listenerAtReceiver.totalDeleted + " deletes, " +
+            listenerAtReceiver.totalUpdated + " updates");
+        System.out.println(
+            "\nSingle pmf - " + benchmarkSingle +
+                "(s).\n Clustered pmfs (one worker thread) -"
+                + benchmarkClusterOneThread +
+                "(s).\n Clustered pmfs (" + NUM_CONCURRENT
+                + " threads - " + benchmarkCluster + "(s).\n");
+
+        Thread.currentThread().yield();
+        try {
+            Thread.currentThread().sleep((int) 500);
+        } catch (InterruptedException e) {
+            fail("unexecpted exception during pause");
+        }
+        assertEquals((NUM_CONCURRENT + 1) * NUM_OBJECTS,
+            listenerAtReceiver.totalAddedClasses);
+        assertEquals((NUM_CONCURRENT + 1) * NUM_OBJECTS,
+            listenerAtReceiver.totalDeleted);
+        assertEquals((NUM_CONCURRENT + 1) * NUM_OBJECTS,
+            listenerAtReceiver.totalUpdated);
+
+        // shutdown
+        pmSingle.close();
+        factorySingle.close();
+
+        factory2TCP.close();
+        senderFactory1TCP.close();
+    }
+
+    /*
+      *	Worker thread that takes ownership of a PM to perform
+      *	transactions. Once transactions are complete the tread
+      *	will close the PM and end.
+      */
+    private class Worker
+        implements Runnable {
+
+        private EntityManager _pm;
+
+        public Worker(EntityManager pm) {
+            _pm = pm;
+        }
+
+        public void run() {
+            doTransactions(_pm, NUM_OBJECTS);
+            endEm(_pm);
+        }
+    }
+
+    protected double doTransactions(EntityManager pm, int numObjects) {
+        // Perform a series of transactions  that will trigger
+        // adds, deletes, and udpates
+        Duration timeToAMD = new Duration(
+            "Adds, removes, and dletes for " + numObjects + " objects.");
+        timeToAMD.start();
+
+        // create objects
+        RuntimeTest1[] persistables = new RuntimeTest1[numObjects];
+        for (int i = 0; i < persistables.length; i++) {
+            persistables[i] = new RuntimeTest1("foo #" + i, i);
+        }
+
+        // add them
+        // This will generate a larger number of transaction in a very
+        // short amount of time (old socket-per-transaction would
+        // exhaust jvm socket pool)
+        for (int i = 0; i < persistables.length; i++) {
+            startTx(pm);
+            pm.persist(persistables[i]);
+            endTx(pm);
+        }
+
+        // modify them
+        startTx(pm);
+        for (int i = 0; i < persistables.length; i++) {
+            persistables[i].setStringField("bazzed" + i);
+        }
+        endTx(pm);
+
+        // delete them
+        startTx(pm);
+        for (int i = 0; i < persistables.length; i++) {
+            pm.remove(persistables[i]);
+        }
+        endTx(pm);
+
+        timeToAMD.stop();
+        return timeToAMD.getDurationAsSeconds();
+    }
+
+    static int _fetchGroupSerial = 0;
+
+    protected OpenJPAEntityManagerFactory createDistinctFactory(
+        Class providerClass, String classProps1) {
+        String transmit = "TransmitPersistedObjectIds=true";
+        if (classProps1 == null || classProps1.length() == 0)
+            classProps1 = transmit;
+        else
+            classProps1 += "," + transmit;
+
+        Map propsMap;
+        if (providerClass != null) {
+
+            propsMap = new HashMap();
+            propsMap.put("openjpa.RemoteCommitProvider", Configurations.
+                getPlugin(providerClass.getName(), classProps1));
+            propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup" +
+                _fetchGroupSerial);
+        } else {
+            // No RCP
+
+            propsMap = new HashMap();
+            propsMap.put("openjpa.RemoteCommitProvider",
+                "sjvm(TransmitPersistedObjectIds=true)");
+            propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup" +
+                _fetchGroupSerial);
+        }
+        _fetchGroupSerial += 1;
+
+        return getEmf(propsMap);
+    }
+
+    protected static class RemoteCommitListenerTestImpl
+        implements RemoteCommitListener {
+
+        Collection addClasses;
+        Collection added;
+        Collection updated;
+        Collection deleted;
+        int totalAddedClasses;
+        int totalUpdated;
+        int totalDeleted;
+
+        public synchronized void afterCommit(RemoteCommitEvent event) {
+            this.addClasses = event.getPersistedTypeNames();
+            this.updated = event.getUpdatedObjectIds();
+            this.deleted = event.getDeletedObjectIds();
+
+            totalAddedClasses += addClasses.size();
+            totalUpdated += updated.size();
+            totalDeleted += deleted.size();
+        }
+
+        public void close() {
+        }
+    }
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteRecovery.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteRecovery.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteRecovery.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteRecovery.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,327 @@
+/*
+ * 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.persistence.event;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.EntityManager;
+
+
+import org.apache.openjpa.persistence.event.common.apps.Duration;
+import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+import org.apache.openjpa.event.RemoteCommitEvent;
+import org.apache.openjpa.event.RemoteCommitListener;
+import org.apache.openjpa.event.TCPRemoteCommitProvider;
+import org.apache.openjpa.lib.conf.Configurations;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+
+public class TestTCPRemoteRecovery
+    extends AbstractTestCase {
+
+    public TestTCPRemoteRecovery(String s) {
+        super(s, "eventcactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+    }
+
+    public void tearDownTestClass()
+        throws Exception {
+        //super.tearDownTestClass();
+    }
+
+    private static final int NUM_OBJECTS = 1;
+
+    private void pause(double seconds) {
+        try {
+            Thread.currentThread().yield();
+            Thread.currentThread().sleep((int) seconds * 1000);
+        } catch (Exception e) {
+        }
+    }
+
+    public void testReceiverRecovers() {
+        // Create two pmfs in a cluster that are using RCPTCP.
+        OpenJPAEntityManagerFactory pmfSender = createDistinctFactory(
+            TCPRemoteCommitProvider.class,
+            "Port=5636, Addresses=127.0.0.1:5636;127.0.0.1:6636");
+        OpenJPAEntityManagerFactory pmfReceiver = createDistinctFactory(
+            TCPRemoteCommitProvider.class,
+            "Port=6636, Addresses=127.0.0.1:6636;127.0.0.1:5636");
+
+        // Register a RCEListener with the RCEM. Our RCEListener will
+        // record the total number of a,d, and u recevied from each
+        // RCE as the sending PM performs commits.
+        RemoteCommitListenerTestImpl listenerAtReceiver
+            = new RemoteCommitListenerTestImpl();
+        ((OpenJPAEntityManagerFactorySPI) pmfReceiver).getConfiguration()
+            .getRemoteCommitEventManager().
+            addListener(listenerAtReceiver);
+
+        EntityManager pmSender = pmfSender.createEntityManager();
+
+        System.out.println("-------------------");
+        System.out.println("2 PMFs created, acting as a cluster using ports " +
+            "5636 and 6636");
+        System.out.println("Testing scenario where receiver is failed, then " +
+            "recovered ");
+        System.out.println("after two timeouts all the while with the " +
+            "sending pm continuing");
+        System.out.println("to send.");
+
+        // Perform a set of transactions. Events will be communicated
+        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
+
+        // Wait for a bit so the receiver can get the event.
+        pause(1);
+        // Now Fail the receiver in the cluster
+        System.out.println("About to close the receiving pmf.");
+        pmfReceiver.close();
+        // Wait for a bit longer so the listener's threads all
+        // get closed out.
+        pause(1);
+        assertEquals(1, listenerAtReceiver.totalAddedClasses);
+        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalDeleted);
+        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalUpdated);
+
+        System.out.println("You should now see 1 WARN triggered as the " +
+            "sender-pmf tries to send.");
+        // Perform second set of transactions. This will trigger a single
+        // log WARN as the pmf won't be able to communciate events to the
+        // second member of the cluster.
+        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
+
+        // Wait for a recoverytime, try transactions again, this will
+        // trigger an INFO
+        pause(15.1);
+        System.out.println("Waited for a while. Should see 1 INFO for next " +
+            "transaction.");
+
+        // This will trigger a single log INFO
+        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
+        // This delay should ensure this second sent of
+        // transmissions is dropped as expected. If we
+        // don't pause, the new pmf can be created, then the
+        // events will be sent by the worker threads, and
+        // the new pmf will receive this messages (which
+        // are supposed to be dropped)
+        pause(1.1);
+
+        // -----
+        // Now recovery the Receiver and test that messages
+        // resume being delivered.
+        // -----
+
+        System.out.println("Recovering receiver pmf.");
+        // Recreate the listener pmf of the cluster.
+        pmfReceiver = createDistinctFactory(
+            TCPRemoteCommitProvider.class,
+            "Port=6636, Addresses=127.0.0.1:6636;127.0.0.1:5636");
+        pause(1.0);
+        // reRegister the same listener
+        ((OpenJPAEntityManagerFactorySPI) pmfReceiver).getConfiguration()
+            .getRemoteCommitEventManager().
+            addListener(listenerAtReceiver);
+        assertEquals(1, listenerAtReceiver.totalAddedClasses);
+        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalDeleted);
+        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalUpdated);
+
+        System.out.println("Now waiting a recoverytime so that the sender");
+        System.out.println("will resume trying to connect to the receiver.");
+        pause(15.1);
+
+        // These events should get communicated.
+        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
+
+        // Wait for a last little bit so the listener thread in
+        // the receiver PMF can get all messages.
+        pause(1.0);
+        assertEquals(2, listenerAtReceiver.totalAddedClasses);
+        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalDeleted);
+        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalUpdated);
+
+        // shutdown
+        pmSender.close();
+        pmfSender.close();
+        pmfReceiver.close();
+    }
+
+    public void testSenderRecovers() {
+        // Create two pmfs in a cluster that are using RCPTCP.
+        OpenJPAEntityManagerFactory pmfSender = createDistinctFactory(
+            TCPRemoteCommitProvider.class,
+            "Port=5637, Addresses=127.0.0.1:5637;127.0.0.1:6637");
+        OpenJPAEntityManagerFactory pmfReceiver = createDistinctFactory(
+            TCPRemoteCommitProvider.class,
+            "Port=6637, Addresses=127.0.0.1:6637;127.0.0.1:5637");
+
+        RemoteCommitListenerTestImpl listenerAtReceiver
+            = new RemoteCommitListenerTestImpl();
+        ((OpenJPAEntityManagerFactorySPI) pmfReceiver).getConfiguration()
+            .getRemoteCommitEventManager().
+            addListener(listenerAtReceiver);
+
+        EntityManager pmSender = pmfSender.createEntityManager();
+
+        System.out.println("-------------------");
+        System.out.println("2 PMFs created, acting as a cluster using ports " +
+            "5637 and 6637");
+        System.out.println("Testing scenario where sender fails and then " +
+            "later recovers.");
+        System.out.println("All the while the receiving pm stays up and " +
+            "should receive");
+        System.out.println("Events (both before and after the sender's " +
+            "failure).");
+
+        // Perform a set of transactions. Events in the cluster will be
+        // communicated
+        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
+
+        // Wait for a bit so the sockets in our sender PMF can fully transmit
+        // their Event messages to the receiver PMF.
+        pause(2.1);
+        // Fail the Sender in our cluster
+        System.out.println("Sender pmf closed.");
+        pmSender.close();
+        pmfSender.close();
+
+        // Wait for a while, try again, this will let close exception propagate
+        pause(4.1);
+        System.out.println("Waited for a while.");
+        System.out.println("Recovering the sender pmf.");
+
+        pmfSender = createDistinctFactory(
+            TCPRemoteCommitProvider.class,
+            "Port=5637, Addresses=127.0.0.1:5637;127.0.0.1:6637");
+        pmSender = pmfSender.createEntityManager();
+        // Perform a second set of transactions. Events in the cluster will be
+        // communicated
+        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
+
+        // Wait for a bit so the listener thread in the receiver PMF can get all
+        // messages.
+        pause(4.1);
+        assertEquals(2, listenerAtReceiver.totalAddedClasses);
+        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalDeleted);
+        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalUpdated);
+
+        // shutdown
+        pmSender.close();
+        pmfSender.close();
+        pmfReceiver.close();
+    }
+
+    protected double performAddsModifiesDeletes(EntityManager pm,
+        int numObjects) {
+        // Perform a series of transactions that will trigger adds,
+        // deletes, and udpates
+        Duration timeToAMD = new Duration(
+            "Adds, removes, and dletes for " + numObjects + " objects.");
+        timeToAMD.start();
+
+        // create objects
+        RuntimeTest1[] persistables = new RuntimeTest1[numObjects];
+        for (int i = 0; i < persistables.length; i++) {
+            persistables[i] = new RuntimeTest1("foo #" + i, i);
+        }
+
+        // add them
+        for (int i = 0; i < persistables.length; i++) {
+            startTx(pm);
+            pm.persist(persistables[i]);
+            endTx(pm);
+        }
+
+        // modify them
+        startTx(pm);
+        for (int i = 0; i < persistables.length; i++) {
+            persistables[i].setStringField("bazzed" + i);
+        }
+        endTx(pm);
+
+        // delete them
+        startTx(pm);
+        for (int i = 0; i < persistables.length; i++) {
+            pm.remove(persistables[i]);
+        }
+        endTx(pm);
+
+        timeToAMD.stop();
+        return timeToAMD.getDurationAsSeconds();
+    }
+
+    static int _fetchGroupSerial = 0;
+
+    protected OpenJPAEntityManagerFactory createDistinctFactory(
+        Class providerClass, String classProps1) {
+        Map propsMap;
+
+        if (providerClass != null) {
+
+            propsMap = new HashMap();
+            propsMap.put("openjpa.RemoteCommitProvider", Configurations.
+                getPlugin(providerClass.getName(), classProps1));
+            propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup" +
+                _fetchGroupSerial);
+        } else {
+            // No RCP
+            propsMap = new HashMap();
+            propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
+            propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup" +
+                _fetchGroupSerial);
+        }
+        _fetchGroupSerial += 1;
+
+        return getEmf(propsMap);
+    }
+
+    protected static class RemoteCommitListenerTestImpl
+        implements RemoteCommitListener {
+
+        Collection updated;
+        Collection deleted;
+        int totalAddedClasses;
+        int totalUpdated;
+        int totalDeleted;
+
+        public synchronized void afterCommit(RemoteCommitEvent event) {
+            this.updated = event.getUpdatedObjectIds();
+            this.deleted = event.getDeletedObjectIds();
+
+            totalAddedClasses += event.getPersistedTypeNames().size();
+            totalUpdated += updated.size();
+            totalDeleted += deleted.size();
+            System.out.println("Aftercommit " + this);
+        }
+
+        public void close() {
+        }
+
+        public String toString() {
+            String returnString = "Added clsses " + totalAddedClasses +
+                " Dels " + totalDeleted + " Ups " + totalUpdated;
+            return returnString;
+        }
+    }
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteRecoveryTransmitAdds.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteRecoveryTransmitAdds.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteRecoveryTransmitAdds.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestTCPRemoteRecoveryTransmitAdds.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,335 @@
+/*
+ * 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.persistence.event;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.EntityManager;
+
+
+import org.apache.openjpa.persistence.event.common.apps.Duration;
+import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+import org.apache.openjpa.event.RemoteCommitEvent;
+import org.apache.openjpa.event.RemoteCommitListener;
+import org.apache.openjpa.event.TCPRemoteCommitProvider;
+import org.apache.openjpa.lib.conf.Configurations;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+
+public class TestTCPRemoteRecoveryTransmitAdds
+    extends AbstractTestCase {
+
+    public TestTCPRemoteRecoveryTransmitAdds(String s) {
+        super(s, "eventcactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+    }
+
+    public void tearDownTestClass()
+        throws Exception {
+        //super.tearDownTestClass();
+    }
+
+    private static final int NUM_OBJECTS = 1;
+
+    private void pause(double seconds) {
+        try {
+            Thread.currentThread().yield();
+            Thread.currentThread().sleep((int) seconds * 1000);
+        } catch (Exception e) {
+        }
+    }
+
+    public void testReceiverRecovers() {
+        // Create two pmfs in a cluster that are using RCPTCP.
+        OpenJPAEntityManagerFactory pmfSender = createDistinctFactory(
+            TCPRemoteCommitProvider.class,
+            "Port=5636, Addresses=127.0.0.1:5636;127.0.0.1:6636");
+        OpenJPAEntityManagerFactory pmfReceiver = createDistinctFactory(
+            TCPRemoteCommitProvider.class,
+            "Port=6636, Addresses=127.0.0.1:6636;127.0.0.1:5636");
+
+        // Register a RCEListener with the RCEM. Our RCEListener will
+        // record the total number of a,d, and u recevied from each
+        // RCE as the sending PM performs commits.
+        RemoteCommitListenerTestImpl listenerAtReceiver
+            = new RemoteCommitListenerTestImpl();
+        ((OpenJPAEntityManagerFactorySPI) pmfReceiver).getConfiguration()
+            .getRemoteCommitEventManager().
+            addListener(listenerAtReceiver);
+
+        EntityManager pmSender = pmfSender.createEntityManager();
+
+        System.out.println("-------------------");
+        System.out.println("2 PMFs created, acting as a cluster using ports " +
+            "5636 and 6636");
+        System.out.println("Testing scenario where receiver is failed, then " +
+            "recovered ");
+        System.out.println("after two timeouts all the while with the " +
+            "sending pm continuing");
+        System.out.println("to send.");
+
+        // Perform a set of transactions. Events will be communicated
+        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
+
+        // Wait for a bit so the receiver can get the event.
+        pause(3);
+        // Now Fail the receiver in the cluster
+        System.out.println("About to close the receiving pmf.");
+        pmfReceiver.close();
+        // Wait for a bit longer so the listener's threads all
+        // get closed out.
+        pause(3);
+        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalAdded);
+        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalDeleted);
+        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalUpdated);
+
+        System.out.println("You should now see 1 WARN triggered as the " +
+            "sender-pmf tries to send.");
+        // Perform second set of transactions. This will trigger a single
+        // log WARN as the pmf won't be able to communciate events to the
+        // second member of the cluster.
+        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
+
+        // Wait for a recoverytime, try transactions again, this will
+        // trigger an INFO
+        pause(15.1);
+        System.out.println("Waited for a while. Should see 1 INFO for next " +
+            "transaction.");
+
+        // This will trigger a single log INFO
+        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
+        // This delay should ensure this second sent of
+        // transmissions is dropped as expected. If we
+        // don't pause, the new pmf can be created, then the
+        // events will be sent by the worker threads, and
+        // the new pmf will receive this messages (which
+        // are supposed to be dropped)
+        pause(1.1);
+
+        // -----
+        // Now recovery the Receiver and test that messages
+        // resume being delivered.
+        // -----
+
+        System.out.println("Recovering receiver pmf.");
+        // Recreate the listener pmf of the cluster.
+        pmfReceiver = createDistinctFactory(
+            TCPRemoteCommitProvider.class,
+            "Port=6636, Addresses=127.0.0.1:6636;127.0.0.1:5636");
+        pause(1.0);
+        // reRegister the same listener
+        ((OpenJPAEntityManagerFactorySPI) pmfReceiver).getConfiguration()
+            .getRemoteCommitEventManager().
+            addListener(listenerAtReceiver);
+        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalAdded);
+        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalDeleted);
+        assertEquals(NUM_OBJECTS, listenerAtReceiver.totalUpdated);
+
+        System.out.println("Now waiting a recoverytime so that the sender");
+        System.out.println("will resume trying to connect to the receiver.");
+        pause(15.1);
+
+        // These events should get communicated.
+        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
+
+        // Wait for a last little bit so the listener thread in
+        // the receiver PMF can get all messages.
+        pause(1.0);
+        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalAdded);
+        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalDeleted);
+        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalUpdated);
+
+        // shutdown
+        pmSender.close();
+        pmfSender.close();
+        pmfReceiver.close();
+    }
+
+    public void testSenderRecovers() {
+        // Create two pmfs in a cluster that are using RCPTCP.
+        OpenJPAEntityManagerFactory pmfSender = createDistinctFactory(
+            TCPRemoteCommitProvider.class,
+            "Port=5637, Addresses=127.0.0.1:5637;127.0.0.1:6637");
+        OpenJPAEntityManagerFactory pmfReceiver = createDistinctFactory(
+            TCPRemoteCommitProvider.class,
+            "Port=6637, Addresses=127.0.0.1:6637;127.0.0.1:5637");
+
+        RemoteCommitListenerTestImpl listenerAtReceiver
+            = new RemoteCommitListenerTestImpl();
+        ((OpenJPAEntityManagerFactorySPI) pmfReceiver).getConfiguration()
+            .getRemoteCommitEventManager().
+            addListener(listenerAtReceiver);
+
+        EntityManager pmSender = pmfSender.createEntityManager();
+
+        System.out.println("-------------------");
+        System.out.println("2 PMFs created, acting as a cluster using ports " +
+            "5637 and 6637");
+        System.out.println("Testing scenario where sender fails and then " +
+            "later recovers.");
+        System.out.println("All the while the receiving pm stays up and " +
+            "should receive");
+        System.out.println("Events (both before and after the sender's " +
+            "failure).");
+
+        // Perform a set of transactions. Events in the cluster will be
+        // communicated
+        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
+
+        // Wait for a bit so the sockets in our sender PMF can fully transmit
+        // their Event messages to the receiver PMF.
+        pause(2.1);
+        // Fail the Sender in our cluster
+        System.out.println("Sender pmf closed.");
+        pmSender.close();
+        pmfSender.close();
+
+        // Wait for a while, try again, this will let close exception propagate
+        pause(4.1);
+        System.out.println("Waited for a while.");
+        System.out.println("Recovering the sender pmf.");
+
+        pmfSender = createDistinctFactory(
+            TCPRemoteCommitProvider.class,
+            "Port=5637, Addresses=127.0.0.1:5637;127.0.0.1:6637");
+        pmSender = pmfSender.createEntityManager();
+        // Perform a second set of transactions. Events in the cluster will be
+        // communicated
+        performAddsModifiesDeletes(pmSender, NUM_OBJECTS);
+
+        // Wait for a bit so the listener thread in the receiver PMF can get all
+        // messages.
+        pause(4.1);
+        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalAdded);
+        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalDeleted);
+        assertEquals(2 * NUM_OBJECTS, listenerAtReceiver.totalUpdated);
+
+        // shutdown
+        pmSender.close();
+        pmfSender.close();
+        pmfReceiver.close();
+    }
+
+    protected double performAddsModifiesDeletes(EntityManager pm,
+        int numObjects) {
+        // Perform a series of transactions that will trigger adds,
+        // deletes, and udpates
+        Duration timeToAMD = new Duration(
+            "Adds, removes, and dletes for " + numObjects + " objects.");
+        timeToAMD.start();
+
+        // create objects
+        RuntimeTest1[] persistables = new RuntimeTest1[numObjects];
+        for (int i = 0; i < persistables.length; i++) {
+            persistables[i] = new RuntimeTest1("foo #" + i, i);
+        }
+
+        // add them
+        for (int i = 0; i < persistables.length; i++) {
+            startTx(pm);
+            pm.persist(persistables[i]);
+            endTx(pm);
+        }
+
+        // modify them
+        startTx(pm);
+        for (int i = 0; i < persistables.length; i++) {
+            persistables[i].setStringField("bazzed" + i);
+        }
+        endTx(pm);
+
+        // delete them
+        startTx(pm);
+        for (int i = 0; i < persistables.length; i++) {
+            pm.remove(persistables[i]);
+        }
+        endTx(pm);
+
+        timeToAMD.stop();
+        return timeToAMD.getDurationAsSeconds();
+    }
+
+    static int _fetchGroupSerial = 0;
+
+    protected OpenJPAEntityManagerFactory createDistinctFactory(
+        Class providerClass, String classProps1) {
+        String transmit = "TransmitPersistedObjectIds=true";
+        if (classProps1 == null || classProps1.length() == 0)
+            classProps1 = transmit;
+        else
+            classProps1 += "," + transmit;
+
+        Map propsMap;
+        if (providerClass != null) {
+            propsMap = new HashMap();
+            propsMap.put("openjpa.RemoteCommitProvider", Configurations.
+                getPlugin(providerClass.getName(), classProps1));
+            propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup" +
+                _fetchGroupSerial);
+        } else {
+            // No RCP
+
+            propsMap = new HashMap();
+            propsMap.put("openjpa.RemoteCommitProvider",
+                "sjvm(TransmitPersistedObjectIds=true)");
+            propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup" +
+                _fetchGroupSerial);
+        }
+        _fetchGroupSerial += 1;
+
+        return getEmf(propsMap);
+    }
+
+    protected static class RemoteCommitListenerTestImpl
+        implements RemoteCommitListener {
+
+        Collection added;
+        Collection updated;
+        Collection deleted;
+        int totalAdded;
+        int totalUpdated;
+        int totalDeleted;
+
+        public synchronized void afterCommit(RemoteCommitEvent event) {
+
+            this.added = event.getPersistedObjectIds();
+            this.updated = event.getUpdatedObjectIds();
+            this.deleted = event.getDeletedObjectIds();
+
+            totalAdded += added.size();
+            totalUpdated += updated.size();
+            totalDeleted += deleted.size();
+        }
+
+        public void close() {
+        }
+
+        public String toString() {
+            String returnString = "Adds " + totalAdded + " Dels " +
+                totalDeleted + " Ups " + totalUpdated;
+            return returnString;
+        }
+    }
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/Duration.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/Duration.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/Duration.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/Duration.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,236 @@
+/*
+ * 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.persistence.event.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+
+/*
+
+    Millisecond (only) accuracy timer.
+
+    Java 1.4 supposedly has sun.misc.Perf.
+
+    Java 1.5 has System.nanoTime (JSR 166)
+
+*/
+
+public class Duration
+
+    implements Cloneable {
+
+    private String _name;
+
+    private boolean _started;
+
+    private boolean _running;
+
+    private long _startTime;        // millis
+
+    private long _stopTime;        // millis
+
+    // NYI clock time of day at start
+
+    public Duration(String name) {
+
+        _name = name;
+
+        _started = false;
+
+        _running = false;
+    }
+
+    public String getName() {
+
+        return _name;
+    }
+
+    public synchronized void start() {
+
+        if (_started) {
+
+            throw new RuntimeException("Duration was already started.");
+        }
+
+        _startTime = System.currentTimeMillis();
+
+        _started = true;
+
+        _running = true;
+    }
+
+    public synchronized void stop() {
+
+        if (!_started) {
+
+            throw new RuntimeException("Duration was never started.");
+        }
+
+        if (!_running) {
+
+            throw new RuntimeException("Duration was already stopped.");
+        }
+
+        _stopTime = System.currentTimeMillis();
+
+        _running = false;
+    }
+
+    protected Object clone()
+
+        throws CloneNotSupportedException {
+
+        return super.clone();
+    }
+
+    /*
+
+        Returns a new Duration object from a currently running timer
+
+        as a snapshot of this object.
+
+        The returned timer is stopped, while this object continue on.
+
+    */
+
+    public synchronized Duration getCurrentDuration() {
+
+        if (!_started) {
+
+            throw new RuntimeException("Duration was never started.");
+        }
+
+        if (!_running) {
+
+            throw new RuntimeException("Duration is not running.");
+        }
+
+        long now = System.currentTimeMillis();
+
+        Duration currentDuration;
+
+        try {
+
+            currentDuration = (Duration) this.clone();
+        } catch (Exception e) {
+
+            currentDuration = new Duration("");
+        }
+
+        currentDuration._stopTime = now;
+
+        currentDuration._running = false;
+
+        return currentDuration;
+    }
+
+    /* Obtain the duration that this timer has run (in seconds)	*/
+
+    public synchronized double getDurationAsSeconds() {
+
+        if (!_started) {
+
+            throw new RuntimeException("Duration was never started.");
+        }
+
+        if (_running) {
+
+            // snapshot
+
+            Duration snapshot = getCurrentDuration();
+
+            return (1000.0 * (snapshot._stopTime - snapshot._startTime));
+        }
+
+        // Return a double value. Someday this class may make use of
+
+        // higher precision timing services (e.g. java 1.5)
+
+        return ((_stopTime - _startTime) / (double) 1000.0);
+    }
+
+    public synchronized boolean isRunning() {
+
+        return _running;
+    }
+
+    public synchronized boolean wasStarted() {
+
+        return _started;
+    }
+
+    public String toString() {
+
+        double time = 0.0;
+
+        StringBuffer buf = new StringBuffer(256);
+
+        if (wasStarted()) {
+
+            if (isRunning()) {
+
+                Duration snapshot = getCurrentDuration();
+
+                time = snapshot.getDurationAsSeconds();
+            } else {
+
+                time = getDurationAsSeconds();
+            }
+
+            buf.append("Duration for '" + _name + "' is " + time + " (s).");
+        } else {
+
+            buf.append("Duration for '" + _name +
+
+                "' has not yet been started.");
+        }
+
+        return buf.toString();
+    }
+
+/* Example usage:
+
+       public static void main (String[] args)
+
+        throws Exception
+
+    {
+
+        Duration test = new Duration ("hello, count to 1 million");
+
+        System.out.println (test);
+
+        test.start ();
+
+        for (int i = 0; i < 1000000000; i++)
+
+            {
+
+            }
+
+        test.stop ();
+
+        System.out.println (test);
+
+    }
+
+    */
+}
+

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/RuntimeTest1.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/RuntimeTest1.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/RuntimeTest1.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/RuntimeTest1.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,279 @@
+/*
+ * 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.persistence.event.common.apps;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Set;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.OneToOne;
+
+import org.apache.openjpa.persistence.PersistentCollection;
+
+/**
+ * Used in testing; should be enhanced.
+ */
+@Entity
+public class RuntimeTest1
+    implements Serializable {
+
+    public static final String someStaticField = "someField";
+
+    private byte byteField;
+    private boolean booleanField;
+    private char charField;
+    private double doubleField = 1.0;
+    private float floatField = 1.0f;
+    private int intField;
+    private long longField;
+    private short shortField;
+    private String stringField;
+    private BigInteger bigIntegerField;
+    private BigDecimal bigDecimalField;
+    private Date dateField;
+    private Locale localeField;
+    private Byte byteObjfield;
+    private Boolean booleanObjField;
+    private Character charObjField;
+    private Double doubleObjField;
+    private Float floatObjField = 1.0F;
+    private Integer intObjField;
+    private Long longObjField;
+    private Short shortObjField;
+
+    // transactional only
+    private TransactionalClassPC transField;
+    public String transString;
+
+    // relations
+    @OneToOne(fetch = FetchType.LAZY, cascade = { CascadeType.ALL })
+    private RuntimeTest1 selfOneOne;
+    @PersistentCollection
+    private Set selfOneMany = new HashSet();
+
+    public RuntimeTest1() {
+    }
+
+    public RuntimeTest1(String str, int i) {
+        stringField = str;
+        intField = i;
+
+        //FIXME Seetha Oct 25,2006
+        //mySQL 0.0 float issue
+        floatField = 1.0f;
+    }
+
+    public byte getByteField() {
+        return this.byteField;
+    }
+
+    public void setByteField(byte byteField) {
+        this.byteField = byteField;
+    }
+
+    public boolean getBooleanField() {
+        return this.booleanField;
+    }
+
+    public void setBooleanField(boolean booleanField) {
+        this.booleanField = booleanField;
+    }
+
+    public char getCharField() {
+        return this.charField;
+    }
+
+    public void setCharField(char charField) {
+        this.charField = charField;
+    }
+
+    public double getDoubleField() {
+        return this.doubleField;
+    }
+
+    public void setDoubleField(double doubleField) {
+        this.doubleField = doubleField;
+    }
+
+    public float getFloatField() {
+        return this.floatField;
+    }
+
+    public void setFloatField(float floatField) {
+        this.floatField = floatField;
+    }
+
+    public int getIntField() {
+        return this.intField;
+    }
+
+    public void setIntField(int intField) {
+        this.intField = intField;
+    }
+
+    public long getLongField() {
+        return this.longField;
+    }
+
+    public void setLongField(long longField) {
+        this.longField = longField;
+    }
+
+    public short getShortField() {
+        return this.shortField;
+    }
+
+    public void setShortField(short shortField) {
+        this.shortField = shortField;
+    }
+
+    public String getStringField() {
+        return this.stringField;
+    }
+
+    public void setStringField(String stringField) {
+        this.stringField = stringField;
+    }
+
+    public BigInteger getBigIntegerField() {
+        return this.bigIntegerField;
+    }
+
+    public void setBigIntegerField(BigInteger bigIntegerField) {
+        this.bigIntegerField = bigIntegerField;
+    }
+
+    public BigDecimal getBigDecimalField() {
+        return this.bigDecimalField;
+    }
+
+    public void setBigDecimalField(BigDecimal bigDecimalField) {
+        this.bigDecimalField = bigDecimalField;
+    }
+
+    public Date getDateField() {
+        return this.dateField;
+    }
+
+    public void setDateField(Date dateField) {
+        this.dateField = dateField;
+    }
+
+    public Locale getLocaleField() {
+        return this.localeField;
+    }
+
+    public void setLocaleField(Locale localeField) {
+        this.localeField = localeField;
+    }
+
+    public Byte getByteObjfield() {
+        return this.byteObjfield;
+    }
+
+    public void setByteObjfield(Byte byteObjfield) {
+        this.byteObjfield = byteObjfield;
+    }
+
+    public Boolean getBooleanObjField() {
+        return this.booleanObjField;
+    }
+
+    public void setBooleanObjField(Boolean booleanObjField) {
+        this.booleanObjField = booleanObjField;
+    }
+
+    public Character getCharObjField() {
+        return this.charObjField;
+    }
+
+    public void setCharObjField(Character charObjField) {
+        this.charObjField = charObjField;
+    }
+
+    public Double getDoubleObjField() {
+        return this.doubleObjField;
+    }
+
+    public void setDoubleObjField(Double doubleObjField) {
+        this.doubleObjField = doubleObjField;
+    }
+
+    public Float getFloatObjField() {
+        return this.floatObjField;
+    }
+
+    public void setFloatObjField(Float floatObjField) {
+        this.floatObjField = floatObjField;
+    }
+
+    public Integer getIntObjField() {
+        return this.intObjField;
+    }
+
+    public void setIntObjField(Integer intObjField) {
+        this.intObjField = intObjField;
+    }
+
+    public Long getLongObjField() {
+        return this.longObjField;
+    }
+
+    public void setLongObjField(Long longObjField) {
+        this.longObjField = longObjField;
+    }
+
+    public Short getShortObjField() {
+        return this.shortObjField;
+    }
+
+    public void setShortObjField(Short shortObjField) {
+        this.shortObjField = shortObjField;
+    }
+
+    public TransactionalClassPC getTransField() {
+        return this.transField;
+    }
+
+    public void setTransField(TransactionalClassPC transField) {
+        this.transField = transField;
+    }
+
+    public RuntimeTest1 getSelfOneOne() {
+        return this.selfOneOne;
+    }
+
+    public void setSelfOneOne(RuntimeTest1 selfOneOne) {
+        this.selfOneOne = selfOneOne;
+    }
+
+    public Set getSelfOneMany() {
+        return this.selfOneMany;
+    }
+
+    public void setSelfOneMany(Set selfOneMany) {
+        this.selfOneMany = selfOneMany;
+    }
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/RuntimeTest2.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/RuntimeTest2.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/RuntimeTest2.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/RuntimeTest2.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,48 @@
+/*
+ * 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.persistence.event.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+/**
+ * <p>Persitent type used in testing.</p>
+ *
+ * @author Abe White
+ */
+public class RuntimeTest2
+    extends RuntimeTest1 {
+
+    private int intField2;
+
+    public RuntimeTest2() {
+    }
+
+    public RuntimeTest2(String str, int i) {
+        super(str, i);
+    }
+
+    public int getIntField2() {
+        return this.intField2;
+    }
+
+    public void setIntField2(int intField2) {
+        this.intField2 = intField2;
+    }
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/RuntimeTest4.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/RuntimeTest4.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/RuntimeTest4.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/RuntimeTest4.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,50 @@
+/*
+ * 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.persistence.event.common.apps;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import javax.persistence.Entity;
+
+@Entity
+public class RuntimeTest4 {
+
+    private String name;
+    private Collection runtimeTest5s = new ArrayList();
+
+    public RuntimeTest4(String str) {
+        name = str;
+    }
+
+    public void setName(String val) {
+        name = val;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Collection getRuntimeTest5s() {
+        return runtimeTest5s;
+    }
+
+    public void setRuntimeTest5s(Collection c) {
+        runtimeTest5s = c;
+    }
+}
\ No newline at end of file

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/TransactionalClassPC.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/TransactionalClassPC.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/TransactionalClassPC.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/common/apps/TransactionalClassPC.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,35 @@
+/*
+ * 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.persistence.event.common.apps;
+
+import javax.persistence.Entity;
+
+@Entity
+public class TransactionalClassPC {
+
+    private int intField;
+
+    public int getIntField() {
+        return this.intField;
+    }
+
+    public void setIntField(int intField) {
+        this.intField = intField;
+    }
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/header
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/header?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/header (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/header Fri Feb 15 01:19:55 2008
@@ -0,0 +1,19 @@
+/*
+ * 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 bea

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AttachA.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AttachA.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AttachA.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AttachA.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,118 @@
+/*
+ * 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.persistence.jdbc.common.apps;
+
+import org.apache.openjpa.kernel.*;
+
+import java.util.*;
+import java.io.*;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.lang.annotation.Annotation;
+
+@Entity
+
+
+public class AttachA
+    implements Serializable, PreDetachCallback,
+    PostDetachCallback, PreAttachCallback, PostAttachCallback {
+
+    // transient method for testing callbacks
+    public transient Object detachSource = null;
+    public transient Object attachSource = null;
+    public transient int preAttachCalls = 0;
+    public transient int postAttachCalls = 0;
+    public transient int preDetachCalls = 0;
+    public transient int postDetachCalls = 0;
+
+    private String astr;
+    private int aint;
+    private double adbl;
+    private String [] stringArray = new String [0];
+    private AttachE [] attachEArray = new AttachE [0];
+
+    public void jdoPreDetach() {
+        preDetachCalls++;
+    }
+
+    public void jdoPostDetach(Object orig) {
+        postDetachCalls++;
+        detachSource = orig;
+    }
+
+    public void jdoPreAttach() {
+        preAttachCalls++;
+    }
+
+    public void jdoPostAttach(Object orig) {
+        postAttachCalls++;
+        attachSource = orig;
+    }
+
+    public void setAstr(String astr) {
+        this.astr = astr;
+    }
+
+    public String getAstr() {
+        return this.astr;
+    }
+
+    public void setAint(int aint) {
+        this.aint = aint;
+    }
+
+    public int getAint() {
+        return this.aint;
+    }
+
+    public void setAdbl(double adbl) {
+        this.adbl = adbl;
+    }
+
+    public double getAdbl() {
+        return this.adbl;
+    }
+
+    public void setStringArray(String [] stringArray) {
+        this.stringArray = stringArray;
+    }
+
+    public String [] getStringArray() {
+        return this.stringArray;
+    }
+
+    public void setAttachEArray(AttachE [] attachEArray) {
+        this.attachEArray = attachEArray;
+    }
+
+    public AttachE [] getAttachEArray() {
+        return this.attachEArray;
+    }
+
+    private void writeObject(ObjectOutputStream out)
+        throws IOException {
+        out.defaultWriteObject();
+    }
+
+    private void readObject(ObjectInputStream in)
+        throws IOException, ClassNotFoundException {
+        in.defaultReadObject();
+    }
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AttachB.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AttachB.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AttachB.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AttachB.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,79 @@
+/*
+ * 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.persistence.jdbc.common.apps;
+
+import org.apache.openjpa.kernel.*;
+
+import java.io.*;
+import java.util.*;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.lang.annotation.Annotation;
+
+@Entity
+public class AttachB
+    extends AttachA {
+
+    private String bstr;
+    private int bint;
+    private double bdbl;
+    private Set ds = new HashSet();
+    private Map stringIntMap = new TreeMap();
+
+    public void setBstr(String bstr) {
+        this.bstr = bstr;
+    }
+
+    public String getBstr() {
+        return this.bstr;
+    }
+
+    public void setBint(int bint) {
+        this.bint = bint;
+    }
+
+    public int getBint() {
+        return this.bint;
+    }
+
+    public void setBdbl(double bdbl) {
+        this.bdbl = bdbl;
+    }
+
+    public double getBdbl() {
+        return this.bdbl;
+    }
+
+    public void setDs(Set ds) {
+        this.ds = ds;
+    }
+
+    public Set getDs() {
+        return this.ds;
+    }
+
+    public void setStringIntMap(Map stringIntMap) {
+        this.stringIntMap = stringIntMap;
+    }
+
+    public Map getStringIntMap() {
+        return this.stringIntMap;
+    }
+}



Mime
View raw message