[jboss-svn-commits] JBL Code SVN: r21588 - in labs/jbossrules/trunk/drools-core: src/main/java and 3 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Sun Aug 17 22:54:07 EDT 2008


Author: mark.proctor at jboss.com
Date: 2008-08-17 22:54:07 -0400 (Sun, 17 Aug 2008)
New Revision: 21588

Added:
   labs/jbossrules/trunk/drools-core/derbyDB/
   labs/jbossrules/trunk/drools-core/src/main/java/jdbm/
   labs/jbossrules/trunk/drools-core/src/main/java/jdbm/recman/
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/ByteArraySnapshotter.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/DroolsXid.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/InMemoryTransactionManager.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/InMemoryXaResource.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/InMemoryXaResourceTest.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/MockByteArraySnapshotter.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/Transaction.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/TransactionManager.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/TransactionManagerTest.java
Log:
JBRULES-1738 Support XAResource transactions and generic save points
JBRULES-1739 in-memory XAResource

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/ByteArraySnapshotter.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/ByteArraySnapshotter.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/ByteArraySnapshotter.java	2008-08-18 02:54:07 UTC (rev 21588)
@@ -0,0 +1,10 @@
+/**
+ * 
+ */
+package org.drools.transaction;
+
+public interface ByteArraySnapshotter {
+    public byte[] getSnapshot();
+    
+    public void restoreSnapshot(byte[] bytes);       
+}
\ No newline at end of file

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/DroolsXid.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/DroolsXid.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/DroolsXid.java	2008-08-18 02:54:07 UTC (rev 21588)
@@ -0,0 +1,39 @@
+package org.drools.transaction;
+
+import javax.transaction.xa.*;
+
+    
+    public class DroolsXid implements Xid
+    {
+        protected int formatId;
+        protected byte gtrid[];
+        protected byte bqual[];
+
+        public DroolsXid()
+        {
+        }
+
+        public DroolsXid(int formatId, byte gtrid[], byte bqual[])
+        {
+            this.formatId = formatId;
+            this.gtrid = gtrid;
+            this.bqual = bqual;
+        }
+
+
+        public int getFormatId()
+        {
+            return formatId;
+        }
+
+        public byte[] getBranchQualifier()
+        {
+            return bqual;
+        }
+
+        public byte[] getGlobalTransactionId()
+        {
+            return gtrid;
+        }
+
+    }

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/InMemoryTransactionManager.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/InMemoryTransactionManager.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/InMemoryTransactionManager.java	2008-08-18 02:54:07 UTC (rev 21588)
@@ -0,0 +1,34 @@
+package org.drools.transaction;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.OutputStream;
+import java.io.RandomAccessFile;
+import java.nio.channels.FileChannel;
+import java.util.LinkedList;
+import java.util.List;
+
+import jdbm.RecordManager;
+
+import org.drools.StatefulSession;
+import org.drools.common.InternalRuleBase;
+import org.drools.common.InternalWorkingMemory;
+import org.drools.marshalling.DefaultMarshaller;
+import org.drools.reteoo.ReteooStatefulSession;
+import org.drools.reteoo.ReteooWorkingMemory;
+
+import sun.nio.ch.ChannelInputStream;
+
+
+public class InMemoryTransactionManager {       
+    LinkedList<byte[]> levels;
+    
+    byte[] lastSave;  
+    
+    public XAResource getXAResource() {
+        
+    }
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/InMemoryXaResource.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/InMemoryXaResource.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/InMemoryXaResource.java	2008-08-18 02:54:07 UTC (rev 21588)
@@ -0,0 +1,107 @@
+package org.drools.transaction;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+
+import javax.transaction.xa.XAException;
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
+
+import sun.text.CompactShortArray.Iterator;
+
+/**
+ * crude nested transaction manager, not written for performance
+ * @author mproctor
+ *
+ */
+public class InMemoryXaResource implements XAResource {
+    private ByteArraySnapshotter byteArrayAccessorDelegate;
+    
+    //Map<Xid, Transaction> xidMapping = new HashMap<Xid, Transaction>();
+    Map<Xid, byte[]> data = new HashMap<Xid, byte[]>();
+    LinkedList<Xid> list = new LinkedList<Xid>();
+    
+    byte[] lastSave;        
+
+    public InMemoryXaResource(ByteArraySnapshotter byteArrayAccessorDelegate) {
+        this.byteArrayAccessorDelegate = byteArrayAccessorDelegate;
+    }
+
+    public void start(Xid xid,
+                      int flags) throws XAException {
+        byte[] bytes = byteArrayAccessorDelegate.getSnapshot();
+        // The start of the first transaction is recorded as  save point, for HA.
+        if ( this.list.isEmpty() ) {
+            this.lastSave = bytes;
+        }        
+        
+        this.list.add( xid );
+        this.data.put( xid, bytes );
+    }     
+    
+    public void rollback(Xid xid) throws XAException {   
+        if ( this.list.isEmpty() ) {
+            // nothing to rollback
+            return;
+        }
+        byte[] bytes = this.data.get( xid );
+        
+        boolean remove = false;
+        for(java.util.Iterator<Xid> it = this.list.iterator(); it.hasNext(); ) {
+            Xid currentXid = it.next();
+            if ( !remove && currentXid.equals( xid )) {
+                remove = true;
+            } 
+            
+            if ( remove ) {
+                this.data.remove( currentXid );
+                it.remove();
+            }                        
+        }
+                        
+        this.byteArrayAccessorDelegate.restoreSnapshot( bytes );
+    }    
+    
+    public void commit(Xid xid,
+                       boolean onePhase) throws XAException {
+        if ( this.list.getFirst().equals( xid ) && this.list.size() > 1 ) {
+            // first one has committed, so move save point to next transaction
+            this.lastSave = this.data.get( this.list.get( 1 ) );                   
+        } else if ( this.list.size() == 1 ) {
+            // there will be no more transactions after this is removed, so create a new lastSave point
+            this.lastSave = byteArrayAccessorDelegate.getSnapshot();
+        }
+        
+        this.list.remove( xid );
+        this.data.remove( xid );        
+    }
+    
+    public void end(Xid xid,
+                    int flags) throws XAException {    
+    }        
+
+    public void forget(Xid xid) throws XAException {        
+    }
+
+    public int getTransactionTimeout() throws XAException {
+        return 0;
+    }
+
+    public boolean isSameRM(XAResource xares) throws XAException {
+        return false;
+    }
+
+    public int prepare(Xid xid) throws XAException {
+        return 0;
+    }
+
+    public Xid[] recover(int flag) throws XAException {
+        return null;
+    }
+
+    public boolean setTransactionTimeout(int seconds) throws XAException {
+        return false;
+    }      
+
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/InMemoryXaResourceTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/InMemoryXaResourceTest.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/InMemoryXaResourceTest.java	2008-08-18 02:54:07 UTC (rev 21588)
@@ -0,0 +1,113 @@
+package org.drools.transaction;
+
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
+
+import junit.framework.TestCase;
+
+public class InMemoryXaResourceTest extends  TestCase {
+    private byte[] data1 = new byte[] { 1, 1, 1, 1, 1 };
+    private byte[] data2 = new byte[] { 1, 1, 1, 1, 0 };
+    private byte[] data3 = new byte[] { 1, 1, 1, 0, 0 };
+    
+    MockByteArraySnapshotter snapshotter;
+    
+    protected void setUp() throws Exception {
+        this.snapshotter = new MockByteArraySnapshotter();
+    }
+    
+    public void testInitFields() {
+        InMemoryXaResource xa = new InMemoryXaResource( snapshotter );
+        
+        // make sure these are initialised correctly
+        assertEquals( 0, xa.list.size() );
+        assertNull( xa.lastSave );              
+    }
+    
+    public void testSingleTransactionWithRollBack() throws Exception {
+        InMemoryXaResource xa = new InMemoryXaResource( snapshotter );
+        
+        Xid xid = new DroolsXid(100, new byte[]{0x01}, new byte[]{0x01});
+
+        
+        snapshotter.bytes = data1;        
+        xa.start(xid, XAResource.TMNOFLAGS);
+        assertEquals( 1, xa.list.size() ); // we only have one transaction
+        assertSame( xa.data.get( xa.list.get( 0 )), xa.lastSave ); // lastSave is always set to begin of the first transaction
+        
+        snapshotter.bytes = data2;
+        xa.rollback(xid);      
+        
+        assertTrue( assertEquals( data1, snapshotter.bytes ) );
+        assertTrue( xa.list.isEmpty() );
+        assertTrue( xa.data.isEmpty() );        
+    }
+    
+    public void testSingleTransactionWithCommit() throws Exception {
+        InMemoryXaResource xa = new InMemoryXaResource( snapshotter );
+        
+        Xid xid = new DroolsXid(100, new byte[]{0x01}, new byte[]{0x01});
+        
+        snapshotter.bytes = data1;        
+        xa.start(xid, XAResource.TMNOFLAGS);
+        
+        snapshotter.bytes = data2;
+        xa.commit(xid, true);
+        
+        // check levels are empty and that lastsave was updated to be the same as end
+        assertEquals( 0, xa.list.size() );
+        assertSame( data2, xa.lastSave );
+        
+        // should do nothing as there is nothing to rollback
+        xa.rollback(xid);
+        
+        assertTrue( assertEquals( data2, snapshotter.bytes ) );        
+        assertTrue( xa.list.isEmpty() );
+        assertTrue( xa.data.isEmpty() );
+    }         
+    
+    public void testMultipleTransactions() throws Exception {
+        InMemoryXaResource xa = new InMemoryXaResource( snapshotter );
+        
+        Xid xid1 = new DroolsXid(100, new byte[]{0x01}, new byte[]{0x01});
+        
+        snapshotter.bytes = data1;        
+        xa.start(xid1, XAResource.TMNOFLAGS);
+        
+        Xid xid2 = new DroolsXid(100, new byte[]{0x02}, new byte[]{0x02});
+        snapshotter.bytes = data2;
+        xa.start(xid2, XAResource.TMNOFLAGS);        
+        assertEquals( 2, xa.list.size() ); // we now have two levels
+        assertSame( xa.data.get( xa.list.get( 0 ) ), xa.lastSave ); // check lastSave is still first transaction
+        
+        Xid xid3 = new DroolsXid(100, new byte[]{0x03}, new byte[]{0x03});
+        snapshotter.bytes = data3;
+        xa.start(xid3, XAResource.TMNOFLAGS);      
+        assertEquals( 3, xa.list.size() );  // we now have three levels.
+        
+        // commit the first, so the second should become the lastSave point
+        xa.commit( xid1, true );
+        
+        assertSame( xa.data.get( xid2 ), xa.lastSave ); // xid2 should now be the lastSave point
+
+        // rollback xid2, should result in rolling back xid3 too
+        xa.rollback( xid2  );
+        
+        assertTrue( xa.list.isEmpty() );
+        assertTrue( xa.data.isEmpty() );
+    }    
+  
+    public boolean assertEquals( byte[] bytes1, byte[] bytes2) {
+        if ( bytes1.length != bytes2.length ) {
+            return false;
+        }
+        
+        for ( int i = 0; i < bytes1.length; i++ ) {
+            if ( bytes1[i] != bytes2[i] ) {
+                return false;
+            }
+        }
+        
+        return true;
+    }
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/MockByteArraySnapshotter.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/MockByteArraySnapshotter.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/MockByteArraySnapshotter.java	2008-08-18 02:54:07 UTC (rev 21588)
@@ -0,0 +1,24 @@
+/**
+ * 
+ */
+package org.drools.transaction;
+
+public class MockByteArraySnapshotter implements ByteArraySnapshotter {
+    public byte[] bytes;
+
+    public MockByteArraySnapshotter() {
+        
+    }
+    
+    public MockByteArraySnapshotter(byte[] bytes) {
+        this.bytes = bytes;
+    }
+    
+    public byte[] getSnapshot() {
+        return bytes;
+    }
+
+    public void restoreSnapshot(byte[] bytes) {
+        this.bytes = bytes;
+    }        
+}
\ No newline at end of file

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/Transaction.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/Transaction.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/Transaction.java	2008-08-18 02:54:07 UTC (rev 21588)
@@ -0,0 +1,46 @@
+package org.drools.transaction;
+
+import javax.transaction.xa.XAException;
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
+
+public class Transaction {
+    private Xid xid;    
+    
+    XAResource xaResource;
+    
+    public Transaction(Xid xid, XAResource xaResource) {
+        this.xid = xid;
+        this.xaResource = xaResource;
+    }
+    
+    public Xid getXid() {
+        return xid;
+    }    
+    
+    public void start() throws XAException {
+        this.xaResource.start( xid, XAResource.TMNOFLAGS );
+    }
+    
+    public void commit() throws XAException {
+        this.xaResource.commit( xid, true );
+    }
+
+    @Override
+    public int hashCode() {
+        return xid.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if ( this == obj ) return true;
+        if ( obj == null ) return false;
+        if ( getClass() != obj.getClass() ) return false;
+        Transaction other = (Transaction) obj;
+        if ( xid == null ) {
+            if ( other.xid != null ) return false;
+        } else if ( !xid.equals( other.xid ) ) return false;
+        return true;
+    }       
+     
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/TransactionManager.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/TransactionManager.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/TransactionManager.java	2008-08-18 02:54:07 UTC (rev 21588)
@@ -0,0 +1,8 @@
+package org.drools.transaction;
+
+public interface TransactionManager {
+    public void start();
+    public void end();
+    public void rollback();
+    
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/TransactionManagerTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/TransactionManagerTest.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/transaction/TransactionManagerTest.java	2008-08-18 02:54:07 UTC (rev 21588)
@@ -0,0 +1,31 @@
+package org.drools.transaction;
+
+import org.drools.transaction.DefaultTransactionManager.ByteArrayAccessor;
+
+import junit.framework.TestCase;
+
+public class TransactionManagerTest extends TestCase {
+    
+    public void test1() {
+        MockByteArrayAccessor accessor = new MockByteArrayAccessor();
+        DefaultTransactionManager tm = new DefaultTransactionManager( accessor );
+        
+        accessor.bytes = new byte[] { 0, 1, 0, 1 };
+        
+        tm.start();
+    }
+
+    public static class MockByteArrayAccessor implements ByteArraySnapshotter {
+        public byte[] bytes;
+        
+
+        public byte[] getSnapshot() {
+            return this.bytes;
+        }
+
+        public void restoreSnapshot(byte[] bytes) {
+            this.bytes = bytes;
+        }
+        
+    }
+}




More information about the jboss-svn-commits mailing list