directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From s...@apache.org
Subject svn commit: r1302302 - in /directory/apacheds/branches/apacheds-txns: core-api/src/main/java/org/apache/directory/server/core/api/interceptor/context/ core-api/src/test/java/org/apache/directory/server/core/api/ core-integ/src/test/java/org/apache/dire...
Date Mon, 19 Mar 2012 07:08:53 GMT
Author: saya
Date: Mon Mar 19 07:08:52 2012
New Revision: 1302302

URL: http://svn.apache.org/viewvc?rev=1302302&view=rev
Log:
First real end to end test to work the guts of txn system. The test has two threads to do
modify operations on the same attribute of the same entry . They conflict but the resulting
entry is a serialized form of their executions.

the rest is the fix based on this test.

next will come similar tests for other ldap operations.

Added:
    directory/apacheds/branches/apacheds-txns/core-integ/src/test/java/org/apache/directory/server/core/txn/
    directory/apacheds/branches/apacheds-txns/core-integ/src/test/java/org/apache/directory/server/core/txn/TxnConflictIT.java
Modified:
    directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/context/AbstractChangeOperationContext.java
    directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/context/AbstractOperationContext.java
    directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/context/ModifyOperationContext.java
    directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/context/OperationContext.java
    directory/apacheds/branches/apacheds-txns/core-api/src/test/java/org/apache/directory/server/core/api/MockOperation.java
    directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/DefaultTxnManager.java
    directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/DefaultOperationManager.java
    directory/apacheds/branches/apacheds-txns/interceptors/changelog/src/main/java/org/apache/directory/server/core/changelog/ChangeLogInterceptor.java

Modified: directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/context/AbstractChangeOperationContext.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/context/AbstractChangeOperationContext.java?rev=1302302&r1=1302301&r2=1302302&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/context/AbstractChangeOperationContext.java
(original)
+++ directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/context/AbstractChangeOperationContext.java
Mon Mar 19 07:08:52 2012
@@ -53,6 +53,20 @@ public abstract class AbstractChangeOper
     public AbstractChangeOperationContext( CoreSession session )
     {
         super( session );
+        
+        logChange = LogChange.TRUE;
+    }
+    
+    
+    /**
+     * {@inheritDoc}
+     */
+    public void reset()
+    {
+        super.reset();
+        modifiedEntry = null;
+        logChange = LogChange.FALSE;
+        changeLogEvent = null;
     }
 
     

Modified: directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/context/AbstractOperationContext.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/context/AbstractOperationContext.java?rev=1302302&r1=1302301&r2=1302302&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/context/AbstractOperationContext.java
(original)
+++ directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/context/AbstractOperationContext.java
Mon Mar 19 07:08:52 2012
@@ -89,6 +89,15 @@ public abstract class AbstractOperationC
         this.session = session;
         currentInterceptor = 0;
     }
+    
+    
+    /**
+     * {@inheritDoc}
+     */
+    public void reset()
+    {
+        currentInterceptor = 0;
+    }
 
 
     /**

Modified: directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/context/ModifyOperationContext.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/context/ModifyOperationContext.java?rev=1302302&r1=1302301&r2=1302302&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/context/ModifyOperationContext.java
(original)
+++ directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/context/ModifyOperationContext.java
Mon Mar 19 07:08:52 2012
@@ -25,6 +25,7 @@ import java.util.List;
 
 import org.apache.directory.server.core.api.CoreSession;
 import org.apache.directory.server.core.api.OperationEnum;
+import org.apache.directory.server.core.api.changelog.LogChange;
 import org.apache.directory.server.core.api.entry.ServerEntryUtils;
 import org.apache.directory.shared.ldap.model.message.controls.ManageDsaIT;
 import org.apache.directory.shared.ldap.model.entry.DefaultModification;
@@ -67,6 +68,16 @@ public class ModifyOperationContext exte
             setInterceptors( session.getDirectoryService().getInterceptors( OperationEnum.MODIFY
) );
         }
     }
+    
+    
+    /**
+     * {@inheritDoc}
+     */
+    public void reset()
+    {
+        super.reset();
+        alteredEntry = null;
+    }
 
 
     /**

Modified: directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/context/OperationContext.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/context/OperationContext.java?rev=1302302&r1=1302301&r2=1302302&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/context/OperationContext.java
(original)
+++ directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/context/OperationContext.java
Mon Mar 19 07:08:52 2012
@@ -41,6 +41,13 @@ import org.apache.directory.shared.ldap.
 public interface OperationContext
 {
     /**
+     * Called when operation is to be re-executed.Operation context willr reset its state
+     * related to the execution of the operation 
+     */
+    void reset();
+    
+    
+    /**
      * @return The number of the current interceptor in the list
      */
     int getCurrentInterceptor();

Modified: directory/apacheds/branches/apacheds-txns/core-api/src/test/java/org/apache/directory/server/core/api/MockOperation.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-api/src/test/java/org/apache/directory/server/core/api/MockOperation.java?rev=1302302&r1=1302301&r2=1302302&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-api/src/test/java/org/apache/directory/server/core/api/MockOperation.java
(original)
+++ directory/apacheds/branches/apacheds-txns/core-api/src/test/java/org/apache/directory/server/core/api/MockOperation.java
Mon Mar 19 07:08:52 2012
@@ -48,6 +48,12 @@ public class MockOperation implements Op
         this.session = new MockCoreSession( new LdapPrincipal( schemaManager, new Dn( schemaManager
), AuthenticationLevel.STRONG ),
             new MockDirectoryService( count ) );
     }
+    
+    
+    public void reset()
+    {
+        
+    }
 
 
     public EntryFilteringCursor search( SearchOperationContext searchContext ) throws LdapException

Added: directory/apacheds/branches/apacheds-txns/core-integ/src/test/java/org/apache/directory/server/core/txn/TxnConflictIT.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-integ/src/test/java/org/apache/directory/server/core/txn/TxnConflictIT.java?rev=1302302&view=auto
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-integ/src/test/java/org/apache/directory/server/core/txn/TxnConflictIT.java
(added)
+++ directory/apacheds/branches/apacheds-txns/core-integ/src/test/java/org/apache/directory/server/core/txn/TxnConflictIT.java
Mon Mar 19 07:08:52 2012
@@ -0,0 +1,128 @@
+    
+package org.apache.directory.server.core.txn;
+
+import static org.apache.directory.server.core.integ.IntegrationUtils.getSystemContext;
+
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.DirContext;
+import javax.naming.ldap.LdapContext;
+
+import org.apache.directory.server.core.annotations.ApplyLdifs;
+import org.apache.directory.server.core.annotations.CreateDS;
+import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
+import org.apache.directory.server.core.integ.FrameworkRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.apache.directory.server.core.integ.IntegrationUtils;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+
+@RunWith ( FrameworkRunner.class )
+@CreateDS(name = "TxnConflictIT")
+@ApplyLdifs(
+    {
+        "dn: cn=test1, ou=system",
+        "objectClass: top",
+        "objectClass: person",
+        "cn: test1",
+        "sn: Jim",
+        "description: useless guy"
+    }
+)
+
+
+public class TxnConflictIT extends AbstractLdapTestUnit
+{
+    enum ConflictType
+    {
+        MODIFY_MODIFY_CONLICT
+    }
+
+    
+    @Test
+    public void testModifyModifyConflict() throws Exception
+    {
+        try
+        {
+            ConflictingThread cThread = new ConflictingThread( ConflictType.MODIFY_MODIFY_CONLICT
);
+            
+            cThread.start();
+            
+            LdapContext sysRoot = getSystemContext( getService() );
+            
+            // The added value
+            Attributes attrs = new BasicAttributes( "telephoneNumber", "1 650 300 6089",
true );
+    
+            // Add the Ava
+            sysRoot.modifyAttributes( "cn=test1", DirContext.ADD_ATTRIBUTE, attrs );
+            
+            cThread.join();
+            
+            // Entry should contain two telephone numbers now
+            attrs = sysRoot.getAttributes( "cn=test1" );
+            Attribute attr = attrs.get( "telephoneNumber" );
+            assertNotNull( attr );
+            assertEquals( 2, attr.size() );
+            assertTrue( attr.contains( "1 650 300 6089" ) );
+            assertTrue( attr.contains( "1 650 300 6088" ) );
+            
+        }
+        catch( Exception e )
+        {
+            e.printStackTrace();
+            
+            fail();
+        }
+        
+        
+    }
+    
+    class ConflictingThread extends Thread
+    {
+        ConflictType type;
+        
+        public ConflictingThread( ConflictType type )
+        {
+            this.type = type;
+        }
+        
+        private void doConflictingModify() throws Exception
+        {
+            LdapContext sysRoot = getSystemContext( getService() );
+            
+            // The added value
+            Attributes attrs = new BasicAttributes( "telephoneNumber", "1 650 300 6088",
true );
+
+            // Add the Ava
+            sysRoot.modifyAttributes( "cn=test1", DirContext.ADD_ATTRIBUTE, attrs );
+        }
+        
+        public void run()
+        {
+            System.out.println("here1");
+            try
+            {
+                if (type == ConflictType.MODIFY_MODIFY_CONLICT )
+                {
+                    this.doConflictingModify();
+                }
+            }
+            catch( Exception e )
+            {
+                e.printStackTrace();
+                
+                fail();
+            }
+        }
+    }
+
+    
+}
+

Modified: directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/DefaultTxnManager.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/DefaultTxnManager.java?rev=1302302&r1=1302301&r2=1302302&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/DefaultTxnManager.java
(original)
+++ directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/DefaultTxnManager.java
Mon Mar 19 07:08:52 2012
@@ -193,7 +193,9 @@ class DefaultTxnManager implements TxnMa
 
         // abort current txn and start a new read write txn
 
-        abortTransaction();
+      
+        abortReadWriteTxn( ( ReadWriteTxn ) curTxn );
+        curTxn.abortTxn();
         return beginReadWriteTxn( true );
     }
 
@@ -237,20 +239,36 @@ class DefaultTxnManager implements TxnMa
             throw new IllegalStateException( " trying to commit non existent txn " );
         }
 
-        if ( flushFailed )
-        {
-            throw new IOException( "Flushing of txns failed" );
-        }
-
-        prepareForEndingTxn( txn );
+        boolean isExclusive = txn.isExclusive();
 
-        if ( txn instanceof ReadOnlyTxn )
-        {
-            txn.commitTxn( txn.getStartTime() );
+        try
+        {        
+            if ( flushFailed )
+            {
+                throw new IOException( "Flushing of txns failed" );
+            }
+            
+            prepareForEndingTxn( txn );
+    
+            if ( txn instanceof ReadOnlyTxn )
+            {
+                txn.commitTxn( txn.getStartTime() );
+            }
+            else
+            {
+                commitReadWriteTxn( ( ReadWriteTxn ) txn );
+            }
         }
-        else
+        finally
         {
-            commitReadWriteTxn( ( ReadWriteTxn ) txn );
+            if ( !isExclusive )
+            {
+                optimisticLock.readLock().unlock();
+            }
+            else
+            {
+                optimisticLock.writeLock().unlock();
+            }
         }
 
         setCurTxn( null );
@@ -392,6 +410,8 @@ class DefaultTxnManager implements TxnMa
         ReadOnlyTxn txn = new ReadOnlyTxn();
         ReadWriteTxn lastTxnToCheck = null;
 
+        optimisticLock.readLock().lock(); 
+        
         /*
          * Set the start time as the latest committed txn's commit time. We need to make
sure that
          * any change after our start time is not flushed to the partitions. Say we have
txn1 as the
@@ -420,7 +440,6 @@ class DefaultTxnManager implements TxnMa
 
         buildCheckList( txn, lastTxnToCheck );
 
-        optimisticLock.readLock().lock();
         setCurTxn( txn );
 
         //System.out.println( "TRAN: Started " + txn );
@@ -478,7 +497,6 @@ class DefaultTxnManager implements TxnMa
                 lastTxnToCheck = latestVerifiedTxn.get();
 
                 lastTxnToCheck.getRefCount().incrementAndGet();
-
             }
             while ( lastTxnToCheck != latestVerifiedTxn.get() );
         }
@@ -586,7 +604,7 @@ class DefaultTxnManager implements TxnMa
                 throw new IllegalStateException( " prepareForEndingTxn: txn has unpexptected
start time " +
                     txn + " expected: " + lastTxnToCheck );
             }
-
+            
             if ( lastTxnToCheck.getRefCount().get() <= 0 )
             {
                 throw new IllegalStateException( " prepareForEndingTxn: lastTxnToCheck has
unexpected ref cnt " +

Modified: directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/DefaultOperationManager.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/DefaultOperationManager.java?rev=1302302&r1=1302301&r2=1302302&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/DefaultOperationManager.java
(original)
+++ directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/DefaultOperationManager.java
Mon Mar 19 07:08:52 2012
@@ -998,6 +998,7 @@ public class DefaultOperationManager imp
         {
             if ( startedTxn )
             {
+                modifyContext.reset();
                 retryTransactionRW( txnManager );
             }
             else if ( curTxn == null )

Modified: directory/apacheds/branches/apacheds-txns/interceptors/changelog/src/main/java/org/apache/directory/server/core/changelog/ChangeLogInterceptor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/interceptors/changelog/src/main/java/org/apache/directory/server/core/changelog/ChangeLogInterceptor.java?rev=1302302&r1=1302301&r2=1302302&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/interceptors/changelog/src/main/java/org/apache/directory/server/core/changelog/ChangeLogInterceptor.java
(original)
+++ directory/apacheds/branches/apacheds-txns/interceptors/changelog/src/main/java/org/apache/directory/server/core/changelog/ChangeLogInterceptor.java
Mon Mar 19 07:08:52 2012
@@ -220,6 +220,12 @@ public class ChangeLogInterceptor extend
 
         // Call the next interceptor
         next( modifyContext );
+        
+        // If op doesnt want to be logged, skipped
+        if ( !modifyContext.isLogChange() )
+        {
+            return;
+        }
 
         // @TODO: needs big consideration!!!
         // NOTE: perhaps we need to log this as a system operation that cannot and should
not be reapplied?



Mime
View raw message