You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by no...@apache.org on 2010/06/06 12:00:15 UTC

svn commit: r951847 - in /james/imap/trunk: deployment/src/test/java/org/apache/james/imap/functional/jcr/ jcr/src/main/java/org/apache/james/imap/jcr/ jcr/src/main/java/org/apache/james/imap/jcr/mail/ jcr/src/main/java/org/apache/james/imap/jcr/user/

Author: norman
Date: Sun Jun  6 10:00:14 2010
New Revision: 951847

URL: http://svn.apache.org/viewvc?rev=951847&view=rev
Log:
Make it easy to implement own Node Locking mechanism (IMAP-149)

Added:
    james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRVmNodeLocker.java
    james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/NodeLocker.java
Modified:
    james/imap/trunk/deployment/src/test/java/org/apache/james/imap/functional/jcr/JCRHostSystem.java
    james/imap/trunk/deployment/src/test/java/org/apache/james/imap/functional/jcr/JCRStressTest.java
    james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/AbstractJCRMapper.java
    james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRMailboxManager.java
    james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRMailboxSessionMapperFactory.java
    james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRUidConsumer.java
    james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/JCRMailboxMapper.java
    james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/JCRMessageMapper.java
    james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/user/JCRSubscriptionMapper.java

Modified: james/imap/trunk/deployment/src/test/java/org/apache/james/imap/functional/jcr/JCRHostSystem.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/deployment/src/test/java/org/apache/james/imap/functional/jcr/JCRHostSystem.java?rev=951847&r1=951846&r2=951847&view=diff
==============================================================================
--- james/imap/trunk/deployment/src/test/java/org/apache/james/imap/functional/jcr/JCRHostSystem.java (original)
+++ james/imap/trunk/deployment/src/test/java/org/apache/james/imap/functional/jcr/JCRHostSystem.java Sun Jun  6 10:00:14 2010
@@ -32,11 +32,10 @@ import org.apache.james.imap.jcr.JCRMail
 import org.apache.james.imap.jcr.JCRMailboxSessionMapperFactory;
 import org.apache.james.imap.jcr.JCRSubscriptionManager;
 import org.apache.james.imap.jcr.JCRUtils;
+import org.apache.james.imap.jcr.JCRVmNodeLocker;
 import org.apache.james.imap.mailbox.MailboxSession;
 import org.apache.james.imap.main.DefaultImapDecoderFactory;
 import org.apache.james.imap.processor.main.DefaultImapProcessorFactory;
-import org.apache.james.imap.store.Authenticator;
-import org.apache.james.imap.store.Subscriber;
 import org.apache.james.test.functional.HostSystem;
 import org.xml.sax.InputSource;
 
@@ -70,7 +69,7 @@ public class JCRHostSystem extends ImapH
             JCRUtils.registerCnd(repository, workspace, user, pass);
             
             userManager = new InMemoryUserManager();
-            JCRMailboxSessionMapperFactory mf = new JCRMailboxSessionMapperFactory(sessionRepos);
+            JCRMailboxSessionMapperFactory mf = new JCRMailboxSessionMapperFactory(sessionRepos, new JCRVmNodeLocker());
 
             //TODO: Fix the scaling stuff so the tests will pass with max scaling too
             mailboxManager = new JCRMailboxManager(mf, userManager, new JCRSubscriptionManager(mf));

Modified: james/imap/trunk/deployment/src/test/java/org/apache/james/imap/functional/jcr/JCRStressTest.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/deployment/src/test/java/org/apache/james/imap/functional/jcr/JCRStressTest.java?rev=951847&r1=951846&r2=951847&view=diff
==============================================================================
--- james/imap/trunk/deployment/src/test/java/org/apache/james/imap/functional/jcr/JCRStressTest.java (original)
+++ james/imap/trunk/deployment/src/test/java/org/apache/james/imap/functional/jcr/JCRStressTest.java Sun Jun  6 10:00:14 2010
@@ -31,6 +31,7 @@ import org.apache.james.imap.jcr.JCRMail
 import org.apache.james.imap.jcr.JCRMailboxSessionMapperFactory;
 import org.apache.james.imap.jcr.JCRSubscriptionManager;
 import org.apache.james.imap.jcr.JCRUtils;
+import org.apache.james.imap.jcr.JCRVmNodeLocker;
 import org.apache.james.imap.jcr.MailboxSessionJCRRepository;
 import org.apache.james.imap.mailbox.MailboxSession;
 import org.apache.james.imap.store.StoreMailboxManager;
@@ -62,7 +63,7 @@ public class JCRStressTest extends Abstr
         JCRUtils.registerCnd(repository, workspace, user, pass);
 
         MailboxSessionJCRRepository sessionRepos = new GlobalMailboxSessionJCRRepository(repository, workspace, user, pass);
-        JCRMailboxSessionMapperFactory mf = new JCRMailboxSessionMapperFactory(sessionRepos);
+        JCRMailboxSessionMapperFactory mf = new JCRMailboxSessionMapperFactory(sessionRepos, new JCRVmNodeLocker());
         mailboxManager = new JCRMailboxManager(mf, null, new JCRSubscriptionManager(mf));
 
     }

Modified: james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/AbstractJCRMapper.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/AbstractJCRMapper.java?rev=951847&r1=951846&r2=951847&view=diff
==============================================================================
--- james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/AbstractJCRMapper.java (original)
+++ james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/AbstractJCRMapper.java Sun Jun  6 10:00:14 2010
@@ -41,13 +41,19 @@ public abstract class AbstractJCRMapper 
     private final Log logger;
 	private final MailboxSessionJCRRepository repository;
 	private final MailboxSession mSession;
+    private final NodeLocker locker;
 
-    public AbstractJCRMapper(final MailboxSessionJCRRepository repository, MailboxSession mSession, Log logger) {
+    public AbstractJCRMapper(final MailboxSessionJCRRepository repository, MailboxSession mSession, NodeLocker locker, Log logger) {
         this.repository = repository;
         this.mSession = mSession;
         this.logger = logger;
+        this.locker = locker;
     }
 
+    public NodeLocker getNodeLocker() {
+        return locker;
+    }
+    
     /**
      * Return the logger
      * 

Modified: james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRMailboxManager.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRMailboxManager.java?rev=951847&r1=951846&r2=951847&view=diff
==============================================================================
--- james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRMailboxManager.java (original)
+++ james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRMailboxManager.java Sun Jun  6 10:00:14 2010
@@ -40,15 +40,19 @@ import org.apache.james.imap.store.trans
  */
 public class JCRMailboxManager extends StoreMailboxManager<String> implements JCRImapConstants{
 
-	private final JCRMailboxSessionMapperFactory mapperFactory;    
-	private final Log logger = LogFactory.getLog(JCRMailboxManager.class);
+    private final JCRMailboxSessionMapperFactory mapperFactory;
+    private final Log logger = LogFactory.getLog(JCRMailboxManager.class);
     
     public JCRMailboxManager(JCRMailboxSessionMapperFactory mapperFactory, final Authenticator authenticator, final Subscriber subscriber) {
-	    super(mapperFactory, authenticator, subscriber, new JCRUidConsumer(mapperFactory.getRepository()));
-		this.mapperFactory = mapperFactory;
+	    this(mapperFactory, authenticator, subscriber, new JCRVmNodeLocker());
     }
 
+    public JCRMailboxManager(JCRMailboxSessionMapperFactory mapperFactory, final Authenticator authenticator, final Subscriber subscriber, final NodeLocker locker) {
+        super(mapperFactory, authenticator, subscriber, new JCRUidConsumer(mapperFactory.getRepository(), locker));
+        this.mapperFactory = mapperFactory;
+    }
 
+    
     @Override
     protected StoreMessageManager<String> createMessageManager(MailboxEventDispatcher dispatcher, UidConsumer<String> consumer, Mailbox<String> mailboxEntity, MailboxSession session) throws MailboxException{
         return new JCRMessageManager(mapperFactory, dispatcher, consumer, (JCRMailbox) mailboxEntity, logger, getDelimiter(), session);

Modified: james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRMailboxSessionMapperFactory.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRMailboxSessionMapperFactory.java?rev=951847&r1=951846&r2=951847&view=diff
==============================================================================
--- james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRMailboxSessionMapperFactory.java (original)
+++ james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRMailboxSessionMapperFactory.java Sun Jun  6 10:00:14 2010
@@ -42,28 +42,30 @@ public class JCRMailboxSessionMapperFact
     private MailboxSessionJCRRepository repository;
     private Log logger;
     private char delimiter;
+    private NodeLocker locker;
 
-    public JCRMailboxSessionMapperFactory(final MailboxSessionJCRRepository repository) {
+    public JCRMailboxSessionMapperFactory(final MailboxSessionJCRRepository repository, final NodeLocker locker) {
         this.repository = repository;
         this.logger = LogFactory.getLog(JCRSubscriptionManager.class);
         this.delimiter = '.';
+        this.locker = locker;;
     }
 
     @Override
     public MailboxMapper<String> createMailboxMapper(MailboxSession session) throws MailboxException {
-        JCRMailboxMapper mapper = new JCRMailboxMapper(repository, session, logger, delimiter);
+        JCRMailboxMapper mapper = new JCRMailboxMapper(repository, session, locker, logger, delimiter);
         return mapper;
     }
 
     @Override
     public MessageMapper<String> createMessageMapper(MailboxSession session) throws MailboxException {
-        JCRMessageMapper messageMapper = new JCRMessageMapper(repository, session, logger);
+        JCRMessageMapper messageMapper = new JCRMessageMapper(repository, session, locker, logger);
         return messageMapper;
     }
 
     @Override
     public SubscriptionMapper createSubscriptionMapper(MailboxSession session) throws SubscriptionException {
-        JCRSubscriptionMapper mapper = new JCRSubscriptionMapper(repository, session, logger);
+        JCRSubscriptionMapper mapper = new JCRSubscriptionMapper(repository, session, locker, logger);
         return mapper;
     }
     

Modified: james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRUidConsumer.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRUidConsumer.java?rev=951847&r1=951846&r2=951847&view=diff
==============================================================================
--- james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRUidConsumer.java (original)
+++ james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRUidConsumer.java Sun Jun  6 10:00:14 2010
@@ -41,9 +41,11 @@ import org.apache.james.imap.store.mail.
 public class JCRUidConsumer implements UidConsumer<String>{
 
     private MailboxSessionJCRRepository repos;
+    private NodeLocker locker;
     
-    public JCRUidConsumer(MailboxSessionJCRRepository repos) {
+    public JCRUidConsumer(MailboxSessionJCRRepository repos, NodeLocker locker) {
         this.repos = repos;
+        this.locker = locker;
     }
     
     /*
@@ -54,10 +56,9 @@ public class JCRUidConsumer implements U
         try {
             Session jcrSession = repos.login(session);
             Node node = jcrSession.getNodeByIdentifier(mailbox.getMailboxId());
-            return (Long) new Locked() {
-                
-                @Override
-                protected Object run(Node node) throws RepositoryException {
+            long result = locker.execute(new NodeLocker.NodeLockedExecution<Long>() {
+
+                public Long execute(Node node) throws RepositoryException {
                     Property uidProp = node.getProperty(JCRMailbox.LASTUID_PROPERTY);
                     long uid = uidProp.getLong();
                     uid++;
@@ -65,7 +66,13 @@ public class JCRUidConsumer implements U
                     uidProp.getSession().save();
                     return uid;
                 }
-            }.with(node, false);
+
+                public boolean isDeepLocked() {
+                    return true;
+                }
+                
+            }, node, Long.class);
+            return result;
             
          
         } catch (RepositoryException e) {

Added: james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRVmNodeLocker.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRVmNodeLocker.java?rev=951847&view=auto
==============================================================================
--- james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRVmNodeLocker.java (added)
+++ james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRVmNodeLocker.java Sun Jun  6 10:00:14 2010
@@ -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.james.imap.jcr;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.apache.jackrabbit.util.Locked;
+
+/**
+ * {@link NodeLocker} implementation which use {@link Locked} utility to make sure the given node will not get modified while
+ * excecute the {@link NodeLockedExecution}. 
+ * 
+ * This implementation will only work with NON-CLUSTERED JCR.
+ *
+ */
+public class JCRVmNodeLocker implements NodeLocker{
+    
+    @SuppressWarnings("unchecked")
+    public <T> T execute(final NodeLockedExecution<T> exection, Node node, Class<T> returnType) throws RepositoryException, InterruptedException {
+        T result = (T) new Locked() {
+
+            @Override
+            protected Object run(Node node) throws RepositoryException {
+                return exection.execute(node);
+            }
+            
+        }.with(node, exection.isDeepLocked());
+        return result;
+    }
+
+
+
+}

Added: james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/NodeLocker.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/NodeLocker.java?rev=951847&view=auto
==============================================================================
--- james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/NodeLocker.java (added)
+++ james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/NodeLocker.java Sun Jun  6 10:00:14 2010
@@ -0,0 +1,66 @@
+/****************************************************************
+ * 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.james.imap.jcr;
+
+import javax.jcr.InvalidItemStateException;
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+/**
+ * The NodeLocker takes care of locking a {@link Node} and execute the {@link NodeLockedExecution} on it. The implementations need to take care of prevent a {@link InvalidItemStateException} 
+ * in all cases
+ *
+ */
+public interface NodeLocker {
+
+    /**
+     * Execute the given {@link NodeLockedExecution} after locking the {@link Node}
+     * @param <T> the return type of the method
+     * @param exection
+     * @param node
+     * @param returnType
+     * @return result
+     * @throws RepositoryException
+     * @throws InterruptedException
+     */
+    public <T>T execute(NodeLockedExecution<T> exection, Node node, Class<T> returnType) throws RepositoryException, InterruptedException;
+    
+    /**
+     * Execute some code on a Node
+     *
+     * @param <T>
+     */
+    public interface NodeLockedExecution<T> {
+        
+        /**
+         * Execute some code on the locked {@link Node}
+         * @param node
+         * @return result
+         * @throws RepositoryException
+         */
+        public T execute(Node node) throws RepositoryException;
+        
+        /**
+         * Return true if the node needs to be deep locked (all childs too)
+         * 
+         * @return deepLocked
+         */
+        public boolean isDeepLocked();
+    }
+}

Modified: james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/JCRMailboxMapper.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/JCRMailboxMapper.java?rev=951847&r1=951846&r2=951847&view=diff
==============================================================================
--- james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/JCRMailboxMapper.java (original)
+++ james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/JCRMailboxMapper.java Sun Jun  6 10:00:14 2010
@@ -36,6 +36,7 @@ import org.apache.jackrabbit.util.Locked
 import org.apache.james.imap.api.display.HumanReadableText;
 import org.apache.james.imap.jcr.AbstractJCRMapper;
 import org.apache.james.imap.jcr.MailboxSessionJCRRepository;
+import org.apache.james.imap.jcr.NodeLocker;
 import org.apache.james.imap.jcr.mail.model.JCRMailbox;
 import org.apache.james.imap.mailbox.MailboxNotFoundException;
 import org.apache.james.imap.mailbox.MailboxSession;
@@ -52,8 +53,8 @@ public class JCRMailboxMapper extends Ab
 
     private char delimiter;
 
-    public JCRMailboxMapper(final MailboxSessionJCRRepository repos, MailboxSession session, final Log logger, char delimiter) {
-        super(repos, session, logger);
+    public JCRMailboxMapper(final MailboxSessionJCRRepository repos, MailboxSession session, final NodeLocker locker, final Log logger, char delimiter) {
+        super(repos, session, locker, logger);
         this.delimiter = delimiter;
     }
 

Modified: james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/JCRMessageMapper.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/JCRMessageMapper.java?rev=951847&r1=951846&r2=951847&view=diff
==============================================================================
--- james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/JCRMessageMapper.java (original)
+++ james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/JCRMessageMapper.java Sun Jun  6 10:00:14 2010
@@ -38,6 +38,7 @@ import org.apache.jackrabbit.util.Locked
 import org.apache.james.imap.api.display.HumanReadableText;
 import org.apache.james.imap.jcr.AbstractJCRMapper;
 import org.apache.james.imap.jcr.MailboxSessionJCRRepository;
+import org.apache.james.imap.jcr.NodeLocker;
 import org.apache.james.imap.jcr.mail.model.JCRMessage;
 import org.apache.james.imap.mailbox.MailboxSession;
 import org.apache.james.imap.mailbox.MessageRange;
@@ -55,8 +56,8 @@ import org.apache.james.imap.store.mail.
  */
 public class JCRMessageMapper extends AbstractJCRMapper implements MessageMapper<String> {
 
-    public JCRMessageMapper(final MailboxSessionJCRRepository repos, MailboxSession session, final Log logger) {
-        super(repos, session, logger);
+    public JCRMessageMapper(final MailboxSessionJCRRepository repos, MailboxSession session, NodeLocker locker, final Log logger) {
+        super(repos, session, locker, logger);
     }
 
     /*

Modified: james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/user/JCRSubscriptionMapper.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/user/JCRSubscriptionMapper.java?rev=951847&r1=951846&r2=951847&view=diff
==============================================================================
--- james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/user/JCRSubscriptionMapper.java (original)
+++ james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/user/JCRSubscriptionMapper.java Sun Jun  6 10:00:14 2010
@@ -34,6 +34,7 @@ import org.apache.jackrabbit.commons.Jcr
 import org.apache.james.imap.api.display.HumanReadableText;
 import org.apache.james.imap.jcr.AbstractJCRMapper;
 import org.apache.james.imap.jcr.MailboxSessionJCRRepository;
+import org.apache.james.imap.jcr.NodeLocker;
 import org.apache.james.imap.jcr.user.model.JCRSubscription;
 import org.apache.james.imap.mailbox.MailboxSession;
 import org.apache.james.imap.mailbox.SubscriptionException;
@@ -46,8 +47,8 @@ import org.apache.james.imap.store.user.
  */
 public class JCRSubscriptionMapper extends AbstractJCRMapper implements SubscriptionMapper {
 
-    public JCRSubscriptionMapper(final MailboxSessionJCRRepository repos, MailboxSession session, final Log log) {
-        super(repos,session, log);
+    public JCRSubscriptionMapper(final MailboxSessionJCRRepository repos, MailboxSession session, final NodeLocker locker, final Log log) {
+        super(repos,session, locker, log);
     }
 
     /*



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