Author: norman
Date: Sat Sep  3 18:19:07 2011
New Revision: 1164903

URL: http://svn.apache.org/viewvc?rev=1164903&view=rev
Log:
Make sure we have an higher uid on each append so we don't generate out of 
order events and so are imap compliant. See MAILBOX-131

Modified:
    
james/mailbox/trunk/api/src/test/java/org/apache/james/mailbox/AbstractStressTest.java
    
james/mailbox/trunk/jcr/src/main/java/org/apache/james/mailbox/jcr/JCRMailboxManager.java
    
james/mailbox/trunk/jcr/src/main/java/org/apache/james/mailbox/jcr/JCRMessageManager.java
    
james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMessageManager.java
    
james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMailboxManager.java
    
james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java
    
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
    
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java

Modified: 
james/mailbox/trunk/api/src/test/java/org/apache/james/mailbox/AbstractStressTest.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/api/src/test/java/org/apache/james/mailbox/AbstractStressTest.java?rev=1164903&r1=1164902&r2=1164903&view=diff
==============================================================================
--- 
james/mailbox/trunk/api/src/test/java/org/apache/james/mailbox/AbstractStressTest.java
 (original)
+++ 
james/mailbox/trunk/api/src/test/java/org/apache/james/mailbox/AbstractStressTest.java
 Sat Sep  3 18:19:07 2011
@@ -19,7 +19,9 @@
 package org.apache.james.mailbox;
 
 import java.io.ByteArrayInputStream;
+import java.util.ArrayList;
 import java.util.Date;
+import java.util.List;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutorService;
@@ -28,6 +30,8 @@ import java.util.concurrent.atomic.Atomi
 
 import javax.mail.Flags;
 
+import junit.framework.Assert;
+
 import org.apache.james.mailbox.MailboxConstants;
 import org.apache.james.mailbox.MailboxException;
 import org.apache.james.mailbox.MailboxManager;
@@ -49,13 +53,26 @@ public abstract class AbstractStressTest
        
         final CountDownLatch latch = new CountDownLatch(APPEND_OPERATIONS);
         final ExecutorService pool = 
Executors.newFixedThreadPool(APPEND_OPERATIONS/2);
-        
+        final List<Long> uList = new ArrayList<Long>();
         MailboxSession session = 
getMailboxManager().createSystemSession("test", 
LoggerFactory.getLogger("Test"));
         getMailboxManager().startProcessingRequest(session);
         final MailboxPath path = new 
MailboxPath(MailboxConstants.USER_NAMESPACE, "username", "INBOX");
         getMailboxManager().createMailbox(path, session);
+        getMailboxManager().addListener(path, new MailboxListener() {
+                       @Override
+                       public boolean isClosed() {
+                               return false;
+                       }
+                       
+                       @Override
+                       public void event(Event event) {
+                               long u = ((Added) event).getUids().get(0);
+                               uList.add(u);
+                       }
+               }, session);
         getMailboxManager().endProcessingRequest(session);
         getMailboxManager().logout(session, false);
+        
         final AtomicBoolean fail = new AtomicBoolean(false);
         final ConcurrentHashMap<Long, Object> uids = new 
ConcurrentHashMap<Long, Object>();
         
@@ -76,6 +93,7 @@ public abstract class AbstractStressTest
                         getMailboxManager().startProcessingRequest(session);
                         MessageManager m = 
getMailboxManager().getMailbox(path, session);
                         Long uid =  m.appendMessage(new 
ByteArrayInputStream("Subject: test\r\n\r\ntestmail".getBytes()), new Date(), 
session, false, new Flags());
+                        
                         System.out.println("Append message with uid=" + uid);
                         if (uids.put(uid, new Object()) != null) {
                             fail.set(true);
@@ -96,6 +114,17 @@ public abstract class AbstractStressTest
         
         latch.await();
         
+        // check if the uids were higher on each append. See MAILBOX-131
+        long last = 0;
+        for (int i = 0; i < uList.size(); i++) {
+            long l = uList.get(i);
+            if (l <= last) {
+                Assert.fail(l + "->" + last);
+            } else {
+                last = l;
+            }
+
+        }
         org.junit.Assert.assertFalse("Unable to append all 
messages",fail.get());
         pool.shutdown();
 

Modified: 
james/mailbox/trunk/jcr/src/main/java/org/apache/james/mailbox/jcr/JCRMailboxManager.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/jcr/src/main/java/org/apache/james/mailbox/jcr/JCRMailboxManager.java?rev=1164903&r1=1164902&r2=1164903&view=diff
==============================================================================
--- 
james/mailbox/trunk/jcr/src/main/java/org/apache/james/mailbox/jcr/JCRMailboxManager.java
 (original)
+++ 
james/mailbox/trunk/jcr/src/main/java/org/apache/james/mailbox/jcr/JCRMailboxManager.java
 Sat Sep  3 18:19:07 2011
@@ -50,7 +50,7 @@ public class JCRMailboxManager extends S
     
     @Override
     protected StoreMessageManager<String> createMessageManager(Mailbox<String> 
mailboxEntity, MailboxSession session) throws MailboxException{
-        return new JCRMessageManager(getMapperFactory(), 
getMessageSearchIndex(), getEventDispatcher(), (JCRMailbox) mailboxEntity, 
logger, getDelimiter());
+        return new JCRMessageManager(getMapperFactory(), 
getMessageSearchIndex(), getEventDispatcher(), getLocker(), (JCRMailbox) 
mailboxEntity, logger, getDelimiter());
     }
 
     @Override

Modified: 
james/mailbox/trunk/jcr/src/main/java/org/apache/james/mailbox/jcr/JCRMessageManager.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/jcr/src/main/java/org/apache/james/mailbox/jcr/JCRMessageManager.java?rev=1164903&r1=1164902&r2=1164903&view=diff
==============================================================================
--- 
james/mailbox/trunk/jcr/src/main/java/org/apache/james/mailbox/jcr/JCRMessageManager.java
 (original)
+++ 
james/mailbox/trunk/jcr/src/main/java/org/apache/james/mailbox/jcr/JCRMessageManager.java
 Sat Sep  3 18:19:07 2011
@@ -24,6 +24,7 @@ import javax.mail.Flags;
 import javax.mail.internet.SharedInputStream;
 
 import org.apache.james.mailbox.MailboxException;
+import org.apache.james.mailbox.MailboxPathLocker;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.jcr.mail.model.JCRMailbox;
 import org.apache.james.mailbox.jcr.mail.model.JCRMessage;
@@ -44,8 +45,8 @@ public class JCRMessageManager extends S
     private final Logger log;
 
     public JCRMessageManager(MailboxSessionMapperFactory<String> 
mapperFactory, MessageSearchIndex<String> index, 
-            final MailboxEventDispatcher<String> dispatcher, final JCRMailbox 
mailbox, final Logger log, final char delimiter) throws MailboxException {
-        super(mapperFactory, index, dispatcher, mailbox);
+            final MailboxEventDispatcher<String> dispatcher, final 
MailboxPathLocker locker, final JCRMailbox mailbox, final Logger log, final 
char delimiter) throws MailboxException {
+        super(mapperFactory, index, dispatcher, locker, mailbox);
         this.log = log;
     }
 

Modified: 
james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMessageManager.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMessageManager.java?rev=1164903&r1=1164902&r2=1164903&view=diff
==============================================================================
--- 
james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMessageManager.java
 (original)
+++ 
james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMessageManager.java
 Sat Sep  3 18:19:07 2011
@@ -24,6 +24,7 @@ import javax.mail.Flags;
 import javax.mail.internet.SharedInputStream;
 
 import org.apache.james.mailbox.MailboxException;
+import org.apache.james.mailbox.MailboxPathLocker;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.jpa.mail.model.JPAMailbox;
 import org.apache.james.mailbox.jpa.mail.model.openjpa.JPAMessage;
@@ -40,8 +41,8 @@ import org.apache.james.mailbox.store.se
  */
 public class JPAMessageManager extends StoreMessageManager<Long> {
     
-    public JPAMessageManager(MailboxSessionMapperFactory<Long> mapperFactory, 
final MessageSearchIndex<Long> index, final MailboxEventDispatcher<Long> 
dispatcher,final Mailbox<Long> mailbox) throws MailboxException {
-        super(mapperFactory, index, dispatcher, mailbox);     
+    public JPAMessageManager(MailboxSessionMapperFactory<Long> mapperFactory, 
final MessageSearchIndex<Long> index, final MailboxEventDispatcher<Long> 
dispatcher, final MailboxPathLocker locker, final Mailbox<Long> mailbox) throws 
MailboxException {
+        super(mapperFactory, index, dispatcher, locker, mailbox);     
     }
     
     @Override

Modified: 
james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMailboxManager.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMailboxManager.java?rev=1164903&r1=1164902&r2=1164903&view=diff
==============================================================================
--- 
james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMailboxManager.java
 (original)
+++ 
james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMailboxManager.java
 Sat Sep  3 18:19:07 2011
@@ -65,7 +65,7 @@ public class OpenJPAMailboxManager exten
 
     @Override
     protected StoreMessageManager<Long> createMessageManager(Mailbox<Long> 
mailboxRow, MailboxSession session) throws MailboxException {
-        StoreMessageManager<Long> result =  new 
OpenJPAMessageManager(getMapperFactory(), getMessageSearchIndex(), 
getEventDispatcher(), mailboxRow, feature);
+        StoreMessageManager<Long> result =  new 
OpenJPAMessageManager(getMapperFactory(), getMessageSearchIndex(), 
getEventDispatcher(), getLocker(), mailboxRow, feature);
         return result;
     }
 }

Modified: 
james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java?rev=1164903&r1=1164902&r2=1164903&view=diff
==============================================================================
--- 
james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java
 (original)
+++ 
james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java
 Sat Sep  3 18:19:07 2011
@@ -25,6 +25,7 @@ import javax.mail.Flags;
 import javax.mail.internet.SharedInputStream;
 
 import org.apache.james.mailbox.MailboxException;
+import org.apache.james.mailbox.MailboxPathLocker;
 import org.apache.james.mailbox.jpa.JPAMessageManager;
 import org.apache.james.mailbox.jpa.mail.model.JPAMailbox;
 import org.apache.james.mailbox.jpa.mail.model.openjpa.JPAEncryptedMessage;
@@ -50,13 +51,13 @@ public class OpenJPAMessageManager exten
     }
     
     public OpenJPAMessageManager(MailboxSessionMapperFactory<Long> 
mapperFactory, MessageSearchIndex<Long> index,
-            MailboxEventDispatcher<Long> dispatcher, Mailbox<Long> mailbox) 
throws MailboxException {
-        this(mapperFactory, index, dispatcher, mailbox, AdvancedFeature.None);
+            MailboxEventDispatcher<Long> dispatcher, MailboxPathLocker locker, 
Mailbox<Long> mailbox) throws MailboxException {
+        this(mapperFactory, index, dispatcher, locker,  mailbox, 
AdvancedFeature.None);
     }
 
     public OpenJPAMessageManager(MailboxSessionMapperFactory<Long> 
mapperFactory, MessageSearchIndex<Long> index, 
-            MailboxEventDispatcher<Long> dispatcher, Mailbox<Long> mailbox, 
final AdvancedFeature f) throws MailboxException {
-        super(mapperFactory,  index, dispatcher, mailbox);
+            MailboxEventDispatcher<Long> dispatcher, MailboxPathLocker locker, 
Mailbox<Long> mailbox, final AdvancedFeature f) throws MailboxException {
+        super(mapperFactory,  index, dispatcher, locker, mailbox);
         this.feature = f;
     }
 

Modified: 
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java?rev=1164903&r1=1164902&r2=1164903&view=diff
==============================================================================
--- 
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
 (original)
+++ 
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
 Sat Sep  3 18:19:07 2011
@@ -148,6 +148,10 @@ public class StoreMailboxManager<Id> imp
         return mailboxSessionMapperFactory;
     }
     
+    public MailboxPathLocker getLocker() {
+        return locker;
+    }
+    
     
     /**
      * Set the {@link AbstractDelegatingMailboxListener} to use with this 
{@link MailboxManager} instance. If none is set here a {@link 
HashMapDelegatingMailboxListener} instance will
@@ -258,7 +262,7 @@ public class StoreMailboxManager<Id> imp
      * @return storeMailbox
      */
     protected StoreMessageManager<Id> createMessageManager(Mailbox<Id> 
mailbox, MailboxSession session) throws MailboxException {
-        return new StoreMessageManager<Id>(getMapperFactory(), 
getMessageSearchIndex(), getEventDispatcher(), mailbox);
+        return new StoreMessageManager<Id>(getMapperFactory(), 
getMessageSearchIndex(), getEventDispatcher(), getLocker(), mailbox);
     }
 
     /**

Modified: 
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java?rev=1164903&r1=1164902&r2=1164903&view=diff
==============================================================================
--- 
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
 (original)
+++ 
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
 Sat Sep  3 18:19:07 2011
@@ -41,6 +41,7 @@ import org.apache.commons.io.IOUtils;
 import org.apache.commons.io.input.TeeInputStream;
 import org.apache.james.mailbox.MailboxException;
 import org.apache.james.mailbox.MailboxListener;
+import org.apache.james.mailbox.MailboxPathLocker;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MessageMetaData;
@@ -103,12 +104,15 @@ public class StoreMessageManager<Id> imp
     private final MessageMapperFactory<Id> mapperFactory;
 
     private final MessageSearchIndex<Id> index;
+
+       private MailboxPathLocker locker;
     
-    public StoreMessageManager(final MessageMapperFactory<Id> mapperFactory, 
final MessageSearchIndex<Id> index, final MailboxEventDispatcher<Id> 
dispatcher, final Mailbox<Id> mailbox) throws MailboxException {
+    public StoreMessageManager(final MessageMapperFactory<Id> mapperFactory, 
final MessageSearchIndex<Id> index, final MailboxEventDispatcher<Id> 
dispatcher, final MailboxPathLocker locker, final Mailbox<Id> mailbox) throws 
MailboxException {
         this.mailbox = mailbox;
         this.dispatcher = dispatcher;
         this.mapperFactory = mapperFactory;
         this.index = index;
+        this.locker = locker;
     }
     
     
@@ -193,6 +197,7 @@ public class StoreMessageManager<Id> imp
     public long appendMessage(final InputStream msgIn, Date internalDate,
             final MailboxSession mailboxSession,final boolean isRecent, final 
Flags flagsToBeSet)
     throws MailboxException {
+        
         File file = null;
         TeeInputStream tmpMsgIn = null;
         BodyOffsetInputStream bIn = null;
@@ -315,12 +320,19 @@ public class StoreMessageManager<Id> imp
             final int size = (int) file.length();
 
             final Message<Id> message = createMessage(internalDate, size, 
bodyStartOctet, contentIn, flags, propertyBuilder);
-            MessageMetaData data = appendMessageToStore(message, 
mailboxSession);
-                       
-            Map<Long, MessageMetaData> uids = new HashMap<Long, 
MessageMetaData>();
-            uids.put(data.getUid(), data);
-            dispatcher.added(mailboxSession, uids, getMailboxEntity());
-            return data.getUid();
+            return locker.executeWithLock(mailboxSession, new 
StoreMailboxPath<Id>(getMailboxEntity()), new 
MailboxPathLocker.LockAwareExecution<Long>() {
+
+                @Override
+                public Long execute() throws MailboxException {
+                    MessageMetaData data = appendMessageToStore(message, 
mailboxSession);
+                    
+                    Map<Long, MessageMetaData> uids = new HashMap<Long, 
MessageMetaData>();
+                    uids.put(data.getUid(), data);
+                    dispatcher.added(mailboxSession, uids, getMailboxEntity());
+                    return data.getUid();
+                }
+            }, true);
+            
         } catch (IOException e) {
             throw new MailboxException("Unable to parse message", e);
         } catch (MimeException e) {



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org
For additional commands, e-mail: server-dev-h...@james.apache.org

Reply via email to