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 ma...@apache.org on 2019/11/13 14:58:02 UTC

[james-project] 01/09: [Refactoring] remove usage of AbstractMailRepository for JDBC to enable refactoring

This is an automated email from the ASF dual-hosted git repository.

matthieu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit b76cc624046c6376723f3dde9536c9e021acbf2f
Author: Matthieu Baechler <ma...@apache.org>
AuthorDate: Fri Nov 8 18:35:00 2019 +0100

    [Refactoring] remove usage of AbstractMailRepository for JDBC to enable refactoring
---
 .../mailrepository/jdbc/JDBCMailRepository.java    | 114 +++++++++++++++++++--
 1 file changed, 108 insertions(+), 6 deletions(-)

diff --git a/server/data/data-jdbc/src/main/java/org/apache/james/mailrepository/jdbc/JDBCMailRepository.java b/server/data/data-jdbc/src/main/java/org/apache/james/mailrepository/jdbc/JDBCMailRepository.java
index f6a7405..822f6c3 100644
--- a/server/data/data-jdbc/src/main/java/org/apache/james/mailrepository/jdbc/JDBCMailRepository.java
+++ b/server/data/data-jdbc/src/main/java/org/apache/james/mailrepository/jdbc/JDBCMailRepository.java
@@ -35,6 +35,7 @@ import java.sql.SQLException;
 import java.sql.Statement;
 import java.sql.Types;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -55,8 +56,11 @@ import org.apache.commons.configuration2.tree.ImmutableNode;
 import org.apache.commons.lang3.SerializationUtils;
 import org.apache.james.core.MailAddress;
 import org.apache.james.filesystem.api.FileSystem;
+import org.apache.james.lifecycle.api.Configurable;
 import org.apache.james.mailrepository.api.MailKey;
-import org.apache.james.mailrepository.lib.AbstractMailRepository;
+import org.apache.james.mailrepository.api.MailRepository;
+import org.apache.james.mailrepository.lib.Lock;
+import org.apache.james.repository.api.Initializable;
 import org.apache.james.repository.file.FilePersistentStreamRepository;
 import org.apache.james.server.core.MailImpl;
 import org.apache.james.server.core.MimeMessageCopyOnWriteProxy;
@@ -68,6 +72,7 @@ import org.apache.mailet.Mail;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.github.fge.lambdas.Throwing;
 import com.github.steveash.guavate.Guavate;
 import com.google.common.collect.ImmutableList;
 
@@ -98,10 +103,21 @@ import com.google.common.collect.ImmutableList;
  * @version CVS $Revision$ $Date: 2010-12-29 21:47:46 +0100 (Wed, 29
  *          Dec 2010) $
  */
-public class JDBCMailRepository extends AbstractMailRepository {
+public class JDBCMailRepository implements MailRepository, Configurable, Initializable {
     private static final Logger LOGGER = LoggerFactory.getLogger(JDBCMailRepository.class);
 
     /**
+     * Whether 'deep debugging' is turned on.
+     */
+    private static final boolean DEEP_DEBUG = false;
+
+    /**
+     * A lock used to control access to repository elements, locking access
+     * based on the key
+     */
+    private final Lock lock = new Lock();
+
+    /**
      * The table name parsed from the destination URL
      */
     protected String tableName;
@@ -169,8 +185,7 @@ public class JDBCMailRepository extends AbstractMailRepository {
     }
 
     @Override
-    protected void doConfigure(HierarchicalConfiguration<ImmutableNode> configuration) throws ConfigurationException {
-        super.doConfigure(configuration);
+    public void configure(HierarchicalConfiguration<ImmutableNode> configuration) throws ConfigurationException {
         LOGGER.debug("{}.configure()", getClass().getName());
         destination = configuration.getString("[@destinationURL]");
 
@@ -225,6 +240,33 @@ public class JDBCMailRepository extends AbstractMailRepository {
     }
 
     /**
+     * Releases a lock on a message identified the key
+     *
+     * @param key
+     *            the key of the message to be unlocked
+     *
+     * @return true if successfully released the lock, false otherwise
+     */
+    @Override
+    public boolean unlock(MailKey key) {
+        return lock.unlock(key);
+    }
+
+    /**
+     * Obtains a lock on a message identified by key
+     *
+     * @param key
+     *            the key of the message to be locked
+     *
+     * @return true if successfully obtained the lock, false otherwise
+     */
+    @Override
+    public boolean lock(MailKey key) {
+        return lock.lock(key);
+    }
+
+
+    /**
      * Initialises the JDBC repository.
      * <ol>
      * <li>Tests the connection to the database.</li>
@@ -328,7 +370,7 @@ public class JDBCMailRepository extends AbstractMailRepository {
      * @throws SQLException
      *             if a fatal situation is met
      */
-    protected void checkJdbcAttributesSupport(DatabaseMetaData dbMetaData) throws SQLException {
+    private void checkJdbcAttributesSupport(DatabaseMetaData dbMetaData) throws SQLException {
         String attributesColumnName = "message_attributes";
         boolean hasUpdateMessageAttributesSQL = false;
         boolean hasRetrieveMessageAttributesSQL = false;
@@ -381,7 +423,37 @@ public class JDBCMailRepository extends AbstractMailRepository {
     }
 
     @Override
-    protected void internalStore(Mail mc) throws IOException, MessagingException {
+    public MailKey store(Mail mc) throws MessagingException {
+        boolean wasLocked = true;
+        MailKey key = MailKey.forMail(mc);
+        try {
+            synchronized (this) {
+                wasLocked = lock.isLocked(key);
+                if (!wasLocked) {
+                    // If it wasn't locked, we want a lock during the store
+                    lock(key);
+                }
+            }
+            internalStore(mc);
+            return key;
+        } catch (MessagingException e) {
+            LOGGER.error("Exception caught while storing mail {}", key, e);
+            throw e;
+        } catch (Exception e) {
+            LOGGER.error("Exception caught while storing mail {}", key, e);
+            throw new MessagingException("Exception caught while storing mail " + key, e);
+        } finally {
+            if (!wasLocked) {
+                // If it wasn't locked, we need to unlock now
+                unlock(key);
+                synchronized (this) {
+                    notify();
+                }
+            }
+        }
+    }
+
+    private void internalStore(Mail mc) throws IOException, MessagingException {
         Connection conn = null;
         try {
             conn = datasource.getConnection();
@@ -726,6 +798,30 @@ public class JDBCMailRepository extends AbstractMailRepository {
     }
 
     @Override
+    public void remove(Mail mail) throws MessagingException {
+        remove(MailKey.forMail(mail));
+    }
+
+    @Override
+    public void remove(Collection<Mail> mails) throws MessagingException {
+        for (Mail mail : mails) {
+            remove(mail);
+        }
+    }
+
+    @Override
+    public void remove(MailKey key) throws MessagingException {
+        if (lock(key)) {
+            try {
+                internalRemove(key);
+            } finally {
+                unlock(key);
+            }
+        } else {
+            throw new MessagingException("Cannot lock " + key + " to remove it");
+        }
+    }
+
     protected void internalRemove(MailKey key) throws MessagingException {
         Connection conn = null;
         PreparedStatement removeMessage = null;
@@ -809,6 +905,12 @@ public class JDBCMailRepository extends AbstractMailRepository {
     }
 
     @Override
+    public void removeAll() throws MessagingException {
+        ImmutableList.copyOf(list())
+            .forEach(Throwing.<MailKey>consumer(this::remove).sneakyThrow());
+    }
+
+    @Override
     public int hashCode() {
         int result = 17;
         if (tableName != null) {


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