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
The following commit(s) were added to refs/heads/master by this push:
new 1f2f818c23 JAMES-4096 Rename INBOX (#2549)
1f2f818c23 is described below
commit 1f2f818c23b7ce0b676c582d8e355aabcae6978c
Author: hungphan227 <[email protected]>
AuthorDate: Fri Dec 6 23:49:39 2024 +0700
JAMES-4096 Rename INBOX (#2549)
Co-authored-by: hung phan <[email protected]>
---
.../james/mailbox/store/StoreMailboxManager.java | 41 ++--
.../apache/james/mpt/imapmailbox/suite/Rename.java | 6 +
.../org/apache/james/imap/scripts/RenameInbox.test | 75 ++++++
.../contract/MailboxSetMethodContract.scala | 269 ++++++++++++++++++++-
.../jmap/method/MailboxSetUpdatePerformer.scala | 71 +++---
5 files changed, 417 insertions(+), 45 deletions(-)
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 86972fbd2a..4eda433a06 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
@@ -37,6 +37,7 @@ import org.apache.james.core.Username;
import org.apache.james.core.quota.QuotaCountUsage;
import org.apache.james.core.quota.QuotaSizeUsage;
import org.apache.james.events.EventBus;
+import org.apache.james.mailbox.DefaultMailboxes;
import org.apache.james.mailbox.MailboxAnnotationManager;
import org.apache.james.mailbox.MailboxManager;
import org.apache.james.mailbox.MailboxPathLocker;
@@ -689,22 +690,7 @@ public class StoreMailboxManager implements MailboxManager
{
resultBuilder.add(new MailboxRenamedResult(mailboxId, from,
newMailboxPath));
return mailboxId;
})
- .then(Mono.from(locker.executeReactiveWithLockReactive(from,
mapper.findMailboxWithPathLike(query)
- .concatMap(sub -> {
- String subOriginalName = sub.getName();
- String subNewName = newMailboxPath.getName() +
subOriginalName.substring(from.getName().length());
- MailboxPath fromPath = new MailboxPath(from,
subOriginalName);
- sub.setName(subNewName);
- sub.setUser(toSession.getUser());
- return mapper.rename(sub)
- .map(mailboxId -> {
- resultBuilder.add(new
MailboxRenamedResult(sub.getMailboxId(), fromPath,
sub.generateAssociatedPath()));
- return mailboxId;
- })
- .retryWhen(Retry.backoff(5, Duration.ofMillis(10)))
- .then(Mono.fromRunnable(() -> LOGGER.debug("Rename
mailbox sub-mailbox {} to {}", subOriginalName, subNewName)));
- }, LOW_CONCURRENCY)
- .then(), MailboxPathLocker.LockType.Write)))
+ .then(Mono.from(renameSubMailboxes(newMailboxPath, toSession,
mapper, from, query, resultBuilder)))
.then(Mono.defer(() -> Flux.fromIterable(resultBuilder.build())
.concatMap(result ->
eventBus.dispatch(EventFactory.mailboxRenamed()
.randomEventId()
@@ -718,6 +704,29 @@ public class StoreMailboxManager implements MailboxManager
{
.then(Mono.fromCallable(resultBuilder::build));
}
+ private Publisher<Void> renameSubMailboxes(MailboxPath newMailboxPath,
MailboxSession toSession, MailboxMapper mapper,
+ MailboxPath from,
MailboxQuery.UserBound query, ImmutableList.Builder<MailboxRenamedResult>
resultBuilder) {
+ if (DefaultMailboxes.INBOX.equalsIgnoreCase(from.getName())) {
+ return Mono.empty();
+ }
+ return locker.executeReactiveWithLockReactive(from,
mapper.findMailboxWithPathLike(query)
+ .concatMap(sub -> {
+ String subOriginalName = sub.getName();
+ String subNewName = newMailboxPath.getName() +
subOriginalName.substring(from.getName().length());
+ MailboxPath fromPath = new MailboxPath(from, subOriginalName);
+ sub.setName(subNewName);
+ sub.setUser(toSession.getUser());
+ return mapper.rename(sub)
+ .map(mailboxId -> {
+ resultBuilder.add(new
MailboxRenamedResult(sub.getMailboxId(), fromPath,
sub.generateAssociatedPath()));
+ return mailboxId;
+ })
+ .retryWhen(Retry.backoff(5, Duration.ofMillis(10)))
+ .then(Mono.fromRunnable(() -> LOGGER.debug("Rename mailbox
sub-mailbox {} to {}", subOriginalName, subNewName)));
+ }, LOW_CONCURRENCY)
+ .then(), MailboxPathLocker.LockType.Write);
+ }
+
@Override
public List<MessageRange> copyMessages(MessageRange set, MailboxPath from,
MailboxPath to, MailboxSession session) throws MailboxException {
return MailboxReactorUtils.block(copyMessagesReactive(set, from, to,
session).collectList());
diff --git
a/mpt/impl/imap-mailbox/core/src/main/java/org/apache/james/mpt/imapmailbox/suite/Rename.java
b/mpt/impl/imap-mailbox/core/src/main/java/org/apache/james/mpt/imapmailbox/suite/Rename.java
index 6ab8d07750..e912e604a5 100644
---
a/mpt/impl/imap-mailbox/core/src/main/java/org/apache/james/mpt/imapmailbox/suite/Rename.java
+++
b/mpt/impl/imap-mailbox/core/src/main/java/org/apache/james/mpt/imapmailbox/suite/Rename.java
@@ -108,4 +108,10 @@ public abstract class Rename implements ImapTestConstants {
.withLocale(Locale.KOREA)
.run("RenameSelected");
}
+
+ @Test
+ public void testRenameInbox() throws Exception {
+ simpleScriptedTestProtocol
+ .run("RenameInbox");
+ }
}
diff --git
a/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/RenameInbox.test
b/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/RenameInbox.test
new file mode 100644
index 0000000000..50e7998144
--- /dev/null
+++
b/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/RenameInbox.test
@@ -0,0 +1,75 @@
+################################################################
+# 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. #
+################################################################
+
+C: A0 APPEND INBOX {185+}
+C: From: Timothy Tayler <[email protected]>
+C: To: Samual Smith <[email protected]>
+C: Date: Thu, 14 Feb 2008 12:00:00 +0000 (GMT)
+C: Subject: A Simple Email
+C:
+C: This is a very simple email.
+C:
+S: A0 OK (\[.+\] )?APPEND completed\.
+
+C: A1 CREATE INBOX.child
+S: A1 OK \[MAILBOXID \(.+\)\] CREATE completed\.
+
+C: A2 RENAME INBOX testmailbox
+S: A2 OK RENAME completed\.
+
+C: A3 SELECT testmailbox
+S: \* OK \[MAILBOXID \(.+\)\] Ok
+S: \* FLAGS \(\\Answered \\Deleted \\Draft \\Flagged \\Seen\)
+S: \* 1 EXISTS
+S: \* 1 RECENT
+S: \* OK \[UIDVALIDITY \d+\].*
+S: \* OK \[UNSEEN 1].*
+S: \* OK \[PERMANENTFLAGS \(\\Answered \\Deleted \\Draft \\Flagged \\\Seen(
\\\*)?\)\].*
+S: \* OK \[HIGHESTMODSEQ \d+\].*
+S: \* OK \[UIDNEXT 2\].*
+S: A3 OK \[READ-WRITE\] SELECT completed\.
+
+C: A4 SELECT INBOX
+S: \* OK \[MAILBOXID \(.+\)\] Ok
+S: \* FLAGS \(\\Answered \\Deleted \\Draft \\Flagged \\Seen\)
+S: \* 0 EXISTS
+S: \* 0 RECENT
+S: \* OK \[UIDVALIDITY \d+\].*
+S: \* OK \[PERMANENTFLAGS \(\\Answered \\Deleted \\Draft \\Flagged \\\Seen(
\\\*)?\)\].*
+S: \* OK \[HIGHESTMODSEQ \d+\].*
+S: \* OK \[UIDNEXT 1\].*
+S: A4 OK \[READ-WRITE\] SELECT completed\.
+
+C: A5 SELECT INBOX.child
+S: \* OK \[MAILBOXID \(.+\)\] Ok
+S: \* FLAGS \(\\Answered \\Deleted \\Draft \\Flagged \\Seen\)
+S: \* 0 EXISTS
+S: \* 0 RECENT
+S: \* OK \[UIDVALIDITY \d+\].*
+S: \* OK \[PERMANENTFLAGS \(\\Answered \\Deleted \\Draft \\Flagged \\\Seen(
\\\*)?\)\].*
+S: \* OK \[HIGHESTMODSEQ \d+\].*
+S: \* OK \[UIDNEXT 1\].*
+S: A5 OK \[READ-WRITE\] SELECT completed\.
+
+C: A6 LIST "" "*"
+S: \* LIST \(\\HasChildren\) "\." "INBOX"
+S: \* LIST \(\\HasNoChildren\) "\." "INBOX\.child"
+S: \* LIST \(\\HasNoChildren\) "\." "selected"
+S: \* LIST \(\\HasNoChildren\) "\." "testmailbox"
+S: A6 OK LIST completed\.
diff --git
a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/MailboxSetMethodContract.scala
b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/MailboxSetMethodContract.scala
index f6d96190c9..9263595755 100644
---
a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/MailboxSetMethodContract.scala
+++
b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/MailboxSetMethodContract.scala
@@ -37,9 +37,10 @@ import org.apache.james.jmap.http.UserCredential
import
org.apache.james.jmap.rfc8621.contract.Fixture.{ACCEPT_RFC8621_VERSION_HEADER,
ACCOUNT_ID, ANDRE, BOB, BOB_PASSWORD, CEDRIC, DAVID, DOMAIN, authScheme,
baseRequestSpecBuilder}
import org.apache.james.jmap.rfc8621.contract.tags.CategoryTags
import org.apache.james.jmap.{JmapGuiceProbe, MessageIdProbe}
+import org.apache.james.mailbox.DefaultMailboxes
import org.apache.james.mailbox.MessageManager.AppendCommand
import org.apache.james.mailbox.model.MailboxACL.{EntryKey, Right}
-import org.apache.james.mailbox.model.{MailboxACL, MailboxId, MailboxPath}
+import org.apache.james.mailbox.model.{MailboxACL, MailboxConstants,
MailboxId, MailboxPath}
import org.apache.james.mime4j.dom.Message
import org.apache.james.modules.{ACLProbeImpl, MailboxProbeImpl}
import org.apache.james.util.concurrency.ConcurrentTestRunner
@@ -3802,7 +3803,7 @@ trait MailboxSetMethodContract {
@Test
def updateShouldNotRenameSystemMailboxes(server: GuiceJamesServer): Unit = {
val mailboxId: MailboxId = server.getProbe(classOf[MailboxProbeImpl])
- .createMailbox(MailboxPath.forUser(BOB, "INBOX"))
+ .createMailbox(MailboxPath.forUser(BOB, DefaultMailboxes.DRAFTS))
val request =
s"""
|{
@@ -3854,6 +3855,270 @@ trait MailboxSetMethodContract {
|}""".stripMargin)
}
+ @Test
+ def updateShouldRenameInbox(server: GuiceJamesServer): Unit = {
+ val bobPath = MailboxPath.inbox(BOB)
+ val mailboxId: MailboxId =
server.getProbe(classOf[MailboxProbeImpl]).createMailbox(bobPath)
+ server.getProbe(classOf[MailboxProbeImpl]).appendMessage(BOB.asString(),
bobPath,
+
AppendCommand.from(Message.Builder.of.setSubject("test").setBody("testmail",
StandardCharsets.UTF_8).build))
+
+ val request =
+ s"""
+ |{
+ | "using": [ "urn:ietf:params:jmap:core",
"urn:ietf:params:jmap:mail" ],
+ | "methodCalls": [
+ | ["Mailbox/set",
+ | {
+ | "accountId":
"29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6",
+ | "update": {
+ | "${mailboxId.serialize}" : {
+ | "name": "newName"
+ | }
+ | }
+ | },
+ | "c2"],
+ | ["Mailbox/get",
+ | {
+ | "accountId":
"29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6",
+ | "properties": ["id", "name", "totalEmails"],
+ | "ids": ["${mailboxId.serialize}"]
+ | },
+ | "c2"]
+ | ]
+ |}
+ |""".stripMargin
+
+ val response = `given`
+ .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER)
+ .body(request)
+ .when
+ .post
+ .`then`
+ .log().ifValidationFails()
+ .statusCode(SC_OK)
+ .contentType(JSON)
+ .extract
+ .body
+ .asString
+
+ assertThatJson(response)
+ .whenIgnoringPaths("methodResponses[1][1].state",
"methodResponses[0][1].newState", "methodResponses[0][1].oldState")
+ .isEqualTo(
+ s"""{
+ | "sessionState": "${SESSION_STATE.value}",
+ | "methodResponses": [
+ | ["Mailbox/set", {
+ | "accountId":
"29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6",
+ | "updated": {
+ | "${mailboxId.serialize}": {}
+ | }
+ | }, "c2"],
+ | ["Mailbox/get", {
+ | "accountId":
"29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6",
+ | "state": "${INSTANCE.value}",
+ | "list": [{
+ | "id": "${mailboxId.serialize}",
+ | "name": "newName",
+ | "totalEmails": 1
+ | }],
+ | "notFound": []
+ | }, "c2"]
+ | ]
+ |}""".stripMargin)
+ }
+
+ @Test
+ def renameInboxShouldCreateNewInbox(server: GuiceJamesServer): Unit = {
+ val bobPath = MailboxPath.inbox(BOB)
+ val mailboxId: MailboxId =
server.getProbe(classOf[MailboxProbeImpl]).createMailbox(bobPath)
+ server.getProbe(classOf[MailboxProbeImpl]).appendMessage(BOB.asString(),
bobPath,
+
AppendCommand.from(Message.Builder.of.setSubject("test").setBody("testmail",
StandardCharsets.UTF_8).build))
+
+ val request =
+ s"""
+ |{
+ | "using": [ "urn:ietf:params:jmap:core",
"urn:ietf:params:jmap:mail" ],
+ | "methodCalls": [
+ | ["Mailbox/set",
+ | {
+ | "accountId":
"29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6",
+ | "update": {
+ | "${mailboxId.serialize}" : {
+ | "name": "newName"
+ | }
+ | }
+ | },
+ | "c2"],
+ | ["Mailbox/get",
+ | {
+ | "accountId":
"29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6",
+ | "properties": ["id", "name"],
+ | "ids": ["${mailboxId.serialize}"]
+ | },
+ | "c2"]
+ | ]
+ |}
+ |""".stripMargin
+
+ `given`
+ .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER)
+ .body(request)
+ .when
+ .post
+ .`then`
+ .log().ifValidationFails()
+ .statusCode(SC_OK)
+ .contentType(JSON)
+ .extract
+ .body
+ .asString
+
+ val newInboxId: MailboxId =
server.getProbe(classOf[MailboxProbeImpl]).getMailboxId("#private",
BOB.asString(), MailboxConstants.INBOX)
+
+ val request2 =
+ s"""
+ |{
+ | "using": [ "urn:ietf:params:jmap:core",
"urn:ietf:params:jmap:mail" ],
+ | "methodCalls": [
+ | ["Mailbox/get",
+ | {
+ | "accountId":
"29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6",
+ | "properties": ["id", "name", "totalEmails"],
+ | "ids": ["${newInboxId.serialize}"]
+ | },
+ | "c2"]
+ | ]
+ |}
+ |""".stripMargin
+
+ val response2 = `given`
+ .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER)
+ .body(request2)
+ .when
+ .post
+ .`then`
+ .log().ifValidationFails()
+ .statusCode(SC_OK)
+ .contentType(JSON)
+ .extract
+ .body
+ .asString
+
+ assertThatJson(response2)
+ .whenIgnoringPaths("methodResponses[0][1].state",
"methodResponses[0][1].newState", "methodResponses[0][1].oldState")
+ .isEqualTo(
+ s"""{
+ | "sessionState": "${SESSION_STATE.value}",
+ | "methodResponses": [
+ | ["Mailbox/get", {
+ | "accountId":
"29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6",
+ | "state": "${INSTANCE.value}",
+ | "list": [{
+ | "id": "${newInboxId.serialize}",
+ | "name": "INBOX",
+ | "totalEmails": 0
+ | }],
+ | "notFound": []
+ | }, "c2"]
+ | ]
+ |}""".stripMargin)
+ }
+
+ @Test
+ def renameInboxShouldNotAffectSubMailboxes(server: GuiceJamesServer): Unit =
{
+ val mailboxId: MailboxId =
server.getProbe(classOf[MailboxProbeImpl]).createMailbox(MailboxPath.forUser(BOB,
"INBOX"))
+ val subInboxId: MailboxId =
server.getProbe(classOf[MailboxProbeImpl]).createMailbox(MailboxPath.forUser(BOB,
"INBOX.subInbox"))
+
+ val request =
+ s"""
+ |{
+ | "using": [ "urn:ietf:params:jmap:core",
"urn:ietf:params:jmap:mail" ],
+ | "methodCalls": [
+ | ["Mailbox/set",
+ | {
+ | "accountId":
"29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6",
+ | "update": {
+ | "${mailboxId.serialize}" : {
+ | "name": "newName"
+ | }
+ | }
+ | },
+ | "c2"],
+ | ["Mailbox/get",
+ | {
+ | "accountId":
"29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6",
+ | "properties": ["id", "name"],
+ | "ids": ["${mailboxId.serialize}"]
+ | },
+ | "c2"]
+ | ]
+ |}
+ |""".stripMargin
+
+ `given`
+ .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER)
+ .body(request)
+ .when
+ .post
+ .`then`
+ .log().ifValidationFails()
+ .statusCode(SC_OK)
+ .contentType(JSON)
+ .extract
+ .body
+ .asString
+
+ val newInboxId: MailboxId =
server.getProbe(classOf[MailboxProbeImpl]).getMailboxId("#private",
BOB.asString(), MailboxConstants.INBOX)
+
+ val request2 =
+ s"""
+ |{
+ | "using": [ "urn:ietf:params:jmap:core",
"urn:ietf:params:jmap:mail" ],
+ | "methodCalls": [
+ | ["Mailbox/get",
+ | {
+ | "accountId":
"29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6",
+ | "properties": ["id", "name", "parentId"],
+ | "ids": ["${subInboxId.serialize}"]
+ | },
+ | "c2"]
+ | ]
+ |}
+ |""".stripMargin
+
+ val response2 = `given`
+ .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER)
+ .body(request2)
+ .when
+ .post
+ .`then`
+ .log().ifValidationFails()
+ .statusCode(SC_OK)
+ .contentType(JSON)
+ .extract
+ .body
+ .asString
+
+ assertThatJson(response2)
+ .whenIgnoringPaths("methodResponses[0][1].state",
"methodResponses[0][1].newState", "methodResponses[0][1].oldState")
+ .isEqualTo(
+ s"""{
+ | "sessionState": "${SESSION_STATE.value}",
+ | "methodResponses": [
+ | ["Mailbox/get", {
+ | "accountId":
"29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6",
+ | "state": "${INSTANCE.value}",
+ | "list": [{
+ | "id": "${subInboxId.serialize}",
+ | "name": "subInbox",
+ | "parentId": "${newInboxId.serialize}"
+ | }],
+ | "notFound": []
+ | }, "c2"]
+ | ]
+ |}""".stripMargin)
+ }
+
@Test
def destroyShouldNotRemoveSystemMailboxes(server: GuiceJamesServer): Unit = {
val mailboxId: MailboxId = server.getProbe(classOf[MailboxProbeImpl])
diff --git
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetUpdatePerformer.scala
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetUpdatePerformer.scala
index 615d96b193..7824aff7d2 100644
---
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetUpdatePerformer.scala
+++
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetUpdatePerformer.scala
@@ -32,7 +32,7 @@ import
org.apache.james.mailbox.MailboxManager.{MailboxSearchFetchType, RenameOp
import org.apache.james.mailbox.exception.{DifferentDomainException,
InsufficientRightsException, MailboxExistsException, MailboxNameException,
MailboxNotFoundException}
import org.apache.james.mailbox.model.search.{MailboxQuery, PrefixedWildcard}
import org.apache.james.mailbox.model.{MailboxId, MailboxPath}
-import org.apache.james.mailbox.{MailboxManager, MailboxSession,
MessageManager, Role, SubscriptionManager}
+import org.apache.james.mailbox.{DefaultMailboxes, MailboxManager,
MailboxSession, MessageManager, Role, SubscriptionManager}
import org.apache.james.util.{AuditTrail, ReactorUtils}
import org.slf4j.LoggerFactory
import reactor.core.scala.publisher.{SFlux, SMono}
@@ -164,31 +164,33 @@ class MailboxSetUpdatePerformer @Inject()(serializer:
MailboxSerializer,
validatedPatch: ValidatedMailboxPatchObject,
mailboxSession: MailboxSession):
SMono[MailboxUpdateResult] = {
if (validatedPatch.shouldUpdateMailboxPath) {
- SMono.fromCallable[MailboxUpdateResult](() => {
- try {
- val mailbox = mailboxManager.getMailbox(mailboxId, mailboxSession)
- if (isASystemMailbox(mailbox)) {
- throw SystemMailboxChangeException(mailboxId)
- }
- if
(validatedPatch.parentIdUpdate.flatMap(_.newId).contains(mailboxId)) {
- throw LoopInMailboxGraphException(mailboxId)
- }
- val oldPath = mailbox.getMailboxPath
- val newPath = applyParentIdUpdate(mailboxId,
validatedPatch.parentIdUpdate, mailboxSession)
- .andThen(applyNameUpdate(validatedPatch.nameUpdate,
mailboxSession))
- .apply(oldPath)
- if (!oldPath.equals(newPath)) {
- mailboxManager.renameMailbox(mailboxId,
- newPath,
- RenameOption.RENAME_SUBSCRIPTIONS,
- mailboxSession)
- }
- MailboxUpdateSuccess(mailboxId)
- } catch {
- case e: Exception => MailboxUpdateFailure(unparsedMailboxId, e,
Some(validatedPatch))
- }
- })
- .subscribeOn(ReactorUtils.BLOCKING_CALL_WRAPPER)
+ SMono(mailboxManager.getMailboxReactive(mailboxId, mailboxSession))
+ .flatMap(mailbox =>
+ SMono.fromCallable[MailboxUpdateResult](() => {
+ try {
+ if (isASystemMailbox(mailbox) &&
!DefaultMailboxes.INBOX.equalsIgnoreCase(mailbox.getMailboxPath.getName)) {
+ throw SystemMailboxChangeException(mailboxId)
+ }
+ if
(validatedPatch.parentIdUpdate.flatMap(_.newId).contains(mailboxId)) {
+ throw LoopInMailboxGraphException(mailboxId)
+ }
+ val oldPath = mailbox.getMailboxPath
+ val newPath = applyParentIdUpdate(mailboxId,
validatedPatch.parentIdUpdate, mailboxSession)
+ .andThen(applyNameUpdate(validatedPatch.nameUpdate,
mailboxSession))
+ .apply(oldPath)
+ if (!oldPath.equals(newPath)) {
+ mailboxManager.renameMailbox(mailboxId,
+ newPath,
+ RenameOption.RENAME_SUBSCRIPTIONS,
+ mailboxSession)
+ }
+ MailboxUpdateSuccess(mailboxId)
+ } catch {
+ case e: Exception => MailboxUpdateFailure(unparsedMailboxId, e,
Some(validatedPatch))
+ }
+ }).subscribeOn(ReactorUtils.BLOCKING_CALL_WRAPPER)
+ .flatMap(updateResult =>
createInboxIfNeeded(mailbox.getMailboxPath, mailboxSession)
+ .`then`(SMono.just(updateResult))))
} else {
SMono.just[MailboxUpdateResult](MailboxUpdateSuccess(mailboxId))
}
@@ -269,6 +271,21 @@ class MailboxSetUpdatePerformer @Inject()(serializer:
MailboxSerializer,
}
- private def isASystemMailbox(mailbox: MessageManager): Boolean =
Role.from(mailbox.getMailboxPath.getName).isPresent
+ private def createInboxIfNeeded(existingPath: MailboxPath, session:
MailboxSession): SMono[Unit] = {
+ if (!existingPath.getName.equalsIgnoreCase(DefaultMailboxes.INBOX)) {
+ return SMono.empty
+ }
+ SMono(mailboxManager.mailboxExists(existingPath, session)).flatMap(exists
=> createInbox(exists, existingPath, session))
+ }
+
+ private def createInbox(exists: Boolean, existingPath: MailboxPath, session:
MailboxSession): SMono[Unit] = {
+ if (exists) {
+ return SMono.empty
+ }
+ SMono(mailboxManager.createMailboxReactive(existingPath, session))
+ .`then`()
+ }
+ private def isASystemMailbox(mailbox: MessageManager): Boolean =
+ Role.from(mailbox.getMailboxPath.getName).isPresent
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]