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 eed9ea5b8cae2c5c74d2cad78f2ade8bd399b069
Author: Benoit Tellier <[email protected]>
AuthorDate: Thu Oct 22 15:01:24 2020 +0700

    JAMES-3410 Optimisation Group destroys together
    
    This enables several enhancements, like grouping mailbox context and access 
checks, grouping quota updates.
---
 .../apache/james/jmap/method/EmailSetMethod.scala  | 48 ++++++++++++++--------
 1 file changed, 30 insertions(+), 18 deletions(-)

diff --git 
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSetMethod.scala
 
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSetMethod.scala
index 8c83e61..1d1b519 100644
--- 
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSetMethod.scala
+++ 
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSetMethod.scala
@@ -81,13 +81,13 @@ class EmailSetMethod @Inject()(serializer: 
EmailSetSerializer,
   }
 
   object DestroyResult {
-    def from(deleteResult: DeleteResult): DestroyResult = {
-      val notFound = deleteResult.getNotFound.asScala
-
-      deleteResult.getDestroyed.asScala
-        .headOption
+    def from(deleteResult: DeleteResult): Seq[DestroyResult] = {
+      val success: Seq[DestroySuccess] = 
deleteResult.getDestroyed.asScala.toSeq
         .map(DestroySuccess)
-        .getOrElse(DestroyFailure(EmailSet.asUnparsed(notFound.head), 
MessageNotFoundExeception(notFound.head)))
+      val notFound: Seq[DestroyResult] = deleteResult.getNotFound.asScala.toSeq
+          .map(id => DestroyFailure(EmailSet.asUnparsed(id), 
MessageNotFoundExeception(id)))
+
+      success ++ notFound
     }
   }
 
@@ -163,11 +163,30 @@ class EmailSetMethod @Inject()(serializer: 
EmailSetSerializer,
       case errors: JsError => SMono.raiseError(new 
IllegalArgumentException(ResponseSerializer.serialize(errors).toString))
     }
 
-  private def destroy(emailSetRequest: EmailSetRequest, mailboxSession: 
MailboxSession): SMono[DestroyResults] =
-    
SFlux.fromIterable(emailSetRequest.destroy.getOrElse(DestroyIds(Seq())).value)
-      .flatMap(id => deleteMessage(id, mailboxSession))
-      .collectSeq()
-      .map(DestroyResults)
+  private def destroy(emailSetRequest: EmailSetRequest, mailboxSession: 
MailboxSession): SMono[DestroyResults] = {
+    if (emailSetRequest.destroy.isDefined) {
+      val messageIdsValidation: Seq[Either[DestroyFailure, MessageId]] = 
emailSetRequest.destroy.get.value
+        .map(unparsedId => 
EmailSet.parse(messageIdFactory)(unparsedId).toEither
+          .left.map(e => DestroyFailure(unparsedId, e)))
+      val messageIds: Seq[MessageId] = messageIdsValidation.flatMap {
+        case Right(messageId) => Some(messageId)
+        case _ => None
+      }
+      val parsingErrors: Seq[DestroyFailure] = messageIdsValidation.flatMap {
+        case Left(e) => Some(e)
+        case _ => None
+      }
+
+      SMono.fromCallable(() => 
messageIdManager.delete(messageIds.toList.asJava, mailboxSession))
+        .map(DestroyResult.from)
+        .subscribeOn(Schedulers.elastic())
+        .onErrorResume(e => SMono.just(messageIds.map(id => 
DestroyFailure(EmailSet.asUnparsed(id), e))))
+        .map(_ ++ parsingErrors)
+        .map(DestroyResults)
+    } else {
+      SMono.just(DestroyResults(Seq()))
+    }
+  }
 
   private def update(emailSetRequest: EmailSetRequest, mailboxSession: 
MailboxSession): SMono[UpdateResults] = {
     emailSetRequest.update
@@ -341,11 +360,4 @@ class EmailSetMethod @Inject()(serializer: 
EmailSetSerializer,
         .`then`(SMono.just[UpdateResult](UpdateSuccess(messageId)))
     }
   }
-
-  private def deleteMessage(destroyId: UnparsedMessageId, mailboxSession: 
MailboxSession): SMono[DestroyResult] =
-    EmailSet.parse(messageIdFactory)(destroyId)
-      .fold(e => SMono.just(DestroyFailure(destroyId, e)),
-        parsedId => SMono.fromCallable(() => 
DestroyResult.from(messageIdManager.delete(parsedId, mailboxSession)))
-          .subscribeOn(Schedulers.elastic)
-          .onErrorRecover(e => DestroyFailure(EmailSet.asUnparsed(parsedId), 
e)))
 }
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to