This is an automated email from the ASF dual-hosted git repository. rcordier pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 365e9b20b66e47ac3d7b9d2d77355d437c2e0f59 Author: Rene Cordier <[email protected]> AuthorDate: Wed Feb 12 11:55:07 2020 +0700 JAMES-3057 Separate the create from rename logic in other mailbox implementations --- .../cassandra/mail/CassandraMailboxMapper.java | 16 +++++----- .../james/mailbox/jpa/mail/JPAMailboxMapper.java | 21 +++++++++++++ .../jpa/mail/TransactionalMailboxMapper.java | 5 ++++ .../mailbox/maildir/mail/MaildirMailboxMapper.java | 35 ++++++++++++++++++++++ .../inmemory/mail/InMemoryMailboxMapper.java | 15 ++++++++++ .../james/mailbox/store/mail/MailboxMapper.java | 8 +---- 6 files changed, 84 insertions(+), 16 deletions(-) diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java index 5f89b42..096a525 100644 --- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java +++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java @@ -172,21 +172,19 @@ public class CassandraMailboxMapper implements MailboxMapper { CassandraId cassandraId = CassandraId.timeBased(); mailbox.setMailboxId(cassandraId); - if (!tryCreate(mailbox, cassandraId).block()) { + if (!tryCreate(mailbox, cassandraId)) { throw new MailboxExistsException(mailbox.generateAssociatedPath().asString()); } return cassandraId; } - private Mono<Boolean> tryCreate(Mailbox cassandraMailbox, CassandraId cassandraId) { + private boolean tryCreate(Mailbox cassandraMailbox, CassandraId cassandraId) { return mailboxPathV2DAO.save(cassandraMailbox.generateAssociatedPath(), cassandraId) - .flatMap(isCreated -> { - if (isCreated) { - return mailboxDAO.save(cassandraMailbox) - .thenReturn(isCreated); - } - return Mono.just(isCreated); - }); + .filter(isCreated -> isCreated) + .flatMap(mailboxHasCreated -> mailboxDAO.save(cassandraMailbox) + .thenReturn(true)) + .switchIfEmpty(Mono.just(false)) + .block(); } @Override diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMailboxMapper.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMailboxMapper.java index 3d57fbb..2dfb016 100644 --- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMailboxMapper.java +++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMailboxMapper.java @@ -47,6 +47,7 @@ import org.apache.james.mailbox.store.mail.MailboxMapper; import com.github.steveash.guavate.Guavate; import com.google.common.base.Objects; +import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; /** @@ -82,6 +83,26 @@ public class JPAMailboxMapper extends JPATransactionalMapper implements MailboxM throw new MailboxException("Commit of transaction failed", e); } } + + @Override + public MailboxId create(Mailbox mailbox) throws MailboxException { + Preconditions.checkArgument(mailbox.getMailboxId() == null, "A mailbox we want to create should not have a mailboxId set already"); + + try { + if (isPathAlreadyUsedByAnotherMailbox(mailbox)) { + throw new MailboxExistsException(mailbox.getName()); + } + + this.lastMailboxName = mailbox.getName(); + JPAMailbox persistedMailbox = JPAMailbox.from(mailbox); + + getEntityManager().persist(persistedMailbox); + mailbox.setMailboxId(persistedMailbox.getMailboxId()); + return persistedMailbox.getMailboxId(); + } catch (PersistenceException e) { + throw new MailboxException("Save of mailbox " + mailbox.getName() + " failed", e); + } + } @Override public MailboxId rename(Mailbox mailbox) throws MailboxException { diff --git a/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/mail/TransactionalMailboxMapper.java b/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/mail/TransactionalMailboxMapper.java index a2f3fd5..c0c3f64 100644 --- a/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/mail/TransactionalMailboxMapper.java +++ b/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/mail/TransactionalMailboxMapper.java @@ -53,6 +53,11 @@ public class TransactionalMailboxMapper implements MailboxMapper { } @Override + public MailboxId create(Mailbox mailbox) throws MailboxException { + return wrapped.execute(() -> wrapped.create(mailbox)); + } + + @Override public MailboxId rename(Mailbox mailbox) throws MailboxException { return wrapped.execute(() -> wrapped.rename(mailbox)); } diff --git a/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMailboxMapper.java b/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMailboxMapper.java index 016231e..c91288c 100644 --- a/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMailboxMapper.java +++ b/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMailboxMapper.java @@ -52,6 +52,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.github.steveash.guavate.Guavate; +import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; public class MaildirMailboxMapper extends NonTransactionalMapper implements MailboxMapper { @@ -160,6 +161,40 @@ public class MaildirMailboxMapper extends NonTransactionalMapper implements Mail } @Override + public MailboxId create(Mailbox mailbox) throws MailboxException { + Preconditions.checkArgument(mailbox.getMailboxId() == null, "A mailbox we want to create should not have a mailboxId set already"); + + MaildirId maildirId = MaildirId.random(); + MaildirFolder folder = maildirStore.createMaildirFolder(mailbox); + + if (!folder.exists()) { + boolean folderExist = folder.getRootFile().exists(); + if (!folderExist && !folder.getRootFile().mkdirs()) { + throw new MailboxException("Failed to save Mailbox " + mailbox); + } + + boolean isCreated = folder.getCurFolder().mkdir() + && folder.getNewFolder().mkdir() + && folder.getTmpFolder().mkdir(); + if (!isCreated) { + throw new MailboxException("Failed to save Mailbox " + mailbox, new IOException("Needed folder structure can not be created")); + } + } + + try { + folder.setUidValidity(mailbox.getUidValidity()); + folder.setMailboxId(maildirId); + mailbox.setMailboxId(maildirId); + } catch (IOException ioe) { + throw new MailboxException("Failed to save Mailbox " + mailbox, ioe); + + } + folder.setACL(mailbox.getACL()); + + return maildirId; + } + + @Override public MailboxId rename(Mailbox mailbox) throws MailboxException { MaildirId maildirId = Optional.ofNullable(mailbox.getMailboxId()) .map(mailboxId -> (MaildirId) mailboxId) diff --git a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryMailboxMapper.java b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryMailboxMapper.java index ac84241..9336233 100644 --- a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryMailboxMapper.java +++ b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryMailboxMapper.java @@ -41,6 +41,7 @@ import org.apache.james.mailbox.store.mail.MailboxMapper; import com.github.steveash.guavate.Guavate; import com.google.common.base.Objects; +import com.google.common.base.Preconditions; public class InMemoryMailboxMapper implements MailboxMapper { @@ -92,6 +93,20 @@ public class InMemoryMailboxMapper implements MailboxMapper { } @Override + public MailboxId create(Mailbox mailbox) throws MailboxException { + Preconditions.checkArgument(mailbox.getMailboxId() == null, "A mailbox we want to create should not have a mailboxId set already"); + + InMemoryId id = InMemoryId.of(mailboxIdGenerator.incrementAndGet()); + mailbox.setMailboxId(id); + + Mailbox previousMailbox = mailboxesByPath.putIfAbsent(mailbox.generateAssociatedPath(), mailbox); + if (previousMailbox != null) { + throw new MailboxExistsException(mailbox.getName()); + } + return mailbox.getMailboxId(); + } + + @Override public MailboxId rename(Mailbox mailbox) throws MailboxException { InMemoryId id = (InMemoryId) mailbox.getMailboxId(); if (id == null) { diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/MailboxMapper.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/MailboxMapper.java index 3e138a7..a005dd2 100644 --- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/MailboxMapper.java +++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/MailboxMapper.java @@ -32,8 +32,6 @@ import org.apache.james.mailbox.model.MailboxPath; import org.apache.james.mailbox.model.search.MailboxQuery; import org.apache.james.mailbox.store.transaction.Mapper; -import com.google.common.base.Preconditions; - /** * Mapper for {@link Mailbox} actions. A {@link MailboxMapper} has a lifecycle from the start of a request * to the end of the request. @@ -44,11 +42,7 @@ public interface MailboxMapper extends Mapper { /** * Create the given {@link Mailbox} to the underlying storage */ - default MailboxId create(Mailbox mailbox) throws MailboxException { - Preconditions.checkArgument(mailbox.getMailboxId() == null, "A mailbox we want to create should not have a mailboxId set already"); - - return rename(mailbox); - } + MailboxId create(Mailbox mailbox) throws MailboxException; /** * Rename the given {@link Mailbox} to the underlying storage --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
