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 bt...@apache.org on 2020/07/01 05:07:49 UTC
[james-project] 03/03: JAMES-3212: handle subcrible/unsubcrible
child's folder when update mailbox
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit bffdedf5e3c27a0e1861e377644f064b0c122493
Author: duc91 <du...@gmail.com>
AuthorDate: Tue Jun 16 16:57:26 2020 +0700
JAMES-3212: handle subcrible/unsubcrible child's folder when update mailbox
---
.../org/apache/james/mailbox/MailboxManager.java | 58 +++++-
.../apache/james/mailbox/MailboxManagerTest.java | 197 +++++++++++++++++++++
.../cassandra/CassandraMailboxManagerTest.java | 7 +
.../james/mailbox/jpa/JPAMailboxManagerTest.java | 7 +
.../DomainUserMaildirMailboxManagerTest.java | 21 ++-
.../maildir/FullUserMaildirMailboxManagerTest.java | 18 ++
.../mailbox/inmemory/MemoryMailboxManagerTest.java | 7 +
.../james/mailbox/store/MailboxReactorUtils.java | 7 +-
.../james/mailbox/store/StoreMailboxManager.java | 149 ++++++++++------
.../integration/SetMailboxesMethodTest.java | 145 ++++++++++++++-
.../draft/methods/SetMailboxesUpdateProcessor.java | 14 +-
.../methods/SetMessagesCreationProcessor.java | 2 +-
.../methods/SetMailboxesUpdateProcessorTest.java | 5 +-
13 files changed, 553 insertions(+), 84 deletions(-)
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/MailboxManager.java b/mailbox/api/src/main/java/org/apache/james/mailbox/MailboxManager.java
index ee859af..1b235bd 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/MailboxManager.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/MailboxManager.java
@@ -21,6 +21,7 @@ package org.apache.james.mailbox;
import java.util.EnumSet;
import java.util.List;
+import java.util.Objects;
import java.util.Optional;
import org.apache.james.mailbox.exception.MailboxException;
@@ -163,6 +164,51 @@ public interface MailboxManager extends RequestAware, RightManager, MailboxAnnot
*/
Mailbox deleteMailbox(MailboxId mailboxId, MailboxSession session) throws MailboxException;
+ class MailboxRenamedResult {
+ private final MailboxId mailboxId;
+ private final MailboxPath originPath;
+ private final MailboxPath destinationPath;
+
+ public MailboxRenamedResult(MailboxId mailboxId, MailboxPath originPath, MailboxPath destinationPath) {
+ this.mailboxId = mailboxId;
+ this.originPath = originPath;
+ this.destinationPath = destinationPath;
+ }
+
+ public MailboxId getMailboxId() {
+ return mailboxId;
+ }
+
+ public MailboxPath getOriginPath() {
+ return originPath;
+ }
+
+ public MailboxPath getDestinationPath() {
+ return destinationPath;
+ }
+
+ @Override
+ public final boolean equals(Object o) {
+ if (o instanceof MailboxRenamedResult) {
+ MailboxRenamedResult that = (MailboxRenamedResult) o;
+
+ return Objects.equals(this.mailboxId, that.mailboxId)
+ && Objects.equals(this.originPath, that.originPath)
+ && Objects.equals(this.destinationPath, that.destinationPath);
+ }
+ return false;
+ }
+
+ @Override
+ public final int hashCode() {
+ return Objects.hash(mailboxId, originPath, destinationPath);
+ }
+ }
+
+ enum RenameOption {
+ NONE, RENAME_SUBSCRIPTIONS
+ }
+
/**
* Renames a mailbox.
*
@@ -179,7 +225,11 @@ public interface MailboxManager extends RequestAware, RightManager, MailboxAnnot
* @throws MailboxNotFoundException
* when the <code>from</code> mailbox does not exist
*/
- void renameMailbox(MailboxPath from, MailboxPath to, MailboxSession session) throws MailboxException;
+ List<MailboxRenamedResult> renameMailbox(MailboxPath from, MailboxPath to, RenameOption option, MailboxSession session) throws MailboxException;
+
+ default List<MailboxRenamedResult> renameMailbox(MailboxPath from, MailboxPath to, MailboxSession session) throws MailboxException {
+ return renameMailbox(from, to, RenameOption.NONE, session);
+ }
/**
* Renames a mailbox.
@@ -197,7 +247,11 @@ public interface MailboxManager extends RequestAware, RightManager, MailboxAnnot
* @throws MailboxNotFoundException
* when the <code>mailboxId</code> original mailbox does not exist
*/
- void renameMailbox(MailboxId mailboxId, MailboxPath newMailboxPath, MailboxSession session) throws MailboxException;
+ List<MailboxRenamedResult> renameMailbox(MailboxId mailboxId, MailboxPath newMailboxPath, RenameOption option, MailboxSession session) throws MailboxException;
+
+ default List<MailboxRenamedResult> renameMailbox(MailboxId mailboxId, MailboxPath newMailboxPath, MailboxSession session) throws MailboxException {
+ return renameMailbox(mailboxId, newMailboxPath, RenameOption.NONE, session);
+ }
/**
* Copy the given {@link MessageRange} from one Mailbox to the other.
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java
index 3d92d48..09069fe 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java
@@ -18,6 +18,7 @@
****************************************************************/
package org.apache.james.mailbox;
+import static org.apache.james.mailbox.MailboxManager.RenameOption.RENAME_SUBSCRIPTIONS;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -45,6 +46,7 @@ import org.apache.james.core.quota.QuotaCountUsage;
import org.apache.james.core.quota.QuotaSizeLimit;
import org.apache.james.core.quota.QuotaSizeUsage;
import org.apache.james.mailbox.MailboxManager.MailboxCapabilities;
+import org.apache.james.mailbox.MailboxManager.MailboxRenamedResult;
import org.apache.james.mailbox.MessageManager.AppendCommand;
import org.apache.james.mailbox.events.EventBus;
import org.apache.james.mailbox.events.MailboxIdRegistrationKey;
@@ -112,6 +114,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
private static final int DEFAULT_MAXIMUM_LIMIT = 256;
protected T mailboxManager;
+ private SubscriptionManager subscriptionManager;
private MailboxSession session;
protected Message.Builder message;
@@ -120,6 +123,8 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
protected abstract T provideMailboxManager();
+ protected abstract SubscriptionManager provideSubscriptionManager();
+
protected abstract EventBus retrieveEventBus(T mailboxManager);
protected Set<PreDeletionHook> preDeletionHooks() {
@@ -130,6 +135,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
void setUp() throws Exception {
setupMockForPreDeletionHooks();
this.mailboxManager = provideMailboxManager();
+ this.subscriptionManager = provideSubscriptionManager();
this.message = Message.Builder.of()
.setSubject("test")
@@ -1533,6 +1539,197 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
@Nested
public class BasicFeaturesTests {
+
+ @Test
+ void renameMailboxShouldReturnAllRenamedResultsIncludeChildren() throws MailboxException {
+ MailboxSession session = mailboxManager.createSystemSession(USER_1);
+
+ MailboxPath mailboxPath1 = MailboxPath.forUser(USER_1, "mbx1");
+ MailboxPath mailboxPath2 = MailboxPath.forUser(USER_1, "mbx1.mbx2");
+ MailboxPath mailboxPath3 = MailboxPath.forUser(USER_1, "mbx1.mbx2.mbx3");
+ MailboxPath mailboxPath4 = MailboxPath.forUser(USER_1, "mbx1.mbx2.mbx3.mbx4");
+ MailboxPath newMailboxPath = MailboxPath.forUser(USER_1, "mbx1.mbx9");
+
+ mailboxManager.createMailbox(mailboxPath1, session);
+ Optional<MailboxId> mailboxId2 = mailboxManager.createMailbox(mailboxPath2, session);
+ Optional<MailboxId> mailboxId3 = mailboxManager.createMailbox(mailboxPath3, session);
+ Optional<MailboxId> mailboxId4 = mailboxManager.createMailbox(mailboxPath4, session);
+
+ List<MailboxRenamedResult> mailboxRenamedResults = mailboxManager.renameMailbox(mailboxPath2, newMailboxPath, session);
+
+ SoftAssertions.assertSoftly(softly -> {
+ softly.assertThat(mailboxRenamedResults).hasSize(3);
+ softly.assertThat(mailboxRenamedResults).contains(
+ new MailboxRenamedResult(mailboxId2.get(), mailboxPath2, MailboxPath.forUser(USER_1, "mbx1.mbx9")),
+ new MailboxRenamedResult(mailboxId3.get(), mailboxPath3, MailboxPath.forUser(USER_1, "mbx1.mbx9.mbx3")),
+ new MailboxRenamedResult(mailboxId4.get(), mailboxPath4, MailboxPath.forUser(USER_1, "mbx1.mbx9.mbx3.mbx4"))
+ );
+ });
+ }
+
+ @Test
+ void renameMailboxShouldReturnRenamedMailboxOnlyWhenNoChildren() throws MailboxException {
+ MailboxSession session = mailboxManager.createSystemSession(USER_1);
+
+ MailboxPath mailboxPath1 = MailboxPath.forUser(USER_1, "mbx1");
+ MailboxPath mailboxPath2 = MailboxPath.forUser(USER_1, "mbx1.mbx2");
+ MailboxPath originalPath = MailboxPath.forUser(USER_1, "mbx1.mbx2.mbx3");
+ MailboxPath newMailboxPath = MailboxPath.forUser(USER_1, "mbx1.mbx2.mbx9");
+
+ mailboxManager.createMailbox(mailboxPath1, session);
+ mailboxManager.createMailbox(mailboxPath2, session);
+ Optional<MailboxId> mailboxId3 = mailboxManager.createMailbox(originalPath, session);
+
+ List<MailboxRenamedResult> mailboxRenamedResults = mailboxManager.renameMailbox(originalPath, newMailboxPath, session);
+
+ SoftAssertions.assertSoftly(softly -> {
+ softly.assertThat(mailboxRenamedResults).hasSize(1);
+ softly.assertThat(mailboxRenamedResults).contains(
+ new MailboxRenamedResult(mailboxId3.get(), originalPath, newMailboxPath)
+ );
+ });
+ }
+
+ @Test
+ void renameMailboxShouldRenamedChildMailboxesWithRenameOption() throws MailboxException {
+ MailboxSession session = mailboxManager.createSystemSession(USER_1);
+
+ MailboxPath originalPath = MailboxPath.forUser(USER_1, "mbx1");
+ MailboxPath mailboxPath2 = MailboxPath.forUser(USER_1, "mbx1.mbx2");
+ MailboxPath mailboxPath3 = MailboxPath.forUser(USER_1, "mbx1.mbx2.mbx3");
+ MailboxPath newMailboxPath = MailboxPath.forUser(USER_1, "mbx9");
+
+ mailboxManager.createMailbox(originalPath, session);
+ mailboxManager.createMailbox(mailboxPath2, session);
+ subscriptionManager.subscribe(session, originalPath.getName());
+ subscriptionManager.subscribe(session, mailboxPath2.getName());
+
+ mailboxManager.createMailbox(mailboxPath3, session);
+ subscriptionManager.subscribe(session, mailboxPath3.getName());
+
+ mailboxManager.renameMailbox(originalPath, newMailboxPath, RENAME_SUBSCRIPTIONS, session);
+
+ assertThat(subscriptionManager.subscriptions(session)).containsExactly(
+ newMailboxPath.getName(),
+ "mbx9.mbx2",
+ "mbx9.mbx2.mbx3"
+ );
+ }
+
+ @Test
+ void renameMailboxShouldRenameSubscriptionWhenCalledWithRenameSubscriptionOption() throws MailboxException {
+ MailboxSession session = mailboxManager.createSystemSession(USER_1);
+
+ MailboxPath originalPath = MailboxPath.forUser(USER_1, "mbx1");
+ MailboxPath newMailboxPath = MailboxPath.forUser(USER_1, "mbx2");
+
+ mailboxManager.createMailbox(originalPath, session);
+ subscriptionManager.subscribe(session, originalPath.getName());
+
+ mailboxManager.renameMailbox(originalPath, newMailboxPath, RENAME_SUBSCRIPTIONS, session);
+
+ assertThat(subscriptionManager.subscriptions(session)).containsExactly(newMailboxPath.getName());
+ }
+
+ @Test
+ void renameMailboxShouldNotSubscribeUnsubscribedMailboxes() throws MailboxException {
+ MailboxSession session = mailboxManager.createSystemSession(USER_1);
+
+ MailboxPath originalPath = MailboxPath.forUser(USER_1, "mbx1");
+ MailboxPath newMailboxPath = MailboxPath.forUser(USER_1, "mbx2");
+
+ mailboxManager.createMailbox(originalPath, session);
+
+ mailboxManager.renameMailbox(originalPath, newMailboxPath, RENAME_SUBSCRIPTIONS, session);
+
+ assertThat(subscriptionManager.subscriptions(session)).isEmpty();
+ }
+
+ @Test
+ void renameMailboxShouldNotRenameSubscriptionWhenCalledWithoutRenameSubscriptionOption() throws MailboxException {
+ MailboxSession session = mailboxManager.createSystemSession(USER_1);
+
+ MailboxPath originalPath = MailboxPath.forUser(USER_1, "mbx1");
+ MailboxPath newMailboxPath = MailboxPath.forUser(USER_1, "mbx2");
+
+ mailboxManager.createMailbox(originalPath, session);
+ subscriptionManager.subscribe(session, originalPath.getName());
+
+ mailboxManager.renameMailbox(originalPath, newMailboxPath, MailboxManager.RenameOption.NONE, session);
+
+ assertThat(subscriptionManager.subscriptions(session)).containsExactly(originalPath.getName());
+ }
+
+ @Test
+ void renameMailboxByIdShouldRenamedMailboxesWithRenameOption() throws MailboxException {
+ MailboxSession session = mailboxManager.createSystemSession(USER_1);
+
+ MailboxPath originalPath = MailboxPath.forUser(USER_1, "mbx1");
+ MailboxPath mailboxPath2 = MailboxPath.forUser(USER_1, "mbx1.mbx2");
+ MailboxPath mailboxPath3 = MailboxPath.forUser(USER_1, "mbx1.mbx2.mbx3");
+ MailboxPath newMailboxPath = MailboxPath.forUser(USER_1, "mbx9");
+
+ Optional<MailboxId> id = mailboxManager.createMailbox(originalPath, session);
+ mailboxManager.createMailbox(mailboxPath2, session);
+ subscriptionManager.subscribe(session, originalPath.getName());
+ subscriptionManager.subscribe(session, mailboxPath2.getName());
+
+ mailboxManager.createMailbox(mailboxPath3, session);
+ subscriptionManager.subscribe(session, mailboxPath3.getName());
+
+ mailboxManager.renameMailbox(id.get(), newMailboxPath, RENAME_SUBSCRIPTIONS, session);
+
+ assertThat(subscriptionManager.subscriptions(session)).containsExactly(
+ newMailboxPath.getName(),
+ "mbx9.mbx2",
+ "mbx9.mbx2.mbx3"
+ );
+ }
+
+ @Test
+ void renameMailboxByIdShouldRenameSubscriptionWhenCalledWithRenameSubscriptionOption() throws MailboxException {
+ MailboxSession session = mailboxManager.createSystemSession(USER_1);
+
+ MailboxPath originalPath = MailboxPath.forUser(USER_1, "mbx1");
+ MailboxPath newMailboxPath = MailboxPath.forUser(USER_1, "mbx2");
+
+ Optional<MailboxId> id = mailboxManager.createMailbox(originalPath, session);
+ subscriptionManager.subscribe(session, originalPath.getName());
+
+ mailboxManager.renameMailbox(id.get(), newMailboxPath, RENAME_SUBSCRIPTIONS, session);
+
+ assertThat(subscriptionManager.subscriptions(session)).containsExactly(newMailboxPath.getName());
+ }
+
+ @Test
+ void renameMailboxByIdShouldNotSubscribeUnsubscribedMailboxes() throws MailboxException {
+ MailboxSession session = mailboxManager.createSystemSession(USER_1);
+
+ MailboxPath originalPath = MailboxPath.forUser(USER_1, "mbx1");
+ MailboxPath newMailboxPath = MailboxPath.forUser(USER_1, "mbx2");
+
+ Optional<MailboxId> id = mailboxManager.createMailbox(originalPath, session);
+
+ mailboxManager.renameMailbox(id.get(), newMailboxPath, RENAME_SUBSCRIPTIONS, session);
+
+ assertThat(subscriptionManager.subscriptions(session)).isEmpty();
+ }
+
+ @Test
+ void renameMailboxByIdShouldNotRenameSubscriptionWhenCalledWithoutRenameSubscriptionOption() throws MailboxException {
+ MailboxSession session = mailboxManager.createSystemSession(USER_1);
+
+ MailboxPath originalPath = MailboxPath.forUser(USER_1, "mbx1");
+ MailboxPath newMailboxPath = MailboxPath.forUser(USER_1, "mbx2");
+
+ Optional<MailboxId> id = mailboxManager.createMailbox(originalPath, session);
+ subscriptionManager.subscribe(session, originalPath.getName());
+
+ mailboxManager.renameMailbox(id.get(), newMailboxPath, MailboxManager.RenameOption.NONE, session);
+
+ assertThat(subscriptionManager.subscriptions(session)).containsExactly(originalPath.getName());
+ }
+
@Test
void user1ShouldNotHaveAnInbox() throws Exception {
session = mailboxManager.createSystemSession(USER_1);
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerTest.java
index f57f28e..328fcc6 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerTest.java
@@ -39,6 +39,7 @@ import org.apache.james.mailbox.MailboxManagerTest;
import org.apache.james.mailbox.MailboxSession;
import org.apache.james.mailbox.MessageManager;
import org.apache.james.mailbox.MessageManager.AppendResult;
+import org.apache.james.mailbox.SubscriptionManager;
import org.apache.james.mailbox.cassandra.ids.CassandraId;
import org.apache.james.mailbox.cassandra.ids.CassandraMessageId;
import org.apache.james.mailbox.cassandra.mail.CassandraACLMapper;
@@ -65,6 +66,7 @@ import org.apache.james.mailbox.model.MessageAttachmentMetadata;
import org.apache.james.mailbox.model.MessageRange;
import org.apache.james.mailbox.model.MessageResult;
import org.apache.james.mailbox.store.PreDeletionHooks;
+import org.apache.james.mailbox.store.StoreSubscriptionManager;
import org.apache.james.mailbox.store.mail.MessageMapper;
import org.apache.james.metrics.tests.RecordingMetricFactory;
import org.apache.james.util.ClassLoaderUtils;
@@ -92,6 +94,11 @@ public class CassandraMailboxManagerTest extends MailboxManagerTest<CassandraMai
}
@Override
+ protected SubscriptionManager provideSubscriptionManager() {
+ return new StoreSubscriptionManager(provideMailboxManager().getMapperFactory());
+ }
+
+ @Override
protected EventBus retrieveEventBus(CassandraMailboxManager mailboxManager) {
return mailboxManager.getEventBus();
}
diff --git a/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/JPAMailboxManagerTest.java b/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/JPAMailboxManagerTest.java
index 4b917d9..530a596 100644
--- a/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/JPAMailboxManagerTest.java
+++ b/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/JPAMailboxManagerTest.java
@@ -22,8 +22,10 @@ import java.util.Optional;
import org.apache.james.backends.jpa.JpaTestCluster;
import org.apache.james.mailbox.MailboxManagerTest;
+import org.apache.james.mailbox.SubscriptionManager;
import org.apache.james.mailbox.events.EventBus;
import org.apache.james.mailbox.jpa.openjpa.OpenJPAMailboxManager;
+import org.apache.james.mailbox.store.StoreSubscriptionManager;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Nested;
@@ -48,6 +50,11 @@ class JPAMailboxManagerTest extends MailboxManagerTest<OpenJPAMailboxManager> {
return openJPAMailboxManager.get();
}
+ @Override
+ protected SubscriptionManager provideSubscriptionManager() {
+ return new StoreSubscriptionManager(provideMailboxManager().getMapperFactory());
+ }
+
@AfterEach
void tearDownJpa() {
JPA_TEST_CLUSTER.clear(JPAMailboxFixture.MAILBOX_TABLE_NAMES);
diff --git a/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/DomainUserMaildirMailboxManagerTest.java b/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/DomainUserMaildirMailboxManagerTest.java
index c54dd2c..601b019 100644
--- a/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/DomainUserMaildirMailboxManagerTest.java
+++ b/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/DomainUserMaildirMailboxManagerTest.java
@@ -18,10 +18,14 @@
****************************************************************/
package org.apache.james.mailbox.maildir;
+import java.util.Optional;
+
import org.apache.james.junit.TemporaryFolderExtension;
import org.apache.james.mailbox.MailboxManagerTest;
+import org.apache.james.mailbox.SubscriptionManager;
import org.apache.james.mailbox.events.EventBus;
import org.apache.james.mailbox.store.StoreMailboxManager;
+import org.apache.james.mailbox.store.StoreSubscriptionManager;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
@@ -88,11 +92,24 @@ class DomainUserMaildirMailboxManagerTest extends MailboxManagerTest<StoreMailbo
@RegisterExtension
TemporaryFolderExtension temporaryFolder = new TemporaryFolderExtension();
-
+ Optional<StoreMailboxManager> mailboxManager = Optional.empty();
+
@Override
protected StoreMailboxManager provideMailboxManager() {
+ if (!mailboxManager.isPresent()) {
+ mailboxManager = Optional.of(createMailboxManager());
+ }
+ return mailboxManager.get();
+ }
+
+ @Override
+ protected SubscriptionManager provideSubscriptionManager() {
+ return new StoreSubscriptionManager(provideMailboxManager().getMapperFactory());
+ }
+
+ private StoreMailboxManager createMailboxManager() {
try {
- return MaildirMailboxManagerProvider.createMailboxManager("/%domain/%user", temporaryFolder.getTemporaryFolder().getTempDir());
+ return MaildirMailboxManagerProvider.createMailboxManager("/%fulluser", temporaryFolder.getTemporaryFolder().getTempDir());
} catch (Exception e) {
throw new RuntimeException(e);
}
diff --git a/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/FullUserMaildirMailboxManagerTest.java b/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/FullUserMaildirMailboxManagerTest.java
index cb5d08f..e580662 100644
--- a/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/FullUserMaildirMailboxManagerTest.java
+++ b/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/FullUserMaildirMailboxManagerTest.java
@@ -18,10 +18,15 @@
****************************************************************/
package org.apache.james.mailbox.maildir;
+import java.util.Optional;
+
import org.apache.james.junit.TemporaryFolderExtension;
import org.apache.james.mailbox.MailboxManagerTest;
+import org.apache.james.mailbox.SubscriptionManager;
import org.apache.james.mailbox.events.EventBus;
import org.apache.james.mailbox.store.StoreMailboxManager;
+import org.apache.james.mailbox.store.StoreSubscriptionManager;
+import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.extension.RegisterExtension;
@@ -36,9 +41,22 @@ class FullUserMaildirMailboxManagerTest extends MailboxManagerTest<StoreMailboxM
@RegisterExtension
TemporaryFolderExtension temporaryFolder = new TemporaryFolderExtension();
+ Optional<StoreMailboxManager> mailboxManager = Optional.empty();
@Override
protected StoreMailboxManager provideMailboxManager() {
+ if (!mailboxManager.isPresent()) {
+ mailboxManager = Optional.of(createMailboxManager());
+ }
+ return mailboxManager.get();
+ }
+
+ @Override
+ protected SubscriptionManager provideSubscriptionManager() {
+ return new StoreSubscriptionManager(provideMailboxManager().getMapperFactory());
+ }
+
+ private StoreMailboxManager createMailboxManager() {
try {
return MaildirMailboxManagerProvider.createMailboxManager("/%fulluser", temporaryFolder.getTemporaryFolder().getTempDir());
} catch (Exception e) {
diff --git a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/MemoryMailboxManagerTest.java b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/MemoryMailboxManagerTest.java
index 7eb0846..c02c55f 100644
--- a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/MemoryMailboxManagerTest.java
+++ b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/MemoryMailboxManagerTest.java
@@ -20,7 +20,9 @@
package org.apache.james.mailbox.inmemory;
import org.apache.james.mailbox.MailboxManagerTest;
+import org.apache.james.mailbox.SubscriptionManager;
import org.apache.james.mailbox.events.EventBus;
+import org.apache.james.mailbox.store.StoreSubscriptionManager;
class MemoryMailboxManagerTest extends MailboxManagerTest<InMemoryMailboxManager> {
@@ -30,6 +32,11 @@ class MemoryMailboxManagerTest extends MailboxManagerTest<InMemoryMailboxManager
}
@Override
+ protected SubscriptionManager provideSubscriptionManager() {
+ return new StoreSubscriptionManager(provideMailboxManager().getMapperFactory());
+ }
+
+ @Override
protected EventBus retrieveEventBus(InMemoryMailboxManager mailboxManager) {
return mailboxManager.getEventBus();
}
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/MailboxReactorUtils.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/MailboxReactorUtils.java
index c8e3cd3..0bfa8f8 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/MailboxReactorUtils.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/MailboxReactorUtils.java
@@ -22,6 +22,7 @@ package org.apache.james.mailbox.store;
import java.util.Optional;
import org.apache.james.mailbox.exception.MailboxException;
+import org.reactivestreams.Publisher;
import reactor.core.publisher.Mono;
@@ -37,7 +38,11 @@ public abstract class MailboxReactorUtils {
throw e;
}
}
-
+
+ public static <T> T block(Publisher<T> publisher) throws MailboxException {
+ return block(Mono.from(publisher));
+ }
+
public static <T> Optional<T> blockOptional(Mono<T> publisher) throws MailboxException {
try {
return publisher.blockOptional();
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
index cab65d7..091e40b 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
@@ -50,6 +50,7 @@ import org.apache.james.mailbox.exception.InsufficientRightsException;
import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.exception.MailboxExistsException;
import org.apache.james.mailbox.exception.MailboxNotFoundException;
+import org.apache.james.mailbox.exception.SubscriptionException;
import org.apache.james.mailbox.exception.UnsupportedRightException;
import org.apache.james.mailbox.extension.PreDeletionHook;
import org.apache.james.mailbox.model.Mailbox;
@@ -82,6 +83,8 @@ import org.apache.james.mailbox.store.mail.model.impl.MessageParser;
import org.apache.james.mailbox.store.quota.QuotaComponents;
import org.apache.james.mailbox.store.search.MessageSearchIndex;
import org.apache.james.mailbox.store.transaction.Mapper;
+import org.apache.james.mailbox.store.user.SubscriptionMapper;
+import org.apache.james.mailbox.store.user.model.Subscription;
import org.apache.james.util.FunctionalUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -89,6 +92,7 @@ import org.slf4j.LoggerFactory;
import com.github.fge.lambdas.Throwing;
import com.github.steveash.guavate.Guavate;
import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
@@ -101,7 +105,6 @@ import reactor.core.publisher.Mono;
* to extend just this class or use it directly.
* <p/>
* If you need a more low-level api just implement {@link MailboxManager} directly
- *
*/
public class StoreMailboxManager implements MailboxManager {
private static final Logger LOGGER = LoggerFactory.getLogger(StoreMailboxManager.class);
@@ -170,7 +173,7 @@ public class StoreMailboxManager implements MailboxManager {
public EnumSet<MessageCapabilities> getSupportedMessageCapabilities() {
return DEFAULT_NO_MESSAGE_CAPABILITIES;
}
-
+
@Override
public EnumSet<SearchCapabilities> getSupportedSearchCapabilities() {
return index.getSupportedCapabilities(getSupportedMessageCapabilities());
@@ -248,14 +251,13 @@ public class StoreMailboxManager implements MailboxManager {
*/
protected StoreMessageManager createMessageManager(Mailbox mailbox, MailboxSession session) throws MailboxException {
return new StoreMessageManager(DEFAULT_NO_MESSAGE_CAPABILITIES, getMapperFactory(), getMessageSearchIndex(), getEventBus(),
- getLocker(), mailbox, quotaManager,
+ getLocker(), mailbox, quotaManager,
getQuotaComponents().getQuotaRootResolver(), configuration.getBatchSizes(),
getStoreRightManager(), preDeletionHooks, new MessageStorer.WithoutAttachment(mailboxSessionMapperFactory, messageIdFactory, new MessageFactory.StoreMessageFactory()));
}
@Override
- public MessageManager getMailbox(MailboxPath mailboxPath, MailboxSession session)
- throws MailboxException {
+ public MessageManager getMailbox(MailboxPath mailboxPath, MailboxSession session) throws MailboxException {
final MailboxMapper mapper = mailboxSessionMapperFactory.getMailboxMapper(session);
Mailbox mailboxRow = mapper.findMailboxByPath(mailboxPath)
.blockOptional()
@@ -275,8 +277,7 @@ public class StoreMailboxManager implements MailboxManager {
}
@Override
- public MessageManager getMailbox(MailboxId mailboxId, MailboxSession session)
- throws MailboxException {
+ public MessageManager getMailbox(MailboxId mailboxId, MailboxSession session) throws MailboxException {
MailboxMapper mapper = mailboxSessionMapperFactory.getMailboxMapper(session);
Mailbox mailboxRow = block(mapper.findMailboxById(mailboxId));
@@ -303,8 +304,7 @@ public class StoreMailboxManager implements MailboxManager {
}
@Override
- public Optional<MailboxId> createMailbox(MailboxPath mailboxPath, MailboxSession mailboxSession)
- throws MailboxException {
+ public Optional<MailboxId> createMailbox(MailboxPath mailboxPath, MailboxSession mailboxSession) throws MailboxException {
LOGGER.debug("createMailbox {}", mailboxPath);
assertMailboxPathBelongToUser(mailboxSession, mailboxPath);
@@ -343,7 +343,7 @@ public class StoreMailboxManager implements MailboxManager {
private Stream<MailboxId> manageMailboxCreation(MailboxSession mailboxSession, boolean isRootPath, MailboxPath mailboxPath) throws MailboxException {
if (mailboxPath.isInbox()) {
- if (block(Mono.from(hasInbox(mailboxSession)))) {
+ if (block(hasInbox(mailboxSession))) {
return duplicatedINBOXCreation(isRootPath, mailboxPath);
}
@@ -376,11 +376,11 @@ public class StoreMailboxManager implements MailboxManager {
.flatMap(mailbox ->
// notify listeners
eventBus.dispatch(EventFactory.mailboxAdded()
- .randomEventId()
- .mailboxSession(mailboxSession)
- .mailbox(mailbox)
- .build(),
- new MailboxIdRegistrationKey(mailbox.getMailboxId()))))));
+ .randomEventId()
+ .mailboxSession(mailboxSession)
+ .mailbox(mailbox)
+ .build(),
+ new MailboxIdRegistrationKey(mailbox.getMailboxId()))))));
} catch (Exception e) {
if (e instanceof MailboxExistsException) {
LOGGER.info("{} mailbox was created concurrently", mailboxPath.asString());
@@ -421,12 +421,12 @@ public class StoreMailboxManager implements MailboxManager {
MailboxMapper mailboxMapper = mailboxSessionMapperFactory.getMailboxMapper(session);
return mailboxMapper.execute(() -> block(mailboxMapper.findMailboxById(mailboxId)
- .map(Throwing.<Mailbox, Mailbox>function(mailbox -> {
- assertIsOwner(session, mailbox.generateAssociatedPath());
- return mailbox;
- }).sneakyThrow())
- .flatMap(Throwing.<Mailbox, Mono<Mailbox>>function(mailbox ->
- doDeleteMailbox(mailboxMapper, mailbox, session)).sneakyThrow())));
+ .map(Throwing.<Mailbox, Mailbox>function(mailbox -> {
+ assertIsOwner(session, mailbox.generateAssociatedPath());
+ return mailbox;
+ }).sneakyThrow())
+ .flatMap(Throwing.<Mailbox, Mono<Mailbox>>function(mailbox ->
+ doDeleteMailbox(mailboxMapper, mailbox, session)).sneakyThrow())));
}
private Mono<Mailbox> doDeleteMailbox(MailboxMapper mailboxMapper, Mailbox mailbox, MailboxSession session) throws MailboxException {
@@ -447,14 +447,14 @@ public class StoreMailboxManager implements MailboxManager {
return preDeletionHooks.runHooks(PreDeletionHook.DeleteOperation.from(metadata))
.then(mailboxMapper.delete(mailbox))
.then(eventBus.dispatch(EventFactory.mailboxDeleted()
- .randomEventId()
- .mailboxSession(session)
- .mailbox(mailbox)
- .quotaRoot(quotaRoot)
- .quotaCount(QuotaCountUsage.count(messageCount))
- .quotaSize(QuotaSizeUsage.size(totalSize))
- .build(),
- new MailboxIdRegistrationKey(mailbox.getMailboxId())));
+ .randomEventId()
+ .mailboxSession(session)
+ .mailbox(mailbox)
+ .quotaRoot(quotaRoot)
+ .quotaCount(QuotaCountUsage.count(messageCount))
+ .quotaSize(QuotaSizeUsage.size(totalSize))
+ .build(),
+ new MailboxIdRegistrationKey(mailbox.getMailboxId())));
})
// We need to create a copy of the mailbox as maybe we can not refer to the real
// mailbox once we remove it
@@ -462,7 +462,8 @@ public class StoreMailboxManager implements MailboxManager {
}
@Override
- public void renameMailbox(MailboxPath from, MailboxPath to, MailboxSession session) throws MailboxException {
+ public List<MailboxRenamedResult> renameMailbox(MailboxPath from, MailboxPath to, RenameOption option,
+ MailboxSession session) throws MailboxException {
LOGGER.debug("renameMailbox {} to {}", from, to);
MailboxPath sanitizedMailboxPath = to.sanitize(session.getPathDelimiter());
validateDestinationPath(sanitizedMailboxPath, session);
@@ -470,26 +471,46 @@ public class StoreMailboxManager implements MailboxManager {
assertIsOwner(session, from);
MailboxMapper mapper = mailboxSessionMapperFactory.getMailboxMapper(session);
- mapper.execute(Mapper.toTransaction(() -> {
+ return mapper.execute(() -> {
Mailbox mailbox = blockOptional(mapper.findMailboxByPath(from))
.orElseThrow(() -> new MailboxNotFoundException(from));
- doRenameMailbox(mailbox, sanitizedMailboxPath, session, mapper);
- }));
+ return renameSubscriptionsIfNeeded(
+ doRenameMailbox(mailbox, sanitizedMailboxPath, session, mapper), option, session);
+ });
+ }
+
+ private List<MailboxRenamedResult> renameSubscriptionsIfNeeded(List<MailboxRenamedResult> renamedResults,
+ RenameOption option, MailboxSession session) throws SubscriptionException {
+ if (option == RenameOption.RENAME_SUBSCRIPTIONS) {
+ SubscriptionMapper subscriptionMapper = mailboxSessionMapperFactory.getSubscriptionMapper(session);
+ List<Subscription> subscriptionsForUser = subscriptionMapper.findSubscriptionsForUser(session.getUser());
+ renamedResults.forEach(Throwing.<MailboxRenamedResult>consumer(renamedResult -> {
+ Subscription subscription = new Subscription(session.getUser(), renamedResult.getOriginPath().getName());
+ if (subscriptionsForUser.contains(subscription)) {
+ subscriptionMapper.delete(subscription);
+ subscriptionMapper.save(new Subscription(session.getUser(), renamedResult.getDestinationPath().getName()));
+ }
+ }).sneakyThrow());
+ }
+ return renamedResults;
}
@Override
- public void renameMailbox(MailboxId mailboxId, MailboxPath newMailboxPath, MailboxSession session) throws MailboxException {
+ public List<MailboxRenamedResult> renameMailbox(MailboxId mailboxId, MailboxPath newMailboxPath, RenameOption option,
+ MailboxSession session) throws MailboxException {
LOGGER.debug("renameMailbox {} to {}", mailboxId, newMailboxPath);
MailboxPath sanitizedMailboxPath = newMailboxPath.sanitize(session.getPathDelimiter());
validateDestinationPath(sanitizedMailboxPath, session);
MailboxMapper mapper = mailboxSessionMapperFactory.getMailboxMapper(session);
- mapper.execute(Mapper.toTransaction(() -> {
- Mailbox mailbox = block(mapper.findMailboxById(mailboxId));
+ return mapper.execute(() -> {
+ Mailbox mailbox = mapper.findMailboxById(mailboxId).blockOptional()
+ .orElseThrow(() -> new MailboxNotFoundException(mailboxId));
assertIsOwner(session, mailbox.generateAssociatedPath());
- doRenameMailbox(mailbox, sanitizedMailboxPath, session, mapper);
- }));
+ return renameSubscriptionsIfNeeded(
+ doRenameMailbox(mailbox, sanitizedMailboxPath, session, mapper), option, session);
+ });
}
private void validateDestinationPath(MailboxPath newMailboxPath, MailboxSession session) throws MailboxException {
@@ -507,21 +528,27 @@ public class StoreMailboxManager implements MailboxManager {
}
}
- private void doRenameMailbox(Mailbox mailbox, MailboxPath newMailboxPath, MailboxSession session, MailboxMapper mapper) throws MailboxException {
+ private List<MailboxRenamedResult> doRenameMailbox(Mailbox mailbox, MailboxPath newMailboxPath, MailboxSession session, MailboxMapper mapper) throws MailboxException {
// TODO put this into a serilizable transaction
+ ImmutableList.Builder<MailboxRenamedResult> resultBuilder = ImmutableList.builder();
+
MailboxPath from = mailbox.generateAssociatedPath();
mailbox.setNamespace(newMailboxPath.getNamespace());
mailbox.setUser(newMailboxPath.getUser());
mailbox.setName(newMailboxPath.getName());
+
block(mapper.rename(mailbox)
- .then(eventBus.dispatch(EventFactory.mailboxRenamed()
- .randomEventId()
- .mailboxSession(session)
- .mailboxId(mailbox.getMailboxId())
- .oldPath(from)
- .newPath(newMailboxPath)
- .build(),
+ .map(mailboxId -> {
+ resultBuilder.add(new MailboxRenamedResult(mailboxId, from, newMailboxPath));
+ return mailboxId;
+ }).then(eventBus.dispatch(EventFactory.mailboxRenamed()
+ .randomEventId()
+ .mailboxSession(session)
+ .mailboxId(mailbox.getMailboxId())
+ .oldPath(from)
+ .newPath(newMailboxPath)
+ .build(),
new MailboxIdRegistrationKey(mailbox.getMailboxId()))));
// rename submailboxes
@@ -538,13 +565,16 @@ public class StoreMailboxManager implements MailboxManager {
MailboxPath fromPath = new MailboxPath(from, subOriginalName);
sub.setName(subNewName);
return mapper.rename(sub)
- .then(eventBus.dispatch(EventFactory.mailboxRenamed()
- .randomEventId()
- .mailboxSession(session)
- .mailboxId(sub.getMailboxId())
- .oldPath(fromPath)
- .newPath(sub.generateAssociatedPath())
- .build(),
+ .map(mailboxId -> {
+ resultBuilder.add(new MailboxRenamedResult(sub.getMailboxId(), fromPath, sub.generateAssociatedPath()));
+ return mailboxId;
+ }).then(eventBus.dispatch(EventFactory.mailboxRenamed()
+ .randomEventId()
+ .mailboxSession(session)
+ .mailboxId(sub.getMailboxId())
+ .oldPath(fromPath)
+ .newPath(sub.generateAssociatedPath())
+ .build(),
new MailboxIdRegistrationKey(sub.getMailboxId())))
.then(Mono.fromRunnable(() -> LOGGER.debug("Rename mailbox sub-mailbox {} to {}", subOriginalName, subNewName)));
})
@@ -553,6 +583,7 @@ public class StoreMailboxManager implements MailboxManager {
return null;
}, MailboxPathLocker.LockType.Write);
+ return resultBuilder.build();
}
@Override
@@ -571,7 +602,7 @@ public class StoreMailboxManager implements MailboxManager {
return copyMessages(set, session, toMailbox, fromMailbox);
}
-
+
private List<MessageRange> copyMessages(MessageRange set, MailboxSession session, StoreMessageManager toMailbox, StoreMessageManager fromMailbox) throws MailboxException {
return configuration.getCopyBatcher().batchMessages(set,
messageRange -> fromMailbox.copyTo(messageRange, toMailbox, session));
@@ -673,7 +704,7 @@ public class StoreMailboxManager implements MailboxManager {
private Flux<MailboxId> getInMailboxes(ImmutableSet<MailboxId> inMailboxes, MailboxSession session) throws MailboxException {
- if (inMailboxes.isEmpty()) {
+ if (inMailboxes.isEmpty()) {
return getAllReadableMailbox(session);
} else {
return filterReadable(inMailboxes, session);
@@ -782,13 +813,13 @@ public class StoreMailboxManager implements MailboxManager {
@Override
public List<MailboxAnnotation> getAnnotationsByKeys(MailboxPath mailboxPath, MailboxSession session, Set<MailboxAnnotationKey> keys)
- throws MailboxException {
+ throws MailboxException {
return annotationManager.getAnnotationsByKeys(mailboxPath, session, keys);
}
@Override
public void updateAnnotations(MailboxPath mailboxPath, MailboxSession session, List<MailboxAnnotation> mailboxAnnotations)
- throws MailboxException {
+ throws MailboxException {
annotationManager.updateAnnotations(mailboxPath, session, mailboxAnnotations);
}
@@ -800,13 +831,13 @@ public class StoreMailboxManager implements MailboxManager {
@Override
public List<MailboxAnnotation> getAnnotationsByKeysWithOneDepth(MailboxPath mailboxPath, MailboxSession session,
- Set<MailboxAnnotationKey> keys) throws MailboxException {
+ Set<MailboxAnnotationKey> keys) throws MailboxException {
return annotationManager.getAnnotationsByKeysWithOneDepth(mailboxPath, session, keys);
}
@Override
public List<MailboxAnnotation> getAnnotationsByKeysWithAllDepth(MailboxPath mailboxPath, MailboxSession session,
- Set<MailboxAnnotationKey> keys) throws MailboxException {
+ Set<MailboxAnnotationKey> keys) throws MailboxException {
return annotationManager.getAnnotationsByKeysWithAllDepth(mailboxPath, session, keys);
}
diff --git a/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/SetMailboxesMethodTest.java b/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/SetMailboxesMethodTest.java
index 2d9e3d0..86a9586 100644
--- a/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/SetMailboxesMethodTest.java
+++ b/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/SetMailboxesMethodTest.java
@@ -21,6 +21,7 @@ package org.apache.james.jmap.draft.methods.integration;
import static io.restassured.RestAssured.given;
import static io.restassured.RestAssured.with;
+import static io.restassured.http.ContentType.JSON;
import static org.apache.james.jmap.HttpJmapAuthentication.authenticateJamesUser;
import static org.apache.james.jmap.JMAPTestingConstants.ARGUMENTS;
import static org.apache.james.jmap.JMAPTestingConstants.DOMAIN;
@@ -74,6 +75,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import io.restassured.RestAssured;
+import io.restassured.response.Response;
public abstract class SetMailboxesMethodTest {
@@ -81,7 +83,7 @@ public abstract class SetMailboxesMethodTest {
private static final String WRITE = String.valueOf(Right.Write.asCharacter());
private static final String DELETE_MESSAGES = String.valueOf(Right.DeleteMessages.asCharacter());
- private static int MAILBOX_NAME_LENGTH_64K = 65536;
+ private static final int MAILBOX_NAME_LENGTH_64K = 65536;
protected abstract GuiceJamesServer createJmapServer() throws IOException;
@@ -338,17 +340,15 @@ public abstract class SetMailboxesMethodTest {
@Test
public void subscriptionUserShouldBeChangedWhenUpdateMailbox() throws Exception {
- mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, username.asString(), "root");
-
- String initialMailboxName = "root.myBox";
- MailboxId mailboxId = mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, username.asString(), initialMailboxName);
+ String initialMailboxName = "myBox";
+ String mailboxId = createMailBoxThroughJMAP(initialMailboxName);
String requestBody =
"[" +
" [ \"setMailboxes\"," +
" {" +
" \"update\": {" +
- " \"" + mailboxId.serialize() + "\" : {" +
+ " \"" + mailboxId + "\" : {" +
" \"name\" : \"mySecondBox\"" +
" }" +
" }" +
@@ -367,6 +367,139 @@ public abstract class SetMailboxesMethodTest {
}
@Test
+ public void subscriptionUserShouldBeChangedWhenUpdateParentMailbox() throws Exception {
+ MailboxId parentId = mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, username.asString(), "root");
+
+ String secondMailboxName = "second";
+ String secondMailboxId = createSubMailBox(parentId.serialize(), secondMailboxName);
+
+ String thirdMailBoxName = "third";
+ String thirdMailboxId = createSubMailBox(secondMailboxId, thirdMailBoxName);
+
+ String fourthMailboxName = "fourth";
+ createSubMailBox(thirdMailboxId, fourthMailboxName);
+
+ String requestBody =
+ "[" +
+ " [ \"setMailboxes\"," +
+ " {" +
+ " \"update\": {" +
+ " \"" + thirdMailboxId + "\" : {" +
+ " \"name\" : \"thirdtest\" ," +
+ " \"parentId\" : \"" + secondMailboxId + "\"" +
+ " }" +
+ " }" +
+ " }," +
+ " \"#0\"" +
+ " ]" +
+ "]";
+ with()
+ .header("Authorization", accessToken.asString())
+ .body(requestBody)
+ .post("/jmap");
+
+ assertThat(mailboxProbe.listSubscriptions(username.asString()))
+ .contains("root.second.thirdtest.fourth")
+ .doesNotContain("root.second.third.fourth");
+ }
+
+ @Test
+ public void subscriptionUserShouldBeChangedForAllChildrenWhenUpdateParentMailbox() throws Exception {
+ MailboxId parentId = mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, username.asString(), "root");
+
+ String secondMailboxName = "second";
+ String secondMailboxId = createSubMailBox(parentId.serialize(), secondMailboxName);
+
+ String thirdMailBoxName = "third";
+ String thirdMailboxId = createSubMailBox(secondMailboxId, thirdMailBoxName);
+
+ String fourthMailboxName = "fourth";
+ createSubMailBox(thirdMailboxId, fourthMailboxName);
+
+ String requestBody =
+ "[" +
+ " [ \"setMailboxes\"," +
+ " {" +
+ " \"update\": {" +
+ " \"" + secondMailboxId + "\" : {" +
+ " \"name\" : \"secondtest\" ," +
+ " \"parentId\" : \"" + parentId.serialize() + "\"" +
+ " }" +
+ " }" +
+ " }," +
+ " \"#0\"" +
+ " ]" +
+ "]";
+ with()
+ .header("Authorization", accessToken.asString())
+ .body(requestBody)
+ .post("/jmap");
+
+ assertThat(mailboxProbe.listSubscriptions(username.asString()))
+ .contains("root.secondtest.third.fourth")
+ .doesNotContain("root.second.third.fourth");
+ }
+
+ private String createSubMailBox(String parentMailboxId, String childMailboxName) {
+ String clientIdentifier = "whatever";
+ String createChildMailbox =
+ "[" +
+ " [ \"setMailboxes\"," +
+ " {" +
+ " \"create\": {" +
+ " \"" + clientIdentifier + "\" : {" +
+ " \"name\" : \"" + childMailboxName + "\"," +
+ " \"parentId\" : \"" + parentMailboxId + "\"" +
+ " }" +
+ " }" +
+ " }," +
+ " \"#0\"" +
+ " ]" +
+ "]";
+
+ Response response = given()
+ .header("Authorization", accessToken.asString())
+ .body(createChildMailbox)
+ .when()
+ .post("/jmap")
+ .then()
+ .contentType(JSON)
+ .extract()
+ .response();
+
+ return response.jsonPath().get("[0][1].created." + clientIdentifier + ".id");
+ }
+
+ private String createMailBoxThroughJMAP(String mailboxName) {
+ String clientIdentifier = "whatever";
+ String createMailbox =
+ "[" +
+ " [ \"setMailboxes\"," +
+ " {" +
+ " \"create\": {" +
+ " \"" + clientIdentifier + "\" : {" +
+ " \"name\" : \"" + mailboxName + "\"" +
+ " }" +
+ " }" +
+ " }," +
+ " \"#0\"" +
+ " ]" +
+ "]";
+
+ Response response = given()
+ .header("Authorization", accessToken.asString())
+ .body(createMailbox)
+ .when()
+ .post("/jmap")
+ .then()
+ .contentType(JSON)
+ .extract()
+ .response();
+
+ return response.jsonPath().get("[0][1].created." + clientIdentifier + ".id");
+ }
+
+ @Test
public void subscriptionUserShouldBeChangedWhenCreateThenUpdateMailboxNameWithJMAP() throws Exception {
String requestBody =
"[" +
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetMailboxesUpdateProcessor.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetMailboxesUpdateProcessor.java
index b64d8d8..1d79ceb 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetMailboxesUpdateProcessor.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetMailboxesUpdateProcessor.java
@@ -41,7 +41,6 @@ import org.apache.james.mailbox.MailboxManager;
import org.apache.james.mailbox.MailboxSession;
import org.apache.james.mailbox.MessageManager;
import org.apache.james.mailbox.Role;
-import org.apache.james.mailbox.SubscriptionManager;
import org.apache.james.mailbox.exception.DifferentDomainException;
import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.exception.MailboxExistsException;
@@ -70,14 +69,12 @@ public class SetMailboxesUpdateProcessor implements SetMailboxesProcessor {
private final MailboxManager mailboxManager;
private final MailboxFactory mailboxFactory;
private final MetricFactory metricFactory;
- private final SubscriptionManager subscriptionManager;
@Inject
@VisibleForTesting
- SetMailboxesUpdateProcessor(MailboxUtils mailboxUtils, MailboxManager mailboxManager, SubscriptionManager subscriptionManager, MailboxFactory mailboxFactory, MetricFactory metricFactory) {
+ SetMailboxesUpdateProcessor(MailboxUtils mailboxUtils, MailboxManager mailboxManager, MailboxFactory mailboxFactory, MetricFactory metricFactory) {
this.mailboxUtils = mailboxUtils;
this.mailboxManager = mailboxManager;
- this.subscriptionManager = subscriptionManager;
this.mailboxFactory = mailboxFactory;
this.metricFactory = metricFactory;
}
@@ -156,7 +153,7 @@ public class SetMailboxesUpdateProcessor implements SetMailboxesProcessor {
.description("An error occurred when updating the mailbox")
.build());
}
- }
+ }
private void assertNotSharedOutboxOrDraftMailbox(Mailbox mailbox, MailboxUpdateRequest updateRequest) {
Preconditions.checkArgument(!updateRequest.getSharedWith().isPresent() || !mailbox.hasRole(Role.OUTBOX), "Sharing 'Outbox' is forbidden");
@@ -258,6 +255,7 @@ public class SetMailboxesUpdateProcessor implements SetMailboxesProcessor {
private void updateMailbox(Mailbox mailbox, MailboxUpdateRequest updateRequest, MailboxSession mailboxSession) throws MailboxException {
MailboxPath originMailboxPath = mailboxManager.getMailbox(mailbox.getId(), mailboxSession).getMailboxPath();
MailboxPath destinationMailboxPath = computeNewMailboxPath(mailbox, originMailboxPath, updateRequest, mailboxSession);
+
if (updateRequest.getSharedWith().isPresent()) {
mailboxManager.setRights(mailbox.getId(),
updateRequest.getSharedWith()
@@ -266,11 +264,9 @@ public class SetMailboxesUpdateProcessor implements SetMailboxesProcessor {
.toMailboxAcl(),
mailboxSession);
}
- if (!originMailboxPath.equals(destinationMailboxPath)) {
- mailboxManager.renameMailbox(mailbox.getId(), destinationMailboxPath, mailboxSession);
- subscriptionManager.unsubscribe(mailboxSession, originMailboxPath.getName());
- subscriptionManager.subscribe(mailboxSession, destinationMailboxPath.getName());
+ if (!originMailboxPath.equals(destinationMailboxPath)) {
+ mailboxManager.renameMailbox(mailbox.getId(), destinationMailboxPath, MailboxManager.RenameOption.RENAME_SUBSCRIPTIONS, mailboxSession);
}
}
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetMessagesCreationProcessor.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetMessagesCreationProcessor.java
index a384bd8..9936468 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetMessagesCreationProcessor.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetMessagesCreationProcessor.java
@@ -221,7 +221,7 @@ public class SetMessagesCreationProcessor implements SetMessagesProcessor {
}
private void performCreate(CreationMessageEntry entry, Builder responseBuilder, MailboxSession session)
- throws MailboxException, InvalidMailboxForCreationException, MessagingException, AttachmentsNotFoundException, IOException {
+ throws MailboxException, MessagingException, AttachmentsNotFoundException, IOException {
if (isAppendToMailboxWithRole(Role.OUTBOX, entry.getValue(), session)) {
sendMailViaOutbox(entry, responseBuilder, session);
diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMailboxesUpdateProcessorTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMailboxesUpdateProcessorTest.java
index 34cc705..79859c4 100644
--- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMailboxesUpdateProcessorTest.java
+++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMailboxesUpdateProcessorTest.java
@@ -37,7 +37,6 @@ import org.apache.james.jmap.draft.utils.MailboxUtils;
import org.apache.james.mailbox.MailboxManager;
import org.apache.james.mailbox.MailboxSession;
import org.apache.james.mailbox.MessageManager;
-import org.apache.james.mailbox.SubscriptionManager;
import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.inmemory.InMemoryId;
import org.apache.james.metrics.api.MetricFactory;
@@ -49,7 +48,6 @@ import org.mockito.Mockito;
public class SetMailboxesUpdateProcessorTest {
private MailboxManager mockedMailboxManager;
- private SubscriptionManager mockSubscriptionManager;
private MailboxUtils mockedMailboxUtils;
private MailboxFactory mockedMailboxFactory;
private MailboxSession mockedMailboxSession;
@@ -58,12 +56,11 @@ public class SetMailboxesUpdateProcessorTest {
@Before
public void setup() {
mockedMailboxManager = mock(MailboxManager.class);
- mockSubscriptionManager = mock(SubscriptionManager.class);
mockedMailboxUtils = mock(MailboxUtils.class);
mockedMailboxFactory = mock(MailboxFactory.class);
mockedMailboxSession = mock(MailboxSession.class);
MetricFactory metricFactory = new RecordingMetricFactory();
- sut = new SetMailboxesUpdateProcessor(mockedMailboxUtils, mockedMailboxManager, mockSubscriptionManager, mockedMailboxFactory, metricFactory);
+ sut = new SetMailboxesUpdateProcessor(mockedMailboxUtils, mockedMailboxManager, mockedMailboxFactory, metricFactory);
}
@Test
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org